@riktajs/mcp 0.10.2 ā 0.10.3
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/dist/index.cjs +493 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +719 -0
- package/dist/index.d.ts +679 -35
- package/dist/index.js +438 -78
- package/dist/index.js.map +1 -1
- package/package.json +13 -6
- package/dist/constants.d.ts +0 -23
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -23
- package/dist/constants.js.map +0 -1
- package/dist/decorators/index.d.ts +0 -9
- package/dist/decorators/index.d.ts.map +0 -1
- package/dist/decorators/index.js +0 -12
- package/dist/decorators/index.js.map +0 -1
- package/dist/decorators/mcp-prompt.decorator.d.ts +0 -52
- package/dist/decorators/mcp-prompt.decorator.d.ts.map +0 -1
- package/dist/decorators/mcp-prompt.decorator.js +0 -64
- package/dist/decorators/mcp-prompt.decorator.js.map +0 -1
- package/dist/decorators/mcp-resource.decorator.d.ts +0 -49
- package/dist/decorators/mcp-resource.decorator.d.ts.map +0 -1
- package/dist/decorators/mcp-resource.decorator.js +0 -66
- package/dist/decorators/mcp-resource.decorator.js.map +0 -1
- package/dist/decorators/mcp-tool.decorator.d.ts +0 -45
- package/dist/decorators/mcp-tool.decorator.d.ts.map +0 -1
- package/dist/decorators/mcp-tool.decorator.js +0 -57
- package/dist/decorators/mcp-tool.decorator.js.map +0 -1
- package/dist/discovery/index.d.ts +0 -7
- package/dist/discovery/index.d.ts.map +0 -1
- package/dist/discovery/index.js +0 -7
- package/dist/discovery/index.js.map +0 -1
- package/dist/discovery/mcp-registry.d.ts +0 -80
- package/dist/discovery/mcp-registry.d.ts.map +0 -1
- package/dist/discovery/mcp-registry.js +0 -179
- package/dist/discovery/mcp-registry.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/plugin/index.d.ts +0 -7
- package/dist/plugin/index.d.ts.map +0 -1
- package/dist/plugin/index.js +0 -7
- package/dist/plugin/index.js.map +0 -1
- package/dist/plugin/mcp.plugin.d.ts +0 -72
- package/dist/plugin/mcp.plugin.d.ts.map +0 -1
- package/dist/plugin/mcp.plugin.js +0 -216
- package/dist/plugin/mcp.plugin.js.map +0 -1
- package/dist/types.d.ts +0 -347
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -7
- package/dist/types.js.map +0 -1
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -7
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/zod-to-schema.d.ts +0 -57
- package/dist/utils/zod-to-schema.d.ts.map +0 -1
- package/dist/utils/zod-to-schema.js +0 -72
- package/dist/utils/zod-to-schema.js.map +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/index.ts
|
|
32
|
+
var index_exports = {};
|
|
33
|
+
__export(index_exports, {
|
|
34
|
+
DEFAULT_MCP_PATH: () => DEFAULT_MCP_PATH,
|
|
35
|
+
DEFAULT_SERVER_INFO: () => DEFAULT_SERVER_INFO,
|
|
36
|
+
MCPPrompt: () => MCPPrompt,
|
|
37
|
+
MCPResource: () => MCPResource,
|
|
38
|
+
MCPTool: () => MCPTool,
|
|
39
|
+
MCP_HANDLERS_METADATA: () => MCP_HANDLERS_METADATA,
|
|
40
|
+
MCP_PROMPT_METADATA: () => MCP_PROMPT_METADATA,
|
|
41
|
+
MCP_RESOURCE_METADATA: () => MCP_RESOURCE_METADATA,
|
|
42
|
+
MCP_SERVICE_METADATA: () => MCP_SERVICE_METADATA,
|
|
43
|
+
MCP_TOOL_METADATA: () => MCP_TOOL_METADATA,
|
|
44
|
+
createMCPConfig: () => createMCPConfig,
|
|
45
|
+
getMCPPromptMetadata: () => getMCPPromptMetadata,
|
|
46
|
+
getMCPResourceMetadata: () => getMCPResourceMetadata,
|
|
47
|
+
getMCPToolMetadata: () => getMCPToolMetadata,
|
|
48
|
+
isZodSchema: () => isZodSchema,
|
|
49
|
+
mcpRegistry: () => mcpRegistry,
|
|
50
|
+
mcpServerPlugin: () => mcpServerPlugin,
|
|
51
|
+
registerMCPServer: () => registerMCPServer,
|
|
52
|
+
toMCPSchema: () => toMCPSchema,
|
|
53
|
+
zodToMCPSchema: () => zodToMCPSchema
|
|
54
|
+
});
|
|
55
|
+
module.exports = __toCommonJS(index_exports);
|
|
56
|
+
|
|
57
|
+
// src/constants.ts
|
|
58
|
+
var MCP_TOOL_METADATA = /* @__PURE__ */ Symbol.for("rikta:mcp:tool");
|
|
59
|
+
var MCP_RESOURCE_METADATA = /* @__PURE__ */ Symbol.for("rikta:mcp:resource");
|
|
60
|
+
var MCP_PROMPT_METADATA = /* @__PURE__ */ Symbol.for("rikta:mcp:prompt");
|
|
61
|
+
var MCP_HANDLERS_METADATA = /* @__PURE__ */ Symbol.for("rikta:mcp:handlers");
|
|
62
|
+
var MCP_SERVICE_METADATA = /* @__PURE__ */ Symbol.for("rikta:mcp:service");
|
|
63
|
+
var DEFAULT_MCP_PATH = "/mcp";
|
|
64
|
+
var DEFAULT_SERVER_INFO = {
|
|
65
|
+
name: "rikta-mcp-server",
|
|
66
|
+
version: "1.0.0"
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// src/decorators/mcp-tool.decorator.ts
|
|
70
|
+
var import_reflect_metadata = require("reflect-metadata");
|
|
71
|
+
function MCPTool(options) {
|
|
72
|
+
return (target, propertyKey, descriptor) => {
|
|
73
|
+
Reflect.defineMetadata(MCP_TOOL_METADATA, options, target, propertyKey);
|
|
74
|
+
const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, target.constructor) || [];
|
|
75
|
+
handlers.push({
|
|
76
|
+
type: "tool",
|
|
77
|
+
methodName: propertyKey
|
|
78
|
+
});
|
|
79
|
+
Reflect.defineMetadata(MCP_HANDLERS_METADATA, handlers, target.constructor);
|
|
80
|
+
return descriptor;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
__name(MCPTool, "MCPTool");
|
|
84
|
+
function getMCPToolMetadata(target, propertyKey) {
|
|
85
|
+
return Reflect.getMetadata(MCP_TOOL_METADATA, target.prototype, propertyKey);
|
|
86
|
+
}
|
|
87
|
+
__name(getMCPToolMetadata, "getMCPToolMetadata");
|
|
88
|
+
|
|
89
|
+
// src/decorators/mcp-resource.decorator.ts
|
|
90
|
+
var import_reflect_metadata2 = require("reflect-metadata");
|
|
91
|
+
function MCPResource(options) {
|
|
92
|
+
return (target, propertyKey, descriptor) => {
|
|
93
|
+
const optionsWithDefaults = {
|
|
94
|
+
mimeType: "text/plain",
|
|
95
|
+
...options
|
|
96
|
+
};
|
|
97
|
+
Reflect.defineMetadata(MCP_RESOURCE_METADATA, optionsWithDefaults, target, propertyKey);
|
|
98
|
+
const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, target.constructor) || [];
|
|
99
|
+
handlers.push({
|
|
100
|
+
type: "resource",
|
|
101
|
+
methodName: propertyKey
|
|
102
|
+
});
|
|
103
|
+
Reflect.defineMetadata(MCP_HANDLERS_METADATA, handlers, target.constructor);
|
|
104
|
+
return descriptor;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
__name(MCPResource, "MCPResource");
|
|
108
|
+
function getMCPResourceMetadata(target, propertyKey) {
|
|
109
|
+
return Reflect.getMetadata(MCP_RESOURCE_METADATA, target.prototype, propertyKey);
|
|
110
|
+
}
|
|
111
|
+
__name(getMCPResourceMetadata, "getMCPResourceMetadata");
|
|
112
|
+
|
|
113
|
+
// src/decorators/mcp-prompt.decorator.ts
|
|
114
|
+
var import_reflect_metadata3 = require("reflect-metadata");
|
|
115
|
+
function MCPPrompt(options) {
|
|
116
|
+
return (target, propertyKey, descriptor) => {
|
|
117
|
+
Reflect.defineMetadata(MCP_PROMPT_METADATA, options, target, propertyKey);
|
|
118
|
+
const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, target.constructor) || [];
|
|
119
|
+
handlers.push({
|
|
120
|
+
type: "prompt",
|
|
121
|
+
methodName: propertyKey
|
|
122
|
+
});
|
|
123
|
+
Reflect.defineMetadata(MCP_HANDLERS_METADATA, handlers, target.constructor);
|
|
124
|
+
return descriptor;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
__name(MCPPrompt, "MCPPrompt");
|
|
128
|
+
function getMCPPromptMetadata(target, propertyKey) {
|
|
129
|
+
return Reflect.getMetadata(MCP_PROMPT_METADATA, target.prototype, propertyKey);
|
|
130
|
+
}
|
|
131
|
+
__name(getMCPPromptMetadata, "getMCPPromptMetadata");
|
|
132
|
+
|
|
133
|
+
// src/discovery/mcp-registry.ts
|
|
134
|
+
var import_reflect_metadata4 = require("reflect-metadata");
|
|
135
|
+
var MCPRegistryImpl = class MCPRegistryImpl2 {
|
|
136
|
+
static {
|
|
137
|
+
__name(this, "MCPRegistryImpl");
|
|
138
|
+
}
|
|
139
|
+
static instance;
|
|
140
|
+
/** Registered tools */
|
|
141
|
+
tools = [];
|
|
142
|
+
/** Registered resources */
|
|
143
|
+
resources = [];
|
|
144
|
+
/** Registered prompts */
|
|
145
|
+
prompts = [];
|
|
146
|
+
/** Classes that have been scanned */
|
|
147
|
+
scannedClasses = /* @__PURE__ */ new Set();
|
|
148
|
+
constructor() {
|
|
149
|
+
}
|
|
150
|
+
static getInstance() {
|
|
151
|
+
if (!MCPRegistryImpl2.instance) {
|
|
152
|
+
MCPRegistryImpl2.instance = new MCPRegistryImpl2();
|
|
153
|
+
}
|
|
154
|
+
return MCPRegistryImpl2.instance;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Reset the registry (useful for testing)
|
|
158
|
+
*/
|
|
159
|
+
static reset() {
|
|
160
|
+
const newInstance = new MCPRegistryImpl2();
|
|
161
|
+
MCPRegistryImpl2.instance = newInstance;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Scan a class for MCP decorators and register found handlers
|
|
165
|
+
*
|
|
166
|
+
* @param target - Class constructor to scan
|
|
167
|
+
* @param instance - Instance of the class (for binding handlers)
|
|
168
|
+
*/
|
|
169
|
+
scanClass(target, instance) {
|
|
170
|
+
if (this.scannedClasses.has(target)) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
this.scannedClasses.add(target);
|
|
174
|
+
const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, target) || [];
|
|
175
|
+
for (const handler of handlers) {
|
|
176
|
+
const { type, methodName } = handler;
|
|
177
|
+
switch (type) {
|
|
178
|
+
case "tool":
|
|
179
|
+
this.registerTool(target, instance, methodName);
|
|
180
|
+
break;
|
|
181
|
+
case "resource":
|
|
182
|
+
this.registerResource(target, instance, methodName);
|
|
183
|
+
break;
|
|
184
|
+
case "prompt":
|
|
185
|
+
this.registerPrompt(target, instance, methodName);
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Register a tool from a class method
|
|
192
|
+
*/
|
|
193
|
+
registerTool(target, instance, methodName) {
|
|
194
|
+
const metadata = Reflect.getMetadata(MCP_TOOL_METADATA, target.prototype, methodName);
|
|
195
|
+
if (!metadata) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (this.tools.some((t) => t.name === metadata.name)) {
|
|
199
|
+
console.warn(`[MCP] Duplicate tool name: ${metadata.name}. Skipping.`);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const handler = instance[methodName];
|
|
203
|
+
this.tools.push({
|
|
204
|
+
name: metadata.name,
|
|
205
|
+
description: metadata.description,
|
|
206
|
+
inputSchema: metadata.inputSchema,
|
|
207
|
+
handler: handler.bind(instance),
|
|
208
|
+
targetClass: target,
|
|
209
|
+
methodName
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Register a resource from a class method
|
|
214
|
+
*/
|
|
215
|
+
registerResource(target, instance, methodName) {
|
|
216
|
+
const metadata = Reflect.getMetadata(MCP_RESOURCE_METADATA, target.prototype, methodName);
|
|
217
|
+
if (!metadata) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (this.resources.some((r) => r.uriPattern === metadata.uriPattern)) {
|
|
221
|
+
console.warn(`[MCP] Duplicate resource URI pattern: ${metadata.uriPattern}. Skipping.`);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const handler = instance[methodName];
|
|
225
|
+
this.resources.push({
|
|
226
|
+
uriPattern: metadata.uriPattern,
|
|
227
|
+
name: metadata.name,
|
|
228
|
+
description: metadata.description,
|
|
229
|
+
mimeType: metadata.mimeType || "text/plain",
|
|
230
|
+
uriSchema: metadata.uriSchema,
|
|
231
|
+
handler: handler.bind(instance),
|
|
232
|
+
targetClass: target,
|
|
233
|
+
methodName
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Register a prompt from a class method
|
|
238
|
+
*/
|
|
239
|
+
registerPrompt(target, instance, methodName) {
|
|
240
|
+
const metadata = Reflect.getMetadata(MCP_PROMPT_METADATA, target.prototype, methodName);
|
|
241
|
+
if (!metadata) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (this.prompts.some((p) => p.name === metadata.name)) {
|
|
245
|
+
console.warn(`[MCP] Duplicate prompt name: ${metadata.name}. Skipping.`);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const handler = instance[methodName];
|
|
249
|
+
this.prompts.push({
|
|
250
|
+
name: metadata.name,
|
|
251
|
+
description: metadata.description,
|
|
252
|
+
arguments: metadata.arguments,
|
|
253
|
+
handler: handler.bind(instance),
|
|
254
|
+
targetClass: target,
|
|
255
|
+
methodName
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get all registered tools
|
|
260
|
+
*/
|
|
261
|
+
getTools() {
|
|
262
|
+
return [
|
|
263
|
+
...this.tools
|
|
264
|
+
];
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Get all registered resources
|
|
268
|
+
*/
|
|
269
|
+
getResources() {
|
|
270
|
+
return [
|
|
271
|
+
...this.resources
|
|
272
|
+
];
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Get all registered prompts
|
|
276
|
+
*/
|
|
277
|
+
getPrompts() {
|
|
278
|
+
return [
|
|
279
|
+
...this.prompts
|
|
280
|
+
];
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Check if a class has MCP handlers
|
|
284
|
+
*/
|
|
285
|
+
hasMCPHandlers(target) {
|
|
286
|
+
const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, target);
|
|
287
|
+
return Array.isArray(handlers) && handlers.length > 0;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Get count of all registered handlers
|
|
291
|
+
*/
|
|
292
|
+
getStats() {
|
|
293
|
+
return {
|
|
294
|
+
tools: this.tools.length,
|
|
295
|
+
resources: this.resources.length,
|
|
296
|
+
prompts: this.prompts.length
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
var mcpRegistry = MCPRegistryImpl.getInstance();
|
|
301
|
+
|
|
302
|
+
// src/utils/zod-to-schema.ts
|
|
303
|
+
var import_zod = require("zod");
|
|
304
|
+
function isZodSchema(value) {
|
|
305
|
+
return value !== null && typeof value === "object" && ("_zod" in value || "_def" in value) && "safeParse" in value && typeof value.safeParse === "function";
|
|
306
|
+
}
|
|
307
|
+
__name(isZodSchema, "isZodSchema");
|
|
308
|
+
function zodToMCPSchema(schema) {
|
|
309
|
+
const jsonSchema = import_zod.z.toJSONSchema(schema);
|
|
310
|
+
if (typeof jsonSchema === "object" && jsonSchema !== null) {
|
|
311
|
+
const result = {
|
|
312
|
+
...jsonSchema
|
|
313
|
+
};
|
|
314
|
+
delete result.$schema;
|
|
315
|
+
return result;
|
|
316
|
+
}
|
|
317
|
+
return jsonSchema;
|
|
318
|
+
}
|
|
319
|
+
__name(zodToMCPSchema, "zodToMCPSchema");
|
|
320
|
+
function toMCPSchema(schemaOrUndefined) {
|
|
321
|
+
if (!schemaOrUndefined) {
|
|
322
|
+
return void 0;
|
|
323
|
+
}
|
|
324
|
+
if (isZodSchema(schemaOrUndefined)) {
|
|
325
|
+
return zodToMCPSchema(schemaOrUndefined);
|
|
326
|
+
}
|
|
327
|
+
return void 0;
|
|
328
|
+
}
|
|
329
|
+
__name(toMCPSchema, "toMCPSchema");
|
|
330
|
+
|
|
331
|
+
// src/plugin/mcp.plugin.ts
|
|
332
|
+
var import_fastify_plugin = __toESM(require("fastify-plugin"), 1);
|
|
333
|
+
var import_mcp = __toESM(require("@platformatic/mcp"), 1);
|
|
334
|
+
var import_core = require("@riktajs/core");
|
|
335
|
+
var import_mcp2 = require("@platformatic/mcp");
|
|
336
|
+
var DEFAULT_OPTIONS = {
|
|
337
|
+
enableSSE: true,
|
|
338
|
+
path: DEFAULT_MCP_PATH,
|
|
339
|
+
heartbeat: true,
|
|
340
|
+
heartbeatInterval: 3e4,
|
|
341
|
+
sessionTTL: 3600
|
|
342
|
+
};
|
|
343
|
+
async function mcpPluginImpl(fastify, options) {
|
|
344
|
+
const mergedOptions = {
|
|
345
|
+
...DEFAULT_OPTIONS,
|
|
346
|
+
...options
|
|
347
|
+
};
|
|
348
|
+
const { serverInfo, capabilities, instructions, enableSSE, redis, container } = mergedOptions;
|
|
349
|
+
const effectiveCapabilities = capabilities || {};
|
|
350
|
+
const mcpOptions = {
|
|
351
|
+
serverInfo: serverInfo || DEFAULT_SERVER_INFO,
|
|
352
|
+
capabilities: effectiveCapabilities,
|
|
353
|
+
enableSSE
|
|
354
|
+
};
|
|
355
|
+
if (instructions) {
|
|
356
|
+
mcpOptions.instructions = instructions;
|
|
357
|
+
}
|
|
358
|
+
if (redis) {
|
|
359
|
+
mcpOptions.redis = {
|
|
360
|
+
host: redis.host,
|
|
361
|
+
port: redis.port || 6379,
|
|
362
|
+
password: redis.password,
|
|
363
|
+
db: redis.db || 0
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
await fastify.register(import_mcp.default, mcpOptions);
|
|
367
|
+
if (container) {
|
|
368
|
+
const providers = import_core.registry.getProviders();
|
|
369
|
+
for (const providerClass of providers) {
|
|
370
|
+
const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, providerClass);
|
|
371
|
+
if (handlers && handlers.length > 0) {
|
|
372
|
+
const instance = container.resolve(providerClass);
|
|
373
|
+
mcpRegistry.scanClass(providerClass, instance);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
const tools = mcpRegistry.getTools();
|
|
378
|
+
for (const tool of tools) {
|
|
379
|
+
const inputSchema = toMCPSchema(tool.inputSchema);
|
|
380
|
+
const handler = /* @__PURE__ */ __name(async (params, context) => {
|
|
381
|
+
const enrichedContext = {
|
|
382
|
+
...context,
|
|
383
|
+
request: context?.request,
|
|
384
|
+
reply: context?.reply
|
|
385
|
+
};
|
|
386
|
+
const result = await tool.handler(params, enrichedContext);
|
|
387
|
+
return result;
|
|
388
|
+
}, "handler");
|
|
389
|
+
fastify.mcpAddTool({
|
|
390
|
+
name: tool.name,
|
|
391
|
+
description: tool.description,
|
|
392
|
+
inputSchema
|
|
393
|
+
}, handler);
|
|
394
|
+
}
|
|
395
|
+
const resources = mcpRegistry.getResources();
|
|
396
|
+
for (const resource of resources) {
|
|
397
|
+
const handler = /* @__PURE__ */ __name(async (uri, context) => {
|
|
398
|
+
const enrichedContext = {
|
|
399
|
+
...context,
|
|
400
|
+
request: context?.request,
|
|
401
|
+
reply: context?.reply
|
|
402
|
+
};
|
|
403
|
+
const result = await resource.handler(uri, enrichedContext);
|
|
404
|
+
return result;
|
|
405
|
+
}, "handler");
|
|
406
|
+
fastify.mcpAddResource({
|
|
407
|
+
uriPattern: resource.uriPattern,
|
|
408
|
+
name: resource.name,
|
|
409
|
+
description: resource.description,
|
|
410
|
+
mimeType: resource.mimeType
|
|
411
|
+
}, handler);
|
|
412
|
+
}
|
|
413
|
+
const prompts = mcpRegistry.getPrompts();
|
|
414
|
+
for (const prompt of prompts) {
|
|
415
|
+
const handler = /* @__PURE__ */ __name(async (name, args, context) => {
|
|
416
|
+
const enrichedContext = {
|
|
417
|
+
...context,
|
|
418
|
+
request: context?.request,
|
|
419
|
+
reply: context?.reply
|
|
420
|
+
};
|
|
421
|
+
const result = await prompt.handler(args, enrichedContext);
|
|
422
|
+
return result;
|
|
423
|
+
}, "handler");
|
|
424
|
+
fastify.mcpAddPrompt({
|
|
425
|
+
name: prompt.name,
|
|
426
|
+
description: prompt.description
|
|
427
|
+
}, handler);
|
|
428
|
+
}
|
|
429
|
+
if (tools.length > 0) {
|
|
430
|
+
effectiveCapabilities.tools = {};
|
|
431
|
+
}
|
|
432
|
+
if (resources.length > 0) {
|
|
433
|
+
effectiveCapabilities.resources = {};
|
|
434
|
+
}
|
|
435
|
+
if (prompts.length > 0) {
|
|
436
|
+
effectiveCapabilities.prompts = {};
|
|
437
|
+
}
|
|
438
|
+
const stats = mcpRegistry.getStats();
|
|
439
|
+
if (stats.tools > 0 || stats.resources > 0 || stats.prompts > 0) {
|
|
440
|
+
console.log(`
|
|
441
|
+
\u{1F916} MCP Server registered:`);
|
|
442
|
+
console.log(` \u{1F4CD} Endpoint: ${mergedOptions.path}`);
|
|
443
|
+
if (stats.tools > 0) console.log(` \u{1F527} Tools: ${stats.tools}`);
|
|
444
|
+
if (stats.resources > 0) console.log(` \u{1F4C1} Resources: ${stats.resources}`);
|
|
445
|
+
if (stats.prompts > 0) console.log(` \u{1F4AC} Prompts: ${stats.prompts}`);
|
|
446
|
+
if (redis) console.log(` \u{1F4E1} Redis: ${redis.host}:${redis.port || 6379}`);
|
|
447
|
+
console.log("");
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
__name(mcpPluginImpl, "mcpPluginImpl");
|
|
451
|
+
var mcpServerPlugin = (0, import_fastify_plugin.default)(mcpPluginImpl, {
|
|
452
|
+
name: "@riktajs/mcp",
|
|
453
|
+
fastify: "5.x"
|
|
454
|
+
});
|
|
455
|
+
async function registerMCPServer(app, options = {}) {
|
|
456
|
+
const container = "getContainer" in app ? app.getContainer() : void 0;
|
|
457
|
+
await app.server.register(mcpServerPlugin, {
|
|
458
|
+
...options,
|
|
459
|
+
container
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
__name(registerMCPServer, "registerMCPServer");
|
|
463
|
+
function createMCPConfig(options) {
|
|
464
|
+
return {
|
|
465
|
+
...DEFAULT_OPTIONS,
|
|
466
|
+
...options
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
__name(createMCPConfig, "createMCPConfig");
|
|
470
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
471
|
+
0 && (module.exports = {
|
|
472
|
+
DEFAULT_MCP_PATH,
|
|
473
|
+
DEFAULT_SERVER_INFO,
|
|
474
|
+
MCPPrompt,
|
|
475
|
+
MCPResource,
|
|
476
|
+
MCPTool,
|
|
477
|
+
MCP_HANDLERS_METADATA,
|
|
478
|
+
MCP_PROMPT_METADATA,
|
|
479
|
+
MCP_RESOURCE_METADATA,
|
|
480
|
+
MCP_SERVICE_METADATA,
|
|
481
|
+
MCP_TOOL_METADATA,
|
|
482
|
+
createMCPConfig,
|
|
483
|
+
getMCPPromptMetadata,
|
|
484
|
+
getMCPResourceMetadata,
|
|
485
|
+
getMCPToolMetadata,
|
|
486
|
+
isZodSchema,
|
|
487
|
+
mcpRegistry,
|
|
488
|
+
mcpServerPlugin,
|
|
489
|
+
registerMCPServer,
|
|
490
|
+
toMCPSchema,
|
|
491
|
+
zodToMCPSchema
|
|
492
|
+
});
|
|
493
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/decorators/mcp-tool.decorator.ts","../src/decorators/mcp-resource.decorator.ts","../src/decorators/mcp-prompt.decorator.ts","../src/discovery/mcp-registry.ts","../src/utils/zod-to-schema.ts","../src/plugin/mcp.plugin.ts"],"sourcesContent":["/**\r\n * @riktajs/mcp\r\n * \r\n * Model Context Protocol (MCP) integration for Rikta Framework.\r\n * Connect AI assistants like Claude and GPT to your Rikta backend.\r\n * \r\n * This package provides decorators and utilities to expose your services\r\n * as MCP tools, resources, and prompts that AI assistants can use.\r\n * \r\n * Features:\r\n * - Decorator-based API (@MCPTool, @MCPResource, @MCPPrompt)\r\n * - Auto-discovery of MCP handlers from @Injectable classes\r\n * - Zod schema integration for input validation\r\n * - SSE (Server-Sent Events) support for real-time notifications\r\n * - Redis support for horizontal scaling\r\n * - Full TypeScript support\r\n * \r\n * @example\r\n * ```typescript\r\n * import { Rikta, Injectable } from '@riktajs/core';\r\n * import { registerMCPServer, MCPTool, MCPResource } from '@riktajs/mcp';\r\n * import { z } from 'zod';\r\n * \r\n * @Injectable()\r\n * class FileService {\r\n * @MCPTool({\r\n * name: 'list_files',\r\n * description: 'List files in a directory',\r\n * inputSchema: z.object({\r\n * path: z.string().describe('Directory path')\r\n * })\r\n * })\r\n * async listFiles(params: { path: string }) {\r\n * const files = await fs.readdir(params.path);\r\n * return {\r\n * content: [{ type: 'text', text: files.join('\\n') }]\r\n * };\r\n * }\r\n * \r\n * @MCPResource({\r\n * uriPattern: 'file://read',\r\n * name: 'Read File',\r\n * description: 'Read file contents'\r\n * })\r\n * async readFile(uri: string) {\r\n * const url = new URL(uri);\r\n * const content = await fs.readFile(url.searchParams.get('path')!, 'utf-8');\r\n * return {\r\n * contents: [{ uri, text: content, mimeType: 'text/plain' }]\r\n * };\r\n * }\r\n * }\r\n * \r\n * const app = await Rikta.create({ port: 3000 });\r\n * \r\n * await registerMCPServer(app, {\r\n * serverInfo: { name: 'file-server', version: '1.0.0' },\r\n * instructions: 'A file system server for reading and listing files',\r\n * });\r\n * \r\n * await app.listen();\r\n * // MCP available at http://localhost:3000/mcp\r\n * // - POST /mcp for JSON-RPC requests\r\n * // - GET /mcp for SSE connections\r\n * ```\r\n * \r\n * @packageDocumentation\r\n */\r\n\r\n// Export constants\r\nexport * from './constants.js';\r\n\r\n// Export types\r\nexport type * from './types.js';\r\n\r\n// Export decorators\r\nexport * from './decorators/index.js';\r\n\r\n// Export discovery/registry\r\nexport { mcpRegistry } from './discovery/index.js';\r\n\r\n// Export utilities\r\nexport { zodToMCPSchema, toMCPSchema, isZodSchema } from './utils/index.js';\r\n\r\n// Export plugin\r\nexport { registerMCPServer, createMCPConfig, mcpServerPlugin } from './plugin/index.js';\r\n","/**\r\n * @riktajs/mcp - Constants\r\n * \r\n * Metadata keys for MCP decorators using Symbol.for() for cross-package sharing.\r\n */\r\n\r\n/** Metadata key for @MCPTool decorator */\r\nexport const MCP_TOOL_METADATA = Symbol.for('rikta:mcp:tool');\r\n\r\n/** Metadata key for @MCPResource decorator */\r\nexport const MCP_RESOURCE_METADATA = Symbol.for('rikta:mcp:resource');\r\n\r\n/** Metadata key for @MCPPrompt decorator */\r\nexport const MCP_PROMPT_METADATA = Symbol.for('rikta:mcp:prompt');\r\n\r\n/** Metadata key for storing all MCP handler methods on a class */\r\nexport const MCP_HANDLERS_METADATA = Symbol.for('rikta:mcp:handlers');\r\n\r\n/** Metadata key to mark a class as an MCP service */\r\nexport const MCP_SERVICE_METADATA = Symbol.for('rikta:mcp:service');\r\n\r\n/** Default MCP endpoint path */\r\nexport const DEFAULT_MCP_PATH = '/mcp';\r\n\r\n/** Default server info */\r\nexport const DEFAULT_SERVER_INFO = {\r\n name: 'rikta-mcp-server',\r\n version: '1.0.0',\r\n} as const;\r\n","/**\r\n * @MCPTool Decorator\r\n * \r\n * Marks a method as an MCP tool that can be called by AI assistants.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { Injectable } from '@riktajs/core';\r\n * import { MCPTool } from '@riktajs/mcp';\r\n * import { z } from 'zod';\r\n * \r\n * @Injectable()\r\n * class FileService {\r\n * @MCPTool({\r\n * name: 'read_file',\r\n * description: 'Read contents of a file',\r\n * inputSchema: z.object({\r\n * path: z.string().describe('File path to read')\r\n * })\r\n * })\r\n * async readFile(params: { path: string }) {\r\n * const content = await fs.readFile(params.path, 'utf-8');\r\n * return {\r\n * content: [{ type: 'text', text: content }]\r\n * };\r\n * }\r\n * }\r\n * ```\r\n */\r\nimport 'reflect-metadata';\r\nimport { MCP_TOOL_METADATA, MCP_HANDLERS_METADATA } from '../constants.js';\r\nimport type { MCPToolOptions } from '../types.js';\r\n\r\n/**\r\n * @MCPTool() decorator\r\n * \r\n * Registers a method as an MCP tool that AI assistants can invoke.\r\n * \r\n * @param options - Tool configuration options\r\n */\r\nexport function MCPTool(options: MCPToolOptions): MethodDecorator {\r\n return (\r\n target: Object,\r\n propertyKey: string | symbol,\r\n descriptor: PropertyDescriptor\r\n ): PropertyDescriptor => {\r\n // Store tool metadata on the method\r\n Reflect.defineMetadata(MCP_TOOL_METADATA, options, target, propertyKey);\r\n\r\n // Add to the class's list of MCP handlers\r\n const handlers: Array<{ type: 'tool' | 'resource' | 'prompt'; methodName: string | symbol }> = \r\n Reflect.getMetadata(MCP_HANDLERS_METADATA, target.constructor) || [];\r\n \r\n handlers.push({ type: 'tool', methodName: propertyKey });\r\n Reflect.defineMetadata(MCP_HANDLERS_METADATA, handlers, target.constructor);\r\n\r\n return descriptor;\r\n };\r\n}\r\n\r\n/**\r\n * Get tool metadata from a method\r\n * @internal\r\n */\r\nexport function getMCPToolMetadata(\r\n target: Function,\r\n propertyKey: string | symbol\r\n): MCPToolOptions | undefined {\r\n return Reflect.getMetadata(MCP_TOOL_METADATA, target.prototype, propertyKey);\r\n}\r\n","/**\r\n * @MCPResource Decorator\r\n * \r\n * Marks a method as an MCP resource provider.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { Injectable } from '@riktajs/core';\r\n * import { MCPResource } from '@riktajs/mcp';\r\n * \r\n * @Injectable()\r\n * class FileService {\r\n * @MCPResource({\r\n * uriPattern: 'file://read',\r\n * name: 'Read File',\r\n * description: 'Read file contents by path',\r\n * mimeType: 'text/plain'\r\n * })\r\n * async readFile(uri: string) {\r\n * const url = new URL(uri);\r\n * const filePath = url.searchParams.get('path');\r\n * const content = await fs.readFile(filePath!, 'utf-8');\r\n * return {\r\n * contents: [{\r\n * uri,\r\n * text: content,\r\n * mimeType: 'text/plain'\r\n * }]\r\n * };\r\n * }\r\n * }\r\n * ```\r\n */\r\nimport 'reflect-metadata';\r\nimport { MCP_RESOURCE_METADATA, MCP_HANDLERS_METADATA } from '../constants.js';\r\nimport type { MCPResourceOptions } from '../types.js';\r\n\r\n/**\r\n * @MCPResource() decorator\r\n * \r\n * Registers a method as an MCP resource provider.\r\n * \r\n * @param options - Resource configuration options\r\n */\r\nexport function MCPResource(options: MCPResourceOptions): MethodDecorator {\r\n return (\r\n target: Object,\r\n propertyKey: string | symbol,\r\n descriptor: PropertyDescriptor\r\n ): PropertyDescriptor => {\r\n // Set default mimeType if not provided\r\n const optionsWithDefaults: MCPResourceOptions = {\r\n mimeType: 'text/plain',\r\n ...options,\r\n };\r\n\r\n // Store resource metadata on the method\r\n Reflect.defineMetadata(MCP_RESOURCE_METADATA, optionsWithDefaults, target, propertyKey);\r\n\r\n // Add to the class's list of MCP handlers\r\n const handlers: Array<{ type: 'tool' | 'resource' | 'prompt'; methodName: string | symbol }> = \r\n Reflect.getMetadata(MCP_HANDLERS_METADATA, target.constructor) || [];\r\n \r\n handlers.push({ type: 'resource', methodName: propertyKey });\r\n Reflect.defineMetadata(MCP_HANDLERS_METADATA, handlers, target.constructor);\r\n\r\n return descriptor;\r\n };\r\n}\r\n\r\n/**\r\n * Get resource metadata from a method\r\n * @internal\r\n */\r\nexport function getMCPResourceMetadata(\r\n target: Function,\r\n propertyKey: string | symbol\r\n): MCPResourceOptions | undefined {\r\n return Reflect.getMetadata(MCP_RESOURCE_METADATA, target.prototype, propertyKey);\r\n}\r\n","/**\r\n * @MCPPrompt Decorator\r\n * \r\n * Marks a method as an MCP prompt template.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { Injectable } from '@riktajs/core';\r\n * import { MCPPrompt } from '@riktajs/mcp';\r\n * \r\n * @Injectable()\r\n * class PromptService {\r\n * @MCPPrompt({\r\n * name: 'code_review',\r\n * description: 'Generate a code review prompt',\r\n * arguments: [\r\n * { name: 'language', description: 'Programming language', required: true },\r\n * { name: 'code', description: 'Code to review', required: true }\r\n * ]\r\n * })\r\n * async codeReview(args: { language: string; code: string }) {\r\n * return {\r\n * messages: [\r\n * {\r\n * role: 'user',\r\n * content: {\r\n * type: 'text',\r\n * text: `Please review this ${args.language} code:\\n\\n${args.code}`\r\n * }\r\n * }\r\n * ]\r\n * };\r\n * }\r\n * }\r\n * ```\r\n */\r\nimport 'reflect-metadata';\r\nimport { MCP_PROMPT_METADATA, MCP_HANDLERS_METADATA } from '../constants.js';\r\nimport type { MCPPromptOptions } from '../types.js';\r\n\r\n/**\r\n * @MCPPrompt() decorator\r\n * \r\n * Registers a method as an MCP prompt template.\r\n * \r\n * @param options - Prompt configuration options\r\n */\r\nexport function MCPPrompt(options: MCPPromptOptions): MethodDecorator {\r\n return (\r\n target: Object,\r\n propertyKey: string | symbol,\r\n descriptor: PropertyDescriptor\r\n ): PropertyDescriptor => {\r\n // Store prompt metadata on the method\r\n Reflect.defineMetadata(MCP_PROMPT_METADATA, options, target, propertyKey);\r\n\r\n // Add to the class's list of MCP handlers\r\n const handlers: Array<{ type: 'tool' | 'resource' | 'prompt'; methodName: string | symbol }> = \r\n Reflect.getMetadata(MCP_HANDLERS_METADATA, target.constructor) || [];\r\n \r\n handlers.push({ type: 'prompt', methodName: propertyKey });\r\n Reflect.defineMetadata(MCP_HANDLERS_METADATA, handlers, target.constructor);\r\n\r\n return descriptor;\r\n };\r\n}\r\n\r\n/**\r\n * Get prompt metadata from a method\r\n * @internal\r\n */\r\nexport function getMCPPromptMetadata(\r\n target: Function,\r\n propertyKey: string | symbol\r\n): MCPPromptOptions | undefined {\r\n return Reflect.getMetadata(MCP_PROMPT_METADATA, target.prototype, propertyKey);\r\n}\r\n","/**\r\n * @riktajs/mcp - MCP Registry\r\n * \r\n * Discovers and stores MCP handlers (tools, resources, prompts) from decorated classes.\r\n * Works with Rikta's registry to auto-discover @Injectable classes with MCP decorators.\r\n */\r\nimport 'reflect-metadata';\r\nimport {\r\n MCP_TOOL_METADATA,\r\n MCP_RESOURCE_METADATA,\r\n MCP_PROMPT_METADATA,\r\n MCP_HANDLERS_METADATA,\r\n} from '../constants.js';\r\nimport type {\r\n MCPToolOptions,\r\n MCPResourceOptions,\r\n MCPPromptOptions,\r\n RegisteredMCPTool,\r\n RegisteredMCPResource,\r\n RegisteredMCPPrompt,\r\n} from '../types.js';\r\n\r\n// Type for any class constructor\r\ntype Constructor<T = unknown> = new (...args: unknown[]) => T;\r\n\r\n/**\r\n * Handler type stored in class metadata\r\n */\r\ninterface HandlerEntry {\r\n type: 'tool' | 'resource' | 'prompt';\r\n methodName: string | symbol;\r\n}\r\n\r\n/**\r\n * MCP Registry\r\n * \r\n * Central registry for all discovered MCP handlers.\r\n * Scans @Injectable classes for @MCPTool, @MCPResource, @MCPPrompt decorators.\r\n */\r\nclass MCPRegistryImpl {\r\n private static instance: MCPRegistryImpl;\r\n \r\n /** Registered tools */\r\n private tools: RegisteredMCPTool[] = [];\r\n \r\n /** Registered resources */\r\n private resources: RegisteredMCPResource[] = [];\r\n \r\n /** Registered prompts */\r\n private prompts: RegisteredMCPPrompt[] = [];\r\n\r\n /** Classes that have been scanned */\r\n private scannedClasses = new Set<Function>();\r\n\r\n private constructor() {}\r\n\r\n static getInstance(): MCPRegistryImpl {\r\n if (!MCPRegistryImpl.instance) {\r\n MCPRegistryImpl.instance = new MCPRegistryImpl();\r\n }\r\n return MCPRegistryImpl.instance;\r\n }\r\n\r\n /**\r\n * Reset the registry (useful for testing)\r\n */\r\n static reset(): void {\r\n const newInstance = new MCPRegistryImpl();\r\n MCPRegistryImpl.instance = newInstance;\r\n }\r\n\r\n /**\r\n * Scan a class for MCP decorators and register found handlers\r\n * \r\n * @param target - Class constructor to scan\r\n * @param instance - Instance of the class (for binding handlers)\r\n */\r\n scanClass(target: Constructor, instance: unknown): void {\r\n // Skip if already scanned\r\n if (this.scannedClasses.has(target)) {\r\n return;\r\n }\r\n this.scannedClasses.add(target);\r\n\r\n // Get all MCP handlers registered on this class\r\n const handlers: HandlerEntry[] = Reflect.getMetadata(MCP_HANDLERS_METADATA, target) || [];\r\n\r\n for (const handler of handlers) {\r\n const { type, methodName } = handler;\r\n\r\n switch (type) {\r\n case 'tool':\r\n this.registerTool(target, instance, methodName);\r\n break;\r\n case 'resource':\r\n this.registerResource(target, instance, methodName);\r\n break;\r\n case 'prompt':\r\n this.registerPrompt(target, instance, methodName);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Register a tool from a class method\r\n */\r\n private registerTool(target: Constructor, instance: unknown, methodName: string | symbol): void {\r\n const metadata: MCPToolOptions | undefined = Reflect.getMetadata(\r\n MCP_TOOL_METADATA,\r\n target.prototype,\r\n methodName\r\n );\r\n\r\n if (!metadata) {\r\n return;\r\n }\r\n\r\n // Check for duplicate tool names\r\n if (this.tools.some(t => t.name === metadata.name)) {\r\n console.warn(`[MCP] Duplicate tool name: ${metadata.name}. Skipping.`);\r\n return;\r\n }\r\n\r\n const handler = (instance as Record<string | symbol, Function>)[methodName];\r\n \r\n this.tools.push({\r\n name: metadata.name,\r\n description: metadata.description,\r\n inputSchema: metadata.inputSchema,\r\n handler: handler.bind(instance),\r\n targetClass: target,\r\n methodName,\r\n });\r\n }\r\n\r\n /**\r\n * Register a resource from a class method\r\n */\r\n private registerResource(target: Constructor, instance: unknown, methodName: string | symbol): void {\r\n const metadata: MCPResourceOptions | undefined = Reflect.getMetadata(\r\n MCP_RESOURCE_METADATA,\r\n target.prototype,\r\n methodName\r\n );\r\n\r\n if (!metadata) {\r\n return;\r\n }\r\n\r\n // Check for duplicate resource patterns\r\n if (this.resources.some(r => r.uriPattern === metadata.uriPattern)) {\r\n console.warn(`[MCP] Duplicate resource URI pattern: ${metadata.uriPattern}. Skipping.`);\r\n return;\r\n }\r\n\r\n const handler = (instance as Record<string | symbol, Function>)[methodName];\r\n \r\n this.resources.push({\r\n uriPattern: metadata.uriPattern,\r\n name: metadata.name,\r\n description: metadata.description,\r\n mimeType: metadata.mimeType || 'text/plain',\r\n uriSchema: metadata.uriSchema,\r\n handler: handler.bind(instance),\r\n targetClass: target,\r\n methodName,\r\n });\r\n }\r\n\r\n /**\r\n * Register a prompt from a class method\r\n */\r\n private registerPrompt(target: Constructor, instance: unknown, methodName: string | symbol): void {\r\n const metadata: MCPPromptOptions | undefined = Reflect.getMetadata(\r\n MCP_PROMPT_METADATA,\r\n target.prototype,\r\n methodName\r\n );\r\n\r\n if (!metadata) {\r\n return;\r\n }\r\n\r\n // Check for duplicate prompt names\r\n if (this.prompts.some(p => p.name === metadata.name)) {\r\n console.warn(`[MCP] Duplicate prompt name: ${metadata.name}. Skipping.`);\r\n return;\r\n }\r\n\r\n const handler = (instance as Record<string | symbol, Function>)[methodName];\r\n \r\n this.prompts.push({\r\n name: metadata.name,\r\n description: metadata.description,\r\n arguments: metadata.arguments,\r\n handler: handler.bind(instance),\r\n targetClass: target,\r\n methodName,\r\n });\r\n }\r\n\r\n /**\r\n * Get all registered tools\r\n */\r\n getTools(): RegisteredMCPTool[] {\r\n return [...this.tools];\r\n }\r\n\r\n /**\r\n * Get all registered resources\r\n */\r\n getResources(): RegisteredMCPResource[] {\r\n return [...this.resources];\r\n }\r\n\r\n /**\r\n * Get all registered prompts\r\n */\r\n getPrompts(): RegisteredMCPPrompt[] {\r\n return [...this.prompts];\r\n }\r\n\r\n /**\r\n * Check if a class has MCP handlers\r\n */\r\n hasMCPHandlers(target: Constructor): boolean {\r\n const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, target);\r\n return Array.isArray(handlers) && handlers.length > 0;\r\n }\r\n\r\n /**\r\n * Get count of all registered handlers\r\n */\r\n getStats(): { tools: number; resources: number; prompts: number } {\r\n return {\r\n tools: this.tools.length,\r\n resources: this.resources.length,\r\n prompts: this.prompts.length,\r\n };\r\n }\r\n}\r\n\r\n/** Singleton instance of MCP registry */\r\nexport const mcpRegistry = MCPRegistryImpl.getInstance();\r\n\r\n/** Export class for testing */\r\nexport { MCPRegistryImpl };\r\n","/**\r\n * @riktajs/mcp - Zod to JSON Schema Conversion\r\n * \r\n * Utilities for converting Zod schemas to JSON Schema format\r\n * compatible with @platformatic/mcp.\r\n */\r\nimport { z } from 'zod';\r\n\r\n/**\r\n * Zod schema type (compatible with zod v4)\r\n */\r\ntype ZodType = z.core.$ZodType;\r\n\r\n/**\r\n * JSON Schema type (simplified)\r\n */\r\nexport type JsonSchema = Record<string, unknown>;\r\n\r\n/**\r\n * Type guard to check if a value is a Zod schema\r\n * Uses duck typing to detect Zod schemas without requiring the full library\r\n * Compatible with both Zod v3 (_def) and Zod v4 (_zod)\r\n */\r\nexport function isZodSchema(value: unknown): value is ZodType {\r\n return (\r\n value !== null &&\r\n typeof value === 'object' &&\r\n ('_zod' in value || '_def' in value) &&\r\n 'safeParse' in value &&\r\n typeof (value as { safeParse: unknown }).safeParse === 'function'\r\n );\r\n}\r\n\r\n/**\r\n * Convert a Zod schema to JSON Schema format for MCP\r\n * \r\n * @param schema - The Zod schema to convert\r\n * @returns JSON Schema object compatible with MCP\r\n * \r\n * @example\r\n * ```typescript\r\n * import { z } from 'zod';\r\n * \r\n * const schema = z.object({\r\n * path: z.string().describe('File path'),\r\n * encoding: z.string().optional(),\r\n * });\r\n * \r\n * const jsonSchema = zodToMCPSchema(schema);\r\n * // {\r\n * // type: 'object',\r\n * // properties: {\r\n * // path: { type: 'string', description: 'File path' },\r\n * // encoding: { type: 'string' }\r\n * // },\r\n * // required: ['path']\r\n * // }\r\n * ```\r\n */\r\nexport function zodToMCPSchema(schema: ZodType): JsonSchema {\r\n // Use Zod v4 native toJSONSchema\r\n const jsonSchema = z.toJSONSchema(schema) as JsonSchema;\r\n\r\n // Remove $schema property as MCP doesn't need it\r\n if (typeof jsonSchema === 'object' && jsonSchema !== null) {\r\n const result = { ...jsonSchema };\r\n delete result.$schema;\r\n return result;\r\n }\r\n\r\n return jsonSchema;\r\n}\r\n\r\n/**\r\n * Convert a Zod schema to JSON Schema, or return undefined if not a Zod schema\r\n * \r\n * @param schemaOrUndefined - The Zod schema or undefined\r\n * @returns JSON Schema object or undefined\r\n */\r\nexport function toMCPSchema(\r\n schemaOrUndefined: ZodType | undefined\r\n): JsonSchema | undefined {\r\n if (!schemaOrUndefined) {\r\n return undefined;\r\n }\r\n \r\n if (isZodSchema(schemaOrUndefined)) {\r\n return zodToMCPSchema(schemaOrUndefined);\r\n }\r\n \r\n return undefined;\r\n}\r\n","/**\r\n * @riktajs/mcp - MCP Plugin\r\n * \r\n * Main plugin that integrates @platformatic/mcp with Rikta Framework.\r\n * Provides registerMCPServer function for easy MCP setup.\r\n */\r\nimport type { FastifyInstance } from 'fastify';\r\nimport fp from 'fastify-plugin';\r\nimport mcpPlugin from '@platformatic/mcp';\r\nimport type { UnsafeToolHandler, UnsafeResourceHandler, UnsafePromptHandler, CallToolResult, ReadResourceResult, GetPromptResult } from '@platformatic/mcp';\r\nimport { registry } from '@riktajs/core';\r\n\r\nimport { mcpRegistry } from '../discovery/mcp-registry.js';\r\nimport { toMCPSchema } from '../utils/zod-to-schema.js';\r\nimport { DEFAULT_MCP_PATH, DEFAULT_SERVER_INFO, MCP_HANDLERS_METADATA } from '../constants.js';\r\nimport type {\r\n MCPServerOptions,\r\n RiktaApplication,\r\n MCPCapabilities,\r\n} from '../types.js';\r\n\r\n// Re-export types from @platformatic/mcp for module augmentation\r\nimport '@platformatic/mcp';\r\n\r\n// Type for any class constructor\r\ntype Constructor<T = unknown> = new (...args: unknown[]) => T;\r\n\r\n// Container interface (minimal for type safety)\r\ninterface Container {\r\n resolve<T>(target: Constructor<T>): T;\r\n}\r\n\r\n/**\r\n * Default options for MCP server\r\n */\r\nconst DEFAULT_OPTIONS: Required<Pick<MCPServerOptions, 'enableSSE' | 'path' | 'heartbeat' | 'heartbeatInterval' | 'sessionTTL'>> = {\r\n enableSSE: true,\r\n path: DEFAULT_MCP_PATH,\r\n heartbeat: true,\r\n heartbeatInterval: 30000,\r\n sessionTTL: 3600,\r\n};\r\n\r\n/**\r\n * MCP plugin implementation for Fastify\r\n * \r\n * Registers @platformatic/mcp and auto-discovers MCP handlers from Rikta services.\r\n */\r\nasync function mcpPluginImpl(\r\n fastify: FastifyInstance,\r\n options: MCPServerOptions & { container?: Container }\r\n): Promise<void> {\r\n const mergedOptions = { ...DEFAULT_OPTIONS, ...options };\r\n const { serverInfo, capabilities, instructions, enableSSE, redis, container } = mergedOptions;\r\n\r\n // Build capabilities based on registered handlers\r\n const effectiveCapabilities: MCPCapabilities = capabilities || {};\r\n \r\n // We'll populate capabilities after scanning\r\n\r\n // Build MCP plugin options\r\n const mcpOptions: Record<string, unknown> = {\r\n serverInfo: serverInfo || DEFAULT_SERVER_INFO,\r\n capabilities: effectiveCapabilities,\r\n enableSSE,\r\n };\r\n\r\n // Add instructions if provided\r\n if (instructions) {\r\n mcpOptions.instructions = instructions;\r\n }\r\n\r\n // Add Redis config if provided\r\n if (redis) {\r\n mcpOptions.redis = {\r\n host: redis.host,\r\n port: redis.port || 6379,\r\n password: redis.password,\r\n db: redis.db || 0,\r\n };\r\n }\r\n\r\n // Register @platformatic/mcp plugin\r\n await fastify.register(mcpPlugin, mcpOptions);\r\n\r\n // Scan all providers from Rikta registry for MCP handlers\r\n if (container) {\r\n const providers = registry.getProviders();\r\n \r\n for (const providerClass of providers) {\r\n // Check if this provider has MCP handlers\r\n const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, providerClass);\r\n if (handlers && handlers.length > 0) {\r\n // Resolve the provider instance from the container\r\n const instance = container.resolve(providerClass);\r\n mcpRegistry.scanClass(providerClass as Constructor, instance);\r\n }\r\n }\r\n }\r\n\r\n // Register all discovered tools\r\n const tools = mcpRegistry.getTools();\r\n for (const tool of tools) {\r\n // Convert Zod schema to JSON Schema for MCP\r\n const inputSchema = toMCPSchema(tool.inputSchema);\r\n \r\n const handler: UnsafeToolHandler = async (params, context) => {\r\n // Enrich context with request/reply if available\r\n const enrichedContext = {\r\n ...context,\r\n request: (context as any)?.request,\r\n reply: (context as any)?.reply,\r\n };\r\n const result = await tool.handler(params, enrichedContext);\r\n return result as CallToolResult;\r\n };\r\n \r\n fastify.mcpAddTool(\r\n {\r\n name: tool.name,\r\n description: tool.description,\r\n inputSchema,\r\n },\r\n handler\r\n );\r\n }\r\n\r\n // Register all discovered resources\r\n const resources = mcpRegistry.getResources();\r\n for (const resource of resources) {\r\n // Convert Zod schema to JSON Schema for MCP (uriSchema is not needed for resources)\r\n \r\n const handler: UnsafeResourceHandler = async (uri, context) => {\r\n // Enrich context with request/reply if available\r\n const enrichedContext = {\r\n ...context,\r\n request: (context as any)?.request,\r\n reply: (context as any)?.reply,\r\n };\r\n const result = await resource.handler(uri, enrichedContext);\r\n return result as ReadResourceResult;\r\n };\r\n \r\n fastify.mcpAddResource(\r\n {\r\n uriPattern: resource.uriPattern,\r\n name: resource.name,\r\n description: resource.description,\r\n mimeType: resource.mimeType,\r\n },\r\n handler\r\n );\r\n }\r\n\r\n // Register all discovered prompts\r\n const prompts = mcpRegistry.getPrompts();\r\n for (const prompt of prompts) {\r\n const handler: UnsafePromptHandler = async (name, args, context) => {\r\n // Enrich context with request/reply if available\r\n const enrichedContext = {\r\n ...context,\r\n request: (context as any)?.request,\r\n reply: (context as any)?.reply,\r\n };\r\n const result = await prompt.handler(args, enrichedContext);\r\n return result as GetPromptResult;\r\n };\r\n \r\n fastify.mcpAddPrompt(\r\n {\r\n name: prompt.name,\r\n description: prompt.description,\r\n },\r\n handler\r\n );\r\n }\r\n\r\n // Update capabilities based on what was registered\r\n if (tools.length > 0) {\r\n effectiveCapabilities.tools = {};\r\n }\r\n if (resources.length > 0) {\r\n effectiveCapabilities.resources = {};\r\n }\r\n if (prompts.length > 0) {\r\n effectiveCapabilities.prompts = {};\r\n }\r\n\r\n // Log registration summary\r\n const stats = mcpRegistry.getStats();\r\n if (stats.tools > 0 || stats.resources > 0 || stats.prompts > 0) {\r\n console.log(`\\nš¤ MCP Server registered:`);\r\n console.log(` š Endpoint: ${mergedOptions.path}`);\r\n if (stats.tools > 0) console.log(` š§ Tools: ${stats.tools}`);\r\n if (stats.resources > 0) console.log(` š Resources: ${stats.resources}`);\r\n if (stats.prompts > 0) console.log(` š¬ Prompts: ${stats.prompts}`);\r\n if (redis) console.log(` š” Redis: ${redis.host}:${redis.port || 6379}`);\r\n console.log('');\r\n }\r\n}\r\n\r\n/**\r\n * Wrapped Fastify plugin with proper encapsulation\r\n */\r\nexport const mcpServerPlugin = fp(mcpPluginImpl, {\r\n name: '@riktajs/mcp',\r\n fastify: '5.x',\r\n});\r\n\r\n/**\r\n * Register MCP server with a Rikta application\r\n * \r\n * This is the main entry point for integrating MCP with Rikta.\r\n * It decorates the Fastify instance with @platformatic/mcp and\r\n * auto-discovers MCP handlers from @Injectable classes.\r\n * \r\n * @param app - Rikta application instance\r\n * @param options - MCP server options\r\n * \r\n * @example\r\n * ```typescript\r\n * import { Rikta } from '@riktajs/core';\r\n * import { registerMCPServer } from '@riktajs/mcp';\r\n * \r\n * const app = await Rikta.create({ port: 3000 });\r\n * \r\n * await registerMCPServer(app, {\r\n * serverInfo: { name: 'my-mcp-server', version: '1.0.0' },\r\n * instructions: 'This server provides file system tools',\r\n * enableSSE: true,\r\n * });\r\n * \r\n * await app.listen();\r\n * // MCP available at http://localhost:3000/mcp\r\n * ```\r\n */\r\nexport async function registerMCPServer(\r\n app: RiktaApplication,\r\n options: MCPServerOptions = {}\r\n): Promise<void> {\r\n // Get the container from the app using getContainer method\r\n const container = 'getContainer' in app \r\n ? (app as unknown as { getContainer(): Container }).getContainer()\r\n : undefined;\r\n \r\n await app.server.register(mcpServerPlugin, {\r\n ...options,\r\n container,\r\n });\r\n}\r\n\r\n/**\r\n * Create MCP configuration object\r\n * \r\n * Helper function to create type-safe MCP configuration.\r\n * \r\n * @param options - MCP server options\r\n * @returns Validated MCP configuration\r\n * \r\n * @example\r\n * ```typescript\r\n * const mcpConfig = createMCPConfig({\r\n * serverInfo: { name: 'my-server', version: '1.0.0' },\r\n * redis: { host: 'localhost', port: 6379 },\r\n * });\r\n * ```\r\n */\r\nexport function createMCPConfig(options: MCPServerOptions): MCPServerOptions {\r\n return {\r\n ...DEFAULT_OPTIONS,\r\n ...options,\r\n };\r\n}\r\n"],"mappings":"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","names":["MCP_TOOL_METADATA","Symbol","for","MCP_RESOURCE_METADATA","MCP_PROMPT_METADATA","MCP_HANDLERS_METADATA","MCP_SERVICE_METADATA","DEFAULT_MCP_PATH","DEFAULT_SERVER_INFO","name","version","MCPTool","options","target","propertyKey","descriptor","Reflect","defineMetadata","MCP_TOOL_METADATA","handlers","getMetadata","MCP_HANDLERS_METADATA","push","type","methodName","getMCPToolMetadata","prototype","import_reflect_metadata","MCPResource","options","target","propertyKey","descriptor","optionsWithDefaults","mimeType","Reflect","defineMetadata","MCP_RESOURCE_METADATA","handlers","getMetadata","MCP_HANDLERS_METADATA","push","type","methodName","getMCPResourceMetadata","prototype","import_reflect_metadata","MCPPrompt","options","target","propertyKey","descriptor","Reflect","defineMetadata","MCP_PROMPT_METADATA","handlers","getMetadata","MCP_HANDLERS_METADATA","push","type","methodName","getMCPPromptMetadata","prototype","import_reflect_metadata","MCPRegistryImpl","instance","tools","resources","prompts","scannedClasses","Set","getInstance","reset","newInstance","scanClass","target","has","add","handlers","Reflect","getMetadata","MCP_HANDLERS_METADATA","handler","type","methodName","registerTool","registerResource","registerPrompt","metadata","MCP_TOOL_METADATA","prototype","some","t","name","console","warn","push","description","inputSchema","bind","targetClass","MCP_RESOURCE_METADATA","r","uriPattern","mimeType","uriSchema","MCP_PROMPT_METADATA","p","arguments","getTools","getResources","getPrompts","hasMCPHandlers","Array","isArray","length","getStats","mcpRegistry","isZodSchema","value","safeParse","zodToMCPSchema","schema","jsonSchema","z","toJSONSchema","result","$schema","toMCPSchema","schemaOrUndefined","undefined","import_mcp","DEFAULT_OPTIONS","enableSSE","path","DEFAULT_MCP_PATH","heartbeat","heartbeatInterval","sessionTTL","mcpPluginImpl","fastify","options","mergedOptions","serverInfo","capabilities","instructions","redis","container","effectiveCapabilities","mcpOptions","DEFAULT_SERVER_INFO","host","port","password","db","register","mcpPlugin","providers","registry","getProviders","providerClass","handlers","Reflect","getMetadata","MCP_HANDLERS_METADATA","length","instance","resolve","mcpRegistry","scanClass","tools","getTools","tool","inputSchema","toMCPSchema","handler","params","context","enrichedContext","request","reply","result","mcpAddTool","name","description","resources","getResources","resource","uri","mcpAddResource","uriPattern","mimeType","prompts","getPrompts","prompt","args","mcpAddPrompt","stats","getStats","console","log","mcpServerPlugin","fp","registerMCPServer","app","getContainer","undefined","server","createMCPConfig"]}
|