Skip to main content
Glama
Touseef-ahmad

nestjs-langgraph-mcp

NestJS + LangGraph MCP POC

A simple proof-of-concept MCP server built with NestJS, using LangGraph as the orchestration layer for tool execution and agent workflows.

Features

  • NestJS application context (no HTTP server required)

  • MCP server over stdio transport

  • LangGraph StateGraph workflow with nodes:

    • route (model-based tool routing)

    • executeTool (executes selected tool)

    • respond (final answer generation)

  • Model provider switch:

    • OpenAI (@langchain/openai)

    • Ollama local model (@langchain/ollama, default qwen2.5:1.5b)

Related MCP server: SampleMCP

Quick Start

  1. Install dependencies:

npm install
  1. Configure environment:

cp .env.example .env
  1. Build and run:

npm run build
npm start

The MCP server starts on stdio.

Model Selection

Default provider is read from MODEL_PROVIDER.

  • Use OpenAI:

    • MODEL_PROVIDER=openai

    • set OPENAI_API_KEY

    • optional OPENAI_MODEL (default gpt-4o-mini)

  • Use Ollama qwen2.5:1.5b:

    • MODEL_PROVIDER=ollama

    • run Ollama locally and pull model:

ollama pull qwen2.5:1.5b
  • optional OLLAMA_BASE_URL and OLLAMA_MODEL

You can override provider/model per MCP tool call (run_agent).

MCP Tools

  • health: returns server status and default model config

  • run_agent: runs the LangGraph workflow

    • input:

      • prompt (string, required)

      • provider (openai or ollama, optional)

      • model (string, optional)

Example MCP Client Config (Claude Desktop style)

{
  "mcpServers": {
    "nestjs-langgraph": {
      "command": "node",
      "args": ["/absolute/path/to/langraph-mcp/dist/main.js"],
      "env": {
        "MODEL_PROVIDER": "ollama",
        "OLLAMA_BASE_URL": "http://localhost:11434",
        "OLLAMA_MODEL": "qwen2.5:1.5b"
      }
    }
  }
}

LangGraph Demo Suite

This repo includes agents and tools built using proper LangGraph.js patterns:

  • Tools: Defined using tool() from @langchain/core/tools with Zod schemas

  • Agents: Built with createReactAgent or custom StateGraph with MessagesAnnotation

  • Tool Execution: Uses ToolNode and toolsCondition from @langchain/langgraph/prebuilt

  • LLM Binding: Tools bound to LLM via .bindTools(tools)

Demo Capabilities

Demo

Capability

01-reasoning

Basic StateGraph workflow

02-parallel

Parallel tool calls via ToolNode

03-handoffs

Agent-to-agent handoffs via coordinator

04-hitl

Human-in-the-loop approval workflow

05-structured

Structured output with Zod validation

06-tracing

Execution tracing through graph

07-discovery

Tool discovery and registry

08-planning

Multi-step planning loop

09-failure

Error handling and retry

10-local

Local Ollama model integration

Project Layout

demos/
├── demo-runner.ts
├── 01-reasoning.demo.ts
├── 02-parallel.demo.ts
├── 03-handoffs.demo.ts
├── 04-hitl.demo.ts
├── 05-structured-output.demo.ts
├── 06-tracing.demo.ts
├── 07-tool-discovery.demo.ts
├── 08-multi-step-planning.demo.ts
├── 09-failure-handling.demo.ts
├── 10-local-model.demo.ts
└── utils/demo-utils.ts

agents/
├── agent.factory.ts
├── tools.ts
├── coordinator.agent.ts
├── employee.agent.ts
├── analytics.agent.ts
├── reporting.agent.ts
├── approval.agent.ts
└── model.config.ts

Prerequisites

Ensure Ollama is running with a tool-capable model:

# qwen2.5:1.5b supports tool calling (recommended)
ollama pull qwen2.5:1.5b
ollama serve

Note: Models like qwen2.5:1.5b do not support tool calling. Use qwen2.5:1.5b, llama3.1, mistral, or qwen2.5 for full demo functionality.

Run all demos:

npm run demo

Run one demo:

npm run demo:one -- 03

Optional HITL switch for demo 04:

DEMO_REVIEW_DECISION=approved npm run demo:one -- 04

Available Tools

4 tools
healthHealth CheckA

Returns basic server status and default model configuration.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description bears the full burden of disclosure. It states that the tool returns server status and model configuration, which are the key behaviors. It does not specify idempotency, but the absence of parameters and the read-like nature make it relatively transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence with no redundant information. It front-loads the purpose and is appropriately sized for a simple tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (no parameters, no output schema), the description is complete enough to understand its purpose. It could optionally mention that it is safe to call repeatedly, but the current description is adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are no parameters, and schema description coverage is 100%. The description adds no parameter-level meaning beyond the schema, which is acceptable for a parameterless tool. Baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verb 'returns' and clearly identifies the resources: server status and default model configuration. It distinguishes from sibling tools like list_agents, main_agent, and run_agent, which all relate to agents, not server health.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not provide explicit guidance on when to use this tool versus alternatives. However, since sibling tools are unrelated (agent-focused), the usage context is implied: use for server health checks. No exclusions or when-not-to-use are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_agentsList Available AgentsA

Returns information about all available agents and their tools.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden for behavioral disclosure. It only says 'returns information', implying a read operation, but does not disclose any behavioral traits such as authorization requirements, performance characteristics, or whether the data is real-time.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence with no wasted words. It is front-loaded with the core action and resource.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple listing tool with no parameters and no output schema, the description is adequate but lacks details about the return format, potential errors, or availability. Competing completeness would benefit from stating what 'information' includes (e.g., names, descriptions).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so baseline is 4. The description does not need to add parameter-level info, and 'all available agents and their tools' provides sufficient semantics for the no-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('returns') and resource ('information about all available agents and their tools'), distinguishing it from sibling tools like 'health', 'main_agent', and 'run_agent' which are not listing operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. The description only states what it does, with no mention of prerequisites, use cases, or conditions for selecting this over siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

main_agentMain AgentA

The main orchestration agent that can handle any request by leveraging all available tools.

Capabilities:

  • Direct tool execution for queries

  • Employee data: list employees, find by name

  • Analytics: engagement scores, trends, project health, timestamps

  • Reporting: structured report generation

  • Approval: risk assessment and approval workflows

Use this as the primary interface for all requests.

ParametersJSON Schema
NameRequiredDescriptionDefault
promptYesThe user request to process

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It lists capabilities but offers no details on behavioral traits like error handling, delegation logic, or rate limits. The description is adequate but lacks depth.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with bullet points and front-loaded purpose. It is slightly verbose but each sentence adds value; could be tightened but is still effective.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given one parameter, no output schema, and no annotations, the description lists capabilities adequately. However, it could be more complete by clarifying behavioral boundaries or expected outcomes for the 'handle any request' claim.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with one parameter 'prompt' described as 'The user request to process.' The description adds no additional meaning beyond the schema, so a baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool as the main orchestration agent that handles any request by leveraging all available tools, and lists specific capabilities. It distinguishes from siblings like health and list_agents by positioning itself as the primary interface.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states 'Use this as the primary interface for all requests,' giving clear guidance on when to use. However, it does not mention when not to use or refer to alternatives among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_agentRun LangGraph AgentC

Runs a LangGraph-orchestrated NestJS agent with optional provider/model selection.

ParametersJSON Schema
NameRequiredDescriptionDefault
promptYesUser request to process
providerNoModel provider
modelNoModel name override

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavioral traits. It only says 'runs', which implies execution, but does not mention side effects, authentication needs, rate limits, or return behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with no wasted words. It is front-loaded with the core purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an execution tool with no output schema and no annotations, the description is too brief. It does not explain what 'running' entails, what the return value is, or any prerequisites.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters. The description adds minimal extra meaning beyond 'optional provider/model selection', so baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'runs' and the resource 'LangGraph-orchestrated NestJS agent', and mentions optional provider/model selection. However, it does not differentiate from the sibling tool 'main_agent', which may have similar functionality.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool vs siblings like 'main_agent' or when to avoid it. The description only states optional customization but lacks use-case context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv1.0.0
    • First observedhealth
    • First observedlist_agents
    • First observedmain_agent
    • First observedrun_agent

TDQS

B3.1/5.0

Scored across 4 tools

Disambiguation3/5

Health and list_agents are clear, but main_agent and run_agent overlap: both execute agents, with main_agent claiming to handle any request and run_agent offering provider/model selection. This could cause confusion about which to use.

Naming Consistency2/5

Tool names mix conventions: 'health' is a noun, 'list_agents' and 'run_agent' are verb_noun, 'main_agent' is adjective_noun. Verbs are not consistently used, leading to an incoherent pattern.

Tool Count3/5

With only 4 tools, the server feels thin for the advertised capabilities (employee data, analytics, reporting, approval). The count is borderline but not extremely low for an agent-centric design.

Completeness2/5

The server lists numerous capabilities (e.g., list employees, engagement scores) but lacks dedicated tools for them—all are funneled through main_agent. This creates a gap where agents cannot directly perform specific operations.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A transport-agnostic MCP server that integrates multiple AI coding agents (Claude Code, Gemini, and Codex) with built-in tools for command execution, calculations, and streaming capabilities. Supports both STDIO and HTTP transports for flexible deployment.
    2 npm
    1
    MIT
  • A
    license
    D
    quality
    D
    maintenance
    A TypeScript MCP server demo supporting local Stdio and remote Streamable HTTP, demonstrating tool invocation for AI agents.
    2
    MIT
  • F
    license
    B
    quality
    D
    maintenance
    An MCP server with LangGraph agent integration that enables AI agents to use custom tools and external APIs for dice rolling, web search, social content creation, and GitHub access via STDIO transport.
    10
    3
    -