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

Method execute

src/mcp/tools.ts:1354–1438  ·  view source on GitHub ↗

* Execute a tool by name

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

Source from the content-addressed store, hash-verified

1352 * Execute a tool by name
1353 */
1354 async execute(toolName: string, args: Record<string, unknown>): Promise<ToolResult> {
1355 try {
1356 // Block the first tool call on the engine's post-open reconcile so we
1357 // never serve rows for files deleted/edited while no MCP server was
1358 // running. The wait is time-boxed (#905): a huge-repo reconcile takes
1359 // minutes, and blocking the first call on all of it reads as a hang, so
1360 // we wait briefly then serve and let it finish in the background. The
1361 // gate is cleared after first await — subsequent calls pay nothing.
1362 // Catch-up failures are logged by the engine; we proceed regardless so a
1363 // transient sync error never breaks tools.
1364 if (this.catchUpGate) {
1365 const gate = this.catchUpGate;
1366 this.catchUpGate = null;
1367 await this.awaitCatchUpGate(gate);
1368 }
1369 // Honor the optional tool allowlist (CODEGRAPH_MCP_TOOLS): a trimmed
1370 // surface rejects ablated tools defensively even if a client cached them.
1371 if (!this.isToolAllowed(toolName)) {
1372 return this.errorResult(`Tool ${toolName} is disabled via CODEGRAPH_MCP_TOOLS`);
1373 }
1374 // Cross-cutting input validation. All tools accept an optional
1375 // `projectPath` and most accept either `query`, `task`, or
1376 // `symbol` — bound their lengths centrally so individual handlers
1377 // can stay focused on tool-specific logic.
1378 const pathCheck = this.validateOptionalPath(args.projectPath, 'projectPath');
1379 if (typeof pathCheck === 'object' && pathCheck !== undefined) {
1380 return pathCheck;
1381 }
1382 // The `path` and `pattern` properties used by codegraph_files are
1383 // also path-shaped — apply the same cap.
1384 if (args.path !== undefined) {
1385 const check = this.validateOptionalPath(args.path, 'path');
1386 if (typeof check === 'object' && check !== undefined) return check;
1387 }
1388 if (args.pattern !== undefined) {
1389 const check = this.validateOptionalPath(args.pattern, 'pattern');
1390 if (typeof check === 'object' && check !== undefined) return check;
1391 }
1392
1393 // codegraph_status reports watcher state (pending files, degraded mode,
1394 // worktree warning) and embeds its own sections — it must run on the MAIN
1395 // thread against the watched default instance, so it is NEVER off-loaded to
1396 // a worker (whose read connection has no watcher). It also skips the
1397 // auto-banner wrapper to avoid duplicating its own pending-files section.
1398 if (toolName === 'codegraph_status') {
1399 return await this.handleStatus(args);
1400 }
1401
1402 // Read tools: off-load the CPU-heavy dispatch to the worker pool when one
1403 // is attached, healthy, AND has finished its first cold start (daemon
1404 // mode), so the daemon's single event loop stays free for the MCP
1405 // transport under concurrent load — otherwise N concurrent explores
1406 // serialize AND starve the transport until the whole batch drains
1407 // (clients then time out). Before the first worker is warm, calls run
1408 // in-process: a call queued behind a cold start sat invisible until the
1409 // 45s busy backstop — the daemon's first tool call stalling for however
1410 // long a worker spawn takes on a loaded machine (the #662 flake). With
1411 // 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