MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / execute

Method execute

src/mcp/tools.ts:1426–1510  ·  view source on GitHub ↗

* Execute a tool by name

(toolName: string, args: Record<string, unknown>)

Source from the content-addressed store, hash-verified

1424 * Execute a tool by name
1425 */
1426 async execute(toolName: string, args: Record<string, unknown>): Promise<ToolResult> {
1427 try {
1428 // Block the first tool call on the engine's post-open reconcile so we
1429 // never serve rows for files deleted/edited while no MCP server was
1430 // running. The wait is time-boxed (#905): a huge-repo reconcile takes
1431 // minutes, and blocking the first call on all of it reads as a hang, so
1432 // we wait briefly then serve and let it finish in the background. The
1433 // gate is cleared after first await — subsequent calls pay nothing.
1434 // Catch-up failures are logged by the engine; we proceed regardless so a
1435 // transient sync error never breaks tools.
1436 if (this.catchUpGate) {
1437 const gate = this.catchUpGate;
1438 this.catchUpGate = null;
1439 await this.awaitCatchUpGate(gate);
1440 }
1441 // Honor the optional tool allowlist (CODEGRAPH_MCP_TOOLS): a trimmed
1442 // surface rejects ablated tools defensively even if a client cached them.
1443 if (!this.isToolAllowed(toolName)) {
1444 return this.errorResult(`Tool ${toolName} is disabled via CODEGRAPH_MCP_TOOLS`);
1445 }
1446 // Cross-cutting input validation. All tools accept an optional
1447 // `projectPath` and most accept either `query`, `task`, or
1448 // `symbol` — bound their lengths centrally so individual handlers
1449 // can stay focused on tool-specific logic.
1450 const pathCheck = this.validateOptionalPath(args.projectPath, 'projectPath');
1451 if (typeof pathCheck === 'object' && pathCheck !== undefined) {
1452 return pathCheck;
1453 }
1454 // The `path` and `pattern` properties used by codegraph_files are
1455 // also path-shaped — apply the same cap.
1456 if (args.path !== undefined) {
1457 const check = this.validateOptionalPath(args.path, 'path');
1458 if (typeof check === 'object' && check !== undefined) return check;
1459 }
1460 if (args.pattern !== undefined) {
1461 const check = this.validateOptionalPath(args.pattern, 'pattern');
1462 if (typeof check === 'object' && check !== undefined) return check;
1463 }
1464
1465 // codegraph_status reports watcher state (pending files, degraded mode,
1466 // worktree warning) and embeds its own sections — it must run on the MAIN
1467 // thread against the watched default instance, so it is NEVER off-loaded to
1468 // a worker (whose read connection has no watcher). It also skips the
1469 // auto-banner wrapper to avoid duplicating its own pending-files section.
1470 if (toolName === 'codegraph_status') {
1471 return await this.handleStatus(args);
1472 }
1473
1474 // Read tools: off-load the CPU-heavy dispatch to the worker pool when one
1475 // is attached, healthy, AND has finished its first cold start (daemon
1476 // mode), so the daemon's single event loop stays free for the MCP
1477 // transport under concurrent load — otherwise N concurrent explores
1478 // serialize AND starve the transport until the whole batch drains
1479 // (clients then time out). Before the first worker is warm, calls run
1480 // in-process: a call queued behind a cold start sat invisible until the
1481 // 45s busy backstop — the daemon's first tool call stalling for however
1482 // long a worker spawn takes on a loaded machine (the #662 flake). With
1483 // no pool (direct mode) or a degraded one, dispatch runs in-process

Callers 15

mainFunction · 0.95
handleLocallyFunction · 0.80
handleToolsCallMethod · 0.80
probe-sweep.mjsFile · 0.80
probe-trace.mjsFile · 0.80
probe-explore.mjsFile · 0.80
probe-node.mjsFile · 0.80
probe-context.mjsFile · 0.80
runOneFunction · 0.80

Calls 10

awaitCatchUpGateMethod · 0.95
isToolAllowedMethod · 0.95
errorResultMethod · 0.95
validateOptionalPathMethod · 0.95
handleStatusMethod · 0.95
executeReadToolMethod · 0.95
withWorktreeNoticeMethod · 0.95
withStalenessNoticeMethod · 0.95
textResultMethod · 0.95
runMethod · 0.65

Tested by 4

textFunction · 0.64
textFunction · 0.64
listedFunction · 0.64
exploreFunction · 0.64