loading…
Search for a command to run...
loading…
A minimal MCP server providing a normalized API for code navigation and repository inspection through tools like symbol searching and call tracing. It enables A
A minimal MCP server providing a normalized API for code navigation and repository inspection through tools like symbol searching and call tracing. It enables AI agents to perform structured analysis of codebases by mapping endpoints, inspecting file trees, and tracing symbol relationships.
Workspace-only MCP server for structural code navigation and repository inspection. It exposes a stable public code.* tool surface for finding symbol definitions, tracing upstream callers for impact analysis, tracing downstream execution flow before logic changes, listing routes/endpoints, searching text, and inspecting workspace trees without opening files blindly.
npm: @navigation-agent/mcp-server
The server runs via npx.
rg) — optional, only needed for code.search_textclaude mcp add --transport stdio navigation-agent -- npx -y @navigation-agent/mcp-server
Add to ~/.config/opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"navigation-agent": {
"type": "local",
"command": ["npx", "-y", "@navigation-agent/mcp-server"],
"enabled": true,
"timeout": 30000
}
}
}
gemini mcp add navigation-agent npx -- -y @navigation-agent/mcp-server
Or add it manually to ~/.gemini/settings.json or .gemini/settings.json:
{
"mcpServers": {
"navigation-agent": {
"command": "npx",
"args": ["-y", "@navigation-agent/mcp-server"],
"timeout": 30000
}
}
}
Use the hyphenated server name navigation-agent. Avoid underscores in Gemini MCP server names because Gemini derives fully-qualified tool names from the server name.
Add to ~/.cursor/mcp.json or .cursor/mcp.json:
{
"mcpServers": {
"navigation-agent": {
"command": "npx",
"args": ["-y", "@navigation-agent/mcp-server"]
}
}
}
codex mcp add navigation-agent -- npx -y @navigation-agent/mcp-server
Or add to ~/.codex/config.toml:
[mcp_servers.navigation-agent]
command = "npx"
args = ["-y", "@navigation-agent/mcp-server"]
startup_timeout_sec = 30
tool_timeout_sec = 60
By default the server analyzes the current working directory. To pin a specific project, set NAVIGATION_MCP_WORKSPACE_ROOT in your MCP config.
This server is built for model-controlled MCP tool use: agents should discover and invoke its tools before opening source files when the task is about workspace code structure.
It publishes both per-tool descriptions and server instructions so MCP clients can teach the model the workflow without relying on a private skill registry.
MCP clients give the model guidance through a few standard channels:
| Channel | What this server provides |
|---|---|
MCP initialize.result.instructions |
A concise workflow: use navigation before reading files, which tool to pick, supported languages/frameworks, and workspace-only limits. |
| Tool descriptions and input schemas | Each code.* tool explains when to use it and lists supported language / framework filters. |
| Structured tool results | Every tool returns the stable envelope tool, status, summary, data, errors, and meta so agents can chain outputs safely. |
| Optional client rules/skills | Clients such as OpenCode, Codex, Cursor, and Gemini can add project rules, but this server does not require a private registry to be useful. |
The important part: the server instructions are part of the MCP handshake, so clients that honor MCP instructions can inject them into the model before tool selection.
skills/navigation-mcp/SKILL.md is an optional portable skill template for clients that support skills. It is not required for normal MCP operation; for OpenCode specifically, skills are discovered from .opencode/skills/<name>/SKILL.md, global OpenCode skills, or Claude/agents-compatible skill directories.
code.inspect_tree to orient in an unknown module or directory without reading files.code.find_symbol when you know a class, function, method, type, enum, or annotation name but not the defining file.find_symbol's returned items[].path into:code.trace_callers for upstream impact: who calls this?code.trace_flow for downstream behavior: what does this call or reach?code.list_endpoints before changing REST, GraphQL, or route surfaces.code.search_text for textual patterns, imports, decorators, or when symbol lookup is not enough.| Situation | Correct fallback |
|---|---|
code.find_symbol returns zero for constants, config keys, decorators, imports, or generated names |
Use code.search_text scoped by path, include, and language. |
| A trace result is too broad or noisy | Narrow path, language, framework, or symbol; for trace_callers, lower max_depth. |
| A route or endpoint inventory returns zero | Retry with a narrower path and the most specific framework or kind before concluding there is no public surface. |
A navigation result has truncated: true |
Narrow the query before reading files or increasing limit. |
Do not treat an empty result as proof by itself. Use one scoped fallback, then explain the limitation if results still stay empty.
The canonical public contract is code.*. Some clients expose MCP tools with a server prefix or normalized separators, for example navigation-agent_code_find_symbol or mcp_navigation-agent_code.find_symbol. Treat those names as aliases of the same canonical tools.
Use navigation-agent as the server name in examples. It is readable, avoids collisions, and avoids underscore-related parser issues in clients that derive fully-qualified tool names from the server id.
| Client | Convention checked |
|---|---|
| Claude Code | Local stdio command uses claude mcp add --transport stdio <name> -- <command> <args...>. Server instructions help Claude's MCP tool search decide when to load these tools. |
| OpenCode | Local MCP servers live under the mcp config key with type: "local" and command as an array. MCP tools are exposed with a server-name prefix, so prompts/rules can say “use navigation-agent”. |
| Gemini CLI | MCP servers live under mcpServers; stdio uses command + args. Gemini appends MCP server instructions to system instructions and assigns names like mcp_{serverName}_{toolName}. |
| Cursor | MCP servers are configured in mcp.json with command + args for stdio or url + headers for remote servers. |
| OpenAI Codex | MCP servers live under [mcp_servers.<name>] in config.toml; codex mcp add <name> -- <command> is the CLI form. |
typescript, javascript, go, java, php, python, rust, csharpreact-router, springDo not use this MCP for web search, external repositories, arbitrary filesystem access, or reading file contents. It is a workspace-only navigation layer.
This table MUST stay in the README because it is the fastest way to understand the public support surface. It is intentionally organized with languages as rows and tools as columns so adding more languages grows downward instead of widening the table.
Tool columns omit the code. prefix to keep the matrix readable.
| Language | inspect_tree |
find_symbol |
search_text |
list_endpoints |
trace_flow |
trace_callers |
|---|---|---|---|---|---|---|
| Java | ✅ | ✅ | ✅ | ✅ Spring REST/GraphQL | ✅ | ✅ |
| TypeScript | ✅ | ✅ | ✅ | ✅ React Router | ✅ | ✅ |
| JavaScript | ✅ | ✅ | ✅ | ✅ React Router | ✅ | ✅ |
| PHP | ✅ | ✅ | ✅ | ⚠️ Public, not re-verified for endpoints | ✅ | ✅ |
| Python | ✅ | ✅ | ✅ | ✅ FastAPI/Flask-style decorators | ✅ | ✅ |
| Rust | ✅ | ✅ | ✅ | ⚠️ Target-dependent / non-web target returned zero | ✅ Qualified symbols | ✅ Qualified symbols |
| Go | ✅ | ✅ | ✅ | ⚠️ No useful endpoint inventory in current example | ✅ | ✅ |
| C# | ✅ | ✅ | ✅ | ⚠️ Stub implementation | ✅ | ✅ |
Legend:
code.inspect_tree and code.search_text also work without a language filter across general workspace files.Important:
typescript, javascript, go, java, php, python, rust, and csharp.JavaProjectIndex::build).The public contract exposes exactly these six tools:
code.inspect_treecode.list_endpointscode.find_symbolcode.search_textcode.trace_flowcode.trace_callersUse snake_case parameters such as max_depth, include_hidden, and file_pattern.
Use this workflow whenever you need to understand behavior or impact inside the workspace:
code.find_symbol — resolve the exact defining file first.code.trace_callers — inspect upstream impact before renaming, deleting, or changing a signature.code.trace_flow — inspect downstream execution before changing logic.read only the files returned by the trace results that actually matter.Rule of thumb:
code.trace_callers for who depends on this?code.trace_flow for what does this reach or invoke?Concrete workspace example:
{
"symbol": "create_order",
"language": "python",
"kind": "function",
"path": "examples/python"
}
{
"path": "examples/python/app/api/endpoints.py",
"symbol": "create_order",
"language": "python",
"recursive": true,
"max_depth": 3
}
{
"path": "examples/python/app/api/endpoints.py",
"symbol": "create_order",
"language": "python"
}
Expected agent behavior:
code.find_symbol first when the defining file is not already knowncode.trace_callers first when the risk is breaking callerscode.trace_flow next when the risk is changing downstream behaviorread the traced files you actually needReact Router example:
{
"symbol": "action",
"kind": "function",
"framework": "react-router",
"path": "app/routes"
}
{
"path": "app/routes/change-password.tsx",
"symbol": "action",
"framework": "react-router",
"recursive": true,
"max_depth": 2
}
{
"path": "app/routes/change-password.tsx",
"symbol": "action",
"framework": "react-router"
}
code.search_text response stylecode.search_text is optimized for agents:
line plus exact spanstopFiles highlights the densest files firstbefore / after text is intentionally omitted from the public response to reduce noise and token costExample shape:
{
"fileCount": 3,
"matchCount": 19,
"totalFileCount": 3,
"totalMatchCount": 19,
"topFiles": [
{
"path": "examples/go/internal/http/handlers/user_handler.go",
"language": "go",
"matchCount": 11
}
],
"items": [
{
"path": "examples/go/internal/http/handlers/user_handler.go",
"language": "go",
"matchCount": 11,
"matches": [
{
"line": 28,
"spans": [{ "colInit": 23, "colEnd": 32 }]
}
]
}
]
}
{
"symbol": "RootUserGraphQLController",
"language": "java",
"kind": "class"
}
{
"path": "app/routes/change-password.tsx",
"symbol": "action",
"framework": "react-router"
}
{
"path": "src/main/java/com/example/FooController.java",
"symbol": "getFoo",
"framework": "spring"
}
These checks were verified against real projects instead of toy stubs:
~/sias/app/back)code.inspect_tree works on real module treescode.find_symbol works on real Spring classescode.search_text works on real Java sourcecode.list_endpoints inventories framework-detectable Spring REST controllers and GraphQL resolvers as likely public entrypointscode.trace_flow works on real controller/resolver entrypointscode.trace_callers works on Java use cases and can identify probable public entrypointsVerified example:
RootUserGraphQLController#getUsersByDependencyRootGetUserUseCase#getUsers~/sias/app/front)code.inspect_tree works on real route treescode.find_symbol works on route-module exportscode.search_text works on real route filescode.list_endpoints inventories React Router route-module loader / action exports as likely route entrypointscode.trace_flow works for same-file route flow extractioncode.trace_callers works for same-file helpers and marks route exports as probable entrypointsVerified example:
app/routes/change-password.tsx#actiongetUserIdAndTokenFromSession, changeMyPassword, getSession, commitSession, getRoleRoutegetRoleRoute <- actionexamples/python)code.inspect_tree works on Python module treescode.find_symbol works on Python classes, functions, and methodscode.search_text works on Python source filescode.list_endpoints inventories FastAPI-style route decorators (@router.get, @app.post, etc.) as likely public API entrypointscode.trace_flow works end-to-end for multi-module Python scenarios, capturing deep recursive trees including branching calls, instance methods (self), and cross-file resolution.code.trace_callers works end-to-end for impact analysis, supporting recursive reverse-tracing across the entire workspace.Verified example (Forward Trace):
app/api/endpoints.py#create_orderorder_service.process_order(...) -> _handle_payment(...) -> payment_service.authorize_payment(...)AuditService, InventoryService, ProductRepository, etc.Verified example (Backward Trace):
app/services/audit.py#log_actionUserService, OrderServiceapp/api/endpoints.py (get_user, create_order)examples/php)code.inspect_tree works on PHP project treescode.find_symbol works on PHP classes and methodscode.search_text works on PHP source filescode.trace_flow works end-to-end for PHP service-to-repository callscode.trace_callers works end-to-end for PHP impact analysisNotes:
code.list_endpoints is publicly exposed for PHP but was not re-verified for useful endpoint inventory in the current exampleVerified example:
src/Service/UserService.php#UserService::persistUser$this->repository->save($user) to src/Repository/MemoryUserRepository.php#savecode.inspect_tree works on real Rust source treescode.find_symbol works on Rust types/functionscode.search_text works on real Rust sourcecode.trace_flow works on real Rust methods when queried with the correct qualified symbolcode.trace_callers works on real Rust methods when queried with the correct qualified symbolNotes:
code.list_endpoints returned zero results on this repository, which is expected for the chosen validation target because it is not a Rust web appVerified example:
crates/navigation-engine/src/capabilities/trace_flow.rs#JavaProjectIndex::buildSelf::new_empty(), index.scan_project(workspace_root), and index.is_empty()JavaProjectIndex::scan_project <- JavaProjectIndex::build./examples/csharp)code.inspect_tree workscode.search_text workscode.find_symbol works for method lookup such as OrderWorkflowService.ProcessOrderAsynccode.trace_flow works end-to-end on the example app and returns the recursive internal call treecode.trace_callers works end-to-end on the example app./examples/go)Real behavior today against examples/go:
code.inspect_tree workscode.search_text workscode.find_symbol works for method lookup such as CreateUsercode.trace_flow works end-to-end on the example app and returns the recursive internal call treecode.trace_callers works end-to-end on the example app, including callback/method-value references and interface-to-implementation reverse matchescode.list_endpoints still returns no useful entrypoint inventory for the current Go exampleCurrent public language filters:
typescriptjavascriptgojavaphppythonrustcsharpCurrent public framework filters:
react-routerspringEvery tool returns the same top-level envelope:
{
"tool": "code.trace_flow",
"status": "ok",
"summary": "Traced 5 callees for 'action' from 'app/routes/change-password.tsx'.",
"data": {},
"errors": [],
"meta": {
"query": {},
"resolvedPath": "app/routes/change-password.tsx",
"truncated": false,
"counts": {},
"detection": {}
}
}
Status meanings:
ok — request succeeded, including zero-result successpartial — request succeeded but was truncated/prunederror — request failed and includes stable error codesNotes:
code.trace_flow returns a rooted recursive tree under data.rootcode.trace_callers returns direct callers plus recursive reverse-trace metadatacode.search_text returns compact grouped matches and topFiles, not full context blocksThis repository has two main layers:
TypeScript MCP runtime (packages/mcp-server/)
code.* contractRust engine (crates/navigation-engine/)
crates/navigation-engine/src/bin/Important:
packages/mcp-server/src/bin/ contains the runtime entrypoint (navigation-mcp.ts)crates/navigation-engine/src/bin/, not in the TypeScript runtimeKey local commands:
npm install
npm --workspace @navigation-agent/mcp-server run check
npm --workspace @navigation-agent/mcp-server run test
cargo test --manifest-path crates/navigation-engine/Cargo.toml
Useful local runtime checks:
npx tsx packages/mcp-server/src/bin/navigation-mcp.ts --describe-tools
npx tsx packages/mcp-server/src/bin/navigation-mcp.ts --transport stdio-legacy --workspace-root /path/to/workspace
MIT
Выполни в терминале:
claude mcp add navigation-agent-mcp -- npx CSA PROJECT - FZCO © 2026 IFZA Business Park, DDP, Premises Number 31174 - 001
Безопасность
Низкий рискАвтоматическая эвристика по публичным данным — не гарантия безопасности.