Home / Function/ handler() — mcp Function Reference

handler() — mcp Function Reference

Architecture documentation for the handler() function in symbol-context.ts from the mcp codebase.

Entity Profile

Dependency Diagram

graph TD
  e5737e93_21e3_4389_2f31_c2c4b7b9ef6c["handler()"]
  f3f1255a_0f7f_c2b0_e99d_eae489cac19d["setupHandlers()"]
  f3f1255a_0f7f_c2b0_e99d_eae489cac19d -->|calls| e5737e93_21e3_4389_2f31_c2c4b7b9ef6c
  05b504b7_268e_7c49_d109_73f7c3744be0["asErrorResult()"]
  e5737e93_21e3_4389_2f31_c2c4b7b9ef6c -->|calls| 05b504b7_268e_7c49_d109_73f7c3744be0
  1721f7fd_bb7b_c8c3_9b4b_5677293ae256["resolveOrFetchGraph()"]
  e5737e93_21e3_4389_2f31_c2c4b7b9ef6c -->|calls| 1721f7fd_bb7b_c8c3_9b4b_5677293ae256
  f8f0f24b_951e_04ad_fb80_1ae3dde982e9["classifyApiError()"]
  e5737e93_21e3_4389_2f31_c2c4b7b9ef6c -->|calls| f8f0f24b_951e_04ad_fb80_1ae3dde982e9
  2d87a17c_e46f_9198_c263_81d7c3c3054e["findSymbol()"]
  e5737e93_21e3_4389_2f31_c2c4b7b9ef6c -->|calls| 2d87a17c_e46f_9198_c263_81d7c3c3054e
  233a620a_de76_be53_26cd_6e06fbe25d41["renderBriefSymbolContext()"]
  e5737e93_21e3_4389_2f31_c2c4b7b9ef6c -->|calls| 233a620a_de76_be53_26cd_6e06fbe25d41
  ed39a19a_30ac_32dd_41e1_ec20219b77f4["renderSymbolContext()"]
  e5737e93_21e3_4389_2f31_c2c4b7b9ef6c -->|calls| ed39a19a_30ac_32dd_41e1_ec20219b77f4
  67622b0f_6b47_8f68_bac5_409b3145d2f2["asTextContentResult()"]
  e5737e93_21e3_4389_2f31_c2c4b7b9ef6c -->|calls| 67622b0f_6b47_8f68_bac5_409b3145d2f2
  style e5737e93_21e3_4389_2f31_c2c4b7b9ef6c fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

src/tools/symbol-context.ts lines 78–157

export const handler: HandlerFunction = async (client, args, defaultWorkdir) => {
  // Extract symbol list: prefer `symbols` array, fall back to single `symbol`
  let symbolList: string[];
  const symbolsArg = args?.symbols;
  const symbolArg = typeof args?.symbol === 'string' ? args.symbol.trim() : '';

  if (Array.isArray(symbolsArg) && symbolsArg.length > 0) {
    symbolList = symbolsArg
      .filter((s): s is string => typeof s === 'string')
      .map(s => s.trim())
      .filter(s => s.length > 0)
      .slice(0, MAX_BATCH_SYMBOLS);
  } else if (symbolArg) {
    symbolList = [symbolArg];
  } else {
    return asErrorResult({
      type: 'validation_error',
      message: 'Missing required "symbol" or "symbols" parameter.',
      code: 'MISSING_SYMBOL',
      recoverable: false,
      suggestion: 'Provide the name of a function, class, or method to look up.',
    });
  }

  const brief = !!args?.brief;
  const rawDir = args?.directory as string | undefined;
  const directory = (rawDir && rawDir.trim()) || defaultWorkdir || process.cwd();

  if (!directory || typeof directory !== 'string') {
    return asErrorResult({
      type: 'validation_error',
      message: 'No directory provided and no default workdir configured.',
      code: 'MISSING_DIRECTORY',
      recoverable: false,
      suggestion: 'Provide a directory parameter or start the MCP server with a workdir argument.',
    });
  }

  let graph: IndexedGraph;
  try {
    graph = await resolveOrFetchGraph(client, directory);
  } catch (error: any) {
    return asErrorResult(classifyApiError(error));
  }

  const isBatch = symbolList.length > 1;
  const useBrief = brief || isBatch;

  const allRendered: string[] = [];
  for (const sym of symbolList) {
    const matches = findSymbol(graph, sym);

    if (matches.length === 0) {
      allRendered.push(
        `## ${sym}\n\nNo symbol matching "${sym}" found in the code graph.`
      );
      continue;
    }

    if (useBrief) {
      // Brief mode: compact output for each top match
      const parts = matches.slice(0, 3).map(node => renderBriefSymbolContext(graph, node));
      allRendered.push(parts.join('\n---\n\n'));
      if (matches.length > 3) {
        allRendered.push(`*... and ${matches.length - 3} more matches for "${sym}".*`);
      }
    } else {
      // Full mode: detailed output (single symbol, not brief)
      const parts = await Promise.all(
        matches.slice(0, 3).map(node => renderSymbolContext(graph, node, directory))
      );
      allRendered.push(parts.join('\n---\n\n'));
      if (matches.length > 3) {
        allRendered.push(`*... and ${matches.length - 3} more matches. Use a more specific name to narrow results.*`);
      }
    }
  }

  return asTextContentResult(allRendered.join('\n\n---\n\n'));
};

Domain

Subdomains

Called By

Frequently Asked Questions

What does handler() do?
handler() is a function in the mcp codebase.
What does handler() call?
handler() calls 7 function(s): asErrorResult, asTextContentResult, classifyApiError, findSymbol, renderBriefSymbolContext, renderSymbolContext, resolveOrFetchGraph.
What calls handler()?
handler() is called by 1 function(s): setupHandlers.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free