@jrmc/adonis-mcp 1.0.0-alpha.9 → 1.0.0-beta.2
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 +811 -26
- package/build/commands/commands.json +1 -1
- package/build/commands/inspector.d.ts +16 -0
- package/build/commands/inspector.d.ts.map +1 -0
- package/build/commands/inspector.js +54 -0
- package/build/commands/make/prompt.d.ts +16 -0
- package/build/commands/make/prompt.d.ts.map +1 -0
- package/build/commands/make/prompt.js +33 -0
- package/build/commands/make/resource.d.ts +16 -0
- package/build/commands/make/resource.d.ts.map +1 -0
- package/build/commands/make/resource.js +33 -0
- package/build/commands/make/tool.d.ts.map +1 -1
- package/build/commands/make/tool.js +0 -2
- package/build/configure.d.ts.map +1 -1
- package/build/configure.js +7 -0
- package/build/index.d.ts +2 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -0
- package/build/providers/mcp_provider.d.ts +3 -0
- package/build/providers/mcp_provider.d.ts.map +1 -1
- package/build/providers/mcp_provider.js +35 -12
- package/build/src/define_config.d.ts.map +1 -1
- package/build/src/define_config.js +0 -3
- package/build/src/enums/error.d.ts.map +1 -1
- package/build/src/enums/error.js +0 -1
- package/build/src/request.d.ts +1 -1
- package/build/src/response.d.ts +24 -23
- package/build/src/response.d.ts.map +1 -1
- package/build/src/response.js +49 -13
- package/build/src/server/annotations/annotations.d.ts +10 -0
- package/build/src/server/annotations/annotations.d.ts.map +1 -0
- package/build/src/server/annotations/annotations.js +9 -0
- package/build/src/server/annotations/audience.d.ts +22 -0
- package/build/src/server/annotations/audience.d.ts.map +1 -0
- package/build/src/server/annotations/audience.js +28 -0
- package/build/src/server/annotations/is_destructive.d.ts +17 -0
- package/build/src/server/annotations/is_destructive.d.ts.map +1 -0
- package/build/src/server/annotations/is_destructive.js +24 -0
- package/build/src/server/annotations/is_idempotent.d.ts +17 -0
- package/build/src/server/annotations/is_idempotent.d.ts.map +1 -0
- package/build/src/server/annotations/is_idempotent.js +24 -0
- package/build/src/server/annotations/is_open_world.d.ts +17 -0
- package/build/src/server/annotations/is_open_world.d.ts.map +1 -0
- package/build/src/server/annotations/is_open_world.js +24 -0
- package/build/src/server/annotations/is_read_only.d.ts +17 -0
- package/build/src/server/annotations/is_read_only.d.ts.map +1 -0
- package/build/src/server/annotations/is_read_only.js +24 -0
- package/build/src/server/annotations/last_modified.d.ts +21 -0
- package/build/src/server/annotations/last_modified.d.ts.map +1 -0
- package/build/src/server/annotations/last_modified.js +28 -0
- package/build/src/server/annotations/priority.d.ts +21 -0
- package/build/src/server/annotations/priority.d.ts.map +1 -0
- package/build/src/server/annotations/priority.js +31 -0
- package/build/src/server/annotations/tool_annotations.d.ts +11 -0
- package/build/src/server/annotations/tool_annotations.d.ts.map +1 -0
- package/build/src/server/annotations/tool_annotations.js +10 -0
- package/build/src/server/contents/audio.d.ts +24 -0
- package/build/src/server/contents/audio.d.ts.map +1 -0
- package/build/src/server/contents/audio.js +57 -0
- package/build/src/server/contents/blob.d.ts +20 -0
- package/build/src/server/contents/blob.d.ts.map +1 -0
- package/build/src/server/contents/blob.js +42 -0
- package/build/src/server/contents/embedded_resource.d.ts +25 -0
- package/build/src/server/contents/embedded_resource.d.ts.map +1 -0
- package/build/src/server/contents/embedded_resource.js +72 -0
- package/build/src/server/contents/error.d.ts +15 -0
- package/build/src/server/contents/error.d.ts.map +1 -0
- package/build/src/server/contents/error.js +16 -0
- package/build/src/server/contents/image.d.ts +24 -0
- package/build/src/server/contents/image.d.ts.map +1 -0
- package/build/src/server/contents/image.js +57 -0
- package/build/src/server/contents/resource_link.d.ts +22 -0
- package/build/src/server/contents/resource_link.d.ts.map +1 -0
- package/build/src/server/contents/resource_link.js +55 -0
- package/build/src/server/contents/structured.d.ts +20 -0
- package/build/src/server/contents/structured.d.ts.map +1 -0
- package/build/src/server/contents/structured.js +26 -0
- package/build/src/server/contents/text.d.ts +24 -0
- package/build/src/server/contents/text.d.ts.map +1 -0
- package/build/src/server/contents/text.js +61 -0
- package/build/src/server/context.d.ts +11 -6
- package/build/src/server/context.d.ts.map +1 -1
- package/build/src/server/context.js +30 -2
- package/build/src/server/contracts/content.d.ts +16 -0
- package/build/src/server/contracts/content.d.ts.map +1 -0
- package/build/src/server/contracts/content.js +8 -0
- package/build/src/server/contracts/context.d.ts +29 -0
- package/build/src/server/contracts/context.d.ts.map +1 -0
- package/build/src/server/contracts/response.d.ts +26 -0
- package/build/src/server/contracts/response.d.ts.map +1 -0
- package/build/src/{types → server/contracts}/transport.d.ts +2 -2
- package/build/src/server/contracts/transport.d.ts.map +1 -0
- package/build/src/server/contracts/transport.js +7 -0
- package/build/src/server/controllers/mcp_controller.d.ts.map +1 -1
- package/build/src/server/controllers/mcp_controller.js +0 -3
- package/build/src/server/exceptions/jsonrpc_exception.d.ts +6 -5
- package/build/src/server/exceptions/jsonrpc_exception.d.ts.map +1 -1
- package/build/src/server/exceptions/jsonrpc_exception.js +18 -9
- package/build/src/server/methods/call_tool.d.ts +2 -2
- package/build/src/server/methods/call_tool.d.ts.map +1 -1
- package/build/src/server/methods/call_tool.js +42 -17
- package/build/src/server/methods/completion.d.ts +12 -0
- package/build/src/server/methods/completion.d.ts.map +1 -0
- package/build/src/server/methods/completion.js +45 -0
- package/build/src/server/methods/get_prompt.d.ts +2 -2
- package/build/src/server/methods/get_prompt.d.ts.map +1 -1
- package/build/src/server/methods/get_prompt.js +55 -2
- package/build/src/server/methods/initialize.d.ts +2 -2
- package/build/src/server/methods/initialize.d.ts.map +1 -1
- package/build/src/server/methods/initialize.js +4 -1
- package/build/src/server/methods/list_prompts.d.ts +2 -2
- package/build/src/server/methods/list_prompts.d.ts.map +1 -1
- package/build/src/server/methods/list_prompts.js +24 -3
- package/build/src/server/methods/list_resource_templates.d.ts +12 -0
- package/build/src/server/methods/list_resource_templates.d.ts.map +1 -0
- package/build/src/server/methods/list_resource_templates.js +34 -0
- package/build/src/server/methods/list_resources.d.ts +2 -2
- package/build/src/server/methods/list_resources.d.ts.map +1 -1
- package/build/src/server/methods/list_resources.js +24 -3
- package/build/src/server/methods/list_tools.d.ts +2 -2
- package/build/src/server/methods/list_tools.d.ts.map +1 -1
- package/build/src/server/methods/list_tools.js +5 -17
- package/build/src/server/methods/ping.d.ts +2 -2
- package/build/src/server/methods/ping.d.ts.map +1 -1
- package/build/src/server/methods/ping.js +1 -1
- package/build/src/server/methods/read_resource.d.ts +2 -2
- package/build/src/server/methods/read_resource.d.ts.map +1 -1
- package/build/src/server/methods/read_resource.js +20 -2
- package/build/src/server/pagination/cursor_paginator.d.ts +2 -4
- package/build/src/server/pagination/cursor_paginator.d.ts.map +1 -1
- package/build/src/server/pagination/cursor_paginator.js +11 -11
- package/build/src/server/prompt.d.ts +27 -0
- package/build/src/server/prompt.d.ts.map +1 -0
- package/build/src/server/prompt.js +32 -0
- package/build/src/server/resource.d.ts +23 -0
- package/build/src/server/resource.d.ts.map +1 -0
- package/build/src/server/resource.js +40 -0
- package/build/src/server/tool.d.ts +19 -9
- package/build/src/server/tool.d.ts.map +1 -1
- package/build/src/server/tool.js +21 -0
- package/build/src/server/transports/fake_transport.d.ts +19 -1
- package/build/src/server/transports/fake_transport.d.ts.map +1 -1
- package/build/src/server/transports/fake_transport.js +28 -1
- package/build/src/server/transports/http_transport.d.ts +4 -3
- package/build/src/server/transports/http_transport.d.ts.map +1 -1
- package/build/src/server/transports/http_transport.js +14 -9
- package/build/src/server/transports/stdio_transport.d.ts +2 -2
- package/build/src/server/transports/stdio_transport.d.ts.map +1 -1
- package/build/src/server/transports/stdio_transport.js +0 -3
- package/build/src/server.d.ts +4 -3
- package/build/src/server.d.ts.map +1 -1
- package/build/src/server.js +15 -9
- package/build/src/types/config.d.ts +1 -0
- package/build/src/types/config.d.ts.map +1 -1
- package/build/src/types/content.d.ts +35 -0
- package/build/src/types/content.d.ts.map +1 -0
- package/build/src/types/content.js +7 -0
- package/build/src/types/context.d.ts +30 -18
- package/build/src/types/context.d.ts.map +1 -1
- package/build/src/types/jsonrpc.d.ts +406 -0
- package/build/src/types/jsonrpc.d.ts.map +1 -0
- package/build/src/types/jsonrpc.js +7 -0
- package/build/src/types/request.d.ts +3 -37
- package/build/src/types/request.d.ts.map +1 -1
- package/build/src/types/response.d.ts +10 -39
- package/build/src/types/response.d.ts.map +1 -1
- package/build/src/utils/find_resource_pattern.d.ts +19 -0
- package/build/src/utils/find_resource_pattern.d.ts.map +1 -0
- package/build/src/utils/find_resource_pattern.js +35 -0
- package/build/src/utils/stdio.d.ts +2 -3
- package/build/src/utils/stdio.d.ts.map +1 -1
- package/build/src/utils/stdio.js +7 -7
- package/build/src/utils/uri_template.d.ts +25 -0
- package/build/src/utils/uri_template.d.ts.map +1 -0
- package/build/src/utils/uri_template.js +241 -0
- package/build/stubs/config.ts.stub +0 -1
- package/build/stubs/make/mcp/prompts/main.ts.stub +32 -16
- package/build/stubs/make/mcp/resources/main.ts.stub +13 -19
- package/build/stubs/make/mcp/tools/main.ts.stub +11 -13
- package/build/stubs/make/middleware/mcp_middleware.ts.stub +48 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +21 -4
- package/build/src/types/notification.d.ts +0 -14
- package/build/src/types/notification.d.ts.map +0 -1
- package/build/src/types/transport.d.ts.map +0 -1
- /package/build/src/{types/notification.js → server/contracts/context.js} +0 -0
- /package/build/src/{types/transport.js → server/contracts/response.js} +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type Variables = Record<string, string | string[]>;
|
|
2
|
+
export declare class UriTemplate {
|
|
3
|
+
/**
|
|
4
|
+
* Returns true if the given string contains any URI template expressions.
|
|
5
|
+
* A template expression is a sequence of characters enclosed in curly braces,
|
|
6
|
+
* like {foo} or {?bar}.
|
|
7
|
+
*/
|
|
8
|
+
static isTemplate(str: string): boolean;
|
|
9
|
+
private static validateLength;
|
|
10
|
+
private readonly template;
|
|
11
|
+
private readonly parts;
|
|
12
|
+
get variableNames(): string[];
|
|
13
|
+
constructor(template: string);
|
|
14
|
+
toString(): string;
|
|
15
|
+
private parse;
|
|
16
|
+
private getOperator;
|
|
17
|
+
private getNames;
|
|
18
|
+
private encodeValue;
|
|
19
|
+
private expandPart;
|
|
20
|
+
expand(variables: Variables): string;
|
|
21
|
+
private escapeRegExp;
|
|
22
|
+
private partToRegExp;
|
|
23
|
+
match(uri: string): Variables | null;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=uri_template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uri_template.d.ts","sourceRoot":"","sources":["../../../src/utils/uri_template.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAA;AASzD,qBAAa,WAAW;IACtB;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAMvC,OAAO,CAAC,MAAM,CAAC,cAAc;IAQ7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAErB;IAED,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;gBAEW,QAAQ,EAAE,MAAM;IAM5B,QAAQ,IAAI,MAAM;IAIlB,OAAO,CAAC,KAAK;IAsDb,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,UAAU;IAsDlB,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM;IA4BpC,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IAkDpB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;CAuCrC"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// Claude-authored implementation of RFC 6570 URI Templates
|
|
2
|
+
import { createError } from '@adonisjs/core/exceptions';
|
|
3
|
+
const MAX_TEMPLATE_LENGTH = 1000000; // 1MB
|
|
4
|
+
const MAX_VARIABLE_LENGTH = 1000000; // 1MB
|
|
5
|
+
const MAX_TEMPLATE_EXPRESSIONS = 10000;
|
|
6
|
+
const MAX_REGEX_LENGTH = 1000000; // 1MB
|
|
7
|
+
export class UriTemplate {
|
|
8
|
+
/**
|
|
9
|
+
* Returns true if the given string contains any URI template expressions.
|
|
10
|
+
* A template expression is a sequence of characters enclosed in curly braces,
|
|
11
|
+
* like {foo} or {?bar}.
|
|
12
|
+
*/
|
|
13
|
+
static isTemplate(str) {
|
|
14
|
+
// Look for any sequence of characters between curly braces
|
|
15
|
+
// that isn't just whitespace
|
|
16
|
+
return /\{[^}\s]+\}/.test(str);
|
|
17
|
+
}
|
|
18
|
+
static validateLength(str, max, context) {
|
|
19
|
+
if (str.length > max) {
|
|
20
|
+
throw createError(`${context} exceeds maximum length of ${max} characters (got ${str.length})`, 'E_URI_TEMPLATE_LENGTH_EXCEEDED');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
template;
|
|
24
|
+
parts;
|
|
25
|
+
get variableNames() {
|
|
26
|
+
return this.parts.flatMap((part) => (typeof part === 'string' ? [] : part.names));
|
|
27
|
+
}
|
|
28
|
+
constructor(template) {
|
|
29
|
+
UriTemplate.validateLength(template, MAX_TEMPLATE_LENGTH, 'Template');
|
|
30
|
+
this.template = template;
|
|
31
|
+
this.parts = this.parse(template);
|
|
32
|
+
}
|
|
33
|
+
toString() {
|
|
34
|
+
return this.template;
|
|
35
|
+
}
|
|
36
|
+
parse(template) {
|
|
37
|
+
const parts = [];
|
|
38
|
+
let currentText = '';
|
|
39
|
+
let i = 0;
|
|
40
|
+
let expressionCount = 0;
|
|
41
|
+
while (i < template.length) {
|
|
42
|
+
if (template[i] === '{') {
|
|
43
|
+
if (currentText) {
|
|
44
|
+
parts.push(currentText);
|
|
45
|
+
currentText = '';
|
|
46
|
+
}
|
|
47
|
+
const end = template.indexOf('}', i);
|
|
48
|
+
if (end === -1)
|
|
49
|
+
throw createError('Unclosed template expression', 'E_URI_TEMPLATE_UNCLOSED_EXPRESSION');
|
|
50
|
+
expressionCount++;
|
|
51
|
+
if (expressionCount > MAX_TEMPLATE_EXPRESSIONS) {
|
|
52
|
+
throw createError(`Template contains too many expressions (max ${MAX_TEMPLATE_EXPRESSIONS})`, 'E_URI_TEMPLATE_TOO_MANY_EXPRESSIONS');
|
|
53
|
+
}
|
|
54
|
+
const expr = template.slice(i + 1, end);
|
|
55
|
+
const operator = this.getOperator(expr);
|
|
56
|
+
const exploded = expr.includes('*');
|
|
57
|
+
const names = this.getNames(expr);
|
|
58
|
+
const name = names[0];
|
|
59
|
+
// Validate variable name length
|
|
60
|
+
for (const name of names) {
|
|
61
|
+
UriTemplate.validateLength(name, MAX_VARIABLE_LENGTH, 'Variable name');
|
|
62
|
+
}
|
|
63
|
+
parts.push({ name, operator, names, exploded });
|
|
64
|
+
i = end + 1;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
currentText += template[i];
|
|
68
|
+
i++;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (currentText) {
|
|
72
|
+
parts.push(currentText);
|
|
73
|
+
}
|
|
74
|
+
return parts;
|
|
75
|
+
}
|
|
76
|
+
getOperator(expr) {
|
|
77
|
+
const operators = ['+', '#', '.', '/', '?', '&'];
|
|
78
|
+
return operators.find((op) => expr.startsWith(op)) || '';
|
|
79
|
+
}
|
|
80
|
+
getNames(expr) {
|
|
81
|
+
const operator = this.getOperator(expr);
|
|
82
|
+
return expr
|
|
83
|
+
.slice(operator.length)
|
|
84
|
+
.split(',')
|
|
85
|
+
.map((name) => name.replace('*', '').trim())
|
|
86
|
+
.filter((name) => name.length > 0);
|
|
87
|
+
}
|
|
88
|
+
encodeValue(value, operator) {
|
|
89
|
+
UriTemplate.validateLength(value, MAX_VARIABLE_LENGTH, 'Variable value');
|
|
90
|
+
if (operator === '+' || operator === '#') {
|
|
91
|
+
return encodeURI(value);
|
|
92
|
+
}
|
|
93
|
+
return encodeURIComponent(value);
|
|
94
|
+
}
|
|
95
|
+
expandPart(part, variables) {
|
|
96
|
+
if (part.operator === '?' || part.operator === '&') {
|
|
97
|
+
const pairs = part.names
|
|
98
|
+
.map((name) => {
|
|
99
|
+
const value = variables[name];
|
|
100
|
+
if (value === undefined)
|
|
101
|
+
return '';
|
|
102
|
+
const encoded = Array.isArray(value)
|
|
103
|
+
? value.map((v) => this.encodeValue(v, part.operator)).join(',')
|
|
104
|
+
: this.encodeValue(value.toString(), part.operator);
|
|
105
|
+
return `${name}=${encoded}`;
|
|
106
|
+
})
|
|
107
|
+
.filter((pair) => pair.length > 0);
|
|
108
|
+
if (pairs.length === 0)
|
|
109
|
+
return '';
|
|
110
|
+
const separator = part.operator === '?' ? '?' : '&';
|
|
111
|
+
return separator + pairs.join('&');
|
|
112
|
+
}
|
|
113
|
+
if (part.names.length > 1) {
|
|
114
|
+
const values = part.names.map((name) => variables[name]).filter((v) => v !== undefined);
|
|
115
|
+
if (values.length === 0)
|
|
116
|
+
return '';
|
|
117
|
+
return values.map((v) => (Array.isArray(v) ? v[0] : v)).join(',');
|
|
118
|
+
}
|
|
119
|
+
const value = variables[part.name];
|
|
120
|
+
if (value === undefined)
|
|
121
|
+
return '';
|
|
122
|
+
const values = Array.isArray(value) ? value : [value];
|
|
123
|
+
const encoded = values.map((v) => this.encodeValue(v, part.operator));
|
|
124
|
+
switch (part.operator) {
|
|
125
|
+
case '':
|
|
126
|
+
return encoded.join(',');
|
|
127
|
+
case '+':
|
|
128
|
+
return encoded.join(',');
|
|
129
|
+
case '#':
|
|
130
|
+
return '#' + encoded.join(',');
|
|
131
|
+
case '.':
|
|
132
|
+
return '.' + encoded.join('.');
|
|
133
|
+
case '/':
|
|
134
|
+
return '/' + encoded.join('/');
|
|
135
|
+
default:
|
|
136
|
+
return encoded.join(',');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
expand(variables) {
|
|
140
|
+
let result = '';
|
|
141
|
+
let hasQueryParam = false;
|
|
142
|
+
for (const part of this.parts) {
|
|
143
|
+
if (typeof part === 'string') {
|
|
144
|
+
result += part;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const expanded = this.expandPart(part, variables);
|
|
148
|
+
if (!expanded)
|
|
149
|
+
continue;
|
|
150
|
+
// Convert ? to & if we already have a query parameter
|
|
151
|
+
if ((part.operator === '?' || part.operator === '&') && hasQueryParam) {
|
|
152
|
+
result += expanded.replace('?', '&');
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
result += expanded;
|
|
156
|
+
}
|
|
157
|
+
if (part.operator === '?' || part.operator === '&') {
|
|
158
|
+
hasQueryParam = true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
escapeRegExp(str) {
|
|
164
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
165
|
+
}
|
|
166
|
+
partToRegExp(part) {
|
|
167
|
+
const patterns = [];
|
|
168
|
+
// Validate variable name length for matching
|
|
169
|
+
for (const name of part.names) {
|
|
170
|
+
UriTemplate.validateLength(name, MAX_VARIABLE_LENGTH, 'Variable name');
|
|
171
|
+
}
|
|
172
|
+
if (part.operator === '?' || part.operator === '&') {
|
|
173
|
+
for (let i = 0; i < part.names.length; i++) {
|
|
174
|
+
const name = part.names[i];
|
|
175
|
+
const prefix = i === 0 ? '\\' + part.operator : '&';
|
|
176
|
+
patterns.push({
|
|
177
|
+
pattern: prefix + this.escapeRegExp(name) + '=([^&]+)',
|
|
178
|
+
name,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return patterns;
|
|
182
|
+
}
|
|
183
|
+
let pattern;
|
|
184
|
+
const name = part.name;
|
|
185
|
+
switch (part.operator) {
|
|
186
|
+
case '':
|
|
187
|
+
pattern = part.exploded ? '([^/]+(?:,[^/]+)*)' : '([^/,]+)';
|
|
188
|
+
break;
|
|
189
|
+
case '+':
|
|
190
|
+
case '#':
|
|
191
|
+
pattern = '(.+)';
|
|
192
|
+
break;
|
|
193
|
+
case '.':
|
|
194
|
+
pattern = '\\.([^/,]+)';
|
|
195
|
+
break;
|
|
196
|
+
case '/':
|
|
197
|
+
pattern = '/' + (part.exploded ? '([^/]+(?:,[^/]+)*)' : '([^/,]+)');
|
|
198
|
+
break;
|
|
199
|
+
default:
|
|
200
|
+
pattern = '([^/]+)';
|
|
201
|
+
}
|
|
202
|
+
patterns.push({ pattern, name });
|
|
203
|
+
return patterns;
|
|
204
|
+
}
|
|
205
|
+
match(uri) {
|
|
206
|
+
UriTemplate.validateLength(uri, MAX_TEMPLATE_LENGTH, 'URI');
|
|
207
|
+
let pattern = '^';
|
|
208
|
+
const names = [];
|
|
209
|
+
for (const part of this.parts) {
|
|
210
|
+
if (typeof part === 'string') {
|
|
211
|
+
pattern += this.escapeRegExp(part);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
const patterns = this.partToRegExp(part);
|
|
215
|
+
for (const { pattern: partPattern, name } of patterns) {
|
|
216
|
+
pattern += partPattern;
|
|
217
|
+
names.push({ name, exploded: part.exploded });
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
pattern += '$';
|
|
222
|
+
UriTemplate.validateLength(pattern, MAX_REGEX_LENGTH, 'Generated regex pattern');
|
|
223
|
+
const regex = new RegExp(pattern);
|
|
224
|
+
const match = uri.match(regex);
|
|
225
|
+
if (!match)
|
|
226
|
+
return null;
|
|
227
|
+
const result = {};
|
|
228
|
+
for (let i = 0; i < names.length; i++) {
|
|
229
|
+
const { name, exploded } = names[i];
|
|
230
|
+
const value = match[i + 1];
|
|
231
|
+
const cleanName = name.replace('*', '');
|
|
232
|
+
if (exploded && value.includes(',')) {
|
|
233
|
+
result[cleanName] = value.split(',');
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
result[cleanName] = value;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return result;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
@@ -1,27 +1,43 @@
|
|
|
1
|
+
{{#var className = `${name}Prompt`}}
|
|
2
|
+
{{#var promptName = string(name).snakeCase()}}
|
|
1
3
|
{{#var resourceFileName = string(className).snakeCase().ext('.ts').toString()}}
|
|
2
4
|
{{{
|
|
3
5
|
exports({
|
|
4
|
-
to: app.makePath(app.rcFile.directories['mcp'] || 'app/mcp/',
|
|
6
|
+
to: app.makePath(app.rcFile.directories['mcp'] || 'app/mcp/', `prompts/`, resourceFileName)
|
|
5
7
|
})
|
|
6
8
|
}}}
|
|
7
|
-
import type {
|
|
9
|
+
import type { PromptContext } from '@jrmc/adonis-mcp/types/context'
|
|
10
|
+
import type { BaseSchema } from '@jrmc/adonis-mcp/types/method'
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
import { Prompt } from '@jrmc/adonis-mcp'
|
|
13
|
+
|
|
14
|
+
type Schema = BaseSchema<{
|
|
15
|
+
text: { type: "string" }
|
|
16
|
+
}>
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export default class {{ className }} extends Prompt<Schema> {
|
|
20
|
+
name = '{{ promptName }}'
|
|
21
|
+
title = 'Prompt title'
|
|
22
|
+
description = 'Prompt description'
|
|
23
|
+
|
|
24
|
+
async handle({ args, response }: PromptContext<Schema>) {
|
|
25
|
+
console.log(args?.text)
|
|
26
|
+
return [
|
|
27
|
+
response.text('Hello, world!')
|
|
28
|
+
]
|
|
15
29
|
}
|
|
16
30
|
|
|
17
|
-
|
|
31
|
+
schema() {
|
|
18
32
|
return {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
type: "object",
|
|
34
|
+
properties: {
|
|
35
|
+
text: {
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "Description text argument"
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
required: ["text"]
|
|
41
|
+
} as Schema
|
|
26
42
|
}
|
|
27
43
|
}
|
|
@@ -1,29 +1,23 @@
|
|
|
1
|
+
{{#var className = `${name}Resource`}}
|
|
1
2
|
{{#var resourceFileName = string(className).snakeCase().ext('.ts').toString()}}
|
|
2
3
|
{{{
|
|
3
4
|
exports({
|
|
4
|
-
to: app.makePath(app.rcFile.directories['mcp'] || 'app/mcp/',
|
|
5
|
+
to: app.makePath(app.rcFile.directories['mcp'] || 'app/mcp/', `resources/`, resourceFileName)
|
|
5
6
|
})
|
|
6
7
|
}}}
|
|
7
|
-
import
|
|
8
|
+
import type { ResourceContext } from '@jrmc/adonis-mcp/types/context'
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
import { Resource } from '@jrmc/adonis-mcp'
|
|
11
|
+
|
|
12
|
+
export default class {{ className }} extends Resource {
|
|
13
|
+
name = 'example.txt'
|
|
14
|
+
uri = 'file:///example.txt'
|
|
15
|
+
mimeType = 'text/plain"'
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
title = 'ToResource title'
|
|
18
|
+
description = 'Resource description'
|
|
17
19
|
|
|
18
|
-
async handle(
|
|
19
|
-
return
|
|
20
|
-
// return {
|
|
21
|
-
// contents: [
|
|
22
|
-
// {
|
|
23
|
-
// uri: uri.href,
|
|
24
|
-
// text: `Profile data for user ${userId}`
|
|
25
|
-
// }
|
|
26
|
-
// ]
|
|
27
|
-
// }
|
|
20
|
+
async handle({ response }: ResourceContext) {
|
|
21
|
+
return response.text('Hello World')
|
|
28
22
|
}
|
|
29
23
|
}
|
|
@@ -1,41 +1,39 @@
|
|
|
1
1
|
{{#var className = `${name}Tool`}}
|
|
2
|
+
{{#var toolName = string(name).snakeCase()}}
|
|
2
3
|
{{#var resourceFileName = string(className).snakeCase().ext('.ts').toString()}}
|
|
3
4
|
{{{
|
|
4
5
|
exports({
|
|
5
|
-
to: app.makePath(app.rcFile.directories['mcp'] ||
|
|
6
|
+
to: app.makePath(app.rcFile.directories['mcp'] || 'app/mcp/', `tools/`, resourceFileName)
|
|
6
7
|
})
|
|
7
8
|
}}}
|
|
8
|
-
import type {
|
|
9
|
-
import type { BaseSchema
|
|
9
|
+
import type { ToolContext } from '@jrmc/adonis-mcp/types/context'
|
|
10
|
+
import type { BaseSchema } from '@jrmc/adonis-mcp/types/method'
|
|
10
11
|
|
|
11
12
|
import { Tool } from '@jrmc/adonis-mcp'
|
|
12
13
|
|
|
13
14
|
type Schema = BaseSchema<{
|
|
14
|
-
|
|
15
|
+
name: { type: "string" }
|
|
15
16
|
}>
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export default class {{ className }} implements Tool<Schema> {
|
|
20
|
-
name = '{{ name }}'
|
|
18
|
+
export default class {{ className }} extends Tool<Schema> {
|
|
19
|
+
name = '{{ toolName }}'
|
|
21
20
|
title = 'Tool title'
|
|
22
21
|
description = 'Tool description'
|
|
23
22
|
|
|
24
|
-
async handle({ args, response }:
|
|
25
|
-
|
|
26
|
-
return response.text(JSON.stringify({ text: 'Hello, world!' }))
|
|
23
|
+
async handle({ args, response }: ToolContext<Schema>) {
|
|
24
|
+
return response.text({{ "`Hello, ${args?.name}`" }})
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
schema() {
|
|
30
28
|
return {
|
|
31
29
|
type: "object",
|
|
32
30
|
properties: {
|
|
33
|
-
|
|
31
|
+
name: {
|
|
34
32
|
type: "string",
|
|
35
33
|
description: "Description text argument"
|
|
36
34
|
},
|
|
37
35
|
},
|
|
38
|
-
required: ["
|
|
36
|
+
required: ["name"]
|
|
39
37
|
} as Schema
|
|
40
38
|
}
|
|
41
39
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.middlewarePath('mcp_middleware.ts') })
|
|
3
|
+
}}}
|
|
4
|
+
import type { HttpContext } from '@adonisjs/core/http'
|
|
5
|
+
import type { NextFn } from '@adonisjs/core/types/http'
|
|
6
|
+
|
|
7
|
+
// import { policies } from '#policies/main'
|
|
8
|
+
// import * as abilities from '#abilities/main'
|
|
9
|
+
// import { Bouncer } from '@adonisjs/bouncer'
|
|
10
|
+
|
|
11
|
+
export default class McpMiddleware {
|
|
12
|
+
async handle(ctx: HttpContext, next: NextFn) {
|
|
13
|
+
const body = ctx.request.body()
|
|
14
|
+
const method = body.method
|
|
15
|
+
|
|
16
|
+
const contentType = ctx.request.header('Content-Type')
|
|
17
|
+
if (!contentType || !['application/json', 'text/event-stream'].includes(contentType)) {
|
|
18
|
+
return ctx.response.badRequest('Content-Type header must be application/json')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (method === 'initialize') {
|
|
22
|
+
ctx.response.safeHeader('MCP-Session-Id', crypto.randomUUID())
|
|
23
|
+
} else {
|
|
24
|
+
const sessionId = ctx.request.header('MCP-Session-Id')
|
|
25
|
+
|
|
26
|
+
if (!sessionId) {
|
|
27
|
+
return ctx.response.badRequest('MCP-Session-Id header is required')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
ctx.response.safeHeader('MCP-Session-Id', sessionId)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return next()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// declare module '@jrmc/adonis-mcp/types/context' {
|
|
38
|
+
// export interface McpContext {
|
|
39
|
+
// auth?: {
|
|
40
|
+
// user?: HttpContext['auth']['user']
|
|
41
|
+
// }
|
|
42
|
+
// bouncer?: Bouncer<
|
|
43
|
+
// Exclude<HttpContext['auth']['user'], undefined>,
|
|
44
|
+
// typeof abilities,
|
|
45
|
+
// typeof policies
|
|
46
|
+
// >
|
|
47
|
+
// }
|
|
48
|
+
// }
|