@vllnt/convex-helpers 0.1.0-canary.1e0f54a
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 +125 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/auth.d.ts +11 -0
- package/dist/mcp/auth.d.ts.map +1 -0
- package/dist/mcp/auth.js +36 -0
- package/dist/mcp/auth.js.map +1 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +5 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/pagination/context.d.ts +9 -0
- package/dist/mcp/pagination/context.d.ts.map +1 -0
- package/dist/mcp/pagination/context.js +21 -0
- package/dist/mcp/pagination/context.js.map +1 -0
- package/dist/mcp/pagination/cursor.d.ts +7 -0
- package/dist/mcp/pagination/cursor.d.ts.map +1 -0
- package/dist/mcp/pagination/cursor.js +60 -0
- package/dist/mcp/pagination/cursor.js.map +1 -0
- package/dist/mcp/pagination/handlers.d.ts +12 -0
- package/dist/mcp/pagination/handlers.d.ts.map +1 -0
- package/dist/mcp/pagination/handlers.js +91 -0
- package/dist/mcp/pagination/handlers.js.map +1 -0
- package/dist/mcp/pagination/types.d.ts +26 -0
- package/dist/mcp/pagination/types.d.ts.map +1 -0
- package/dist/mcp/pagination/types.js +2 -0
- package/dist/mcp/pagination/types.js.map +1 -0
- package/dist/mcp/resources/helpers.d.ts +9 -0
- package/dist/mcp/resources/helpers.d.ts.map +1 -0
- package/dist/mcp/resources/helpers.js +8 -0
- package/dist/mcp/resources/helpers.js.map +1 -0
- package/dist/mcp/resources/register.d.ts +14 -0
- package/dist/mcp/resources/register.d.ts.map +1 -0
- package/dist/mcp/resources/register.js +40 -0
- package/dist/mcp/resources/register.js.map +1 -0
- package/dist/mcp/resources/types.d.ts +7 -0
- package/dist/mcp/resources/types.d.ts.map +1 -0
- package/dist/mcp/resources/types.js +2 -0
- package/dist/mcp/resources/types.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +139 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/helpers.d.ts +16 -0
- package/dist/mcp/tools/helpers.d.ts.map +1 -0
- package/dist/mcp/tools/helpers.js +34 -0
- package/dist/mcp/tools/helpers.js.map +1 -0
- package/dist/mcp/tools/register.d.ts +23 -0
- package/dist/mcp/tools/register.d.ts.map +1 -0
- package/dist/mcp/tools/register.js +195 -0
- package/dist/mcp/tools/register.js.map +1 -0
- package/dist/mcp/tools/types.d.ts +71 -0
- package/dist/mcp/tools/types.d.ts.map +1 -0
- package/dist/mcp/tools/types.js +2 -0
- package/dist/mcp/tools/types.js.map +1 -0
- package/dist/mcp/types.d.ts +50 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +2 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/mcp/validators.d.ts +8 -0
- package/dist/mcp/validators.d.ts.map +1 -0
- package/dist/mcp/validators.js +135 -0
- package/dist/mcp/validators.js.map +1 -0
- package/package.json +95 -0
- package/src/index.test.ts +164 -0
- package/src/index.ts +62 -0
- package/src/mcp/auth.ts +53 -0
- package/src/mcp/index.ts +23 -0
- package/src/mcp/pagination/context.ts +27 -0
- package/src/mcp/pagination/cursor.ts +99 -0
- package/src/mcp/pagination/handlers.ts +172 -0
- package/src/mcp/pagination/types.ts +27 -0
- package/src/mcp/resources/helpers.ts +19 -0
- package/src/mcp/resources/register.ts +63 -0
- package/src/mcp/resources/types.ts +7 -0
- package/src/mcp/server.ts +209 -0
- package/src/mcp/tools/helpers.ts +47 -0
- package/src/mcp/tools/register.ts +256 -0
- package/src/mcp/tools/types.ts +74 -0
- package/src/mcp/types.ts +65 -0
- package/src/mcp/validators.ts +175 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { ConvexClient } from "../types.js";
|
|
4
|
+
import type { ResourceDef } from "./types.js";
|
|
5
|
+
type PreparedResource = {
|
|
6
|
+
description: string | undefined;
|
|
7
|
+
resourceDef: ResourceDef;
|
|
8
|
+
template: ResourceTemplate;
|
|
9
|
+
uriPattern: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function prepareResources(resources: Record<string, ResourceDef>): PreparedResource[];
|
|
12
|
+
export declare function registerResources(mcpServer: McpServer, client: ConvexClient, resources: PreparedResource[]): void;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/mcp/resources/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,KAAK,gBAAgB,GAAG;IACtB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACrC,gBAAgB,EAAE,CAOpB;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,gBAAgB,EAAE,GAC5B,IAAI,CAiCN"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export function prepareResources(resources) {
|
|
3
|
+
return Object.entries(resources).map(([uriPattern, resourceDef]) => ({
|
|
4
|
+
description: resourceDef.description,
|
|
5
|
+
resourceDef,
|
|
6
|
+
template: new ResourceTemplate(uriPattern, { list: undefined }),
|
|
7
|
+
uriPattern,
|
|
8
|
+
}));
|
|
9
|
+
}
|
|
10
|
+
export function registerResources(mcpServer, client, resources) {
|
|
11
|
+
for (const { description, resourceDef, template, uriPattern } of resources) {
|
|
12
|
+
mcpServer.resource(uriPattern, template, {
|
|
13
|
+
description,
|
|
14
|
+
mimeType: "application/json",
|
|
15
|
+
}, async (uri, parameters) => {
|
|
16
|
+
try {
|
|
17
|
+
const result = await client.query(resourceDef.ref, parameters);
|
|
18
|
+
return {
|
|
19
|
+
contents: [
|
|
20
|
+
{
|
|
21
|
+
mimeType: "application/json",
|
|
22
|
+
text: JSON.stringify(result ?? null, null, 2),
|
|
23
|
+
uri: uri.href,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
console.error("[convex-mcp] resource read failed", {
|
|
30
|
+
error,
|
|
31
|
+
resource: uriPattern,
|
|
32
|
+
});
|
|
33
|
+
// Mask the raw Convex error from the client (parity with the tool
|
|
34
|
+
// handler); the real error is logged server-side above.
|
|
35
|
+
throw new Error("Resource read failed");
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/mcp/resources/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAa3E,MAAM,UAAU,gBAAgB,CAC9B,SAAsC;IAEtC,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;QACnE,WAAW,EAAE,WAAW,CAAC,WAAW;QACpC,WAAW;QACX,QAAQ,EAAE,IAAI,gBAAgB,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC/D,UAAU;KACX,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,SAAoB,EACpB,MAAoB,EACpB,SAA6B;IAE7B,KAAK,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3E,SAAS,CAAC,QAAQ,CAChB,UAAU,EACV,QAAQ,EACR;YACE,WAAW;YACX,QAAQ,EAAE,kBAAkB;SAC7B,EACD,KAAK,EAAE,GAAG,EAAE,UAAmC,EAAE,EAAE;YACjD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;gBAC/D,OAAO;oBACL,QAAQ,EAAE;wBACR;4BACE,QAAQ,EAAE,kBAAkB;4BAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;4BAC7C,GAAG,EAAE,GAAG,CAAC,IAAI;yBACd;qBACF;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE;oBACjD,KAAK;oBACL,QAAQ,EAAE,UAAU;iBACrB,CAAC,CAAC;gBACH,kEAAkE;gBAClE,wDAAwD;gBACxD,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/mcp/resources/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,OAAO,CAAC;CACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/mcp/resources/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAgB,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAuB9E,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,eAAe,CAwKrE"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
3
|
+
import { ConvexHttpClient } from "convex/browser";
|
|
4
|
+
import { validateRequest } from "./auth.js";
|
|
5
|
+
import { createPaginationContext } from "./pagination/context.js";
|
|
6
|
+
import { getOriginalToolsList, registerPaginationHandlers, registerTwoPhaseHandlers, } from "./pagination/handlers.js";
|
|
7
|
+
import { prepareResources, registerResources } from "./resources/register.js";
|
|
8
|
+
import { findToolsWithReservedArgs as findToolsWithReservedArguments, prepareTools, registerTools, } from "./tools/register.js";
|
|
9
|
+
function createDefaultClient(convexUrl, convexToken) {
|
|
10
|
+
const client = new ConvexHttpClient(convexUrl);
|
|
11
|
+
if (convexToken) {
|
|
12
|
+
client.setAuth(convexToken);
|
|
13
|
+
}
|
|
14
|
+
return client;
|
|
15
|
+
}
|
|
16
|
+
function addRequestId(response, requestId) {
|
|
17
|
+
const headers = new Headers(response.headers);
|
|
18
|
+
headers.set("X-Request-Id", requestId);
|
|
19
|
+
return new Response(response.body, {
|
|
20
|
+
headers,
|
|
21
|
+
status: response.status,
|
|
22
|
+
statusText: response.statusText,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export function createMCPServer(config) {
|
|
26
|
+
if (!config.auth?.validate) {
|
|
27
|
+
throw new Error("Auth is required. Provide auth.validate to createMCPServer(). " +
|
|
28
|
+
"This package enforces default-deny — no open MCP endpoints.");
|
|
29
|
+
}
|
|
30
|
+
const injectedClient = config.client;
|
|
31
|
+
if (injectedClient && config.auth.convexToken) {
|
|
32
|
+
throw new Error("Cannot use both 'client' and 'auth.convexToken'. When providing a custom client, " +
|
|
33
|
+
"handle auth token propagation in your client implementation directly.");
|
|
34
|
+
}
|
|
35
|
+
let resolvedConvexUrl;
|
|
36
|
+
if (!injectedClient) {
|
|
37
|
+
resolvedConvexUrl =
|
|
38
|
+
config.convexUrl ??
|
|
39
|
+
process.env.CONVEX_URL ??
|
|
40
|
+
process.env.NEXT_PUBLIC_CONVEX_URL;
|
|
41
|
+
if (!resolvedConvexUrl) {
|
|
42
|
+
throw new Error("Convex URL not found. Set CONVEX_URL or NEXT_PUBLIC_CONVEX_URL environment variable, " +
|
|
43
|
+
"or pass convexUrl or client to createMCPServer().");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const serverName = config.name ?? "convex-mcp";
|
|
47
|
+
const serverVersion = config.version ?? "0.1.0";
|
|
48
|
+
const hooks = config.hooks;
|
|
49
|
+
const prepared = prepareTools(config.tools ?? {});
|
|
50
|
+
const preparedRes = prepareResources(config.resources ?? {});
|
|
51
|
+
const paginationCtx = createPaginationContext(config.pagination);
|
|
52
|
+
if (!hooks?.onToolCall) {
|
|
53
|
+
const stripped = findToolsWithReservedArguments(config.tools ?? {});
|
|
54
|
+
if (stripped.size > 0) {
|
|
55
|
+
const summary = [...stripped.entries()]
|
|
56
|
+
.map(([tool, keys]) => `${tool} (${keys.join(", ")})`)
|
|
57
|
+
.join("; ");
|
|
58
|
+
console.warn(`[convex-mcp] tools declare reserved \`_*\` args but no onToolCall hook is configured. ` +
|
|
59
|
+
`These args are stripped from the published schema and will never be injected, ` +
|
|
60
|
+
`so every dispatched call will fail Convex validation. ` +
|
|
61
|
+
`Configure hooks.onToolCall to inject them via extendArgs. Affected tools: ${summary}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function createServerAndTransport(requestId, convexToken, apiKey) {
|
|
65
|
+
const mcpServer = new McpServer({
|
|
66
|
+
name: serverName,
|
|
67
|
+
version: serverVersion,
|
|
68
|
+
});
|
|
69
|
+
let client;
|
|
70
|
+
if (injectedClient) {
|
|
71
|
+
client = injectedClient;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
/* v8 ignore start -- configuration validation guarantees a URL when no client is injected */
|
|
75
|
+
if (!resolvedConvexUrl)
|
|
76
|
+
throw new Error("Convex URL not found after configuration validation.");
|
|
77
|
+
/* v8 ignore stop */
|
|
78
|
+
client = createDefaultClient(resolvedConvexUrl, convexToken);
|
|
79
|
+
}
|
|
80
|
+
registerTools(mcpServer, client, prepared, hooks, requestId, apiKey);
|
|
81
|
+
registerResources(mcpServer, client, preparedRes);
|
|
82
|
+
// CRITICAL: Override MUST happen AFTER registerTools() — McpServer's lazy-init
|
|
83
|
+
// registers the default tools/list handler on the first tool() call.
|
|
84
|
+
// Overriding before would cause assertCanSetRequestHandler to throw.
|
|
85
|
+
const hasTools = prepared.length > 0;
|
|
86
|
+
if (hasTools && paginationCtx.enabled) {
|
|
87
|
+
const getAllTools = getOriginalToolsList(mcpServer);
|
|
88
|
+
registerPaginationHandlers(mcpServer, getAllTools, paginationCtx.pageSize, paginationCtx.secret);
|
|
89
|
+
if (paginationCtx.twoPhaseDiscovery) {
|
|
90
|
+
registerTwoPhaseHandlers(mcpServer, getAllTools, paginationCtx.pageSize, paginationCtx.secret);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
94
|
+
sessionIdGenerator: undefined,
|
|
95
|
+
});
|
|
96
|
+
return { mcpServer, transport };
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
handler() {
|
|
100
|
+
return {
|
|
101
|
+
async GET(request) {
|
|
102
|
+
const requestId = crypto.randomUUID();
|
|
103
|
+
const authResult = await validateRequest(request, config.auth);
|
|
104
|
+
if (!authResult.valid)
|
|
105
|
+
return addRequestId(authResult.response, requestId);
|
|
106
|
+
const { mcpServer, transport } = createServerAndTransport(requestId, authResult.convexToken, authResult.apiKey);
|
|
107
|
+
await mcpServer.connect(transport);
|
|
108
|
+
const response = await transport.handleRequest(request);
|
|
109
|
+
return addRequestId(response, requestId);
|
|
110
|
+
},
|
|
111
|
+
async POST(request) {
|
|
112
|
+
const requestId = crypto.randomUUID();
|
|
113
|
+
const authResult = await validateRequest(request, config.auth);
|
|
114
|
+
if (!authResult.valid)
|
|
115
|
+
return addRequestId(authResult.response, requestId);
|
|
116
|
+
const contentType = request.headers.get("content-type");
|
|
117
|
+
if (!contentType?.includes("application/json")) {
|
|
118
|
+
return addRequestId(new Response(JSON.stringify({
|
|
119
|
+
error: {
|
|
120
|
+
code: -32_700,
|
|
121
|
+
message: "Unsupported Media Type: expected application/json",
|
|
122
|
+
},
|
|
123
|
+
id: null,
|
|
124
|
+
jsonrpc: "2.0",
|
|
125
|
+
}), {
|
|
126
|
+
headers: { "Content-Type": "application/json" },
|
|
127
|
+
status: 415,
|
|
128
|
+
}), requestId);
|
|
129
|
+
}
|
|
130
|
+
const { mcpServer, transport } = createServerAndTransport(requestId, authResult.convexToken, authResult.apiKey);
|
|
131
|
+
await mcpServer.connect(transport);
|
|
132
|
+
const response = await transport.handleRequest(request);
|
|
133
|
+
return addRequestId(response, requestId);
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ConvexValidator } from "../types.js";
|
|
2
|
+
import type { CallContext, HookReturn, ToolDef } from "./types.js";
|
|
3
|
+
type ToolOptions = {
|
|
4
|
+
args?: ConvexValidator;
|
|
5
|
+
description?: string;
|
|
6
|
+
onError?: (ctx: CallContext & {
|
|
7
|
+
phase: "error";
|
|
8
|
+
}) => HookReturn;
|
|
9
|
+
tags?: Record<string, string>;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function query(ref: unknown, options?: ToolOptions): ToolDef;
|
|
13
|
+
export declare function mutation(ref: unknown, options?: ToolOptions): ToolDef;
|
|
14
|
+
export declare function action(ref: unknown, options?: ToolOptions): ToolDef;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEnE,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,GAAG;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,UAAU,CAAC;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAUtE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAUzE;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAUvE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function query(ref, options = {}) {
|
|
2
|
+
return {
|
|
3
|
+
args: options.args,
|
|
4
|
+
description: options.description,
|
|
5
|
+
onError: options.onError,
|
|
6
|
+
ref,
|
|
7
|
+
tags: options.tags,
|
|
8
|
+
timeout: options.timeout,
|
|
9
|
+
type: "query",
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function mutation(ref, options = {}) {
|
|
13
|
+
return {
|
|
14
|
+
args: options.args,
|
|
15
|
+
description: options.description,
|
|
16
|
+
onError: options.onError,
|
|
17
|
+
ref,
|
|
18
|
+
tags: options.tags,
|
|
19
|
+
timeout: options.timeout,
|
|
20
|
+
type: "mutation",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function action(ref, options = {}) {
|
|
24
|
+
return {
|
|
25
|
+
args: options.args,
|
|
26
|
+
description: options.description,
|
|
27
|
+
onError: options.onError,
|
|
28
|
+
ref,
|
|
29
|
+
tags: options.tags,
|
|
30
|
+
timeout: options.timeout,
|
|
31
|
+
type: "action",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/mcp/tools/helpers.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,UAAuB,EAAE;IAC3D,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,GAAG;QACH,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,IAAI,EAAE,OAAO;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAY,EAAE,UAAuB,EAAE;IAC9D,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,GAAG;QACH,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,IAAI,EAAE,UAAU;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAY,EAAE,UAAuB,EAAE;IAC5D,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,GAAG;QACH,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,IAAI,EAAE,QAAQ;KACf,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { z } from "zod";
|
|
3
|
+
import type { ConvexClient } from "../types.js";
|
|
4
|
+
import type { LifecycleHooks, ToolDef } from "./types.js";
|
|
5
|
+
type PreparedTool = {
|
|
6
|
+
description: string;
|
|
7
|
+
name: string;
|
|
8
|
+
toolDef: ToolDef;
|
|
9
|
+
zodShape: Record<string, z.ZodTypeAny>;
|
|
10
|
+
};
|
|
11
|
+
export declare function prepareTools(tools: Record<string, ToolDef>): PreparedTool[];
|
|
12
|
+
/**
|
|
13
|
+
* Returns tools whose top-level args contain reserved `_*` keys.
|
|
14
|
+
*
|
|
15
|
+
* Used by `createMCPServer` at construction to surface a footgun: a tool that
|
|
16
|
+
* declares `_*` args without an `onToolCall` hook will have those args stripped
|
|
17
|
+
* from the published schema and never injected, so every dispatched call will
|
|
18
|
+
* fail Convex's own validator with "missing required arg".
|
|
19
|
+
*/
|
|
20
|
+
export declare function findToolsWithReservedArgs(tools: Record<string, ToolDef>): Map<string, string[]>;
|
|
21
|
+
export declare function registerTools(mcpServer: McpServer, client: ConvexClient, tools: PreparedTool[], hooks: LifecycleHooks | undefined, requestId: string, apiKey: string | undefined): void;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,KAAK,EAEV,cAAc,EAEd,OAAO,EACR,MAAM,YAAY,CAAC;AAEpB,KAAK,YAAY,GAAG;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;CACxC,CAAC;AA0BF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,EAAE,CAa3E;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAQvB;AAiDD,wBAAgB,aAAa,CAC3B,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,cAAc,GAAG,SAAS,EACjC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,IAAI,CA0HN"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { convexArgsToZod as convexArgumentsToZod } from "../validators.js";
|
|
2
|
+
/**
|
|
3
|
+
* Underscore-prefixed arg keys are reserved for framework-injected context.
|
|
4
|
+
*
|
|
5
|
+
* - Request args containing `_*` keys are rejected before hook invocation.
|
|
6
|
+
* - Tool-level Convex validators MAY declare `_*` fields so the action
|
|
7
|
+
* handler receives server-injected values; these are stripped from the
|
|
8
|
+
* published JSON Schema so MCP clients neither see nor pass them.
|
|
9
|
+
*/
|
|
10
|
+
function isReservedKey(key) {
|
|
11
|
+
return key.startsWith("_");
|
|
12
|
+
}
|
|
13
|
+
function stripReservedFromShape(shape) {
|
|
14
|
+
const filtered = {};
|
|
15
|
+
for (const [key, value] of Object.entries(shape)) {
|
|
16
|
+
if (!isReservedKey(key)) {
|
|
17
|
+
filtered[key] = value;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return filtered;
|
|
21
|
+
}
|
|
22
|
+
export function prepareTools(tools) {
|
|
23
|
+
return Object.entries(tools).map(([name, toolDef]) => {
|
|
24
|
+
const zodSchema = toolDef.args
|
|
25
|
+
? convexArgumentsToZod(toolDef.args)
|
|
26
|
+
: undefined;
|
|
27
|
+
const fullShape = zodSchema?.shape ?? {};
|
|
28
|
+
return {
|
|
29
|
+
description: toolDef.description ?? "",
|
|
30
|
+
name,
|
|
31
|
+
toolDef,
|
|
32
|
+
zodShape: stripReservedFromShape(fullShape),
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns tools whose top-level args contain reserved `_*` keys.
|
|
38
|
+
*
|
|
39
|
+
* Used by `createMCPServer` at construction to surface a footgun: a tool that
|
|
40
|
+
* declares `_*` args without an `onToolCall` hook will have those args stripped
|
|
41
|
+
* from the published schema and never injected, so every dispatched call will
|
|
42
|
+
* fail Convex's own validator with "missing required arg".
|
|
43
|
+
*/
|
|
44
|
+
export function findToolsWithReservedArgs(tools) {
|
|
45
|
+
const result = new Map();
|
|
46
|
+
for (const [name, toolDef] of Object.entries(tools)) {
|
|
47
|
+
if (toolDef.args?.kind !== "object" || !toolDef.args.fields)
|
|
48
|
+
continue;
|
|
49
|
+
const reserved = Object.keys(toolDef.args.fields).filter(isReservedKey);
|
|
50
|
+
if (reserved.length > 0)
|
|
51
|
+
result.set(name, reserved);
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
async function invokeHook(hooks, ctx, toolDef) {
|
|
56
|
+
try {
|
|
57
|
+
if (ctx.phase === "error" && toolDef.onError) {
|
|
58
|
+
const result = await toolDef.onError(ctx);
|
|
59
|
+
return result ?? undefined;
|
|
60
|
+
}
|
|
61
|
+
if (hooks?.onToolCall) {
|
|
62
|
+
const result = await hooks.onToolCall(ctx);
|
|
63
|
+
return result ?? undefined;
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
catch (hookError) {
|
|
68
|
+
console.error("[convex-mcp] hook error (swallowed)", {
|
|
69
|
+
error: hookError,
|
|
70
|
+
phase: ctx.phase,
|
|
71
|
+
requestId: ctx.requestId,
|
|
72
|
+
tool: ctx.toolName,
|
|
73
|
+
});
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function executeWithTimeout(promise, timeoutMs) {
|
|
78
|
+
if (!timeoutMs)
|
|
79
|
+
return promise;
|
|
80
|
+
let handle;
|
|
81
|
+
return Promise.race([
|
|
82
|
+
promise.finally(() => {
|
|
83
|
+
clearTimeout(handle);
|
|
84
|
+
}),
|
|
85
|
+
new Promise((_, reject) => {
|
|
86
|
+
handle = setTimeout(() => {
|
|
87
|
+
reject(new Error("Tool execution timed out"));
|
|
88
|
+
}, timeoutMs);
|
|
89
|
+
}),
|
|
90
|
+
]);
|
|
91
|
+
}
|
|
92
|
+
export function registerTools(mcpServer, client, tools, hooks, requestId, apiKey) {
|
|
93
|
+
for (const { description, name, toolDef, zodShape } of tools) {
|
|
94
|
+
mcpServer.tool(name, description, zodShape, async (arguments_) => {
|
|
95
|
+
const startedAt = Date.now();
|
|
96
|
+
const { onError: _onError, ref: _ref, ...safeDef } = toolDef;
|
|
97
|
+
const reservedKeys = Object.keys(arguments_).filter(isReservedKey);
|
|
98
|
+
if (reservedKeys.length > 0) {
|
|
99
|
+
console.warn("[convex-mcp] reserved-key reject", {
|
|
100
|
+
keys: reservedKeys,
|
|
101
|
+
requestId,
|
|
102
|
+
tool: name,
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
content: [
|
|
106
|
+
{
|
|
107
|
+
text: `Reserved arg keys not allowed in request: ${reservedKeys.join(", ")}. ` +
|
|
108
|
+
`Keys starting with "_" are reserved for framework-injected context.`,
|
|
109
|
+
type: "text",
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
isError: true,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const baseCtx = {
|
|
116
|
+
apiKey,
|
|
117
|
+
args: arguments_,
|
|
118
|
+
requestId,
|
|
119
|
+
startedAt,
|
|
120
|
+
toolDef: safeDef,
|
|
121
|
+
toolName: name,
|
|
122
|
+
};
|
|
123
|
+
const beforeCtx = { ...baseCtx, phase: "before" };
|
|
124
|
+
const beforeResult = await invokeHook(hooks, beforeCtx, toolDef);
|
|
125
|
+
if (beforeResult?.abort) {
|
|
126
|
+
return {
|
|
127
|
+
content: [
|
|
128
|
+
{
|
|
129
|
+
text: beforeResult.errorMessage ?? "Tool call rejected",
|
|
130
|
+
type: "text",
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
isError: true,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const dispatchArguments = beforeResult?.extendArgs &&
|
|
137
|
+
Object.keys(beforeResult.extendArgs).length > 0
|
|
138
|
+
? { ...arguments_, ...beforeResult.extendArgs }
|
|
139
|
+
: arguments_;
|
|
140
|
+
try {
|
|
141
|
+
const callPromise = (async () => {
|
|
142
|
+
switch (toolDef.type) {
|
|
143
|
+
case "query":
|
|
144
|
+
return await client.query(toolDef.ref, dispatchArguments);
|
|
145
|
+
case "mutation":
|
|
146
|
+
return await client.mutation(toolDef.ref, dispatchArguments);
|
|
147
|
+
case "action":
|
|
148
|
+
return await client.action(toolDef.ref, dispatchArguments);
|
|
149
|
+
default:
|
|
150
|
+
throw new Error(`Unknown function type: ${String(toolDef.type)}`);
|
|
151
|
+
}
|
|
152
|
+
})();
|
|
153
|
+
const result = await executeWithTimeout(callPromise, toolDef.timeout);
|
|
154
|
+
const durationMs = Date.now() - startedAt;
|
|
155
|
+
const successCtx = {
|
|
156
|
+
...baseCtx,
|
|
157
|
+
durationMs,
|
|
158
|
+
phase: "success",
|
|
159
|
+
result,
|
|
160
|
+
};
|
|
161
|
+
await invokeHook(hooks, successCtx, toolDef);
|
|
162
|
+
return {
|
|
163
|
+
content: [
|
|
164
|
+
{
|
|
165
|
+
text: JSON.stringify(result ?? null, null, 2),
|
|
166
|
+
type: "text",
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
const durationMs = Date.now() - startedAt;
|
|
173
|
+
const errorCtx = {
|
|
174
|
+
...baseCtx,
|
|
175
|
+
durationMs,
|
|
176
|
+
error,
|
|
177
|
+
phase: "error",
|
|
178
|
+
};
|
|
179
|
+
const errorResult = await invokeHook(hooks, errorCtx, toolDef);
|
|
180
|
+
const errorMessage = errorResult?.message ?? "Function execution failed";
|
|
181
|
+
console.error("[convex-mcp] tool execution failed", {
|
|
182
|
+
durationMs,
|
|
183
|
+
error,
|
|
184
|
+
requestId,
|
|
185
|
+
tool: name,
|
|
186
|
+
});
|
|
187
|
+
return {
|
|
188
|
+
content: [{ text: errorMessage, type: "text" }],
|
|
189
|
+
isError: true,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/mcp/tools/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { ConvexValidator } from "../types.js";
|
|
2
|
+
export type FunctionType = "action" | "mutation" | "query";
|
|
3
|
+
export type HookResult = OnCallResult | undefined;
|
|
4
|
+
export type HookReturn = HookResult | Promise<HookResult> | Promise<void>;
|
|
5
|
+
export type ToolDef = {
|
|
6
|
+
args?: ConvexValidator;
|
|
7
|
+
description?: string;
|
|
8
|
+
onError?: (ctx: CallContext & {
|
|
9
|
+
phase: "error";
|
|
10
|
+
}) => HookReturn;
|
|
11
|
+
ref: unknown;
|
|
12
|
+
tags?: Record<string, string>;
|
|
13
|
+
timeout?: number;
|
|
14
|
+
type: FunctionType;
|
|
15
|
+
};
|
|
16
|
+
export type CallContext = {
|
|
17
|
+
apiKey: string | undefined;
|
|
18
|
+
args: Record<string, unknown>;
|
|
19
|
+
durationMs?: number;
|
|
20
|
+
error?: unknown;
|
|
21
|
+
phase: "before" | "error" | "success";
|
|
22
|
+
requestId: string;
|
|
23
|
+
result?: unknown;
|
|
24
|
+
startedAt: number;
|
|
25
|
+
toolDef: Omit<ToolDef, "onError" | "ref">;
|
|
26
|
+
toolName: string;
|
|
27
|
+
};
|
|
28
|
+
export type OnCallResult = {
|
|
29
|
+
/** Set true to abort execution. Only checked during "before" phase. */
|
|
30
|
+
abort?: boolean;
|
|
31
|
+
/** Custom error message when aborting (before phase). Default: "Tool call rejected" */
|
|
32
|
+
errorMessage?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Server-resolved key/value pairs merged into the dispatched function's args
|
|
35
|
+
* before the Convex call. Only honored during the "before" phase.
|
|
36
|
+
*
|
|
37
|
+
* On key collision, hook-supplied values take precedence over request args
|
|
38
|
+
* (server-side wins).
|
|
39
|
+
*
|
|
40
|
+
* Convention: keys MUST use the framework-reserved underscore prefix
|
|
41
|
+
* (e.g., `_mcp_apiKey`, `_request_id`). Request args containing `_`-prefixed
|
|
42
|
+
* keys are rejected before the hook runs, so this prefix is safe for
|
|
43
|
+
* server-side context injection (auth, tracing, multi-tenancy, audit, etc.).
|
|
44
|
+
*
|
|
45
|
+
* Empty objects and undefined are no-ops (no allocation, no merge).
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* hooks: {
|
|
50
|
+
* onToolCall: async ({ apiKey, phase }) => {
|
|
51
|
+
* if (phase !== "before") return;
|
|
52
|
+
* const validated = await validateKey(apiKey);
|
|
53
|
+
* if (!validated.valid) return { abort: true, errorMessage: "Invalid key" };
|
|
54
|
+
* return {
|
|
55
|
+
* extendArgs: {
|
|
56
|
+
* _mcp_apiKey: apiKey,
|
|
57
|
+
* _mcp_scopes: validated.scopes,
|
|
58
|
+
* },
|
|
59
|
+
* };
|
|
60
|
+
* },
|
|
61
|
+
* }
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
extendArgs?: Record<string, unknown>;
|
|
65
|
+
/** Custom error message on failure (error phase). Default: "Function execution failed" */
|
|
66
|
+
message?: string;
|
|
67
|
+
};
|
|
68
|
+
export type LifecycleHooks = {
|
|
69
|
+
onToolCall?: (ctx: CallContext) => HookReturn;
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAE3D,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1E,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,GAAG;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,UAAU,CAAC;IAChE,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uFAAuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,UAAU,CAAC;CAC/C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/mcp/tools/types.ts"],"names":[],"mappings":""}
|