@codeqr/ts-mcp 0.19.3 → 0.24.1
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/auth.d.mts.map +1 -1
- package/auth.d.ts.map +1 -1
- package/code-tool-types.d.mts.map +1 -1
- package/code-tool-types.d.ts.map +1 -1
- package/code-tool-worker.d.mts.map +1 -1
- package/code-tool-worker.d.ts.map +1 -1
- package/code-tool-worker.js +45 -3
- package/code-tool-worker.js.map +1 -1
- package/code-tool-worker.mjs +12 -3
- package/code-tool-worker.mjs.map +1 -1
- package/code-tool.d.mts.map +1 -1
- package/code-tool.d.ts.map +1 -1
- package/code-tool.js +6 -57
- package/code-tool.js.map +1 -1
- package/code-tool.mjs +7 -58
- package/code-tool.mjs.map +1 -1
- package/docs-search-tool.d.mts +4 -2
- package/docs-search-tool.d.mts.map +1 -1
- package/docs-search-tool.d.ts +4 -2
- package/docs-search-tool.d.ts.map +1 -1
- package/docs-search-tool.js +21 -31
- package/docs-search-tool.js.map +1 -1
- package/docs-search-tool.mjs +20 -31
- package/docs-search-tool.mjs.map +1 -1
- package/http.d.mts.map +1 -1
- package/http.d.ts.map +1 -1
- package/http.js +24 -1
- package/http.js.map +1 -1
- package/http.mjs +24 -1
- package/http.mjs.map +1 -1
- package/index.mjs.map +1 -1
- package/instructions.d.mts +4 -1
- package/instructions.d.mts.map +1 -1
- package/instructions.d.ts +4 -1
- package/instructions.d.ts.map +1 -1
- package/instructions.js +21 -18
- package/instructions.js.map +1 -1
- package/instructions.mjs +18 -18
- package/instructions.mjs.map +1 -1
- package/local-docs-search.d.mts +28 -0
- package/local-docs-search.d.mts.map +1 -0
- package/local-docs-search.d.ts +28 -0
- package/local-docs-search.d.ts.map +1 -0
- package/local-docs-search.js +1259 -0
- package/local-docs-search.js.map +1 -0
- package/local-docs-search.mjs +1219 -0
- package/local-docs-search.mjs.map +1 -0
- package/logger.d.mts.map +1 -1
- package/logger.d.ts.map +1 -1
- package/logger.mjs.map +1 -1
- package/methods.d.mts.map +1 -1
- package/methods.d.ts.map +1 -1
- package/methods.js +30 -30
- package/methods.js.map +1 -1
- package/methods.mjs +30 -30
- package/methods.mjs.map +1 -1
- package/options.d.mts +4 -1
- package/options.d.mts.map +1 -1
- package/options.d.ts +4 -1
- package/options.d.ts.map +1 -1
- package/options.js +22 -3
- package/options.js.map +1 -1
- package/options.mjs +22 -3
- package/options.mjs.map +1 -1
- package/package.json +13 -2
- package/server.d.mts +9 -1
- package/server.d.mts.map +1 -1
- package/server.d.ts +9 -1
- package/server.d.ts.map +1 -1
- package/server.js +13 -4
- package/server.js.map +1 -1
- package/server.mjs +13 -4
- package/server.mjs.map +1 -1
- package/src/code-tool-worker.ts +12 -3
- package/src/code-tool.ts +11 -92
- package/src/docs-search-tool.ts +26 -47
- package/src/http.ts +27 -1
- package/src/instructions.ts +24 -27
- package/src/local-docs-search.ts +1368 -0
- package/src/methods.ts +30 -30
- package/src/options.ts +28 -4
- package/src/server.ts +22 -4
- package/src/stdio.ts +4 -1
- package/src/types.ts +2 -0
- package/src/util.ts +2 -2
- package/stdio.d.mts.map +1 -1
- package/stdio.d.ts.map +1 -1
- package/stdio.js +4 -1
- package/stdio.js.map +1 -1
- package/stdio.mjs +4 -1
- package/stdio.mjs.map +1 -1
- package/types.d.mts +5 -0
- package/types.d.mts.map +1 -1
- package/types.d.ts +5 -0
- package/types.d.ts.map +1 -1
- package/types.js.map +1 -1
- package/types.mjs.map +1 -1
- package/util.js +2 -2
- package/util.js.map +1 -1
- package/util.mjs +2 -2
- package/util.mjs.map +1 -1
package/server.d.mts
CHANGED
|
@@ -3,7 +3,10 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
3
3
|
import { ClientOptions } from '@codeqr/ts';
|
|
4
4
|
import { McpOptions } from "./options.mjs";
|
|
5
5
|
import { HandlerFunction, McpRequestContext, ToolCallResult, McpTool } from "./types.mjs";
|
|
6
|
-
export declare const newMcpServer: (stainlessApiKey
|
|
6
|
+
export declare const newMcpServer: ({ stainlessApiKey, customInstructionsPath, }: {
|
|
7
|
+
stainlessApiKey?: string | undefined;
|
|
8
|
+
customInstructionsPath?: string | undefined;
|
|
9
|
+
}) => Promise<McpServer>;
|
|
7
10
|
/**
|
|
8
11
|
* Initializes the provided MCP Server with the given tools and handlers.
|
|
9
12
|
* If not provided, the default client, tools and handlers will be used.
|
|
@@ -14,6 +17,11 @@ export declare function initMcpServer(params: {
|
|
|
14
17
|
mcpOptions?: McpOptions;
|
|
15
18
|
stainlessApiKey?: string | undefined;
|
|
16
19
|
upstreamClientEnvs?: Record<string, string> | undefined;
|
|
20
|
+
mcpSessionId?: string | undefined;
|
|
21
|
+
mcpClientInfo?: {
|
|
22
|
+
name: string;
|
|
23
|
+
version: string;
|
|
24
|
+
} | undefined;
|
|
17
25
|
}): Promise<void>;
|
|
18
26
|
/**
|
|
19
27
|
* Selects the tools to include in the MCP Server based on the provided options.
|
package/server.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.mts","sourceRoot":"","sources":["src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.mts","sourceRoot":"","sources":["src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAO3C,OAAO,EAAE,UAAU,EAAE,sBAAkB;AAEvC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,oBAAgB;AAEtF,eAAO,MAAM,YAAY,GAAU,8CAGhC;IACD,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,sBAAsB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7C,uBAUE,CAAC;AAEJ;;;GAGG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACxD,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,aAAa,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAC/D,iBA0HA;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,EAAE,CAe3D;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,EACnC,OAAO,EACP,UAAU,EACV,IAAI,GACL,EAAE;IACD,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAC3C,GAAG,OAAO,CAAC,cAAc,CAAC,CAE1B"}
|
package/server.d.ts
CHANGED
|
@@ -3,7 +3,10 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
3
3
|
import { ClientOptions } from '@codeqr/ts';
|
|
4
4
|
import { McpOptions } from "./options.js";
|
|
5
5
|
import { HandlerFunction, McpRequestContext, ToolCallResult, McpTool } from "./types.js";
|
|
6
|
-
export declare const newMcpServer: (stainlessApiKey
|
|
6
|
+
export declare const newMcpServer: ({ stainlessApiKey, customInstructionsPath, }: {
|
|
7
|
+
stainlessApiKey?: string | undefined;
|
|
8
|
+
customInstructionsPath?: string | undefined;
|
|
9
|
+
}) => Promise<McpServer>;
|
|
7
10
|
/**
|
|
8
11
|
* Initializes the provided MCP Server with the given tools and handlers.
|
|
9
12
|
* If not provided, the default client, tools and handlers will be used.
|
|
@@ -14,6 +17,11 @@ export declare function initMcpServer(params: {
|
|
|
14
17
|
mcpOptions?: McpOptions;
|
|
15
18
|
stainlessApiKey?: string | undefined;
|
|
16
19
|
upstreamClientEnvs?: Record<string, string> | undefined;
|
|
20
|
+
mcpSessionId?: string | undefined;
|
|
21
|
+
mcpClientInfo?: {
|
|
22
|
+
name: string;
|
|
23
|
+
version: string;
|
|
24
|
+
} | undefined;
|
|
17
25
|
}): Promise<void>;
|
|
18
26
|
/**
|
|
19
27
|
* Selects the tools to include in the MCP Server based on the provided options.
|
package/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAO3C,OAAO,EAAE,UAAU,EAAE,qBAAkB;AAEvC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,mBAAgB;AAEtF,eAAO,MAAM,YAAY,GAAU,8CAGhC;IACD,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,sBAAsB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7C,uBAUE,CAAC;AAEJ;;;GAGG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACxD,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,aAAa,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAC/D,iBA0HA;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,EAAE,CAe3D;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,EACnC,OAAO,EACP,UAAU,EACV,IAAI,GACL,EAAE;IACD,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAC3C,GAAG,OAAO,CAAC,cAAc,CAAC,CAE1B"}
|
package/server.js
CHANGED
|
@@ -13,13 +13,15 @@ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
|
13
13
|
const ts_1 = __importDefault(require("@codeqr/ts"));
|
|
14
14
|
const code_tool_1 = require("./code-tool.js");
|
|
15
15
|
const docs_search_tool_1 = __importDefault(require("./docs-search-tool.js"));
|
|
16
|
+
const docs_search_tool_2 = require("./docs-search-tool.js");
|
|
17
|
+
const local_docs_search_1 = require("./local-docs-search.js");
|
|
16
18
|
const instructions_1 = require("./instructions.js");
|
|
17
19
|
const methods_1 = require("./methods.js");
|
|
18
|
-
const newMcpServer = async (stainlessApiKey) => new mcp_js_1.McpServer({
|
|
20
|
+
const newMcpServer = async ({ stainlessApiKey, customInstructionsPath, }) => new mcp_js_1.McpServer({
|
|
19
21
|
name: 'codeqr_ts_api',
|
|
20
|
-
version: '0.
|
|
22
|
+
version: '0.24.0',
|
|
21
23
|
}, {
|
|
22
|
-
instructions: await (0, instructions_1.getInstructions)(stainlessApiKey),
|
|
24
|
+
instructions: await (0, instructions_1.getInstructions)({ stainlessApiKey, customInstructionsPath }),
|
|
23
25
|
capabilities: { tools: {}, logging: {} },
|
|
24
26
|
});
|
|
25
27
|
exports.newMcpServer = newMcpServer;
|
|
@@ -41,6 +43,11 @@ async function initMcpServer(params) {
|
|
|
41
43
|
warn: logAtLevel('warning'),
|
|
42
44
|
error: logAtLevel('error'),
|
|
43
45
|
};
|
|
46
|
+
if (params.mcpOptions?.docsSearchMode === 'local') {
|
|
47
|
+
const docsDir = params.mcpOptions?.docsDir;
|
|
48
|
+
const localSearch = await local_docs_search_1.LocalDocsSearch.create(docsDir ? { docsDir } : undefined);
|
|
49
|
+
(0, docs_search_tool_2.setLocalSearch)(localSearch);
|
|
50
|
+
}
|
|
44
51
|
let _client;
|
|
45
52
|
let _clientError;
|
|
46
53
|
let _logLevel;
|
|
@@ -102,6 +109,8 @@ async function initMcpServer(params) {
|
|
|
102
109
|
client,
|
|
103
110
|
stainlessApiKey: params.stainlessApiKey ?? params.mcpOptions?.stainlessApiKey,
|
|
104
111
|
upstreamClientEnvs: params.upstreamClientEnvs,
|
|
112
|
+
mcpSessionId: params.mcpSessionId,
|
|
113
|
+
mcpClientInfo: params.mcpClientInfo,
|
|
105
114
|
},
|
|
106
115
|
args,
|
|
107
116
|
});
|
|
@@ -142,7 +151,7 @@ function selectTools(options) {
|
|
|
142
151
|
if (options?.includeCodeTool ?? true) {
|
|
143
152
|
includedTools.push((0, code_tool_1.codeTool)({
|
|
144
153
|
blockedMethods: (0, methods_1.blockedMethodsForCodeTool)(options),
|
|
145
|
-
codeExecutionMode: options?.codeExecutionMode ?? '
|
|
154
|
+
codeExecutionMode: options?.codeExecutionMode ?? 'local',
|
|
146
155
|
}));
|
|
147
156
|
}
|
|
148
157
|
if (options?.includeDocsTools ?? true) {
|
package/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["src/server.ts"],"names":[],"mappings":";AAAA,sFAAsF;;;;;;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["src/server.ts"],"names":[],"mappings":"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"}
|
package/server.mjs
CHANGED
|
@@ -4,13 +4,15 @@ import { CallToolRequestSchema, ListToolsRequestSchema, SetLevelRequestSchema, }
|
|
|
4
4
|
import Codeqr from '@codeqr/ts';
|
|
5
5
|
import { codeTool } from "./code-tool.mjs";
|
|
6
6
|
import docsSearchTool from "./docs-search-tool.mjs";
|
|
7
|
+
import { setLocalSearch } from "./docs-search-tool.mjs";
|
|
8
|
+
import { LocalDocsSearch } from "./local-docs-search.mjs";
|
|
7
9
|
import { getInstructions } from "./instructions.mjs";
|
|
8
10
|
import { blockedMethodsForCodeTool } from "./methods.mjs";
|
|
9
|
-
export const newMcpServer = async (stainlessApiKey) => new McpServer({
|
|
11
|
+
export const newMcpServer = async ({ stainlessApiKey, customInstructionsPath, }) => new McpServer({
|
|
10
12
|
name: 'codeqr_ts_api',
|
|
11
|
-
version: '0.
|
|
13
|
+
version: '0.24.0',
|
|
12
14
|
}, {
|
|
13
|
-
instructions: await getInstructions(stainlessApiKey),
|
|
15
|
+
instructions: await getInstructions({ stainlessApiKey, customInstructionsPath }),
|
|
14
16
|
capabilities: { tools: {}, logging: {} },
|
|
15
17
|
});
|
|
16
18
|
/**
|
|
@@ -31,6 +33,11 @@ export async function initMcpServer(params) {
|
|
|
31
33
|
warn: logAtLevel('warning'),
|
|
32
34
|
error: logAtLevel('error'),
|
|
33
35
|
};
|
|
36
|
+
if (params.mcpOptions?.docsSearchMode === 'local') {
|
|
37
|
+
const docsDir = params.mcpOptions?.docsDir;
|
|
38
|
+
const localSearch = await LocalDocsSearch.create(docsDir ? { docsDir } : undefined);
|
|
39
|
+
setLocalSearch(localSearch);
|
|
40
|
+
}
|
|
34
41
|
let _client;
|
|
35
42
|
let _clientError;
|
|
36
43
|
let _logLevel;
|
|
@@ -92,6 +99,8 @@ export async function initMcpServer(params) {
|
|
|
92
99
|
client,
|
|
93
100
|
stainlessApiKey: params.stainlessApiKey ?? params.mcpOptions?.stainlessApiKey,
|
|
94
101
|
upstreamClientEnvs: params.upstreamClientEnvs,
|
|
102
|
+
mcpSessionId: params.mcpSessionId,
|
|
103
|
+
mcpClientInfo: params.mcpClientInfo,
|
|
95
104
|
},
|
|
96
105
|
args,
|
|
97
106
|
});
|
|
@@ -132,7 +141,7 @@ export function selectTools(options) {
|
|
|
132
141
|
if (options?.includeCodeTool ?? true) {
|
|
133
142
|
includedTools.push(codeTool({
|
|
134
143
|
blockedMethods: blockedMethodsForCodeTool(options),
|
|
135
|
-
codeExecutionMode: options?.codeExecutionMode ?? '
|
|
144
|
+
codeExecutionMode: options?.codeExecutionMode ?? 'local',
|
|
136
145
|
}));
|
|
137
146
|
}
|
|
138
147
|
if (options?.includeDocsTools ?? true) {
|
package/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","sourceRoot":"","sources":["src/server.ts"],"names":[],"mappings":"AAAA,sFAAsF;
|
|
1
|
+
{"version":3,"file":"server.mjs","sourceRoot":"","sources":["src/server.ts"],"names":[],"mappings":"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"}
|
package/src/code-tool-worker.ts
CHANGED
|
@@ -7,6 +7,10 @@ import ts from 'typescript';
|
|
|
7
7
|
import { WorkerOutput } from './code-tool-types';
|
|
8
8
|
import { Codeqr, ClientOptions } from '@codeqr/ts';
|
|
9
9
|
|
|
10
|
+
async function tseval(code: string) {
|
|
11
|
+
return import('data:application/typescript;charset=utf-8;base64,' + Buffer.from(code).toString('base64'));
|
|
12
|
+
}
|
|
13
|
+
|
|
10
14
|
function getRunFunctionSource(code: string): {
|
|
11
15
|
type: 'declaration' | 'expression';
|
|
12
16
|
client: string | undefined;
|
|
@@ -205,7 +209,8 @@ function makeSdkProxy<T extends object>(obj: T, { path, isBelievedBad = false }:
|
|
|
205
209
|
|
|
206
210
|
function parseError(code: string, error: unknown): string | undefined {
|
|
207
211
|
if (!(error instanceof Error)) return;
|
|
208
|
-
const
|
|
212
|
+
const cause = error.cause instanceof Error ? `: ${error.cause.message}` : '';
|
|
213
|
+
const message = error.name ? `${error.name}: ${error.message}${cause}` : `${error.message}${cause}`;
|
|
209
214
|
try {
|
|
210
215
|
// Deno uses V8; the first "<anonymous>:LINE:COLUMN" is the top of stack.
|
|
211
216
|
const lineNumber = error.stack?.match(/<anonymous>:([0-9]+):[0-9]+/)?.[1];
|
|
@@ -261,7 +266,9 @@ const fetch = async (req: Request): Promise<Response> => {
|
|
|
261
266
|
|
|
262
267
|
const log_lines: string[] = [];
|
|
263
268
|
const err_lines: string[] = [];
|
|
264
|
-
const
|
|
269
|
+
const originalConsole = globalThis.console;
|
|
270
|
+
globalThis.console = {
|
|
271
|
+
...originalConsole,
|
|
265
272
|
log: (...args: unknown[]) => {
|
|
266
273
|
log_lines.push(util.format(...args));
|
|
267
274
|
},
|
|
@@ -271,7 +278,7 @@ const fetch = async (req: Request): Promise<Response> => {
|
|
|
271
278
|
};
|
|
272
279
|
try {
|
|
273
280
|
let run_ = async (client: any) => {};
|
|
274
|
-
|
|
281
|
+
run_ = (await tseval(`${code}\nexport default run;`)).default;
|
|
275
282
|
const result = await run_(makeSdkProxy(client, { path: ['client'] }));
|
|
276
283
|
return Response.json({
|
|
277
284
|
is_error: false,
|
|
@@ -289,6 +296,8 @@ const fetch = async (req: Request): Promise<Response> => {
|
|
|
289
296
|
} satisfies WorkerOutput,
|
|
290
297
|
{ status: 400, statusText: 'Code execution error' },
|
|
291
298
|
);
|
|
299
|
+
} finally {
|
|
300
|
+
globalThis.console = originalConsole;
|
|
292
301
|
}
|
|
293
302
|
};
|
|
294
303
|
|
package/src/code-tool.ts
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
ContentBlock,
|
|
5
|
-
McpRequestContext,
|
|
6
|
-
McpTool,
|
|
7
|
-
Metadata,
|
|
8
|
-
ToolCallResult,
|
|
9
|
-
asErrorResult,
|
|
10
|
-
asTextContentResult,
|
|
11
|
-
} from './types';
|
|
3
|
+
import { ContentBlock, McpRequestContext, McpTool, Metadata, ToolCallResult, asErrorResult } from './types';
|
|
12
4
|
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
13
|
-
import {
|
|
14
|
-
import { WorkerInput, WorkerOutput } from './code-tool-types';
|
|
5
|
+
import { WorkerOutput } from './code-tool-types';
|
|
15
6
|
import { getLogger } from './logger';
|
|
16
7
|
import { SdkMethod } from './methods';
|
|
17
8
|
import { McpCodeExecutionMode } from './options';
|
|
@@ -108,13 +99,8 @@ export function codeTool({
|
|
|
108
99
|
let result: ToolCallResult;
|
|
109
100
|
const startTime = Date.now();
|
|
110
101
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
result = await localDenoHandler({ reqContext, args });
|
|
114
|
-
} else {
|
|
115
|
-
logger.debug('Executing code in remote Stainless environment');
|
|
116
|
-
result = await remoteStainlessHandler({ reqContext, args });
|
|
117
|
-
}
|
|
102
|
+
logger.debug('Executing code in local Deno environment');
|
|
103
|
+
result = await localDenoHandler({ reqContext, args });
|
|
118
104
|
|
|
119
105
|
logger.info(
|
|
120
106
|
{
|
|
@@ -131,71 +117,6 @@ export function codeTool({
|
|
|
131
117
|
return { metadata, tool, handler };
|
|
132
118
|
}
|
|
133
119
|
|
|
134
|
-
const remoteStainlessHandler = async ({
|
|
135
|
-
reqContext,
|
|
136
|
-
args,
|
|
137
|
-
}: {
|
|
138
|
-
reqContext: McpRequestContext;
|
|
139
|
-
args: any;
|
|
140
|
-
}): Promise<ToolCallResult> => {
|
|
141
|
-
const code = args.code as string;
|
|
142
|
-
const intent = args.intent as string | undefined;
|
|
143
|
-
const client = reqContext.client;
|
|
144
|
-
|
|
145
|
-
const codeModeEndpoint = readEnv('CODE_MODE_ENDPOINT_URL') ?? 'https://api.stainless.com/api/ai/code-tool';
|
|
146
|
-
|
|
147
|
-
const localClientEnvs = {
|
|
148
|
-
CODEQR_API_KEY: requireValue(
|
|
149
|
-
readEnv('CODEQR_API_KEY') ?? client.apiKey,
|
|
150
|
-
'set CODEQR_API_KEY environment variable or provide apiKey client option',
|
|
151
|
-
),
|
|
152
|
-
CODEQR_BASE_URL: readEnv('CODEQR_BASE_URL') ?? client.baseURL ?? undefined,
|
|
153
|
-
};
|
|
154
|
-
// Merge any upstream client envs from the request header, with upstream values taking precedence.
|
|
155
|
-
const mergedClientEnvs = { ...localClientEnvs, ...reqContext.upstreamClientEnvs };
|
|
156
|
-
|
|
157
|
-
// Setting a Stainless API key authenticates requests to the code tool endpoint.
|
|
158
|
-
const res = await fetch(codeModeEndpoint, {
|
|
159
|
-
method: 'POST',
|
|
160
|
-
headers: {
|
|
161
|
-
...(reqContext.stainlessApiKey && { Authorization: reqContext.stainlessApiKey }),
|
|
162
|
-
'Content-Type': 'application/json',
|
|
163
|
-
'x-stainless-mcp-client-envs': JSON.stringify(mergedClientEnvs),
|
|
164
|
-
},
|
|
165
|
-
body: JSON.stringify({
|
|
166
|
-
project_name: 'codeqr',
|
|
167
|
-
code,
|
|
168
|
-
intent,
|
|
169
|
-
client_opts: {},
|
|
170
|
-
} satisfies WorkerInput),
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
if (!res.ok) {
|
|
174
|
-
if (res.status === 404 && !reqContext.stainlessApiKey) {
|
|
175
|
-
throw new Error(
|
|
176
|
-
'Could not access code tool for this project. You may need to provide a Stainless API key via the STAINLESS_API_KEY environment variable, the --stainless-api-key flag, or the x-stainless-api-key HTTP header.',
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
throw new Error(
|
|
180
|
-
`${res.status}: ${
|
|
181
|
-
res.statusText
|
|
182
|
-
} error when trying to contact Code Tool server. Details: ${await res.text()}`,
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const { is_error, result, log_lines, err_lines } = (await res.json()) as WorkerOutput;
|
|
187
|
-
const hasLogs = log_lines.length > 0 || err_lines.length > 0;
|
|
188
|
-
const output = {
|
|
189
|
-
result,
|
|
190
|
-
...(log_lines.length > 0 && { log_lines }),
|
|
191
|
-
...(err_lines.length > 0 && { err_lines }),
|
|
192
|
-
};
|
|
193
|
-
if (is_error) {
|
|
194
|
-
return asErrorResult(typeof result === 'string' && !hasLogs ? result : JSON.stringify(output, null, 2));
|
|
195
|
-
}
|
|
196
|
-
return asTextContentResult(output);
|
|
197
|
-
};
|
|
198
|
-
|
|
199
120
|
const localDenoHandler = async ({
|
|
200
121
|
reqContext,
|
|
201
122
|
args,
|
|
@@ -285,15 +206,13 @@ const localDenoHandler = async ({
|
|
|
285
206
|
|
|
286
207
|
// Strip null/undefined values so that the worker SDK client can fall back to
|
|
287
208
|
// reading from environment variables (including any upstreamClientEnvs).
|
|
288
|
-
const opts
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}).filter(([_, v]) => v != null),
|
|
296
|
-
) as ClientOptions;
|
|
209
|
+
const opts = {
|
|
210
|
+
...(client.baseURL != null ? { baseURL: client.baseURL } : undefined),
|
|
211
|
+
...(client.apiKey != null ? { apiKey: client.apiKey } : undefined),
|
|
212
|
+
defaultHeaders: {
|
|
213
|
+
'X-Stainless-MCP': 'true',
|
|
214
|
+
},
|
|
215
|
+
} satisfies Partial<ClientOptions> as ClientOptions;
|
|
297
216
|
|
|
298
217
|
const req = worker.request(
|
|
299
218
|
'http://localhost',
|
package/src/docs-search-tool.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
4
4
|
import { Metadata, McpRequestContext, asTextContentResult } from './types';
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
import type { LocalDocsSearch } from './local-docs-search';
|
|
6
7
|
|
|
7
8
|
export const metadata: Metadata = {
|
|
8
9
|
resource: 'all',
|
|
@@ -40,8 +41,28 @@ export const tool: Tool = {
|
|
|
40
41
|
},
|
|
41
42
|
};
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
let _localSearch: LocalDocsSearch | undefined;
|
|
45
|
+
|
|
46
|
+
export function setLocalSearch(search: LocalDocsSearch): void {
|
|
47
|
+
_localSearch = search;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function searchLocal(args: Record<string, unknown>): Promise<unknown> {
|
|
51
|
+
if (!_localSearch) {
|
|
52
|
+
throw new Error('Local search not initialized');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const query = (args['query'] as string) ?? '';
|
|
56
|
+
const language = (args['language'] as string) ?? 'typescript';
|
|
57
|
+
const detail = (args['detail'] as string) ?? 'default';
|
|
58
|
+
|
|
59
|
+
return _localSearch.search({
|
|
60
|
+
query,
|
|
61
|
+
language,
|
|
62
|
+
detail,
|
|
63
|
+
maxResults: 10,
|
|
64
|
+
}).results;
|
|
65
|
+
}
|
|
45
66
|
|
|
46
67
|
export const handler = async ({
|
|
47
68
|
reqContext,
|
|
@@ -50,51 +71,9 @@ export const handler = async ({
|
|
|
50
71
|
reqContext: McpRequestContext;
|
|
51
72
|
args: Record<string, unknown> | undefined;
|
|
52
73
|
}) => {
|
|
53
|
-
const body = args
|
|
54
|
-
const query = new URLSearchParams(body).toString();
|
|
55
|
-
|
|
56
|
-
const startTime = Date.now();
|
|
57
|
-
const result = await fetch(`${docsSearchURL}?${query}`, {
|
|
58
|
-
headers: {
|
|
59
|
-
...(reqContext.stainlessApiKey && { Authorization: reqContext.stainlessApiKey }),
|
|
60
|
-
},
|
|
61
|
-
});
|
|
74
|
+
const body = args ?? {};
|
|
62
75
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (!result.ok) {
|
|
66
|
-
const errorText = await result.text();
|
|
67
|
-
logger.warn(
|
|
68
|
-
{
|
|
69
|
-
durationMs: Date.now() - startTime,
|
|
70
|
-
query: body.query,
|
|
71
|
-
status: result.status,
|
|
72
|
-
statusText: result.statusText,
|
|
73
|
-
errorText,
|
|
74
|
-
},
|
|
75
|
-
'Got error response from docs search tool',
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
if (result.status === 404 && !reqContext.stainlessApiKey) {
|
|
79
|
-
throw new Error(
|
|
80
|
-
'Could not find docs for this project. You may need to provide a Stainless API key via the STAINLESS_API_KEY environment variable, the --stainless-api-key flag, or the x-stainless-api-key HTTP header.',
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
throw new Error(
|
|
85
|
-
`${result.status}: ${result.statusText} when using doc search tool. Details: ${errorText}`,
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const resultBody = await result.json();
|
|
90
|
-
logger.info(
|
|
91
|
-
{
|
|
92
|
-
durationMs: Date.now() - startTime,
|
|
93
|
-
query: body.query,
|
|
94
|
-
},
|
|
95
|
-
'Got docs search result',
|
|
96
|
-
);
|
|
97
|
-
return asTextContentResult(resultBody);
|
|
76
|
+
return asTextContentResult(await searchLocal(body));
|
|
98
77
|
};
|
|
99
78
|
|
|
100
79
|
export default { metadata, tool, handler };
|
package/src/http.ts
CHANGED
|
@@ -23,7 +23,8 @@ const newServer = async ({
|
|
|
23
23
|
res: express.Response;
|
|
24
24
|
}): Promise<McpServer | null> => {
|
|
25
25
|
const stainlessApiKey = getStainlessApiKey(req, mcpOptions);
|
|
26
|
-
const
|
|
26
|
+
const customInstructionsPath = mcpOptions.customInstructionsPath;
|
|
27
|
+
const server = await newMcpServer({ stainlessApiKey, customInstructionsPath });
|
|
27
28
|
|
|
28
29
|
const authOptions = parseClientAuthHeaders(req, false);
|
|
29
30
|
|
|
@@ -68,6 +69,11 @@ const newServer = async ({
|
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
|
|
72
|
+
const mcpClientInfo =
|
|
73
|
+
typeof req.body?.params?.clientInfo?.name === 'string' ?
|
|
74
|
+
{ name: req.body.params.clientInfo.name, version: String(req.body.params.clientInfo.version ?? '') }
|
|
75
|
+
: undefined;
|
|
76
|
+
|
|
71
77
|
await initMcpServer({
|
|
72
78
|
server: server,
|
|
73
79
|
mcpOptions: effectiveMcpOptions,
|
|
@@ -77,8 +83,14 @@ const newServer = async ({
|
|
|
77
83
|
},
|
|
78
84
|
stainlessApiKey: stainlessApiKey,
|
|
79
85
|
upstreamClientEnvs,
|
|
86
|
+
mcpSessionId: (req as any).mcpSessionId,
|
|
87
|
+
mcpClientInfo,
|
|
80
88
|
});
|
|
81
89
|
|
|
90
|
+
if (mcpClientInfo) {
|
|
91
|
+
getLogger().info({ mcpSessionId: (req as any).mcpSessionId, mcpClientInfo }, 'MCP client connected');
|
|
92
|
+
}
|
|
93
|
+
|
|
82
94
|
return server;
|
|
83
95
|
};
|
|
84
96
|
|
|
@@ -134,9 +146,23 @@ export const streamableHTTPApp = ({
|
|
|
134
146
|
const app = express();
|
|
135
147
|
app.set('query parser', 'extended');
|
|
136
148
|
app.use(express.json());
|
|
149
|
+
app.use((req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
150
|
+
const existing = req.headers['mcp-session-id'];
|
|
151
|
+
const sessionId = (Array.isArray(existing) ? existing[0] : existing) || crypto.randomUUID();
|
|
152
|
+
(req as any).mcpSessionId = sessionId;
|
|
153
|
+
const origWriteHead = res.writeHead.bind(res);
|
|
154
|
+
res.writeHead = function (statusCode: number, ...rest: any[]) {
|
|
155
|
+
res.setHeader('mcp-session-id', sessionId);
|
|
156
|
+
return origWriteHead(statusCode, ...rest);
|
|
157
|
+
} as typeof res.writeHead;
|
|
158
|
+
next();
|
|
159
|
+
});
|
|
137
160
|
app.use(
|
|
138
161
|
pinoHttp({
|
|
139
162
|
logger: getLogger(),
|
|
163
|
+
customProps: (req) => ({
|
|
164
|
+
mcpSessionId: (req as any).mcpSessionId,
|
|
165
|
+
}),
|
|
140
166
|
customLogLevel: (req, res) => {
|
|
141
167
|
if (res.statusCode >= 500) {
|
|
142
168
|
return 'error';
|
package/src/instructions.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import fs from 'fs/promises';
|
|
4
4
|
import { getLogger } from './logger';
|
|
5
5
|
|
|
6
6
|
const INSTRUCTIONS_CACHE_TTL_MS = 15 * 60 * 1000; // 15 minutes
|
|
@@ -12,9 +12,15 @@ interface InstructionsCacheEntry {
|
|
|
12
12
|
|
|
13
13
|
const instructionsCache = new Map<string, InstructionsCacheEntry>();
|
|
14
14
|
|
|
15
|
-
export async function getInstructions(
|
|
15
|
+
export async function getInstructions({
|
|
16
|
+
stainlessApiKey,
|
|
17
|
+
customInstructionsPath,
|
|
18
|
+
}: {
|
|
19
|
+
stainlessApiKey?: string | undefined;
|
|
20
|
+
customInstructionsPath?: string | undefined;
|
|
21
|
+
}): Promise<string> {
|
|
16
22
|
const now = Date.now();
|
|
17
|
-
const cacheKey = stainlessApiKey ?? '';
|
|
23
|
+
const cacheKey = customInstructionsPath ?? stainlessApiKey ?? '';
|
|
18
24
|
const cached = instructionsCache.get(cacheKey);
|
|
19
25
|
|
|
20
26
|
if (cached && now - cached.fetchedAt <= INSTRUCTIONS_CACHE_TTL_MS) {
|
|
@@ -28,33 +34,24 @@ export async function getInstructions(stainlessApiKey: string | undefined): Prom
|
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
instructionsCache.set(cacheKey, { fetchedInstructions, fetchedAt: now });
|
|
33
|
-
return fetchedInstructions;
|
|
34
|
-
}
|
|
37
|
+
let fetchedInstructions: string;
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
readEnv('CODE_MODE_INSTRUCTIONS_URL') ?? 'https://api.stainless.com/api/ai/instructions/codeqr',
|
|
41
|
-
{
|
|
42
|
-
method: 'GET',
|
|
43
|
-
headers: { ...(stainlessApiKey && { Authorization: stainlessApiKey }) },
|
|
44
|
-
},
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
let instructions: string | undefined;
|
|
48
|
-
if (!response.ok) {
|
|
49
|
-
getLogger().warn(
|
|
50
|
-
'Warning: failed to retrieve MCP server instructions. Proceeding with default instructions...',
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
instructions =
|
|
39
|
+
if (customInstructionsPath) {
|
|
40
|
+
fetchedInstructions = await fetchLatestInstructionsFromFile(customInstructionsPath);
|
|
41
|
+
} else {
|
|
42
|
+
fetchedInstructions =
|
|
54
43
|
'\n This is the codeqr MCP server.\n\n Available tools:\n - search_docs: Search SDK documentation to find the right methods and parameters.\n - execute: Run TypeScript code against a pre-authenticated SDK client. Define an async run(client) function.\n\n Workflow:\n - If unsure about the API, call search_docs first.\n - Write complete solutions in a single execute call when possible. For large datasets, use API filters to narrow results or paginate within a single execute block.\n - If execute returns an error, read the error and fix your code rather than retrying the same approach.\n - Variables do not persist between execute calls. Return or log all data you need.\n - Individual HTTP requests to the API have a 30-second timeout. If a request times out, try a smaller query or add filters.\n - Code execution has a total timeout of approximately 5 minutes. If your code times out, simplify it or break it into smaller steps.\n ';
|
|
55
44
|
}
|
|
56
45
|
|
|
57
|
-
|
|
46
|
+
instructionsCache.set(cacheKey, { fetchedInstructions, fetchedAt: now });
|
|
47
|
+
return fetchedInstructions;
|
|
48
|
+
}
|
|
58
49
|
|
|
59
|
-
|
|
50
|
+
async function fetchLatestInstructionsFromFile(path: string): Promise<string> {
|
|
51
|
+
try {
|
|
52
|
+
return await fs.readFile(path, 'utf-8');
|
|
53
|
+
} catch (error) {
|
|
54
|
+
getLogger().error({ error, path }, 'Error fetching instructions from file');
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
60
57
|
}
|