@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 +287 -0
- package/dist/index.d.mts +44 -5
- package/dist/index.d.ts +44 -5
- package/dist/index.js +473 -70
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +473 -70
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
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
|
|