mcp-orbit 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.
- package/LICENSE +21 -0
- package/README.md +247 -0
- package/dist/__tests__/helpers/test-server.d.ts +2 -0
- package/dist/__tests__/helpers/test-server.d.ts.map +1 -0
- package/dist/__tests__/helpers/test-server.js +27 -0
- package/dist/__tests__/helpers/test-server.js.map +1 -0
- package/dist/cli.d.ts +23 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +56 -0
- package/dist/cli.js.map +1 -0
- package/dist/clients/mcp-http.d.ts +36 -0
- package/dist/clients/mcp-http.d.ts.map +1 -0
- package/dist/clients/mcp-http.js +148 -0
- package/dist/clients/mcp-http.js.map +1 -0
- package/dist/clients/mcp-stdio.d.ts +38 -0
- package/dist/clients/mcp-stdio.d.ts.map +1 -0
- package/dist/clients/mcp-stdio.js +164 -0
- package/dist/clients/mcp-stdio.js.map +1 -0
- package/dist/clients/types.d.ts +104 -0
- package/dist/clients/types.d.ts.map +1 -0
- package/dist/clients/types.js +8 -0
- package/dist/clients/types.js.map +1 -0
- package/dist/core/prompt-registry.d.ts +56 -0
- package/dist/core/prompt-registry.d.ts.map +1 -0
- package/dist/core/prompt-registry.js +100 -0
- package/dist/core/prompt-registry.js.map +1 -0
- package/dist/core/resource-registry.d.ts +79 -0
- package/dist/core/resource-registry.d.ts.map +1 -0
- package/dist/core/resource-registry.js +135 -0
- package/dist/core/resource-registry.js.map +1 -0
- package/dist/core/resource-uri-templates.d.ts +64 -0
- package/dist/core/resource-uri-templates.d.ts.map +1 -0
- package/dist/core/resource-uri-templates.js +168 -0
- package/dist/core/resource-uri-templates.js.map +1 -0
- package/dist/core/server-http.d.ts +15 -0
- package/dist/core/server-http.d.ts.map +1 -0
- package/dist/core/server-http.js +302 -0
- package/dist/core/server-http.js.map +1 -0
- package/dist/core/server-stdio.d.ts +8 -0
- package/dist/core/server-stdio.d.ts.map +1 -0
- package/dist/core/server-stdio.js +15 -0
- package/dist/core/server-stdio.js.map +1 -0
- package/dist/core/server.d.ts +29 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/server.js +265 -0
- package/dist/core/server.js.map +1 -0
- package/dist/core/types.d.ts +265 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +9 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/dynamic-resource-manager.d.ts +115 -0
- package/dist/utils/dynamic-resource-manager.d.ts.map +1 -0
- package/dist/utils/dynamic-resource-manager.js +460 -0
- package/dist/utils/dynamic-resource-manager.js.map +1 -0
- package/dist/utils/http-client.d.ts +29 -0
- package/dist/utils/http-client.d.ts.map +1 -0
- package/dist/utils/http-client.js +59 -0
- package/dist/utils/http-client.js.map +1 -0
- package/dist/utils/logger.d.ts +25 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +105 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/zod-to-mcp-schema.d.ts +42 -0
- package/dist/utils/zod-to-mcp-schema.d.ts.map +1 -0
- package/dist/utils/zod-to-mcp-schema.js +87 -0
- package/dist/utils/zod-to-mcp-schema.js.map +1 -0
- package/package.json +57 -0
- package/src/__tests__/helpers/test-server.ts +31 -0
- package/src/__tests__/plugin-system.basic.test.ts +137 -0
- package/src/__tests__/server.basic.test.ts +37 -0
- package/src/__tests__/stdio-roundtrip.basic.test.ts +67 -0
- package/src/__tests__/tool-registry.basic.test.ts +114 -0
- package/src/__tests__/zod-schema.basic.test.ts +105 -0
- package/src/cli.ts +58 -0
- package/src/clients/mcp-http.ts +192 -0
- package/src/clients/mcp-stdio.ts +209 -0
- package/src/clients/types.ts +136 -0
- package/src/core/prompt-registry.ts +114 -0
- package/src/core/resource-registry.ts +166 -0
- package/src/core/resource-uri-templates.ts +216 -0
- package/src/core/server-http.ts +407 -0
- package/src/core/server-stdio.ts +20 -0
- package/src/core/server.ts +320 -0
- package/src/core/types.ts +312 -0
- package/src/index.ts +92 -0
- package/src/utils/dynamic-resource-manager.ts +581 -0
- package/src/utils/http-client.ts +86 -0
- package/src/utils/logger.ts +138 -0
- package/src/utils/zod-to-mcp-schema.ts +127 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource Registry - Simplified with RFC 6570 Templates
|
|
3
|
+
*
|
|
4
|
+
* Auto-registration pattern with:
|
|
5
|
+
* - Direct array access for static resources
|
|
6
|
+
* - RFC 6570 URI template support for dynamic resources
|
|
7
|
+
*/
|
|
8
|
+
import { TemplateRegistry } from "./resource-uri-templates.js";
|
|
9
|
+
import logger from "../utils/logger.js";
|
|
10
|
+
const resourceLogger = logger.child("resources");
|
|
11
|
+
// Global resources array - single source of truth
|
|
12
|
+
const resources = [];
|
|
13
|
+
// Template registry for RFC 6570 URI template support
|
|
14
|
+
const templateRegistry = new TemplateRegistry();
|
|
15
|
+
/**
|
|
16
|
+
* Create and register a resource provider
|
|
17
|
+
*
|
|
18
|
+
* Usage:
|
|
19
|
+
* const resource = createAndRegisterResource({ uri, name, read: async () => ({ text }) });
|
|
20
|
+
*
|
|
21
|
+
* Supports both static URIs and RFC 6570 URI templates:
|
|
22
|
+
* - Static: "cache://users/123"
|
|
23
|
+
* - Template: "cache://users/{id}"
|
|
24
|
+
*
|
|
25
|
+
* This function is called during resource module imports (auto-registration pattern)
|
|
26
|
+
*/
|
|
27
|
+
export function createAndRegisterResource(resource) {
|
|
28
|
+
if (resources.some((r) => r.uri === resource.uri)) {
|
|
29
|
+
resourceLogger.warn(`Resource '${resource.uri}' already registered, overwriting...`);
|
|
30
|
+
}
|
|
31
|
+
resources.push(resource);
|
|
32
|
+
if (resource.uri.includes("{")) {
|
|
33
|
+
templateRegistry.registerTemplate(resource.uri);
|
|
34
|
+
resourceLogger.info(`Resource registered (template): ${resource.uri}`);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
resourceLogger.info(`Resource registered: ${resource.uri}`);
|
|
38
|
+
}
|
|
39
|
+
return resource;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Unregister a resource by URI (used when TTL expires)
|
|
43
|
+
*/
|
|
44
|
+
export function unregisterResource(uri) {
|
|
45
|
+
const index = resources.findIndex((r) => r.uri === uri);
|
|
46
|
+
if (index !== -1) {
|
|
47
|
+
resources.splice(index, 1);
|
|
48
|
+
resourceLogger.info(`Resource unregistered: ${uri}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get all resource definitions (for MCP ListResources response)
|
|
53
|
+
*/
|
|
54
|
+
export function getResourceDefinitions() {
|
|
55
|
+
return resources.map((provider) => ({
|
|
56
|
+
uri: provider.uri,
|
|
57
|
+
name: provider.name,
|
|
58
|
+
description: provider.description,
|
|
59
|
+
title: provider.title,
|
|
60
|
+
mimeType: provider.mimeType,
|
|
61
|
+
size: provider.size,
|
|
62
|
+
schema: provider.schema,
|
|
63
|
+
annotations: provider.annotations,
|
|
64
|
+
toolset: provider.toolset,
|
|
65
|
+
scope: provider.scope,
|
|
66
|
+
capabilities: provider.capabilities,
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get a resource by URI
|
|
71
|
+
*/
|
|
72
|
+
export function getResource(uri) {
|
|
73
|
+
return resources.find((r) => r.uri === uri);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Read a resource (resources/read)
|
|
77
|
+
*/
|
|
78
|
+
export async function readResource(uri) {
|
|
79
|
+
const resource = getResource(uri);
|
|
80
|
+
if (!resource) {
|
|
81
|
+
throw new Error(`Resource not found: ${uri}`);
|
|
82
|
+
}
|
|
83
|
+
const content = await resource.read();
|
|
84
|
+
return {
|
|
85
|
+
contents: [
|
|
86
|
+
{
|
|
87
|
+
uri: resource.uri,
|
|
88
|
+
name: resource.name,
|
|
89
|
+
title: resource.title,
|
|
90
|
+
mimeType: resource.mimeType,
|
|
91
|
+
size: resource.size,
|
|
92
|
+
schema: resource.schema,
|
|
93
|
+
annotations: resource.annotations,
|
|
94
|
+
...content,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get count of registered resources
|
|
101
|
+
*/
|
|
102
|
+
export function getResourceCount() {
|
|
103
|
+
return resources.length;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if a resource exists
|
|
107
|
+
*/
|
|
108
|
+
export function hasResource(uri) {
|
|
109
|
+
return resources.some((r) => r.uri === uri);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get all registered RFC 6570 URI template patterns
|
|
113
|
+
*/
|
|
114
|
+
export function getTemplatePatterns() {
|
|
115
|
+
return templateRegistry.getTemplates();
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get template registry (for advanced template operations)
|
|
119
|
+
*/
|
|
120
|
+
export function getTemplateRegistry() {
|
|
121
|
+
return templateRegistry;
|
|
122
|
+
}
|
|
123
|
+
export const resourceRegistry = {
|
|
124
|
+
register: createAndRegisterResource,
|
|
125
|
+
unregister: unregisterResource,
|
|
126
|
+
listDefinitions: getResourceDefinitions,
|
|
127
|
+
read: readResource,
|
|
128
|
+
get count() {
|
|
129
|
+
return getResourceCount();
|
|
130
|
+
},
|
|
131
|
+
has: hasResource,
|
|
132
|
+
getTemplates: getTemplatePatterns,
|
|
133
|
+
getTemplateRegistry,
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=resource-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-registry.js","sourceRoot":"","sources":["../../src/core/resource-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 6570 URI Template Support
|
|
3
|
+
*
|
|
4
|
+
* Implements RFC 6570 URI template matching for resource patterns.
|
|
5
|
+
* Enables pattern-based resource definitions like:
|
|
6
|
+
* - cache://tools/{id}
|
|
7
|
+
* - kraken://balance/{pair}
|
|
8
|
+
*
|
|
9
|
+
* See: https://tools.ietf.org/html/rfc6570
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* RFC 6570 template variables with operators:
|
|
13
|
+
* - Simple expansion: {var}
|
|
14
|
+
* - Reserved expansion: {+var}
|
|
15
|
+
* - Fragment expansion: {#var}
|
|
16
|
+
* - Label expansion: {.var}
|
|
17
|
+
* - Path expansion: {/var}
|
|
18
|
+
* - Parameter expansion: {?var}
|
|
19
|
+
* - Query continuation: {&var}
|
|
20
|
+
*/
|
|
21
|
+
export interface URITemplate {
|
|
22
|
+
pattern: string;
|
|
23
|
+
regex: RegExp;
|
|
24
|
+
variables: string[];
|
|
25
|
+
}
|
|
26
|
+
export interface URIMatch {
|
|
27
|
+
matched: boolean;
|
|
28
|
+
variables: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse RFC 6570 URI template and create a regex matcher
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseURITemplate(template: string): URITemplate;
|
|
34
|
+
/**
|
|
35
|
+
* Match a URI against a template and extract variables
|
|
36
|
+
*/
|
|
37
|
+
export declare function matchURITemplate(uri: string, template: URITemplate): URIMatch;
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a URI template with specific variable values
|
|
40
|
+
* Example: resolveURITemplate("cache://tools/{id}", { id: "123" }) => "cache://tools/123"
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveURITemplate(template: string, variables: Record<string, string>): string;
|
|
43
|
+
/**
|
|
44
|
+
* Template Registry for matching dynamic resources
|
|
45
|
+
*/
|
|
46
|
+
export declare class TemplateRegistry {
|
|
47
|
+
private templates;
|
|
48
|
+
/**
|
|
49
|
+
* Register a URI template pattern
|
|
50
|
+
*/
|
|
51
|
+
registerTemplate(pattern: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* Find matching template for a given URI
|
|
54
|
+
*/
|
|
55
|
+
findMatchingTemplate(uri: string): {
|
|
56
|
+
pattern: string;
|
|
57
|
+
match: URIMatch;
|
|
58
|
+
} | null;
|
|
59
|
+
/**
|
|
60
|
+
* Get all registered templates
|
|
61
|
+
*/
|
|
62
|
+
getTemplates(): string[];
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=resource-uri-templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-uri-templates.d.ts","sourceRoot":"","sources":["../../src/core/resource-uri-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;GASG;AAEH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAuD9D;AA2BD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,QAAQ,CAa7E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAuC9F;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAuC;IAExD;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMvC;;OAEG;IACH,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,QAAQ,CAAA;KAAC,GAAG,IAAI;IAU5E;;OAEG;IACH,YAAY,IAAI,MAAM,EAAE;CAGzB"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 6570 URI Template Support
|
|
3
|
+
*
|
|
4
|
+
* Implements RFC 6570 URI template matching for resource patterns.
|
|
5
|
+
* Enables pattern-based resource definitions like:
|
|
6
|
+
* - cache://tools/{id}
|
|
7
|
+
* - kraken://balance/{pair}
|
|
8
|
+
*
|
|
9
|
+
* See: https://tools.ietf.org/html/rfc6570
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Parse RFC 6570 URI template and create a regex matcher
|
|
13
|
+
*/
|
|
14
|
+
export function parseURITemplate(template) {
|
|
15
|
+
// Extract all template variables: {var}, {+var}, {#var}, etc.
|
|
16
|
+
const variableRegex = /\{([+#./?&]?)([a-zA-Z_][a-zA-Z0-9_]*(?:,[a-zA-Z_][a-zA-Z0-9_]*)*)\}/g;
|
|
17
|
+
const variables = [];
|
|
18
|
+
const parts = [];
|
|
19
|
+
let lastIndex = 0;
|
|
20
|
+
// Build regex pattern from template
|
|
21
|
+
let match;
|
|
22
|
+
while ((match = variableRegex.exec(template)) !== null) {
|
|
23
|
+
// Add literal part before this match
|
|
24
|
+
if (match.index > lastIndex) {
|
|
25
|
+
const literal = template.substring(lastIndex, match.index);
|
|
26
|
+
parts.push({
|
|
27
|
+
type: "literal",
|
|
28
|
+
value: literal.replace(/[.+?^${}()[\]|\\]/g, "\\$&"), // Escape special regex chars
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const operator = match[1]; // e.g., '+', '#', '.', '/', '?', '&'
|
|
32
|
+
const varNames = match[2].split(","); // Handle multiple variables in one template
|
|
33
|
+
varNames.forEach((varName) => {
|
|
34
|
+
if (!variables.includes(varName)) {
|
|
35
|
+
variables.push(varName);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
// Add regex pattern for this template variable
|
|
39
|
+
const replacement = getRegexForOperator(operator, varNames);
|
|
40
|
+
parts.push({
|
|
41
|
+
type: "pattern",
|
|
42
|
+
value: replacement,
|
|
43
|
+
});
|
|
44
|
+
lastIndex = match.index + match[0].length;
|
|
45
|
+
}
|
|
46
|
+
// Add any remaining literal part
|
|
47
|
+
if (lastIndex < template.length) {
|
|
48
|
+
const literal = template.substring(lastIndex);
|
|
49
|
+
parts.push({
|
|
50
|
+
type: "literal",
|
|
51
|
+
value: literal.replace(/[.+?^${}()[\]|\\]/g, "\\$&"),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const regexPattern = parts.map((p) => p.value).join("");
|
|
55
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
56
|
+
return {
|
|
57
|
+
pattern: template,
|
|
58
|
+
regex,
|
|
59
|
+
variables,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get regex pattern for RFC 6570 operator
|
|
64
|
+
*/
|
|
65
|
+
function getRegexForOperator(operator, _varNames) {
|
|
66
|
+
// Different operators allow different characters
|
|
67
|
+
switch (operator) {
|
|
68
|
+
case "+": // Reserved characters allowed
|
|
69
|
+
case "#": // Fragment (reserved chars allowed)
|
|
70
|
+
return `([a-zA-Z0-9\\-_.~:/?#[\\]@!$&'()*+,;=]*)`;
|
|
71
|
+
case ".": // Label (dots, no slashes)
|
|
72
|
+
return `([a-zA-Z0-9\\-_~]*)`;
|
|
73
|
+
case "/": // Path (no leading slash in capture)
|
|
74
|
+
return `([a-zA-Z0-9\\-_~./]*)`;
|
|
75
|
+
case "?": // Query (unreserved + reserved)
|
|
76
|
+
case "&": // Query continuation
|
|
77
|
+
return `([a-zA-Z0-9\\-_.~:/?#[\\]@!$&'()*+,;=%]*)`;
|
|
78
|
+
default: // Simple expansion (unreserved chars only: A-Z a-z 0-9 - . _ ~)
|
|
79
|
+
return `([a-zA-Z0-9\\-_~.]*)`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Match a URI against a template and extract variables
|
|
84
|
+
*/
|
|
85
|
+
export function matchURITemplate(uri, template) {
|
|
86
|
+
const regexMatch = template.regex.exec(uri);
|
|
87
|
+
if (!regexMatch) {
|
|
88
|
+
return { matched: false, variables: {} };
|
|
89
|
+
}
|
|
90
|
+
const variables = {};
|
|
91
|
+
template.variables.forEach((varName, index) => {
|
|
92
|
+
variables[varName] = regexMatch[index + 1] || "";
|
|
93
|
+
});
|
|
94
|
+
return { matched: true, variables };
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolve a URI template with specific variable values
|
|
98
|
+
* Example: resolveURITemplate("cache://tools/{id}", { id: "123" }) => "cache://tools/123"
|
|
99
|
+
*/
|
|
100
|
+
export function resolveURITemplate(template, variables) {
|
|
101
|
+
let resolved = template;
|
|
102
|
+
const variableRegex = /\{([+#./?&]?)([a-zA-Z_][a-zA-Z0-9_]*)\}/g;
|
|
103
|
+
let match;
|
|
104
|
+
while ((match = variableRegex.exec(template)) !== null) {
|
|
105
|
+
const operator = match[1];
|
|
106
|
+
const varName = match[2];
|
|
107
|
+
const value = variables[varName] || "";
|
|
108
|
+
// Build the replacement based on operator
|
|
109
|
+
let replacement = "";
|
|
110
|
+
switch (operator) {
|
|
111
|
+
case "+":
|
|
112
|
+
replacement = value; // Reserved chars allowed, no prefix
|
|
113
|
+
break;
|
|
114
|
+
case "#":
|
|
115
|
+
replacement = value ? `#${value}` : "";
|
|
116
|
+
break;
|
|
117
|
+
case ".":
|
|
118
|
+
replacement = value ? `.${value}` : "";
|
|
119
|
+
break;
|
|
120
|
+
case "/":
|
|
121
|
+
replacement = value ? `/${value}` : "";
|
|
122
|
+
break;
|
|
123
|
+
case "?":
|
|
124
|
+
replacement = value ? `?${varName}=${value}` : "";
|
|
125
|
+
break;
|
|
126
|
+
case "&":
|
|
127
|
+
replacement = value ? `&${varName}=${value}` : "";
|
|
128
|
+
break;
|
|
129
|
+
default:
|
|
130
|
+
replacement = value; // Simple expansion
|
|
131
|
+
}
|
|
132
|
+
resolved = resolved.replace(match[0], replacement);
|
|
133
|
+
}
|
|
134
|
+
return resolved;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Template Registry for matching dynamic resources
|
|
138
|
+
*/
|
|
139
|
+
export class TemplateRegistry {
|
|
140
|
+
templates = new Map();
|
|
141
|
+
/**
|
|
142
|
+
* Register a URI template pattern
|
|
143
|
+
*/
|
|
144
|
+
registerTemplate(pattern) {
|
|
145
|
+
if (!this.templates.has(pattern)) {
|
|
146
|
+
this.templates.set(pattern, parseURITemplate(pattern));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Find matching template for a given URI
|
|
151
|
+
*/
|
|
152
|
+
findMatchingTemplate(uri) {
|
|
153
|
+
for (const [pattern, template] of this.templates) {
|
|
154
|
+
const match = matchURITemplate(uri, template);
|
|
155
|
+
if (match.matched) {
|
|
156
|
+
return { pattern, match };
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get all registered templates
|
|
163
|
+
*/
|
|
164
|
+
getTemplates() {
|
|
165
|
+
return Array.from(this.templates.keys());
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=resource-uri-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-uri-templates.js","sourceRoot":"","sources":["../../src/core/resource-uri-templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Server Transport (Protocol 2025-03-26)
|
|
3
|
+
*
|
|
4
|
+
* Modern MCP server implementation using StreamableHTTPServerTransport
|
|
5
|
+
* - Session management with transport reuse
|
|
6
|
+
* - Support for GET/POST/DELETE methods
|
|
7
|
+
* - Optional resumability with event store
|
|
8
|
+
* - Bearer token authentication
|
|
9
|
+
* - Health check endpoint
|
|
10
|
+
*
|
|
11
|
+
* Based on MCP SDK official examples
|
|
12
|
+
*/
|
|
13
|
+
import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
14
|
+
export declare function startHttpServer(port: number, host: string, mcpServer: Server, logSecurityStatus: () => void, logServerStats: () => void): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=server-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-http.d.ts","sourceRoot":"","sources":["../../src/core/server-http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,2CAA2C,CAAC;AAyStE,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,IAAI,EAC7B,cAAc,EAAE,MAAM,IAAI,GACzB,OAAO,CAAC,IAAI,CAAC,CAsFf"}
|