2026-05-29 18:12:45 +00:00
package tools
import (
"context"
"strings"
"code.nochebuena.dev/einherjar/mcp/internal/index"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
type getSymbolInput struct {
Module string `json:"module" jsonschema:"the module name, e.g. core"`
Name string `json:"name" jsonschema:"the symbol name; for methods use Type.Method"`
SubPackage string `json:"subPackage,omitempty" jsonschema:"narrow to a specific sub-package, e.g. launcher"`
}
type getSymbolOutput struct {
Matches [] index . Symbol `json:"matches"`
}
func registerGetSymbol ( s * mcp . Server , idx * index . Index ) {
mcp . AddTool ( s , & mcp . Tool {
Name : "get_symbol" ,
2026-06-10 10:38:30 -06:00
Description : "Fetch full signature, doc comment, and source location for one symbol. For a struct type the result includes its fields (name, type, struct tag, doc); for an interface type it includes its method set. Returns every match across sub-packages — use the subPackage filter when ambiguous." ,
2026-05-29 18:12:45 +00:00
}, func ( ctx context . Context , req * mcp . CallToolRequest , args getSymbolInput ) ( * mcp . CallToolResult , getSymbolOutput , error ) {
m := idx . FindModule ( args . Module )
if m == nil {
return errorResult ( "module not found: " + args . Module ), getSymbolOutput {}, nil
}
out := getSymbolOutput { Matches : [] index . Symbol {}}
for _ , sym := range m . Symbols {
if ! strings . EqualFold ( sym . Name , args . Name ) {
continue
}
if args . SubPackage != "" && sym . SubPackage != args . SubPackage {
continue
}
out . Matches = append ( out . Matches , sym )
}
return jsonText ( out ), out , nil
})
}