@riktajs/mcp 0.1.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.
Files changed (54) hide show
  1. package/README.md +399 -0
  2. package/dist/constants.d.ts +23 -0
  3. package/dist/constants.d.ts.map +1 -0
  4. package/dist/constants.js +23 -0
  5. package/dist/constants.js.map +1 -0
  6. package/dist/decorators/index.d.ts +9 -0
  7. package/dist/decorators/index.d.ts.map +1 -0
  8. package/dist/decorators/index.js +12 -0
  9. package/dist/decorators/index.js.map +1 -0
  10. package/dist/decorators/mcp-prompt.decorator.d.ts +52 -0
  11. package/dist/decorators/mcp-prompt.decorator.d.ts.map +1 -0
  12. package/dist/decorators/mcp-prompt.decorator.js +64 -0
  13. package/dist/decorators/mcp-prompt.decorator.js.map +1 -0
  14. package/dist/decorators/mcp-resource.decorator.d.ts +49 -0
  15. package/dist/decorators/mcp-resource.decorator.d.ts.map +1 -0
  16. package/dist/decorators/mcp-resource.decorator.js +66 -0
  17. package/dist/decorators/mcp-resource.decorator.js.map +1 -0
  18. package/dist/decorators/mcp-tool.decorator.d.ts +45 -0
  19. package/dist/decorators/mcp-tool.decorator.d.ts.map +1 -0
  20. package/dist/decorators/mcp-tool.decorator.js +57 -0
  21. package/dist/decorators/mcp-tool.decorator.js.map +1 -0
  22. package/dist/discovery/index.d.ts +7 -0
  23. package/dist/discovery/index.d.ts.map +1 -0
  24. package/dist/discovery/index.js +7 -0
  25. package/dist/discovery/index.js.map +1 -0
  26. package/dist/discovery/mcp-registry.d.ts +80 -0
  27. package/dist/discovery/mcp-registry.d.ts.map +1 -0
  28. package/dist/discovery/mcp-registry.js +179 -0
  29. package/dist/discovery/mcp-registry.js.map +1 -0
  30. package/dist/index.d.ts +76 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +81 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/plugin/index.d.ts +7 -0
  35. package/dist/plugin/index.d.ts.map +1 -0
  36. package/dist/plugin/index.js +7 -0
  37. package/dist/plugin/index.js.map +1 -0
  38. package/dist/plugin/mcp.plugin.d.ts +72 -0
  39. package/dist/plugin/mcp.plugin.d.ts.map +1 -0
  40. package/dist/plugin/mcp.plugin.js +198 -0
  41. package/dist/plugin/mcp.plugin.js.map +1 -0
  42. package/dist/types.d.ts +337 -0
  43. package/dist/types.d.ts.map +1 -0
  44. package/dist/types.js +7 -0
  45. package/dist/types.js.map +1 -0
  46. package/dist/utils/index.d.ts +7 -0
  47. package/dist/utils/index.d.ts.map +1 -0
  48. package/dist/utils/index.js +7 -0
  49. package/dist/utils/index.js.map +1 -0
  50. package/dist/utils/zod-to-schema.d.ts +48 -0
  51. package/dist/utils/zod-to-schema.d.ts.map +1 -0
  52. package/dist/utils/zod-to-schema.js +67 -0
  53. package/dist/utils/zod-to-schema.js.map +1 -0
  54. package/package.json +65 -0
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @MCPResource Decorator
3
+ *
4
+ * Marks a method as an MCP resource provider.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { Injectable } from '@riktajs/core';
9
+ * import { MCPResource } from '@riktajs/mcp';
10
+ *
11
+ * @Injectable()
12
+ * class FileService {
13
+ * @MCPResource({
14
+ * uriPattern: 'file://read',
15
+ * name: 'Read File',
16
+ * description: 'Read file contents by path',
17
+ * mimeType: 'text/plain'
18
+ * })
19
+ * async readFile(uri: string) {
20
+ * const url = new URL(uri);
21
+ * const filePath = url.searchParams.get('path');
22
+ * const content = await fs.readFile(filePath!, 'utf-8');
23
+ * return {
24
+ * contents: [{
25
+ * uri,
26
+ * text: content,
27
+ * mimeType: 'text/plain'
28
+ * }]
29
+ * };
30
+ * }
31
+ * }
32
+ * ```
33
+ */
34
+ import 'reflect-metadata';
35
+ import { MCP_RESOURCE_METADATA, MCP_HANDLERS_METADATA } from '../constants.js';
36
+ /**
37
+ * @MCPResource() decorator
38
+ *
39
+ * Registers a method as an MCP resource provider.
40
+ *
41
+ * @param options - Resource configuration options
42
+ */
43
+ export function MCPResource(options) {
44
+ return (target, propertyKey, descriptor) => {
45
+ // Set default mimeType if not provided
46
+ const optionsWithDefaults = {
47
+ mimeType: 'text/plain',
48
+ ...options,
49
+ };
50
+ // Store resource metadata on the method
51
+ Reflect.defineMetadata(MCP_RESOURCE_METADATA, optionsWithDefaults, target, propertyKey);
52
+ // Add to the class's list of MCP handlers
53
+ const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, target.constructor) || [];
54
+ handlers.push({ type: 'resource', methodName: propertyKey });
55
+ Reflect.defineMetadata(MCP_HANDLERS_METADATA, handlers, target.constructor);
56
+ return descriptor;
57
+ };
58
+ }
59
+ /**
60
+ * Get resource metadata from a method
61
+ * @internal
62
+ */
63
+ export function getMCPResourceMetadata(target, propertyKey) {
64
+ return Reflect.getMetadata(MCP_RESOURCE_METADATA, target.prototype, propertyKey);
65
+ }
66
+ //# sourceMappingURL=mcp-resource.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-resource.decorator.js","sourceRoot":"","sources":["../../src/decorators/mcp-resource.decorator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG/E;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,OAA2B;IACrD,OAAO,CACL,MAAc,EACd,WAA4B,EAC5B,UAA8B,EACV,EAAE;QACtB,uCAAuC;QACvC,MAAM,mBAAmB,GAAuB;YAC9C,QAAQ,EAAE,YAAY;YACtB,GAAG,OAAO;SACX,CAAC;QAEF,wCAAwC;QACxC,OAAO,CAAC,cAAc,CAAC,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QAExF,0CAA0C;QAC1C,MAAM,QAAQ,GACZ,OAAO,CAAC,WAAW,CAAC,qBAAqB,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAEvE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,cAAc,CAAC,qBAAqB,EAAE,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAE5E,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAgB,EAChB,WAA4B;IAE5B,OAAO,OAAO,CAAC,WAAW,CAAC,qBAAqB,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AACnF,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @MCPTool Decorator
3
+ *
4
+ * Marks a method as an MCP tool that can be called by AI assistants.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { Injectable } from '@riktajs/core';
9
+ * import { MCPTool } from '@riktajs/mcp';
10
+ * import { z } from 'zod';
11
+ *
12
+ * @Injectable()
13
+ * class FileService {
14
+ * @MCPTool({
15
+ * name: 'read_file',
16
+ * description: 'Read contents of a file',
17
+ * inputSchema: z.object({
18
+ * path: z.string().describe('File path to read')
19
+ * })
20
+ * })
21
+ * async readFile(params: { path: string }) {
22
+ * const content = await fs.readFile(params.path, 'utf-8');
23
+ * return {
24
+ * content: [{ type: 'text', text: content }]
25
+ * };
26
+ * }
27
+ * }
28
+ * ```
29
+ */
30
+ import 'reflect-metadata';
31
+ import type { MCPToolOptions } from '../types.js';
32
+ /**
33
+ * @MCPTool() decorator
34
+ *
35
+ * Registers a method as an MCP tool that AI assistants can invoke.
36
+ *
37
+ * @param options - Tool configuration options
38
+ */
39
+ export declare function MCPTool(options: MCPToolOptions): MethodDecorator;
40
+ /**
41
+ * Get tool metadata from a method
42
+ * @internal
43
+ */
44
+ export declare function getMCPToolMetadata(target: Function, propertyKey: string | symbol): MCPToolOptions | undefined;
45
+ //# sourceMappingURL=mcp-tool.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tool.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/mcp-tool.decorator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,eAAe,CAkBhE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,QAAQ,EAChB,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,cAAc,GAAG,SAAS,CAE5B"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @MCPTool Decorator
3
+ *
4
+ * Marks a method as an MCP tool that can be called by AI assistants.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { Injectable } from '@riktajs/core';
9
+ * import { MCPTool } from '@riktajs/mcp';
10
+ * import { z } from 'zod';
11
+ *
12
+ * @Injectable()
13
+ * class FileService {
14
+ * @MCPTool({
15
+ * name: 'read_file',
16
+ * description: 'Read contents of a file',
17
+ * inputSchema: z.object({
18
+ * path: z.string().describe('File path to read')
19
+ * })
20
+ * })
21
+ * async readFile(params: { path: string }) {
22
+ * const content = await fs.readFile(params.path, 'utf-8');
23
+ * return {
24
+ * content: [{ type: 'text', text: content }]
25
+ * };
26
+ * }
27
+ * }
28
+ * ```
29
+ */
30
+ import 'reflect-metadata';
31
+ import { MCP_TOOL_METADATA, MCP_HANDLERS_METADATA } from '../constants.js';
32
+ /**
33
+ * @MCPTool() decorator
34
+ *
35
+ * Registers a method as an MCP tool that AI assistants can invoke.
36
+ *
37
+ * @param options - Tool configuration options
38
+ */
39
+ export function MCPTool(options) {
40
+ return (target, propertyKey, descriptor) => {
41
+ // Store tool metadata on the method
42
+ Reflect.defineMetadata(MCP_TOOL_METADATA, options, target, propertyKey);
43
+ // Add to the class's list of MCP handlers
44
+ const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, target.constructor) || [];
45
+ handlers.push({ type: 'tool', methodName: propertyKey });
46
+ Reflect.defineMetadata(MCP_HANDLERS_METADATA, handlers, target.constructor);
47
+ return descriptor;
48
+ };
49
+ }
50
+ /**
51
+ * Get tool metadata from a method
52
+ * @internal
53
+ */
54
+ export function getMCPToolMetadata(target, propertyKey) {
55
+ return Reflect.getMetadata(MCP_TOOL_METADATA, target.prototype, propertyKey);
56
+ }
57
+ //# sourceMappingURL=mcp-tool.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tool.decorator.js","sourceRoot":"","sources":["../../src/decorators/mcp-tool.decorator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG3E;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,OAAuB;IAC7C,OAAO,CACL,MAAc,EACd,WAA4B,EAC5B,UAA8B,EACV,EAAE;QACtB,oCAAoC;QACpC,OAAO,CAAC,cAAc,CAAC,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QAExE,0CAA0C;QAC1C,MAAM,QAAQ,GACZ,OAAO,CAAC,WAAW,CAAC,qBAAqB,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAEvE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,cAAc,CAAC,qBAAqB,EAAE,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAE5E,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAgB,EAChB,WAA4B;IAE5B,OAAO,OAAO,CAAC,WAAW,CAAC,iBAAiB,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @riktajs/mcp - Discovery
3
+ *
4
+ * Export MCP registry and discovery utilities.
5
+ */
6
+ export { mcpRegistry, MCPRegistryImpl } from './mcp-registry.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @riktajs/mcp - Discovery
3
+ *
4
+ * Export MCP registry and discovery utilities.
5
+ */
6
+ export { mcpRegistry, MCPRegistryImpl } from './mcp-registry.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @riktajs/mcp - MCP Registry
3
+ *
4
+ * Discovers and stores MCP handlers (tools, resources, prompts) from decorated classes.
5
+ * Works with Rikta's registry to auto-discover @Injectable classes with MCP decorators.
6
+ */
7
+ import 'reflect-metadata';
8
+ import type { RegisteredMCPTool, RegisteredMCPResource, RegisteredMCPPrompt } from '../types.js';
9
+ type Constructor<T = unknown> = new (...args: unknown[]) => T;
10
+ /**
11
+ * MCP Registry
12
+ *
13
+ * Central registry for all discovered MCP handlers.
14
+ * Scans @Injectable classes for @MCPTool, @MCPResource, @MCPPrompt decorators.
15
+ */
16
+ declare class MCPRegistryImpl {
17
+ private static instance;
18
+ /** Registered tools */
19
+ private tools;
20
+ /** Registered resources */
21
+ private resources;
22
+ /** Registered prompts */
23
+ private prompts;
24
+ /** Classes that have been scanned */
25
+ private scannedClasses;
26
+ private constructor();
27
+ static getInstance(): MCPRegistryImpl;
28
+ /**
29
+ * Reset the registry (useful for testing)
30
+ */
31
+ static reset(): void;
32
+ /**
33
+ * Scan a class for MCP decorators and register found handlers
34
+ *
35
+ * @param target - Class constructor to scan
36
+ * @param instance - Instance of the class (for binding handlers)
37
+ */
38
+ scanClass(target: Constructor, instance: unknown): void;
39
+ /**
40
+ * Register a tool from a class method
41
+ */
42
+ private registerTool;
43
+ /**
44
+ * Register a resource from a class method
45
+ */
46
+ private registerResource;
47
+ /**
48
+ * Register a prompt from a class method
49
+ */
50
+ private registerPrompt;
51
+ /**
52
+ * Get all registered tools
53
+ */
54
+ getTools(): RegisteredMCPTool[];
55
+ /**
56
+ * Get all registered resources
57
+ */
58
+ getResources(): RegisteredMCPResource[];
59
+ /**
60
+ * Get all registered prompts
61
+ */
62
+ getPrompts(): RegisteredMCPPrompt[];
63
+ /**
64
+ * Check if a class has MCP handlers
65
+ */
66
+ hasMCPHandlers(target: Constructor): boolean;
67
+ /**
68
+ * Get count of all registered handlers
69
+ */
70
+ getStats(): {
71
+ tools: number;
72
+ resources: number;
73
+ prompts: number;
74
+ };
75
+ }
76
+ /** Singleton instance of MCP registry */
77
+ export declare const mcpRegistry: MCPRegistryImpl;
78
+ /** Export class for testing */
79
+ export { MCPRegistryImpl };
80
+ //# sourceMappingURL=mcp-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-registry.d.ts","sourceRoot":"","sources":["../../src/discovery/mcp-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,kBAAkB,CAAC;AAO1B,OAAO,KAAK,EAIV,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAGrB,KAAK,WAAW,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAU9D;;;;;GAKG;AACH,cAAM,eAAe;IACnB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkB;IAEzC,uBAAuB;IACvB,OAAO,CAAC,KAAK,CAA2B;IAExC,2BAA2B;IAC3B,OAAO,CAAC,SAAS,CAA+B;IAEhD,yBAAyB;IACzB,OAAO,CAAC,OAAO,CAA6B;IAE5C,qCAAqC;IACrC,OAAO,CAAC,cAAc,CAAuB;IAE7C,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,eAAe;IAOrC;;OAEG;IACH,MAAM,CAAC,KAAK,IAAI,IAAI;IAKpB;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IA2BvD;;OAEG;IACH,OAAO,CAAC,YAAY;IA6BpB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA+BxB;;OAEG;IACH,OAAO,CAAC,cAAc;IA6BtB;;OAEG;IACH,QAAQ,IAAI,iBAAiB,EAAE;IAI/B;;OAEG;IACH,YAAY,IAAI,qBAAqB,EAAE;IAIvC;;OAEG;IACH,UAAU,IAAI,mBAAmB,EAAE;IAInC;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO;IAK5C;;OAEG;IACH,QAAQ,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAOlE;AAED,yCAAyC;AACzC,eAAO,MAAM,WAAW,iBAAgC,CAAC;AAEzD,+BAA+B;AAC/B,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * @riktajs/mcp - MCP Registry
3
+ *
4
+ * Discovers and stores MCP handlers (tools, resources, prompts) from decorated classes.
5
+ * Works with Rikta's registry to auto-discover @Injectable classes with MCP decorators.
6
+ */
7
+ import 'reflect-metadata';
8
+ import { MCP_TOOL_METADATA, MCP_RESOURCE_METADATA, MCP_PROMPT_METADATA, MCP_HANDLERS_METADATA, } from '../constants.js';
9
+ /**
10
+ * MCP Registry
11
+ *
12
+ * Central registry for all discovered MCP handlers.
13
+ * Scans @Injectable classes for @MCPTool, @MCPResource, @MCPPrompt decorators.
14
+ */
15
+ class MCPRegistryImpl {
16
+ static instance;
17
+ /** Registered tools */
18
+ tools = [];
19
+ /** Registered resources */
20
+ resources = [];
21
+ /** Registered prompts */
22
+ prompts = [];
23
+ /** Classes that have been scanned */
24
+ scannedClasses = new Set();
25
+ constructor() { }
26
+ static getInstance() {
27
+ if (!MCPRegistryImpl.instance) {
28
+ MCPRegistryImpl.instance = new MCPRegistryImpl();
29
+ }
30
+ return MCPRegistryImpl.instance;
31
+ }
32
+ /**
33
+ * Reset the registry (useful for testing)
34
+ */
35
+ static reset() {
36
+ const newInstance = new MCPRegistryImpl();
37
+ MCPRegistryImpl.instance = newInstance;
38
+ }
39
+ /**
40
+ * Scan a class for MCP decorators and register found handlers
41
+ *
42
+ * @param target - Class constructor to scan
43
+ * @param instance - Instance of the class (for binding handlers)
44
+ */
45
+ scanClass(target, instance) {
46
+ // Skip if already scanned
47
+ if (this.scannedClasses.has(target)) {
48
+ return;
49
+ }
50
+ this.scannedClasses.add(target);
51
+ // Get all MCP handlers registered on this class
52
+ const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, target) || [];
53
+ for (const handler of handlers) {
54
+ const { type, methodName } = handler;
55
+ switch (type) {
56
+ case 'tool':
57
+ this.registerTool(target, instance, methodName);
58
+ break;
59
+ case 'resource':
60
+ this.registerResource(target, instance, methodName);
61
+ break;
62
+ case 'prompt':
63
+ this.registerPrompt(target, instance, methodName);
64
+ break;
65
+ }
66
+ }
67
+ }
68
+ /**
69
+ * Register a tool from a class method
70
+ */
71
+ registerTool(target, instance, methodName) {
72
+ const metadata = Reflect.getMetadata(MCP_TOOL_METADATA, target.prototype, methodName);
73
+ if (!metadata) {
74
+ return;
75
+ }
76
+ // Check for duplicate tool names
77
+ if (this.tools.some(t => t.name === metadata.name)) {
78
+ console.warn(`[MCP] Duplicate tool name: ${metadata.name}. Skipping.`);
79
+ return;
80
+ }
81
+ const handler = instance[methodName];
82
+ this.tools.push({
83
+ name: metadata.name,
84
+ description: metadata.description,
85
+ inputSchema: metadata.inputSchema,
86
+ handler: handler.bind(instance),
87
+ targetClass: target,
88
+ methodName,
89
+ });
90
+ }
91
+ /**
92
+ * Register a resource from a class method
93
+ */
94
+ registerResource(target, instance, methodName) {
95
+ const metadata = Reflect.getMetadata(MCP_RESOURCE_METADATA, target.prototype, methodName);
96
+ if (!metadata) {
97
+ return;
98
+ }
99
+ // Check for duplicate resource patterns
100
+ if (this.resources.some(r => r.uriPattern === metadata.uriPattern)) {
101
+ console.warn(`[MCP] Duplicate resource URI pattern: ${metadata.uriPattern}. Skipping.`);
102
+ return;
103
+ }
104
+ const handler = instance[methodName];
105
+ this.resources.push({
106
+ uriPattern: metadata.uriPattern,
107
+ name: metadata.name,
108
+ description: metadata.description,
109
+ mimeType: metadata.mimeType || 'text/plain',
110
+ uriSchema: metadata.uriSchema,
111
+ handler: handler.bind(instance),
112
+ targetClass: target,
113
+ methodName,
114
+ });
115
+ }
116
+ /**
117
+ * Register a prompt from a class method
118
+ */
119
+ registerPrompt(target, instance, methodName) {
120
+ const metadata = Reflect.getMetadata(MCP_PROMPT_METADATA, target.prototype, methodName);
121
+ if (!metadata) {
122
+ return;
123
+ }
124
+ // Check for duplicate prompt names
125
+ if (this.prompts.some(p => p.name === metadata.name)) {
126
+ console.warn(`[MCP] Duplicate prompt name: ${metadata.name}. Skipping.`);
127
+ return;
128
+ }
129
+ const handler = instance[methodName];
130
+ this.prompts.push({
131
+ name: metadata.name,
132
+ description: metadata.description,
133
+ arguments: metadata.arguments,
134
+ handler: handler.bind(instance),
135
+ targetClass: target,
136
+ methodName,
137
+ });
138
+ }
139
+ /**
140
+ * Get all registered tools
141
+ */
142
+ getTools() {
143
+ return [...this.tools];
144
+ }
145
+ /**
146
+ * Get all registered resources
147
+ */
148
+ getResources() {
149
+ return [...this.resources];
150
+ }
151
+ /**
152
+ * Get all registered prompts
153
+ */
154
+ getPrompts() {
155
+ return [...this.prompts];
156
+ }
157
+ /**
158
+ * Check if a class has MCP handlers
159
+ */
160
+ hasMCPHandlers(target) {
161
+ const handlers = Reflect.getMetadata(MCP_HANDLERS_METADATA, target);
162
+ return Array.isArray(handlers) && handlers.length > 0;
163
+ }
164
+ /**
165
+ * Get count of all registered handlers
166
+ */
167
+ getStats() {
168
+ return {
169
+ tools: this.tools.length,
170
+ resources: this.resources.length,
171
+ prompts: this.prompts.length,
172
+ };
173
+ }
174
+ }
175
+ /** Singleton instance of MCP registry */
176
+ export const mcpRegistry = MCPRegistryImpl.getInstance();
177
+ /** Export class for testing */
178
+ export { MCPRegistryImpl };
179
+ //# sourceMappingURL=mcp-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-registry.js","sourceRoot":"","sources":["../../src/discovery/mcp-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @riktajs/mcp
3
+ *
4
+ * Model Context Protocol (MCP) integration for Rikta Framework.
5
+ * Connect AI assistants like Claude and GPT to your Rikta backend.
6
+ *
7
+ * This package provides decorators and utilities to expose your services
8
+ * as MCP tools, resources, and prompts that AI assistants can use.
9
+ *
10
+ * Features:
11
+ * - Decorator-based API (@MCPTool, @MCPResource, @MCPPrompt)
12
+ * - Auto-discovery of MCP handlers from @Injectable classes
13
+ * - Zod schema integration for input validation
14
+ * - SSE (Server-Sent Events) support for real-time notifications
15
+ * - Redis support for horizontal scaling
16
+ * - Full TypeScript support
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { Rikta, Injectable } from '@riktajs/core';
21
+ * import { registerMCPServer, MCPTool, MCPResource } from '@riktajs/mcp';
22
+ * import { z } from 'zod';
23
+ *
24
+ * @Injectable()
25
+ * class FileService {
26
+ * @MCPTool({
27
+ * name: 'list_files',
28
+ * description: 'List files in a directory',
29
+ * inputSchema: z.object({
30
+ * path: z.string().describe('Directory path')
31
+ * })
32
+ * })
33
+ * async listFiles(params: { path: string }) {
34
+ * const files = await fs.readdir(params.path);
35
+ * return {
36
+ * content: [{ type: 'text', text: files.join('\n') }]
37
+ * };
38
+ * }
39
+ *
40
+ * @MCPResource({
41
+ * uriPattern: 'file://read',
42
+ * name: 'Read File',
43
+ * description: 'Read file contents'
44
+ * })
45
+ * async readFile(uri: string) {
46
+ * const url = new URL(uri);
47
+ * const content = await fs.readFile(url.searchParams.get('path')!, 'utf-8');
48
+ * return {
49
+ * contents: [{ uri, text: content, mimeType: 'text/plain' }]
50
+ * };
51
+ * }
52
+ * }
53
+ *
54
+ * const app = await Rikta.create({ port: 3000 });
55
+ *
56
+ * await registerMCPServer(app, {
57
+ * serverInfo: { name: 'file-server', version: '1.0.0' },
58
+ * instructions: 'A file system server for reading and listing files',
59
+ * });
60
+ *
61
+ * await app.listen();
62
+ * // MCP available at http://localhost:3000/mcp
63
+ * // - POST /mcp for JSON-RPC requests
64
+ * // - GET /mcp for SSE connections
65
+ * ```
66
+ *
67
+ * @packageDocumentation
68
+ */
69
+ export * from './constants.js';
70
+ export type * from './types.js';
71
+ export * from './decorators/index.js';
72
+ export { mcpRegistry } from './discovery/index.js';
73
+ export { zodToMCPSchema, toMCPSchema, isZodSchema } from './utils/index.js';
74
+ export { registerMCPServer, createMCPConfig, mcpServerPlugin } from './plugin/index.js';
75
+ export { z } from 'zod';
76
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAGH,cAAc,gBAAgB,CAAC;AAG/B,mBAAmB,YAAY,CAAC;AAGhC,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG5E,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGxF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @riktajs/mcp
3
+ *
4
+ * Model Context Protocol (MCP) integration for Rikta Framework.
5
+ * Connect AI assistants like Claude and GPT to your Rikta backend.
6
+ *
7
+ * This package provides decorators and utilities to expose your services
8
+ * as MCP tools, resources, and prompts that AI assistants can use.
9
+ *
10
+ * Features:
11
+ * - Decorator-based API (@MCPTool, @MCPResource, @MCPPrompt)
12
+ * - Auto-discovery of MCP handlers from @Injectable classes
13
+ * - Zod schema integration for input validation
14
+ * - SSE (Server-Sent Events) support for real-time notifications
15
+ * - Redis support for horizontal scaling
16
+ * - Full TypeScript support
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { Rikta, Injectable } from '@riktajs/core';
21
+ * import { registerMCPServer, MCPTool, MCPResource } from '@riktajs/mcp';
22
+ * import { z } from 'zod';
23
+ *
24
+ * @Injectable()
25
+ * class FileService {
26
+ * @MCPTool({
27
+ * name: 'list_files',
28
+ * description: 'List files in a directory',
29
+ * inputSchema: z.object({
30
+ * path: z.string().describe('Directory path')
31
+ * })
32
+ * })
33
+ * async listFiles(params: { path: string }) {
34
+ * const files = await fs.readdir(params.path);
35
+ * return {
36
+ * content: [{ type: 'text', text: files.join('\n') }]
37
+ * };
38
+ * }
39
+ *
40
+ * @MCPResource({
41
+ * uriPattern: 'file://read',
42
+ * name: 'Read File',
43
+ * description: 'Read file contents'
44
+ * })
45
+ * async readFile(uri: string) {
46
+ * const url = new URL(uri);
47
+ * const content = await fs.readFile(url.searchParams.get('path')!, 'utf-8');
48
+ * return {
49
+ * contents: [{ uri, text: content, mimeType: 'text/plain' }]
50
+ * };
51
+ * }
52
+ * }
53
+ *
54
+ * const app = await Rikta.create({ port: 3000 });
55
+ *
56
+ * await registerMCPServer(app, {
57
+ * serverInfo: { name: 'file-server', version: '1.0.0' },
58
+ * instructions: 'A file system server for reading and listing files',
59
+ * });
60
+ *
61
+ * await app.listen();
62
+ * // MCP available at http://localhost:3000/mcp
63
+ * // - POST /mcp for JSON-RPC requests
64
+ * // - GET /mcp for SSE connections
65
+ * ```
66
+ *
67
+ * @packageDocumentation
68
+ */
69
+ // Export constants
70
+ export * from './constants.js';
71
+ // Export decorators
72
+ export * from './decorators/index.js';
73
+ // Export discovery/registry
74
+ export { mcpRegistry } from './discovery/index.js';
75
+ // Export utilities
76
+ export { zodToMCPSchema, toMCPSchema, isZodSchema } from './utils/index.js';
77
+ // Export plugin
78
+ export { registerMCPServer, createMCPConfig, mcpServerPlugin } from './plugin/index.js';
79
+ // Re-export zod for convenience
80
+ export { z } from 'zod';
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,mBAAmB;AACnB,cAAc,gBAAgB,CAAC;AAK/B,oBAAoB;AACpB,cAAc,uBAAuB,CAAC;AAEtC,4BAA4B;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,mBAAmB;AACnB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE5E,gBAAgB;AAChB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAExF,gCAAgC;AAChC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @riktajs/mcp - Plugin
3
+ *
4
+ * Export MCP plugin and registration functions.
5
+ */
6
+ export { registerMCPServer, createMCPConfig, mcpServerPlugin } from './mcp.plugin.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @riktajs/mcp - Plugin
3
+ *
4
+ * Export MCP plugin and registration functions.
5
+ */
6
+ export { registerMCPServer, createMCPConfig, mcpServerPlugin } from './mcp.plugin.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}