Use the batch files in the project root:
Build MCP server:
"c:/Users/jespe/Documents/Embarcadero/Studio/Projects/DelphiAST_MCP/build.bat"Build test suite:
"c:/Users/jespe/Documents/Embarcadero/Studio/Projects/DelphiAST_MCP/build-tests.bat"Run the tests:
"c:/Users/jespe/Documents/Embarcadero/Studio/Projects/DelphiAST_MCP/run-tests.bat"- 6 units: AST.Parser, AST.Query, AST.AstGrep, MCP.Tools, MCP.Server, DelphiAST_MCP.dpr
- 18 MCP tools: list_files, parse_unit, get_type_detail, get_method_body, find_references, get_uses_graph, get_syntax_tree, find_usages, get_source, symbol_at_position, resolve_inheritance, get_call_graph, set_project, get_status, is_ready, find_descendants, search_symbols, search_pattern
- Newline-delimited JSON-RPC 2.0 over stdio, protocol version
2024-11-05 - AST caching via
TObjectDictionary<string, TSyntaxNode>
ast-grep provides fast structural pattern matching via tree-sitter. It accelerates search tools but can't handle {$IFDEF} or generic ambiguity, so DelphiAST provides fallback.
Ship pascal.dll (tree-sitter-pascal grammar) next to the MCP server exe. On first set_project, the server auto-creates sgconfig.yml if missing. Requires ast-grep on PATH (npm install -g @ast-grep/cli).
Alternatively, configure explicitly in .delphi-ast.json:
{
"astGrep": {
"exe": "ast-grep",
"configPath": "path/to/sgconfig.yml"
}
}search_patterntool: Shells out toast-grep.exe --jsonfor structural matching. Files with ERROR nodes (parse failures) are re-analyzed by DelphiAST usingFindUsages(simple identifiers only). Response includes_metashowing engine breakdown.- Pre-filter acceleration:
search_symbols,find_references,find_usagesuse ast-grep to narrow candidate files before running full DelphiAST queries. Only activates when ast-grep is available, pattern is a simple identifier, and project has >20 files. Falls back to full scan on any failure. - Graceful degradation: If ast-grep is unavailable (no DLL, not on PATH), all tools work exactly as before — pure DelphiAST.
Patterns must form a complete syntactic node in the grammar — incomplete statement fragments produce ERROR nodes and match nothing.
| Pattern | Works? | Reason |
|---|---|---|
$A := $B |
✓ | Complete assignment node |
procedure $NAME |
✓ | Complete procedure heading |
$A.Free |
✓ | Complete method call |
raise $E |
✓ | Complete raise statement |
if $COND then |
✗ | if without body is syntactically incomplete |
procedure $NAME($$$ARGS) |
✗ | $$$ multi-match unsupported in param lists |
For if patterns, match the body instead: if $COND then $BODY — or search for the condition expression directly.
- Field/variable/parameter names stored as
TValuedSyntaxNodechildren withntNametype (use.Value, not.GetAttribute(anName)) - Property read/write accessors stored as
ntIdentifierchildren ofntRead/ntWritenodes - Use
TUTF8Encoding.Create(False)for BOM-free UTF-8 output in TStreamWriter - Pre-compiled DCUs in DelphiAST source are x86 only; must use
-Bflag for x64 builds ntCall= method calls WITH parentheses (e.g.,Exit,Exception.Create)ntDot= parameterless method/property calls (e.g.,FAnimals[I].GetName)
tests/test-project/- Fixture Delphi filestests/MCP.TestServer.pas- Server process managementtests/MCP.TestHelper.pas- Test helper utilitiestests/Tests.*.pas- Test fixtures for each MCP tool
AST.AstGrep.pas- ast-grep wrapper (CreateProcess, JSON parsing, ERROR detection)AST.Query.pas- AST query operations including call graph extractionMCP.Tools.pas- MCP tool implementations (search_pattern, pre-filter, auto-config)MCP.Server.pas- JSON-RPC server implementation