@mcp-weave/nestjs 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,287 @@
1
+ # @mcp-weave/nestjs
2
+
3
+ NestJS-style decorators for building Model Context Protocol (MCP) servers with TypeScript.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @mcp-weave/nestjs reflect-metadata
9
+ # or
10
+ pnpm add @mcp-weave/nestjs reflect-metadata
11
+ ```
12
+
13
+ **Important:** Enable decorators in your `tsconfig.json`:
14
+
15
+ ```json
16
+ {
17
+ "compilerOptions": {
18
+ "experimentalDecorators": true,
19
+ "emitDecoratorMetadata": true
20
+ }
21
+ }
22
+ ```
23
+
24
+ ## Features
25
+
26
+ - **Class Decorators** - `@McpServer` to define MCP servers
27
+ - **Method Decorators** - `@McpTool`, `@McpResource`, `@McpPrompt`
28
+ - **Parameter Decorators** - `@McpInput`, `@McpParam`, `@McpPromptArg`
29
+ - **Runtime Server** - Start MCP servers from decorated classes
30
+ - **Multiple Transports** - Stdio (default) and SSE (Server-Sent Events)
31
+
32
+ ## Quick Start
33
+
34
+ ```typescript
35
+ import 'reflect-metadata';
36
+ import {
37
+ McpServer,
38
+ McpTool,
39
+ McpResource,
40
+ McpPrompt,
41
+ McpInput,
42
+ McpParam,
43
+ McpPromptArg,
44
+ createMcpServer,
45
+ } from '@mcp-weave/nestjs';
46
+
47
+ @McpServer({
48
+ name: 'my-server',
49
+ version: '1.0.0',
50
+ description: 'My MCP server',
51
+ })
52
+ class MyServer {
53
+ @McpTool({
54
+ name: 'greet',
55
+ description: 'Greets a user',
56
+ inputSchema: {
57
+ type: 'object',
58
+ properties: {
59
+ name: { type: 'string', description: 'Name to greet' },
60
+ },
61
+ required: ['name'],
62
+ },
63
+ })
64
+ greet(@McpInput() input: { name: string }) {
65
+ return `Hello, ${input.name}!`;
66
+ }
67
+
68
+ @McpResource({
69
+ uri: 'config://settings',
70
+ name: 'Settings',
71
+ description: 'Application settings',
72
+ })
73
+ getSettings() {
74
+ return {
75
+ contents: [
76
+ {
77
+ uri: 'config://settings',
78
+ mimeType: 'application/json',
79
+ text: JSON.stringify({ theme: 'dark' }),
80
+ },
81
+ ],
82
+ };
83
+ }
84
+
85
+ @McpPrompt({
86
+ name: 'welcome',
87
+ description: 'Welcome message prompt',
88
+ arguments: [{ name: 'username', description: 'User name', required: true }],
89
+ })
90
+ welcomePrompt(@McpPromptArg('username') username: string) {
91
+ return {
92
+ messages: [
93
+ {
94
+ role: 'user',
95
+ content: { type: 'text', text: `Welcome ${username} to our service!` },
96
+ },
97
+ ],
98
+ };
99
+ }
100
+ }
101
+
102
+ // Start the server
103
+ createMcpServer(MyServer);
104
+ ```
105
+
106
+ ## Decorators
107
+
108
+ ### @McpServer
109
+
110
+ Marks a class as an MCP server.
111
+
112
+ ```typescript
113
+ @McpServer({
114
+ name: 'server-name',
115
+ version: '1.0.0',
116
+ description: 'Optional description',
117
+ })
118
+ class MyServer {}
119
+ ```
120
+
121
+ ### @McpTool
122
+
123
+ Defines an MCP tool (callable function).
124
+
125
+ ```typescript
126
+ @McpTool({
127
+ name: 'tool_name',
128
+ description: 'What the tool does',
129
+ inputSchema: {
130
+ type: 'object',
131
+ properties: {
132
+ param1: { type: 'string' },
133
+ param2: { type: 'number' },
134
+ },
135
+ required: ['param1'],
136
+ },
137
+ })
138
+ myTool(@McpInput() input: ToolInput) {
139
+ return result;
140
+ }
141
+ ```
142
+
143
+ ### @McpResource
144
+
145
+ Defines an MCP resource (readable data).
146
+
147
+ ```typescript
148
+ @McpResource({
149
+ uri: 'resource://path/{id}',
150
+ name: 'Resource Name',
151
+ description: 'Resource description',
152
+ mimeType: 'application/json',
153
+ })
154
+ getResource(@McpParam('id') id: string) {
155
+ return {
156
+ contents: [{ uri: `resource://path/${id}`, text: 'content' }],
157
+ };
158
+ }
159
+ ```
160
+
161
+ ### @McpPrompt
162
+
163
+ Defines an MCP prompt template.
164
+
165
+ ```typescript
166
+ @McpPrompt({
167
+ name: 'prompt_name',
168
+ description: 'Prompt description',
169
+ arguments: [
170
+ { name: 'arg1', description: 'Argument 1', required: true },
171
+ { name: 'arg2', description: 'Argument 2', required: false },
172
+ ],
173
+ })
174
+ myPrompt(
175
+ @McpPromptArg('arg1') arg1: string,
176
+ @McpPromptArg('arg2') arg2?: string
177
+ ) {
178
+ return {
179
+ messages: [{ role: 'user', content: { type: 'text', text: `...` } }],
180
+ };
181
+ }
182
+ ```
183
+
184
+ ## Parameter Decorators
185
+
186
+ | Decorator | Use Case |
187
+ | --------------------- | ---------------------- |
188
+ | `@McpInput()` | Tool input object |
189
+ | `@McpParam(name)` | Resource URI parameter |
190
+ | `@McpPromptArg(name)` | Prompt argument |
191
+
192
+ ## Runtime Server
193
+
194
+ ### createMcpServer
195
+
196
+ Creates and starts an MCP server from a decorated class.
197
+
198
+ ```typescript
199
+ import { createMcpServer } from '@mcp-weave/nestjs';
200
+
201
+ // Starts server on stdio transport
202
+ await createMcpServer(MyServer);
203
+ ```
204
+
205
+ ### McpRuntimeServer
206
+
207
+ For more control, use the class directly:
208
+
209
+ ```typescript
210
+ import { McpRuntimeServer } from '@mcp-weave/nestjs';
211
+
212
+ const server = new McpRuntimeServer(MyServer, {
213
+ transport: 'stdio',
214
+ });
215
+
216
+ await server.start();
217
+ ```
218
+
219
+ ### SSE Transport (Server-Sent Events)
220
+
221
+ For web-based integrations, use the SSE transport:
222
+
223
+ ```typescript
224
+ import { McpRuntimeServer } from '@mcp-weave/nestjs';
225
+
226
+ const server = new McpRuntimeServer(MyServer, {
227
+ transport: 'sse',
228
+ port: 3000,
229
+ endpoint: '/sse',
230
+ });
231
+
232
+ // Starts HTTP server with SSE endpoint
233
+ const httpServer = await server.start();
234
+
235
+ // Server available at:
236
+ // - SSE endpoint: http://localhost:3000/sse
237
+ // - Health check: http://localhost:3000/health
238
+ ```
239
+
240
+ Or use the `startSSE` method directly:
241
+
242
+ ```typescript
243
+ const server = new McpRuntimeServer(MyServer);
244
+
245
+ // Start with SSE transport
246
+ const httpServer = await server.startSSE({
247
+ port: 8080,
248
+ endpoint: '/mcp',
249
+ });
250
+ ```
251
+
252
+ **SSE Features:**
253
+
254
+ - CORS enabled by default
255
+ - Health check endpoint at `/health`
256
+ - Session management for multiple clients
257
+ - Automatic cleanup on connection close
258
+
259
+ ## Metadata Extraction
260
+
261
+ Extract metadata from decorated classes for code generation:
262
+
263
+ ```typescript
264
+ import { extractMetadata, getServerMetadata, getToolsMetadata } from '@mcp-weave/nestjs';
265
+
266
+ const metadata = extractMetadata(MyServer);
267
+ console.log(metadata.server);
268
+ console.log(metadata.tools);
269
+ console.log(metadata.resources);
270
+ console.log(metadata.prompts);
271
+ ```
272
+
273
+ ## Requirements
274
+
275
+ - Node.js >= 18
276
+ - TypeScript >= 5.0
277
+ - `reflect-metadata` package
278
+
279
+ ## Related Packages
280
+
281
+ - [`@mcp-weave/core`](https://www.npmjs.com/package/@mcp-weave/core) - Core types and utilities
282
+ - [`@mcp-weave/testing`](https://www.npmjs.com/package/@mcp-weave/testing) - Testing utilities
283
+ - [`@mcp-weave/cli`](https://www.npmjs.com/package/@mcp-weave/cli) - Command-line interface
284
+
285
+ ## License
286
+
287
+ MIT
package/dist/index.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { ToolInputSchema, PromptArgument, McpParamMetadata, McpPromptMetadata, McpResourceMetadata, McpServerMetadata, McpToolMetadata } from '@mcp-weave/core';
2
2
  export { METADATA_KEYS, McpParamMetadata, McpPromptMetadata, McpResourceMetadata, McpServerMetadata, McpToolMetadata, ScannedMetadata, extractMetadata } from '@mcp-weave/core';
3
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { Server as Server$1 } from '@modelcontextprotocol/sdk/server/index.js';
4
+ import { Server } from 'http';
4
5
 
5
6
  /**
6
7
  * Options for @McpServer decorator
@@ -209,9 +210,17 @@ declare function getParamsMetadata(target: Function): McpParamMetadata[];
209
210
  */
210
211
  interface McpRuntimeOptions {
211
212
  /**
212
- * Transport type
213
+ * Transport type: 'stdio' (default), 'sse', or 'websocket'
213
214
  */
214
- transport?: 'stdio' | 'sse';
215
+ transport?: 'stdio' | 'sse' | 'websocket';
216
+ /**
217
+ * Port for SSE/WebSocket transport (default: 3000)
218
+ */
219
+ port?: number;
220
+ /**
221
+ * Endpoint path for SSE/WebSocket (default: '/sse' or '/ws')
222
+ */
223
+ endpoint?: string;
215
224
  }
216
225
  /**
217
226
  * Runtime MCP server that wraps a decorated class
@@ -230,16 +239,46 @@ declare class McpRuntimeServer {
230
239
  private resolvePromptArgs;
231
240
  private extractUriParams;
232
241
  /**
233
- * Start the MCP server
242
+ * Start the MCP server with stdio transport
234
243
  */
235
244
  start(): Promise<void>;
245
+ /**
246
+ * Start the MCP server with SSE transport
247
+ */
248
+ startSSE(options?: {
249
+ port?: number;
250
+ endpoint?: string;
251
+ }): Promise<Server>;
236
252
  /**
237
253
  * Get the underlying MCP server instance
238
254
  */
239
- getServer(): Server;
255
+ getServer(): Server$1;
256
+ /**
257
+ * Start the MCP server with WebSocket transport
258
+ */
259
+ startWebSocket(options?: {
260
+ port?: number;
261
+ endpoint?: string;
262
+ }): Promise<Server>;
263
+ /**
264
+ * Handle WebSocket JSON-RPC messages
265
+ */
266
+ private handleWebSocketMessage;
240
267
  }
241
268
  /**
242
269
  * Create and start an MCP server from a decorated class
270
+ *
271
+ * @example
272
+ * // Stdio transport (default)
273
+ * await createMcpServer(MyServer);
274
+ *
275
+ * @example
276
+ * // SSE transport
277
+ * await createMcpServer(MyServer, { transport: 'sse', port: 3000 });
278
+ *
279
+ * @example
280
+ * // WebSocket transport
281
+ * await createMcpServer(MyServer, { transport: 'websocket', port: 8080 });
243
282
  */
244
283
  declare function createMcpServer(target: Function, options?: McpRuntimeOptions): Promise<McpRuntimeServer>;
245
284
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { ToolInputSchema, PromptArgument, McpParamMetadata, McpPromptMetadata, McpResourceMetadata, McpServerMetadata, McpToolMetadata } from '@mcp-weave/core';
2
2
  export { METADATA_KEYS, McpParamMetadata, McpPromptMetadata, McpResourceMetadata, McpServerMetadata, McpToolMetadata, ScannedMetadata, extractMetadata } from '@mcp-weave/core';
3
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { Server as Server$1 } from '@modelcontextprotocol/sdk/server/index.js';
4
+ import { Server } from 'http';
4
5
 
5
6
  /**
6
7
  * Options for @McpServer decorator
@@ -209,9 +210,17 @@ declare function getParamsMetadata(target: Function): McpParamMetadata[];
209
210
  */
210
211
  interface McpRuntimeOptions {
211
212
  /**
212
- * Transport type
213
+ * Transport type: 'stdio' (default), 'sse', or 'websocket'
213
214
  */
214
- transport?: 'stdio' | 'sse';
215
+ transport?: 'stdio' | 'sse' | 'websocket';
216
+ /**
217
+ * Port for SSE/WebSocket transport (default: 3000)
218
+ */
219
+ port?: number;
220
+ /**
221
+ * Endpoint path for SSE/WebSocket (default: '/sse' or '/ws')
222
+ */
223
+ endpoint?: string;
215
224
  }
216
225
  /**
217
226
  * Runtime MCP server that wraps a decorated class
@@ -230,16 +239,46 @@ declare class McpRuntimeServer {
230
239
  private resolvePromptArgs;
231
240
  private extractUriParams;
232
241
  /**
233
- * Start the MCP server
242
+ * Start the MCP server with stdio transport
234
243
  */
235
244
  start(): Promise<void>;
245
+ /**
246
+ * Start the MCP server with SSE transport
247
+ */
248
+ startSSE(options?: {
249
+ port?: number;
250
+ endpoint?: string;
251
+ }): Promise<Server>;
236
252
  /**
237
253
  * Get the underlying MCP server instance
238
254
  */
239
- getServer(): Server;
255
+ getServer(): Server$1;
256
+ /**
257
+ * Start the MCP server with WebSocket transport
258
+ */
259
+ startWebSocket(options?: {
260
+ port?: number;
261
+ endpoint?: string;
262
+ }): Promise<Server>;
263
+ /**
264
+ * Handle WebSocket JSON-RPC messages
265
+ */
266
+ private handleWebSocketMessage;
240
267
  }
241
268
  /**
242
269
  * Create and start an MCP server from a decorated class
270
+ *
271
+ * @example
272
+ * // Stdio transport (default)
273
+ * await createMcpServer(MyServer);
274
+ *
275
+ * @example
276
+ * // SSE transport
277
+ * await createMcpServer(MyServer, { transport: 'sse', port: 3000 });
278
+ *
279
+ * @example
280
+ * // WebSocket transport
281
+ * await createMcpServer(MyServer, { transport: 'websocket', port: 8080 });
243
282
  */
244
283
  declare function createMcpServer(target: Function, options?: McpRuntimeOptions): Promise<McpRuntimeServer>;
245
284