{"id":46102500,"url":"https://github.com/btwld/nest-mcp","last_synced_at":"2026-05-03T05:05:21.017Z","repository":{"id":341438589,"uuid":"1167721029","full_name":"btwld/nest-mcp","owner":"btwld","description":"Build Model Context Protocol (MCP) servers, clients, and gateways using the NestJS ecosystem you already know.","archived":false,"fork":false,"pushed_at":"2026-03-01T20:10:55.000Z","size":704,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-01T20:34:02.805Z","etag":null,"topics":["mcp","mcp-client","mcp-gateway","mcp-server","model-context-protocol","modelcontextprotocol","nestjs"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/btwld.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-26T15:58:07.000Z","updated_at":"2026-03-01T20:21:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/btwld/nest-mcp","commit_stats":null,"previous_names":["btwld/nest-mcp"],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/btwld/nest-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/btwld%2Fnest-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/btwld%2Fnest-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/btwld%2Fnest-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/btwld%2Fnest-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/btwld","download_url":"https://codeload.github.com/btwld/nest-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/btwld%2Fnest-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30069372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T01:03:42.280Z","status":"online","status_checked_at":"2026-03-04T02:00:07.464Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mcp","mcp-client","mcp-gateway","mcp-server","model-context-protocol","modelcontextprotocol","nestjs"],"created_at":"2026-03-01T20:03:18.915Z","updated_at":"2026-03-06T06:05:19.995Z","avatar_url":"https://github.com/btwld.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nest-mcp\n\n[![CI](https://github.com/btwld/nest-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/btwld/nest-mcp/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/@nest-mcp/server.svg?label=npm)](https://www.npmjs.com/package/@nest-mcp/server)\n[![npm downloads](https://img.shields.io/npm/dm/@nest-mcp/server.svg)](https://www.npmjs.com/package/@nest-mcp/server)\n[![License](https://img.shields.io/badge/license-BSD--3--Clause-blue)](https://github.com/btwld/nest-mcp/blob/main/LICENSE)\n[![DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/btwld/nest-mcp)\n\nBuild [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers, clients, and gateways using the NestJS ecosystem you already know: decorators, dependency injection, modules, and guards, without learning a new framework.\n\n## Packages\n\n| Package | Description |\n|---------|-------------|\n| [`@nest-mcp/server`](./packages/server) | Build MCP servers with decorators, auth, resilience, and multi-transport support |\n| [`@nest-mcp/client`](./packages/client) | Connect to and consume MCP servers with typed injection and health checks |\n| [`@nest-mcp/gateway`](./packages/gateway) | Aggregate multiple upstream servers behind one unified MCP endpoint |\n| [`@nest-mcp/common`](./packages/common) | Shared types and utilities (peer dependency) |\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────┐\n│             AI Client (LLM host)            │\n└──────────────────────┬──────────────────────┘\n                       │ MCP (Streamable HTTP / SSE / STDIO)\n          ┌────────────▼────────────┐\n          │   @nest-mcp/gateway     │  ← optional aggregation layer\n          │  (NestJS application)   │\n          └──┬──────────────┬───────┘\n             │              │ upstream MCP connections (@nest-mcp/client)\n  ┌──────────▼──┐    ┌──────▼──────┐\n  │  @nest-mcp/ │    │  @nest-mcp/ │  ← MCP servers built with @nest-mcp/server,\n  │   server A  │    │   server B  │     or any other MCP-compatible server\n  └─────────────┘    └─────────────┘\n```\n\n### @nest-mcp/server — internal architecture\n\n```\n  HTTP / SSE / STDIO\n         │\n         ▼\n  ┌─────────────────────────────────────────────────────────┐\n  │                    Transport Layer                      │\n  │        (StreamableHttpService / SseService /            │\n  │                 StdioService)                           │\n  └──────────────────────┬──────────────────────────────────┘\n                         │ MCP request (tool/resource/prompt)\n                         ▼\n  ┌─────────────────────────────────────────────────────────┐\n  │                  Execution Pipeline                     │\n  │                                                         │\n  │  ContextFactory → McpExecutionContext                   │\n  │         │                                               │\n  │         ▼                                               │\n  │  Auth Guards (@Public / @Scopes / @Roles / @Guards)     │\n  │         │                                               │\n  │         ▼                                               │\n  │  Middleware (@UseMiddleware → McpMiddleware chain)      │\n  │         │                                               │\n  │         ▼                                               │\n  │  Resilience (@RateLimit → @CircuitBreaker → @Retry      │\n  │              → @Timeout)                                │\n  │         │                                               │\n  │         ▼                                               │\n  │  ExecutorService → @Tool / @Resource / @Prompt /        │\n  │                    @ResourceTemplate / @Completion      │\n  └─────────────────────────────────────────────────────────┘\n         │                         │\n         ▼                         ▼\n  ┌─────────────┐         ┌────────────────────┐\n  │  Session /  │         │  Dynamic Builders  │\n  │ Subscription│         │  McpToolBuilder /  │\n  │   / Task    │         │ McpResourceBuilder │\n  │  Managers   │         │  McpPromptBuilder  │\n  └─────────────┘         └────────────────────┘\n```\n\n### @nest-mcp/client — internal architecture\n\n```\n  McpClientModule.forRoot({ connections: [...] })\n         │\n         ▼\n  ┌─────────────────────────────────────────────────────────┐\n  │                  McpClientsService                      │\n  │         (registry of named McpClient instances)         │\n  └──────┬─────────────────────┬────────────────────────────┘\n         │                     │\n         ▼                     ▼\n  ┌─────────────┐      ┌───────────────┐\n  │  McpClient  │      │   McpClient   │   (one per connection)\n  │  \"server-a\" │      │  \"server-b\"   │\n  │             │      │               │\n  │  Transport  │      │   Transport   │\n  │  (SSE /     │      │   (Streamable │\n  │  Streamable │      │    HTTP /     │\n  │  HTTP /     │      │    STDIO)     │\n  │  STDIO)     │      │               │\n  │  + auth     │      │   + reconnect │\n  │  headers    │      │   backoff     │\n  └──────┬──────┘      └───────────────┘\n         │\n         ├── @InjectMcpClient('server-a') → injected into any service\n         │\n         ├── @OnMcpNotification(method) → notification handler registry\n         │\n         └── McpClientHealthIndicator → health check (ping-based)\n```\n\n### @nest-mcp/gateway — internal architecture\n\n```\n  AI Client\n     │ MCP request\n     ▼\n  ┌──────────────────────────────────────────────────────────┐\n  │                   McpGatewayModule                       │\n  │                                                          │\n  │  RouterService (aggregated tool/resource/prompt list)    │\n  │    ├── ToolAggregatorService      prefix: weather_*      │\n  │    ├── ResourceAggregatorService  prefix: weather://...  │\n  │    ├── PromptAggregatorService    prefix: weather_*      │\n  │    └── ResourceTemplateAggregator                        │\n  │                                                          │\n  │  On tool call:                                           │\n  │    PolicyEngineService (allow / deny / require_approval) │\n  │         │                                                │\n  │    RequestTransformService (custom hooks)                │\n  │         │                                                │\n  │    ResponseCacheService (TTL cache check)                │\n  │         │  cache miss                                    │\n  │         ▼                                                │\n  │    UpstreamManagerService ──────────────────────────┐    │\n  │    (resolves prefix → upstream connection)          │    │\n  │         │                                           │    │\n  │    ResponseTransformService (custom hooks)          │    │\n  │         │                                           │    │\n  │    ResponseCacheService (store result)              │    │\n  └─────────────────────────────────────────────────────┼────┘\n                                                        │\n         ┌──────────────────────┬─────────────────────┐ │\n         ▼                      ▼                     ▼ │\n  ┌─────────────┐      ┌──────────────┐      ┌──────────────┐\n  │  Upstream A │      │  Upstream B  │      │  Upstream C  │\n  │  (weather)  │      │  (search)    │      │   (...)      │\n  │  McpClient  │      │  McpClient   │      │  McpClient   │\n  └─────────────┘      └──────────────┘      └──────────────┘\n         ↕ health ping          ↕ health ping\n  HealthCheckerService (periodic ping per upstream)\n  TaskAggregatorService (tasks proxied with upstream prefix)\n```\n\n## Installation\n\n```bash\n# Server — expose tools/resources to AI clients\nnpm install @nest-mcp/server @modelcontextprotocol/sdk zod@^4\n\n# Client — call tools on a remote MCP server\nnpm install @nest-mcp/client @modelcontextprotocol/sdk zod@^4\n\n# Gateway — aggregate multiple servers into one\nnpm install @nest-mcp/gateway @modelcontextprotocol/sdk zod@^4\n```\n\nNestJS peer dependencies (if not already installed):\n\n```bash\nnpm install @nestjs/common @nestjs/core reflect-metadata rxjs\n```\n\n## Quick start\n\n### Server\n\nDefine tools with decorators and register the module:\n\n```typescript\n// tools.service.ts\nimport { Injectable } from '@nestjs/common';\nimport { Tool } from '@nest-mcp/server';\nimport { z } from 'zod';\n\n@Injectable()\nexport class ToolsService {\n  @Tool({\n    name: 'greet',\n    description: 'Greet a user by name',\n    schema: z.object({ name: z.string() }),\n  })\n  async greet({ name }: { name: string }) {\n    return `Hello, ${name}!`;\n  }\n}\n```\n\n```typescript\n// app.module.ts\nimport { Module } from '@nestjs/common';\nimport { McpModule, McpTransportType } from '@nest-mcp/server';\nimport { ToolsService } from './tools.service';\n\n@Module({\n  imports: [\n    McpModule.forRoot({\n      name: 'my-server',\n      version: '1.0.0',\n      transports: [{ type: McpTransportType.STREAMABLE_HTTP }],\n    }),\n  ],\n  providers: [ToolsService],\n})\nexport class AppModule {}\n```\n\n### Client\n\nConnect to a server and inject the client:\n\n```typescript\n// app.module.ts\nimport { Module } from '@nestjs/common';\nimport { McpClientModule, McpTransportType } from '@nest-mcp/client';\n\n@Module({\n  imports: [\n    McpClientModule.forRoot({\n      connections: [\n        {\n          name: 'my-server',\n          transport: {\n            type: McpTransportType.STREAMABLE_HTTP,\n            url: 'http://localhost:3000/mcp',\n          },\n        },\n      ],\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n```typescript\n// my.service.ts\nimport { Injectable } from '@nestjs/common';\nimport { InjectMcpClient, McpClient } from '@nest-mcp/client';\n\n@Injectable()\nexport class MyService {\n  constructor(@InjectMcpClient('my-server') private client: McpClient) {}\n\n  async greet(name: string) {\n    return this.client.callTool({ name: 'greet', arguments: { name } });\n  }\n}\n```\n\n### Gateway\n\nAggregate two upstream servers behind one endpoint:\n\n```typescript\n// app.module.ts\nimport { Module } from '@nestjs/common';\nimport { McpGatewayModule, McpTransportType } from '@nest-mcp/gateway';\n\n@Module({\n  imports: [\n    McpGatewayModule.forRoot({\n      name: 'my-gateway',\n      version: '1.0.0',\n      upstreams: [\n        {\n          name: 'weather',\n          transport: { type: McpTransportType.STREAMABLE_HTTP, url: 'http://weather-service/mcp' },\n        },\n        {\n          name: 'search',\n          transport: { type: McpTransportType.STREAMABLE_HTTP, url: 'http://search-service/mcp' },\n        },\n      ],\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\nTools from upstream servers are exposed with a prefix (`weather_forecast`, `search_query`). Downstream clients see one unified server.\n\n## Documentation\n\nFull documentation lives in the [`docs/`](./docs/index.md) folder.\n\n| Section | Description |\n|---------|-------------|\n| [Server docs](./docs/server/README.md) | Decorators, auth, resilience, transports, sessions, testing |\n| [Client docs](./docs/client/README.md) | Connections, injection, notifications, health, OAuth |\n| [Gateway docs](./docs/gateway/README.md) | Upstreams, routing, policies, caching, transforms, tasks |\n\n## Examples\n\nWorking examples live in the [`apps/`](./apps/) directory:\n\n| App | Description |\n|-----|-------------|\n| `example-sse-server` | MCP server using SSE transport |\n| `example-client` | NestJS client consuming a remote MCP server |\n| `example-gateway` | Gateway aggregating multiple upstream servers |\n| `example-stdio` | MCP server using STDIO transport |\n| `example-browser-mcp` | Browser-based MCP integration |\n| `example-postgres-mcp` | MCP server exposing PostgreSQL tools |\n\n## Development\n\nThis is a pnpm monorepo managed with Turborepo.\n\n```bash\n# Install dependencies\npnpm install\n\n# Build all packages\npnpm build\n\n# Run all tests\npnpm test\n\n# Lint\npnpm lint\n\n# Type check\npnpm typecheck\n```\n\n**Requirements:** Node.js \u003e= 20, pnpm \u003e= 9.\n\n## Contributing\n\n1. Fork the repository and create a branch from `main`\n2. Make your changes with tests\n3. Run `pnpm test` and `pnpm lint` to verify\n4. Open a pull request\n\nChanges to published packages require a [changeset](https://github.com/changesets/changesets):\n\n```bash\npnpm changeset\n```\n\n## License\n\nBSD-3-Clause\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbtwld%2Fnest-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbtwld%2Fnest-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbtwld%2Fnest-mcp/lists"}