About MCP
MCP is an MCP server published by irzix in the Agents category: the NestJS-native runtime for governed AI agents.
The repository has 62 stars and 6 forks, with the last commit 16 days ago. Recent commit activity is the strongest signal that reported issues will get attention.
Install
git clone https://github.com/irzix/nestjs-agenticThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about MCP
Powered by Claude · Grounded in docs
Security checks
Static checks derived from the repository 9 hours ago. Heuristics on the source, not an audit.
- ✓README presentThe repository ships documentation.
- ✓License declaredUsable under a stated license.
- ✓Tests presentA test suite exists in the repository.
- ✓Dependencies pinnedA lockfile pins dependency versions.
- !No dynamic code executionSource scan found eval or shell execution. Review how tool inputs reach it before granting credentials.
1 check has not been run yet.
Releases
README
Why nestjs-agentic?
Most agent frameworks introduce a separate runtime and application boundary. nestjs-agentic keeps agent-facing capabilities inside the NestJS module and dependency-injection system:
NestJS service
-> @ToolSet and @Tool
-> context-bound ResolvedTool
-> allow / deny / require_approval policy decision
-> RuntimeAdapter
Application services remain ordinary NestJS providers. The model runtime receives governed tool closures rather than direct access to services or application-owned security context.
Current Capabilities
The current release line is 1.6.x. Core primitives, persistence adapters, and durable execution checkpoints are production-intent; higher-order orchestration packages remain experimental while their contracts stabilize.
| Area | Status | Scope |
|---|---|---|
| Agents, tools, and NestJS DI | Available | Decorators, discovery, feature registration, and context-bound tools. |
| Tool governance & HITL | Available | allow, deny, and require_approval before execution; resumes durably via ApprovalStore. Dual control (N-of-M approvals) for high-risk actions. |
| Structured Output | Available | JSON Schema outputSchema per agent or run, with validation, bounded repair retries, and native OpenAI json_schema support. |
| Telemetry-Safe Observability | Available | Observer events carry redacted errors by default, so credentials in provider errors stay out of telemetry. |
| Model Context Protocol (MCP) | Available | @nestjs-agentic/mcp for Stdio and SSE remote tool discovery, authorization, and execution. |
| Built-in runtime & Model Cascading | Available | Loop execution, streaming, budgets, and FrugalGPT confidence-threshold model cascading. |
| OpenAI & Chat-Completions adapter | Available | @nestjs-agentic/openai for OpenAI, Azure, Ollama, vLLM, Groq, and OpenRouter. |
| Cognitive Memory & SOP Playbooks | Available | @nestjs-agentic/memory for Stanford Tri-Factor scoring, SOP playbooks, and reflection. |
| U-Shaped Context Assembler | Available | @nestjs-agentic/rag & @nestjs-agentic/core for Lost-in-the-Middle attention mitigation. |
| Codebase AST & GraphRAG | Available | @nestjs-agentic/rag for AST code splitting, hybrid vector store, and graph traversal. |
| Debiased Evaluation & Trajectory Metrics | Available | @nestjs-agentic/evaluation for MT-Bench position-debiased judge and AgentBench metrics. |
| Retrieval-Quality Metrics | Available | @nestjs-agentic/evaluation for Recall@k, Precision@k, MRR, nDCG, and faithfulness against a RAGPipeline or KnowledgeBase. |
| Jev Decision Gates | Available | @nestjs-agentic/jev for calibrated allow / human review / deny decisions on tool calls and output, via TypeSafe's Jev. |
| Persistence & Durable Checkpoints | Available | In-memory, Redis, and PostgreSQL drivers for Session, State, Approval, and Idempotency. |
| Sub-Agent Orchestration | Available | @nestjs-agentic/orchestration for parallel delegation, bounded concurrency, and refinement. |
See the product roadmap for milestones and production-readiness criteria.
Packages
| Package | Purpose |
|---|---|
nestjs-agentic |
Meta package that re-exports the core framework |
@nestjs-agentic/core |
Agents, tools, policies, approvals, the built-in runtime, and the adapter contracts |
@nestjs-agentic/mcp |
Model Context Protocol (MCP) client transport and tool provider |
@nestjs-agentic/openai |
OpenAI ModelAdapter, also covering Chat Completions compatible endpoints |
@nestjs-agentic/memory |
Stanford Tri-Factor cognitive scoring, procedural SOP playbooks, and experience reflection |
@nestjs-agentic/rag |
Retrieval strategies, vector stores, and knowledge-graph primitives |
@nestjs-agentic/orchestration |
Sub-agent delegation, parallel execution, and refinement loops |
@nestjs-agentic/evaluation |
Metrics, benchmark execution, and reporting |
@nestjs-agentic/jev |
Jev (TypeSafe System One) action gates, output rails, and evaluation judges |
Installation
npm install nestjs-agentic
Connect a model provider:
npm install @nestjs-agentic/openai openai
Optional packages:
npm install @nestjs-agentic/mcp
npm install @nestjs-agentic/memory
npm install @nestjs-agentic/rag @nestjs-agentic/memory
npm install @nestjs-agentic/orchestration
npm install @nestjs-agentic/evaluation
npm install @nestjs-agentic/jev @typesafe-ai/sdk
Supports NestJS 10, 11 and 12. NestJS 12 ships as ESM only, and these packages are CommonJS, so with NestJS 12 use Node 20.19+ or 22.12+, where require() can load ES modules.
Quick Start
The example uses MockModelAdapter, so the full tool-calling loop runs deterministically without an API key. Swap in your own ModelAdapter to talk to a real provider.
1. Define a policy and tool set
import { Injectable } from '@nestjs/common';
import {
AgentContext,
Context,
Param,
PolicyResult,
Tool,
ToolPolicy,
ToolSet,
UsePolicies,
} from 'nestjs-agentic';
@Injectable()
export class RefundLimitPolicy implements ToolPolicy {
async evaluate(
_ctx: AgentContext,
_toolName: string,
args: Record<string, unknown>,
): Promise<PolicyResult> {
return Number(args.amount) > 500
? { decision: 'require_approval', reason: 'Refund exceeds $500.' }
: { decision: 'allow' };
}
}
@ToolSet({ name: 'orders' })
export class OrderTools {
@Tool({ name: 'refundOrder', description: 'Refund an order' })
@UsePolicies(RefundLimitPolicy)
async refundOrder(
@Param('orderId') orderId: string,
@Param('amount', { type: 'number' }) amount: number,
@Context() ctx: AgentContext,
) {
return { orderId, amount, requestedBy: ctx.security.userId };
}
}
2. Define an agent and module
import { Module } from '@nestjs/common';
import {
Agent,
AgentConfig,
AgenticModule,
AgentProvider,
MockModelAdapter,
} from 'nestjs-agentic';
@Agent({ name: 'support', description: 'Handles support requests' })
export class SupportAgent implements AgentProvider {
constructor(private readonly orderTools: OrderTools) {}
define(): AgentConfig {
return {
instructions: 'Help the user while respecting tool policies.',
tools: [this.orderTools],
};
}
}
const model = new MockModelAdapter();
model
.whenAsked('Refund $600 for order #42')
.callTool('refundOrder', { orderId: '42', amount: 600 })
.reply('That refund needs approval before I can complete it.');
@Module({
imports: [
AgenticModule.forRoot({
defaultModel: { provider: 'mock', model: 'deterministic' },
modelAdapter: model,
limits: { maxIterations: 6 },
}),
AgenticModule.forFeature({
agents: [SupportAgent],
toolSets: [OrderTools],
policies: [RefundLimitPolicy],
}),
],
})
export class AppModule {}
AgenticModule.forFeature() registers these classes inside AgenticModule. Keep an agent, its tool sets, and its policies in a single forFeature() call, and export any application services they inject from a @Global() module.
3. Run the agent and handle approval
import { Body, Controller, Param, Post } from '@nestjs/common';
import { AgentRunner, ApprovalService } from 'nestjs-agentic';
@Controller('support')
export class SupportController {
constructor(
private readonly runner: AgentRunner,
private readonly approvals: ApprovalService,
) {}
@Post('chat')
chat(@Body() body: { sessionId: string; message: string }) {
return this.runner.run('support', {
sessionId: body.sessionId,
message: body.message,
context: {
userId: 'user_123',
tenantId: 'acme',
},
});
}
@Post('approve/:id')
approve(@Param('id') id: string) {
return this.approvals.approve(id);
}
@Post('reject/:id')
reject(@Param('id') id: string) {
return this.approvals.reject(id);
}
}
runner.runStream() exposes structured token, tool_start, tool_result, approval_required, and complete events.
Each run is bounded. Pass limits and a signal to cap iterations, tool calls, tokens, and wall-clock time, or to cancel work in flight:
await runner.run('support', {
sessionId,
message,
limits: { maxIterations: 4, maxToolCalls: 8, timeoutMs: 30_000 },
signal: abortController.signal,
});
Built-in Policies
Before execution:
RateLimitPolicy— process-local sliding-window limits by tenant, user, and tool.DistributedRateLimitPolicy— Redis-backed sliding-window limits shared across replicas, reporting when to retry.CostLimitPolicy— numeric allow, approval, and deny thresholds.IdempotencyPolicy— validates and enforces idempotency keys on side-effecting tools.LoggingPolicy— configurable tool-attempt logging with field masking.
On tool output (output rails), before the model sees it:
SecretRedactionPolicy— masks credentials, API tokens, JWTs, private keys, and connection strings.PiiRedactionPolicy— masks email addresses, phone numbers, Luhn-valid card numbers, and US SSNs.PromptInjectionSanitizationPolicy— strips chat-template and role-delimiter injection markers.CanaryDetectionPolicy— blocks calls and outputs that carry system-prompt canary tokens.
For judgment beyond fixed rules, @nestjs-agentic/jev adds calibrated gates that decide between allow, human review, and deny.
These are framework primitives, not replacements for durable audit storage or application authorization.
Connecting a Model
For OpenAI and any Chat Completions compatible endpoint, use the published adapter:
import { AgenticModule } from 'nestjs-agentic';
import { OpenAiModelAdapter } from '@nestjs-agentic/openai';
AgenticModule.forRoot({
defaultModel: { provider: 'openai', model: 'gpt-4o-mini' },
modelAdapter: new OpenAiModelAdapter({ apiKey: process.env.OPENAI_API_KEY }),
});
The same adapter targets local and third-party servers by pointing baseUrl at them, for example http://localhost:11434/v1 for Ollama. See @nestjs-agentic/openai for Azure, reasoning models, and compatibility notes.
For any other provider, implement ModelAdapter directly. It handles only provider communication; the framework owns the loop, validation, policies, budgets, and streaming.
import type { ModelAdapter, ModelRequest, ModelResponse } from 'nestjs-agentic';
export class MyModelAdapter implements ModelAdapter {
async generate(request: ModelRequest): Promise<ModelResponse> {
const completion = await callProvider({
model: request.model.model,
messages: request.messages,
tools: request.tools,
signal: request.signal,
});
return {
content: completion.text,
toolCalls: completion.toolCalls,
usage: completion.usage,
finishReason: completion.toolCalls.length ? 'tool_calls' : 'stop',
};
}
}
The core package does not import external model SDKs. Custom model adapters implement ModelAdapter directly, while the framework manages loop execution, policy enforcement, budgets, and streaming.
Documentation
Runnable examples are available in examples.
Sponsorship & Support
nestjs-agentic is an open-source framework dedicated to production-grade, governed AI agent systems in NestJS. If you or your organization find value in the project, consider supporting ongoing development:
- 💖 Sponsor on GitHub
- ⭐ Star the repository on GitHub
- 🤝 Contribute features, adapters, and improvements
License
README fetched from the repository 9 hours ago. The original is authoritative.