Home / Function/ renderSymbolContext() — mcp Function Reference

renderSymbolContext() — mcp Function Reference

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

Entity Profile

Dependency Diagram

graph TD
  ed39a19a_30ac_32dd_41e1_ec20219b77f4["renderSymbolContext()"]
  e5737e93_21e3_4389_2f31_c2c4b7b9ef6c["handler()"]
  e5737e93_21e3_4389_2f31_c2c4b7b9ef6c -->|calls| ed39a19a_30ac_32dd_41e1_ec20219b77f4
  6666a1f2_0912_ade3_4b0e_42190c41cd97["normalizePath()"]
  ed39a19a_30ac_32dd_41e1_ec20219b77f4 -->|calls| 6666a1f2_0912_ade3_4b0e_42190c41cd97
  26d5f729_7e5d_b48c_83ae_0c596ef3a161["findDomain()"]
  ed39a19a_30ac_32dd_41e1_ec20219b77f4 -->|calls| 26d5f729_7e5d_b48c_83ae_0c596ef3a161
  02b5f117_2b53_1bd3_5222_b3ed6f74bd32["languageFromExtension()"]
  ed39a19a_30ac_32dd_41e1_ec20219b77f4 -->|calls| 02b5f117_2b53_1bd3_5222_b3ed6f74bd32
  d6ed9355_f977_306b_b0ef_d7220fdefe68["get()"]
  ed39a19a_30ac_32dd_41e1_ec20219b77f4 -->|calls| d6ed9355_f977_306b_b0ef_d7220fdefe68
  style ed39a19a_30ac_32dd_41e1_ec20219b77f4 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

src/tools/symbol-context.ts lines 308–464

export async function renderSymbolContext(graph: IndexedGraph, node: CodeGraphNode, directory: string): Promise<string> {
  const name = node.properties?.name as string || '(unknown)';
  const rawFilePath = node.properties?.filePath as string || '';
  const filePath = normalizePath(rawFilePath);
  const startLine = node.properties?.startLine as number || 0;
  const endLine = node.properties?.endLine as number || 0;
  const kind = node.properties?.kind as string || node.labels?.[0]?.toLowerCase() || 'symbol';
  const language = node.properties?.language as string || '';

  const lines: string[] = [];

  // Header
  lines.push(`## ${name}`);
  lines.push('');
  lines.push(`**Defined in:** ${filePath}${startLine ? ':' + startLine : ''}${endLine ? '-' + endLine : ''}`);
  lines.push(`**Type:** ${kind}${language ? ' (' + language + ')' : ''}`);

  // Domain
  const domain = findDomain(graph, node.id);
  if (domain) {
    lines.push(`**Domain:** ${domain}`);
  }
  lines.push('');

  // Source code
  if (filePath && startLine > 0) {
    try {
      const absPath = path.resolve(directory, filePath);
      const content = await fs.readFile(absPath, 'utf-8');
      const fileLines = content.split('\n');
      const end = endLine > 0 ? Math.min(endLine, startLine + MAX_SOURCE_LINES - 1) : startLine + MAX_SOURCE_LINES - 1;
      const sourceSlice = fileLines.slice(startLine - 1, end);
      if (sourceSlice.length > 0) {
        const lang = languageFromExtension(filePath);
        lines.push(`### Source`);
        lines.push('');
        lines.push(`\`\`\`${lang}`);
        lines.push(sourceSlice.join('\n'));
        lines.push('```');
        if (endLine > 0 && endLine > startLine + MAX_SOURCE_LINES - 1) {
          lines.push(`*... truncated (showing ${MAX_SOURCE_LINES} of ${endLine - startLine + 1} lines)*`);
        }
        lines.push('');
      }
    } catch {
      // File unreadable — skip source section silently
    }
  }

  // Callers
  const adj = graph.callAdj.get(node.id);
  if (adj && adj.in.length > 0) {
    lines.push(`### Called by (${adj.in.length} callers):`);
    lines.push('');
    const callers = adj.in
      .map(id => graph.nodeById.get(id))
      .filter((n): n is CodeGraphNode => !!n)
      .sort((a, b) => {
        const aPath = a.properties?.filePath as string || '';
        const bPath = b.properties?.filePath as string || '';
        return aPath.localeCompare(bPath);
      })
      .slice(0, MAX_SYMBOL_CALLERS);

    for (const caller of callers) {
      const cName = caller.properties?.name as string || '(unknown)';
      const cFile = normalizePath(caller.properties?.filePath as string || '');
      const cLine = caller.properties?.startLine as number || 0;
      lines.push(`- \`${cName}\` — ${cFile}${cLine ? ':' + cLine : ''}`);
    }

    if (adj.in.length > MAX_SYMBOL_CALLERS) {
      lines.push(`- *... and ${adj.in.length - MAX_SYMBOL_CALLERS} more*`);
    }
    lines.push('');
  }

  // Callees
  if (adj && adj.out.length > 0) {
    lines.push(`### Calls (${adj.out.length} functions):`);
    lines.push('');
    const callees = adj.out
      .map(id => graph.nodeById.get(id))
      .filter((n): n is CodeGraphNode => !!n)
      .slice(0, MAX_SYMBOL_CALLEES);

    for (const callee of callees) {
      const cName = callee.properties?.name as string || '(unknown)';
      const cFile = normalizePath(callee.properties?.filePath as string || '');
      const cLine = callee.properties?.startLine as number || 0;
      lines.push(`- \`${cName}\` — ${cFile}${cLine ? ':' + cLine : ''}`);
    }

    if (adj.out.length > MAX_SYMBOL_CALLEES) {
      lines.push(`- *... and ${adj.out.length - MAX_SYMBOL_CALLEES} more*`);
    }
    lines.push('');
  }

  // Related symbols in same file
  if (filePath) {
    const pathEntry = graph.pathIndex.get(filePath) ?? graph.pathIndex.get(rawFilePath);
    if (pathEntry) {
      const relatedIds = [
        ...pathEntry.functionIds,
        ...pathEntry.classIds,
        ...pathEntry.typeIds,
      ].filter(id => id !== node.id);

      if (relatedIds.length > 0) {
        lines.push(`### Other symbols in ${filePath}:`);
        lines.push('');

        const related = relatedIds
          .map(id => graph.nodeById.get(id))
          .filter((n): n is CodeGraphNode => !!n)
          .sort((a, b) => {
            const aLine = a.properties?.startLine as number || 0;
            const bLine = b.properties?.startLine as number || 0;
            return aLine - bLine;
          })
          .slice(0, MAX_SYMBOL_RELATED);

        for (const rel of related) {
          const rName = rel.properties?.name as string || '(unknown)';
          const rKind = rel.labels?.[0]?.toLowerCase() || '';
          const rLine = rel.properties?.startLine as number || 0;
          lines.push(`- \`${rName}\` (${rKind}) — line ${rLine}`);
        }

        if (relatedIds.length > MAX_SYMBOL_RELATED) {
          lines.push(`- *... and ${relatedIds.length - MAX_SYMBOL_RELATED} more*`);
        }
        lines.push('');
      }
    }
  }

  // Import relationships (for files containing this symbol)
  if (filePath) {
    const fileEntry = graph.pathIndex.get(filePath) ?? graph.pathIndex.get(rawFilePath);
    if (fileEntry?.fileId) {
      const fileAdj = graph.importAdj.get(fileEntry.fileId);
      if (fileAdj) {
        const importedBy = fileAdj.in.length;
        const imports = fileAdj.out.length;
        if (importedBy > 0 || imports > 0) {
          lines.push(`### File imports:`);
          lines.push(`- Imported by ${importedBy} files | Imports ${imports} modules`);
          lines.push('');
        }
      }
    }
  }

  return lines.join('\n');
}

Domain

Subdomains

Called By

Frequently Asked Questions

What does renderSymbolContext() do?
renderSymbolContext() is a function in the mcp codebase.
What does renderSymbolContext() call?
renderSymbolContext() calls 4 function(s): findDomain, get, languageFromExtension, normalizePath.
What calls renderSymbolContext()?
renderSymbolContext() is called by 1 function(s): handler.

Analyze Your Own Codebase

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

Try Supermodel Free