find_symbol
Search for symbols by name across Godot projects using LSP for accuracy or regex as fallback, filtering by type and limiting results.
Instructions
Find symbols by name across the project. Uses LSP when available, regex parser as fallback. Results include a metadata.source field indicating whether LSP or regex was used. Report whether results came from LSP or regex fallback, as LSP provides more accurate signatures and locations.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Symbol name to search for (substring match) | |
| type | No | Symbol type to filter by | any |
| maxResults | No | Maximum results to return |
Implementation Reference
- src/tools/symbol-tools.ts:119-205 (handler)The handler for the `find_symbol` tool, which attempts an LSP workspace symbol search first and falls back to a script index search if LSP is unavailable.
handler: async (ctx) => { const { name, type = "any", maxResults = 50 } = ctx.args; const lsp = getLspClient(); // Try LSP workspace symbol search first if (lsp?.connected) { try { const symbols = await lsp.workspaceSymbol(name); let filtered = symbols; if (type !== "any") { filtered = symbols.filter((s) => matchesTypeFilter(s.kind, type)); } const data = filtered.slice(0, maxResults).map((s) => ({ name: s.name, kind: symbolKindName(s.kind), file: s.location.uri.replace("file://", ""), line: s.location.range.start.line + 1, container: s.containerName, })); return makeTextResponse({ data, truncated: filtered.length > maxResults, totalCount: filtered.length, metadata: { source: "lsp" }, }); } catch { // Fall through to fallback } } // Fallback: search script index const results: Array<{ name: string; kind: string; file: string; line: number; }> = []; const matchesFilter = (kind: string): boolean => type === "any" || type === kind; for (const [path, script] of await index.scriptIndex.all()) { // Collect symbol arrays with their kinds for uniform iteration const symbolSources: Array<{ kind: string; items: Array<{ name: string; line: number }>; }> = []; if (matchesFilter("function")) symbolSources.push({ kind: "function", items: script.functions }); if (matchesFilter("signal")) symbolSources.push({ kind: "signal", items: script.signals }); if (matchesFilter("variable")) symbolSources.push({ kind: "variable", items: script.exports }); if (matchesFilter("enum")) symbolSources.push({ kind: "enum", items: script.enums }); if (matchesFilter("constant")) symbolSources.push({ kind: "constant", items: script.constants }); for (const { kind, items } of symbolSources) { for (const item of items) { if (item.name.includes(name)) { results.push({ name: item.name, kind, file: path, line: item.line }); } } } // Classes need special handling (className + innerClasses) if (matchesFilter("class")) { if (script.className?.includes(name)) { results.push({ name: script.className, kind: "class", file: path, line: 1 }); } for (const ic of script.innerClasses) { if (ic.name.includes(name)) { results.push({ name: ic.name, kind: "class", file: path, line: ic.line }); } } } } const truncated = results.length > maxResults; return makeTextResponse({ data: results.slice(0, maxResults), truncated, totalCount: results.length, metadata: { source: "fallback" }, }); }, - src/tools/symbol-tools.ts:103-118 (schema)Zod schema defining the input arguments for the `find_symbol` tool (name, type, maxResults).
schema: { name: z.string().describe("Symbol name to search for (substring match)"), type: z .enum(["function", "signal", "variable", "class", "enum", "constant", "any"]) .optional() .default("any") .describe("Symbol type to filter by"), maxResults: z .number() .int() .min(1) .max(500) .optional() .default(50) .describe("Maximum results to return"), }, - src/tools/symbol-tools.ts:90-91 (registration)Registration of the `find_symbol` tool within the `createSymbolTools` function.
{ name: "find_symbol",