Skip to main content
Glama

incoming_calls

Identify all functions or methods that call a specified symbol in Svelte code to analyze dependencies and understand usage patterns.

Instructions

Find all functions/methods that call the specified symbol.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filePathYesAbsolute path to the file
symbolNameYesName of the symbol to find
symbolKindNoKind of symbol

Implementation Reference

  • Tool registration and handler implementation for 'incoming_calls'. It attempts to use 'textDocument/prepareCallHierarchy' and 'callHierarchy/incomingCalls' from the LSP, falling back to 'incomingCallsFallback' if not supported.
    server.registerTool(
      "incoming_calls",
      {
        title: "Incoming Calls",
        description:
          "Find all functions/methods that call the specified symbol.",
        inputSchema: z.object({
          filePath: z.string().describe("Absolute path to the file"),
          symbolName: z
            .string()
            .describe("Name of the symbol to find"),
          symbolKind: z.string().optional().describe("Kind of symbol"),
        }),
      },
      async ({ filePath, symbolName, symbolKind }): Promise<ToolResult> => {
        try {
          const prep = await prepareSymbolRequest(lsp, filePath, symbolName, symbolKind);
          if ("error" in prep) return textResult(prep.error);
    
          // Try native call hierarchy
          try {
            const prepareResult = await lsp.request(
              "textDocument/prepareCallHierarchy",
              makePositionParams(prep.ctx)
            );
            if (Array.isArray(prepareResult) && prepareResult.length > 0) {
              const result = await lsp.request(
                "callHierarchy/incomingCalls",
                { item: prepareResult[0] }
              );
              if (Array.isArray(result) && result.length > 0) {
                const lines: string[] = [
                  `Found ${result.length} caller(s) of '${symbolName}':`,
                  "",
                ];
                for (const call of result) {
                  if (call.from) {
                    lines.push(formatHierarchyItem(call.from));
                  }
                }
                return textResult(lines.join("\n"));
              }
            }
          } catch {
            // call hierarchy not supported, try fallback
          }
    
          // Fallback: use references
          return textResult(
            await incomingCallsFallback(lsp, prep.ctx, symbolName)
          );
        } catch (ex) {
          return textResult(formatError(ex));
        }
      }
    );
  • Fallback handler for 'incoming_calls' when the native call hierarchy LSP method is not supported. It uses 'textDocument/references' to find callers.
    async function incomingCallsFallback(
      lsp: LspClient,
      ctx: { uri: string; line: number; character: number },
      symbolName: string
    ): Promise<string> {
      const params = {
        textDocument: { uri: ctx.uri },
        position: { line: ctx.line, character: ctx.character },
        context: { includeDeclaration: false },
      };
    
      const refs = await lsp.request("textDocument/references", params);
      if (!Array.isArray(refs) || refs.length === 0) {
        return `No incoming calls found for '${symbolName}'.`;
      }
    
      const callers: Array<{
        name: string;
        kind: string;
        path: string;
        line: number;
      }> = [];
      const seen = new Set<string>();
      const symbolCache = new Map<string, any[]>();
    
      for (const r of refs) {
        const refUri = r.uri;
        const refLine = r.range?.start?.line;
        if (!refUri || refLine == null) continue;
    
        const refPath = uriToPath(refUri);
    
        if (!symbolCache.has(refUri)) {
          await lsp.ensureDocumentOpen(refPath);
          const symResult = await lsp.request("textDocument/documentSymbol", {
            textDocument: { uri: refUri },
          });
          symbolCache.set(refUri, Array.isArray(symResult) ? symResult : []);
        }
    
        const symbols = symbolCache.get(refUri)!;
        const container = findContainingMethod(symbols, refLine);
        if (!container) continue;
    
        const name = container.name ?? "?";
        const kind = symbolKindName(container.kind ?? 0);
        const range = container.selectionRange ?? container.range;
        const line = (range?.start?.line ?? 0) + 1;
    
        const key = `${name}:${refPath}:${line}`;
        if (seen.has(key)) continue;
        seen.add(key);
    
        callers.push({ name, kind, path: refPath, line });
      }
    
      if (callers.length === 0) {
        return `No incoming calls found for '${symbolName}'.`;
      }
    
      const lines: string[] = [
        `Found ${callers.length} caller(s) of '${symbolName}':`,
        "",
      ];
      for (const c of callers) {
        lines.push(`  ${c.name} (${c.kind}) - ${c.path}:${c.line}`);
      }
      return lines.join("\n");
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/adainrivers/SvelteLS.MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server