Skip to content

Commit c623ce2

Browse files
authored
Merge pull request #24 from mcpc-tech/feat/code-execution-mode
feat: add code execution mode example and fix TypeScript addFormats u…
2 parents 834dd12 + 9662cbd commit c623ce2

File tree

21 files changed

+970
-107
lines changed

21 files changed

+970
-107
lines changed

deno.lock

Lines changed: 23 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/cli/deno.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@mcpc/cli",
3-
"version": "0.1.11",
3+
"version": "0.1.12-beta.1",
44
"repository": {
55
"type": "git",
66
"url": "git+https://github.com/mcpc-tech/mcpc.git"
@@ -12,7 +12,7 @@
1212
"./app": "./src/app.ts"
1313
},
1414
"imports": {
15-
"@mcpc/core": "jsr:@mcpc/core@^0.3.1",
15+
"@mcpc/core": "jsr:@mcpc/core@^0.3.2-beta.1",
1616
"@mcpc/utils": "jsr:@mcpc/utils@^0.2.2",
1717
"@modelcontextprotocol/sdk": "npm:@modelcontextprotocol/sdk@^1.8.0",
1818
"@mcpc-tech/ripgrep-napi": "npm:@mcpc-tech/ripgrep-napi@^0.0.4",

packages/core/deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@mcpc/core",
3-
"version": "0.3.1",
3+
"version": "0.3.2-beta.1",
44
"repository": {
55
"type": "git",
66
"url": "git+https://github.com/mcpc-tech/mcpc.git"
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Example: Code Execution Mode (KISS Pattern)
3+
*
4+
* Demonstrates the simplified code execution pattern with clear parameter names.
5+
* This example shows how to:
6+
* 1. Use definitionsOf to get tool schemas
7+
* 2. Execute JavaScript code with hasDefinitions declaring known tools
8+
*
9+
* Based on: https://www.anthropic.com/engineering/code-execution-with-mcp
10+
*
11+
* Simple workflow:
12+
* 1. First call: { definitionsOf: ['read_file', 'move_file'] } - get schemas
13+
* 2. Second call: {
14+
* code: 'const result = await callMCPTool("read_file", {...})',
15+
* hasDefinitions: ['read_file']
16+
* } - execute code
17+
*
18+
* Key benefits:
19+
* - Clear parameter names: definitionsOf, hasDefinitions, code
20+
* - Schema enforces: code requires hasDefinitions (non-empty)
21+
* - Both code and definitionsOf can be used together
22+
* - Simple, intuitive workflow
23+
*/
24+
25+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
26+
import { type ComposeDefinition, mcpc } from "../mod.ts";
27+
28+
export const toolDefinitions: ComposeDefinition[] = [
29+
{
30+
name: "file-organizer",
31+
description:
32+
`I am a smart file organizer that helps users manage their files efficiently.
33+
34+
Available tools:
35+
<tool name="@wonderwhy-er/desktop-commander.list_directory"/>
36+
<tool name="@wonderwhy-er/desktop-commander.create_directory"/>
37+
<tool name="@wonderwhy-er/desktop-commander.move_file"/>
38+
<tool name="@wonderwhy-er/desktop-commander.read_file"/>
39+
<tool name="@wonderwhy-er/desktop-commander.write_file">
40+
41+
I can:
42+
1. List directory contents to understand the current file structure
43+
2. Create new directories for organization
44+
3. Move files to appropriate folders based on type, date, or content
45+
4. Delete unnecessary files after confirmation
46+
5. Read file contents to understand what they contain
47+
6. Create new files or modify existing ones
48+
49+
I always ask for confirmation before making destructive changes and provide clear explanations of what I'm doing.`,
50+
options: {
51+
mode: "code_execution",
52+
},
53+
deps: {
54+
mcpServers: {
55+
"@wonderwhy-er/desktop-commander": {
56+
command: "npx",
57+
args: ["-y", "@wonderwhy-er/desktop-commander@latest"],
58+
transportType: "stdio" as const,
59+
},
60+
},
61+
},
62+
},
63+
];
64+
65+
export const server = await mcpc(
66+
[
67+
{
68+
name: "basic-file-manager",
69+
version: "1.0.0",
70+
},
71+
{
72+
capabilities: {
73+
tools: {
74+
listChanged: true,
75+
},
76+
},
77+
},
78+
],
79+
toolDefinitions,
80+
);
81+
82+
const transport = new StdioServerTransport();
83+
await server.connect(transport);

packages/core/src/compose.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ import { sortPluginsByOrder, validatePlugins } from "./plugin-utils.ts";
2929
// Import new manager modules
3030
import { PluginManager } from "./utils/plugin-manager.ts";
3131
import { ToolManager } from "./utils/tool-manager.ts";
32-
import { buildDependencyGroups } from "./utils/compose-helpers.ts";
32+
import {
33+
buildDependencyGroups,
34+
processToolsWithPlugins,
35+
} from "./utils/compose-helpers.ts";
3336
import { sanitizePropertyKey } from "./utils/common/provider.ts";
3437

3538
const ALL_TOOLS_PLACEHOLDER = "__ALL__";
@@ -344,10 +347,7 @@ export class ComposableMCPServer extends Server {
344347
externalTools: Record<string, ComposedTool>,
345348
mode: ExecutionMode,
346349
): Promise<void> {
347-
const { processToolsWithPlugins: processTools } = await import(
348-
"./utils/compose-helpers.ts"
349-
);
350-
await processTools(this, externalTools, mode);
350+
await processToolsWithPlugins(this, externalTools, mode);
351351
}
352352

353353
/**

packages/core/src/executors/agentic/agentic-executor.ts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,12 @@
11
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2-
import { Ajv } from "ajv";
3-
import { AggregateAjvError } from "@segment/ajv-human-errors";
4-
import addFormats from "ajv-formats";
52
import type { ComposableMCPServer } from "../../compose.ts";
63
import { CompiledPrompts } from "../../prompts/index.ts";
74
import { createLogger, type MCPLogger } from "../../utils/logger.ts";
5+
import { validateSchema } from "../../utils/schema-validator.ts";
86
import type { Span } from "@opentelemetry/api";
97
import { endSpan, initializeTracing, startSpan } from "../../utils/tracing.ts";
108
import process from "node:process";
119

12-
const ajv = new Ajv({
13-
allErrors: true,
14-
verbose: true,
15-
});
16-
// @ts-ignore -
17-
addFormats(ajv);
18-
1910
export class AgenticExecutor {
2011
private logger: MCPLogger;
2112
private tracingEnabled: boolean = false;
@@ -313,14 +304,6 @@ export class AgenticExecutor {
313304
if (args.decision === "complete") {
314305
return { valid: true };
315306
}
316-
const validate = ajv.compile(schema);
317-
if (!validate(args)) {
318-
const errors = new AggregateAjvError(validate.errors!);
319-
return {
320-
valid: false,
321-
error: errors.message,
322-
};
323-
}
324-
return { valid: true };
307+
return validateSchema(args, schema);
325308
}
326309
}

0 commit comments

Comments
 (0)