Skip to content

Commit c65e4a3

Browse files
feat(mcp): enable optional code execution tool on http mcp servers
1 parent c1688e1 commit c65e4a3

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

packages/mcp-server/src/options.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,10 @@ const coerceArray = <T extends z.ZodTypeAny>(zodType: T) =>
284284
);
285285

286286
const QueryOptions = z.object({
287-
tools: coerceArray(z.enum(['dynamic', 'all', 'docs'])).describe('Use dynamic tools or all tools'),
288-
no_tools: coerceArray(z.enum(['dynamic', 'all', 'docs'])).describe('Do not use dynamic tools or all tools'),
287+
tools: coerceArray(z.enum(['dynamic', 'all', 'code', 'docs'])).describe('Specify which MCP tools to use'),
288+
no_tools: coerceArray(z.enum(['dynamic', 'all', 'code', 'docs'])).describe(
289+
'Specify which MCP tools to not use.',
290+
),
289291
tool: coerceArray(z.string()).describe('Include tools matching the specified names'),
290292
resource: coerceArray(z.string()).describe('Include tools matching the specified resources'),
291293
operation: coerceArray(z.enum(['read', 'write'])).describe(
@@ -385,11 +387,16 @@ export function parseQueryOptions(defaultOptions: McpOptions, query: unknown): M
385387
: queryOptions.tools?.includes('docs') ? true
386388
: defaultOptions.includeDocsTools;
387389

390+
let codeTools: boolean | undefined =
391+
queryOptions.no_tools && queryOptions.no_tools?.includes('code') ? false
392+
: queryOptions.tools?.includes('code') && defaultOptions.includeCodeTools ? true
393+
: defaultOptions.includeCodeTools;
394+
388395
return {
389396
client: queryOptions.client ?? defaultOptions.client,
390397
includeDynamicTools: dynamicTools,
391398
includeAllTools: allTools,
392-
includeCodeTools: undefined,
399+
includeCodeTools: codeTools,
393400
includeDocsTools: docsTools,
394401
filters,
395402
capabilities: clientCapabilities,

packages/mcp-server/tests/options.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ describe('parseQueryOptions', () => {
171171
const defaultOptions = {
172172
client: undefined,
173173
includeDynamicTools: undefined,
174+
includeCodeTools: undefined,
174175
includeAllTools: undefined,
175176
filters: [],
176177
capabilities: {
@@ -383,6 +384,27 @@ describe('parseQueryOptions', () => {
383384
{ type: 'tool', op: 'exclude', value: 'exclude-tool' },
384385
]);
385386
});
387+
388+
it('code tools are enabled on http servers with default option set', () => {
389+
const query = 'tools=code';
390+
const result = parseQueryOptions({ ...defaultOptions, includeCodeTools: true }, query);
391+
392+
expect(result.includeCodeTools).toBe(true);
393+
});
394+
395+
it('code tools are prevented on http servers when no default option set', () => {
396+
const query = 'tools=code';
397+
const result = parseQueryOptions(defaultOptions, query);
398+
399+
expect(result.includeCodeTools).toBe(undefined);
400+
});
401+
402+
it('code tools are prevented on http servers when default option is explicitly false', () => {
403+
const query = 'tools=code';
404+
const result = parseQueryOptions({ ...defaultOptions, includeCodeTools: false }, query);
405+
406+
expect(result.includeCodeTools).toBe(false);
407+
});
386408
});
387409

388410
describe('parseEmbeddedJSON', () => {

0 commit comments

Comments
 (0)