Hybrid LSP Semantic Resolution in codebase-memory-mcp: 10 Specific Features Explained
Hybrid LSP semantic resolution is a lightweight C module inside the codebase-memory-mcp static binary that performs language-aware type resolution across nine language families, enabling IDE-level "Go to Definition" accuracy without spawning external language servers.
The codebase-memory-mcp repository builds persistent knowledge graphs by combining tree-sitter syntactic analysis with a Hybrid LSP pass that resolves semantic types. This architecture delivers accurate cross-file symbol bindings and call-graph resolution while maintaining zero external dependencies.
Core Architecture of the Hybrid LSP Layer
The implementation resides in internal/cbm/lsp/ as a compiled C module that integrates directly into the indexing pipeline.
Lightweight C Implementation
Unlike traditional Language Server Protocol clients that spawn external processes, the Hybrid LSP layer runs inside the single static binary. The code in internal/cbm/lsp/ provides structurally compatible resolution logic for major language servers including pyright, tsserver, gopls, and rust-analyzer, without requiring their installation.
Tree-Sitter Integration
After tree-sitter builds the Abstract Syntax Tree (AST), the parser invokes HybridLSPResolve from internal/cbm/parser/parser.c to perform the semantic pass. This creates CALLS, USAGE, and RESOLVED_CALLS edges in internal/graph/edges.c that carry full type information.
10 Specific Features of Hybrid LSP Semantic Resolution
The Hybrid LSP layer adds ten specific resolution capabilities that transform syntactic matches into semantically accurate graph edges.
1. Cross-File Definition Registry
The LSP pass registers all top-level symbols—functions, classes, methods, constants, and interfaces—in a per-language registry. This registry enables lookups across compilation units, storing symbols for later resolution during the graph construction phase.
2. Import-Graph Resolution
Using the symbol registry combined with import or require statements, the system locates the exact definition a call refers to. The logic handles aliasing, re-exports, and relative path resolution to map caller to callee accurately across file boundaries.
3. Generic and Type-Parameter Substitution
The resolver substitutes generic type arguments (e.g., Array<T>, Map<K,V>) and propagates concrete types through call chains. This ensures that parameterized functions and classes resolve to their instantiated types rather than raw generic signatures.
4. Return-Type Inference
The system infers function return types from function bodies, including async/await patterns, generators, and overloaded signatures. Downstream calls receive accurate argument-type checking based on these inferred returns, enabling precise dataflow analysis.
5. JSX and JSDoc Handling
For JavaScript and TypeScript codebases, the Hybrid LSP parses JSX component signatures and JSDoc annotations. This resolves prop types without requiring a full type-checking server, enabling accurate component relationship mapping in React and similar frameworks.
6. PHP Namespace and Trait Resolution
The PHP resolver in internal/cbm/lsp/php.c follows use statements and trait composition paths. It correctly handles late-static-binding to resolve method calls to their actual implementations rather than just declaration sites.
7. C# LINQ and Extension-Method Dispatch
For C# code, the system discovers extension methods and Language Integrated Query (LINQ) query operators. It maps these syntactic sugar expressions to their underlying static method implementations, creating accurate call edges for fluent API chains.
8. Java Overload and Lambda Resolution
The Java resolver selects the correct overloaded method based on argument types at the call site. It also resolves lambda expressions to their target functional interfaces, enabling precise flow analysis through anonymous implementations.
9. Kotlin Scope-Function and Extension-Function Handling
Kotlin resolution treats scope functions (apply, let, run, etc.) as standard calls. The system resolves extension functions defined in other files and tracks their receiver contexts through the call chain to maintain accurate type information.
10. Rust UFCS Resolution
The Rust implementation supports Universal Function Call Syntax (UFCS), resolving trait-method calls whether invoked via method syntax (obj.method()) or explicit UFCS (Trait::method(&obj)). This captures trait implementations regardless of the specific call style used.
Supported Language Families
The Hybrid LSP semantic resolution covers nine primary language families with specific compatibility mappings:
- Python (pyright references)
- TypeScript / JavaScript / JSX / TSX (tsserver / typescript-go)
- PHP (PHP Language Server semantics including namespaces and traits)
- C# (Roslyn features including LINQ and file-scoped namespaces)
- Go (gopls compatible)
- C / C++ (Clangd compatible heuristics)
- Java (Eclipse JDT features including class hierarchies)
- Kotlin (Kotlin compiler features including scope functions)
- Rust (rust-analyzer features including UFCS)
- Perl (experimental Perl LSP support)
Benefits for Knowledge Graph Accuracy
The Hybrid LSP layer provides specific advantages for semantic code understanding.
Accurate Call-Edge Resolution
Graph edges reflect true runtime bindings rather than textual matches. The RESOLVED_CALLS edges in internal/graph/edges.c carry full type information, mirroring what an IDE "Go to Definition" operation would return.
Zero-Runtime Dependencies
Because the C implementation compiles into the static binary, no per-project LSP setup or external server processes are required. Users index repositories immediately without configuring language servers.
Performance Characteristics
The Hybrid LSP pass runs within the same parse pipeline as tree-sitter. This design keeps indexing times sub-second per file and enables sub-millisecond query latency against the resulting knowledge graph.
Implementation Files and Code Structure
The resolution logic spans several key source files:
internal/cbm/lsp/– Core C implementation of the Hybrid LSP layerinternal/cbm/lsp/python.c,typescript.c,php.c– Language-specific resolution logicinternal/cbm/parser/parser.c– Integration point that callsHybridLSPResolveinternal/graph/edges.c– Graph edge creation using LSP results
Query Examples Using Hybrid LSP Data
The resolved semantic graph enables precise queries across the codebase.
CLI Query Examples
Index a repository and query resolved calls:
$ codebase-memory-mcp index /path/to/repo
$ codebase-memory-mcp query "CALLS WHERE caller = 'service/user.go:CreateUser'"
The output shows the exact function that CreateUser invokes, resolved through the Hybrid LSP pass (e.g., repository.UserRepo.Insert).
Semantic Search via CLI
Search for functions with specific semantic characteristics:
$ codebase-memory-mcp semantic_query "function that parses JWT tokens"
The Hybrid LSP resolves the jwt.decode call chain across Python files, returning the concrete function definition with its module path.
Programmatic Go SDK Access
Query the knowledge graph programmatically using the Go client:
package main
import (
"fmt"
"github.com/DeusData/codebase-memory-mcp/pkg/go/client"
)
func main() {
c := client.NewClient("http://localhost:8080")
// Find all implementations of an interface
res, _ := c.Query(`
MATCH (i:Interface {name: "UserRepo"})<-[:IMPLEMENTS]-(c:Class)
RETURN c.name
`)
fmt.Println(res)
}
The Hybrid LSP resolves the interface hierarchy to return accurate implementation classes.
Summary
-
Hybrid LSP semantic resolution combines tree-sitter AST parsing with a C-based type resolution layer to create accurate knowledge graphs in
codebase-memory-mcp. -
The implementation in
internal/cbm/lsp/supports nine language families with IDE-compatible resolution logic for Python, TypeScript, Go, Rust, Java, C#, Kotlin, PHP, and C/C++. -
Ten specific features—including cross-file registries, import-graph resolution, generic substitution, and language-specific handlers for PHP traits, C# LINQ, Java lambdas, Kotlin extensions, and Rust UFCS—enable precise symbol binding.
-
The system operates with zero external dependencies, compiling into a single static binary that achieves sub-second indexing and sub-millisecond query performance.
Frequently Asked Questions
What is Hybrid LSP semantic resolution?
Hybrid LSP semantic resolution is the technology inside codebase-memory-mcp that performs language-aware type analysis without external language servers. It combines tree-sitter's syntactic parsing with a lightweight C module that resolves symbols, generics, and call targets to build a knowledge graph with IDE-level accuracy.
How does Hybrid LSP semantic resolution differ from standard tree-sitter parsing?
Tree-sitter parsing provides syntactic structure (AST nodes), while the Hybrid LSP layer adds semantic meaning by resolving which specific function or type a reference points to across files. According to the source code in internal/cbm/parser/parser.c, the HybridLSPResolve function enriches the AST with binding information before the graph edges are created in internal/graph/edges.c.
Which programming languages support generic type resolution?
The Hybrid LSP layer supports generic and type-parameter substitution for Java, C#, TypeScript, Kotlin, Rust, and Go. The resolver propagates concrete types through call chains by analyzing generic arguments at instantiation sites, as implemented in the language-specific files within internal/cbm/lsp/.
Does codebase-memory-mcp require external language server installations?
No. The Hybrid LSP implementation is a compiled C module embedded in the static binary. It is structurally compatible with references to pyright, tsserver, gopls, and other servers, but requires no external setup or runtime dependencies to perform semantic resolution.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →