Are you the author? Sign in to claim
Ask for the symbol, not the file. Token-efficient MCP server giving AI coding agents symbol-level reads of TS/JS, Rust
Ask for the symbol you need—not the entire file.
.ts
.tsx
.js
.jsx
.rs
.py
.java
.go
.json
.md
Quick start · Language support · Tools · Troubleshooting · Tool reference
SymbolPeek is an MCP server that gives an AI coding agent a symbol-level view of your codebase. Instead of reading a whole file to answer "what does this function do" or "who calls it", the agent asks for one declaration and gets exactly that.
TypeScript and JavaScript are analyzed with the official TypeScript Compiler API. Rust, Python, Java, Go, JSON, and Markdown use embedded Tree-sitter for syntax-level operations.
Requirements
.ts, .tsx, .js, and .jsx
analysis. Rust, Python, Java, Go, JSON, and Markdown work without it.No clone, Rust toolchain, or manual build is required.
macOS or Linux
curl -fsSL https://raw.githubusercontent.com/pioner92/symbolpeek-mcp/main/scripts/install.sh | sh
Windows PowerShell
irm https://raw.githubusercontent.com/pioner92/symbolpeek-mcp/main/scripts/install.ps1 | iex
The installer verifies the release checksum, installs the package, and then prints the exact command to connect your client. It touches nothing outside its own install directory — no client configuration is modified for you.
| Item | macOS / Linux | Windows |
|---|---|---|
| Package (binary + bundled TypeScript runtime) | ~/.local/share/symbolpeek | %LOCALAPPDATA%\SymbolPeek |
symbolpeek and sym commands | linked into ~/.local/bin | added to the user PATH |
| Lifetime statistics and tool usage (created on first use) | ~/.config/symbolpeek/stats.json (Linux)~/Library/Application Support/SymbolPeek/stats.json (macOS) | %APPDATA%\SymbolPeek\stats.json |
Disabled-tool configuration (created by sym tools) | ~/.config/symbolpeek/config.json (Linux)~/Library/Application Support/SymbolPeek/config.json (macOS) | %APPDATA%\SymbolPeek\config.json |
That is the complete list. Connecting the MCP server and installing the optional agent guidance are separate, explicit steps. See Uninstall to remove everything.
To inspect the installer before running it:
curl -fsSL https://raw.githubusercontent.com/pioner92/symbolpeek-mcp/main/scripts/install.sh -o install-symbolpeek.sh
less install-symbolpeek.sh
sh install-symbolpeek.sh
The installer prints these commands with the correct absolute path already
filled in. Use the absolute path form — it works regardless of how your client
inherits PATH:
# Codex (macOS/Linux)
codex mcp add symbolpeek -- "$HOME/.local/share/symbolpeek/symbolpeek"
# Claude Code (macOS/Linux)
claude mcp add --transport stdio --scope user symbolpeek -- "$HOME/.local/share/symbolpeek/symbolpeek"
# Codex (Windows)
codex mcp add symbolpeek -- "$env:LOCALAPPDATA\SymbolPeek\symbolpeek.exe"
# Claude Code (Windows)
claude mcp add --transport stdio --scope user symbolpeek -- "$env:LOCALAPPDATA\SymbolPeek\symbolpeek.exe"
Restart the client, then verify: codex mcp list, or /mcp inside Claude Code.
Use --scope project with Claude Code to enable the server for one project only.
The tools work as soon as the server is connected. SymbolPeek also ships a short skill that tells the agent to reach for those tools before opening whole files — without it the model calls them less often.
Install it only for the clients you actually use:
symbolpeek install-skills codex # writes ~/.codex/skills/symbolpeek
symbolpeek install-skills claude # writes ~/.claude/skills/symbolpeek
symbolpeek install-skills all # both
CODEX_HOME and CLAUDE_CONFIG_DIR override those locations. Restart the
client afterwards so it discovers the skill.
Try it with a prompt like:
Use the symbolpeek MCP server. List the symbols in the absolute path
/project/src/dashboard.tsx, then read_symbol_context for Dashboard.
After that, find_references for useAuth and go_to_definition for one usage.
Configuration templates are checked in at
config/codex-mcp.toml.example and
config/claude-mcp.json.example.
A real request against this repository's own TypeScript worker
(src/language/typescript/worker.js, 1,791 lines / 65 KB):
read_symbol(path: ".../src/language/typescript/worker.js",
symbol: "createProject.collectImports")
{
"symbol": "createProject.collectImports",
"kind": "function",
"file": ".../src/language/typescript/worker.js",
"lines": { "start": 713, "end": 751 },
"source": "function collectImports(fileName, collected, visited) {\n ...\n}",
"analysis": { "backend": "ts-compiler-api", "analysis_level": "syntax", "complete": true }
}
The agent receives 2.0 KB instead of 65 KB — the 39 lines it asked for rather than 1,791 lines it did not. Nested symbols are addressable by qualified name, so the agent never has to read the enclosing function to reach the inner one.
Every language-aware operation, exactly as reported by get_capabilities:
| Operation | .ts .tsx .js .jsx | .rs | .py .java .go | .json | .md |
|---|---|---|---|---|---|
read_symbol | ✅ | ✅ | ✅ | ✅ | ✅ |
read_symbols | ✅ | ✅ | ✅ | ✅ | ✅ |
list_symbols | ✅ | ✅ | ✅ | ✅ | ✅ |
search_symbols | ✅ | ✅ | ✅ | ✅ | ✅ |
get_document_outline | ✅ | ✅ | ✅ | ✅ | ✅ |
find_dependencies | ✅ | ✅¹ | ✅¹ | — | — |
read_symbol_context | ✅ | ✅¹ | ✅¹ | — | — |
find_implementations | ✅ | ✅² | — | — | — |
find_references | ✅ | — | — | — | — |
find_calls | ✅ | — | — | — | — |
go_to_definition | ✅ | — | — | — | — |
get_type | ✅ | — | — | — | — |
get_diagnostics | ✅ | — | — | — | — |
get_call_hierarchy | ✅ | — | — | — | — |
rename_symbol (writes files) | ✅ | — | — | — | — |
check_safe_to_delete | ✅ | — | — | — | — |
| Backend | TypeScript Compiler API | Tree-sitter | Tree-sitter | Tree-sitter | Tree-sitter |
| Analysis level | semantic | syntax | syntax | syntax | syntax |
¹ Same-file only — conservative, no cross-file resolution.
² Explicit impl Type and impl Trait for Type blocks. Alias, re-export, and
blanket-impl resolution requires rust-analyzer and is not supported.
Unsupported operations fail with an explicit error rather than returning empty
results. get_capabilities returns this same matrix at runtime.
| Tool | What it answers |
|---|---|
read_symbol | "Show me the exact source for this symbol." |
read_symbols | "Read several symbols at once (batch, cross-file, per-item ok)." |
list_symbols | "What are the top-level symbols in this file?" |
search_symbols | "Where is this symbol defined across the workspace?" |
go_to_definition | "Where is the definition behind this usage?" |
read_symbol_context | "Give me this symbol plus its minimal local context." |
| Tool | What it answers |
|---|---|
find_references | "Where is this symbol referenced across the project?" |
find_calls | "Who calls this symbol (callers) / what does it call (callees)?" |
find_dependencies | "Which local symbols does this symbol depend on?" |
get_call_hierarchy | "What callers and callees surround this symbol?" |
| Tool | What it answers |
|---|---|
get_type | "What is the inferred type or signature at this location?" |
find_implementations | "Which classes implement this interface or contract?" |
get_document_outline | "What is the nested declaration structure of this file?" |
get_diagnostics | "What TypeScript compiler diagnostics affect this file or symbol?" |
| Tool | What it answers |
|---|---|
rename_symbol | "Rename this symbol project-wide." Writes files directly — refused before any write if the new name collides with a declaration already in scope |
check_safe_to_delete | "Are these files safe to delete?" — one path or a whole set; references within the set don't block |
| Tool | What it answers |
|---|---|
get_capabilities | "Which operations does each language support?" |
Every request shape, option, and response format is documented in the MCP tool reference.
To reduce the MCP startup context, disable tools that your workflow does not need:
sym tools # interactive menu
sym tools list
sym tools disable get_type get_diagnostics
sym tools enable get_type
sym tools reset # enable everything
Changes take effect after restarting the MCP server. Disabled tools are omitted
from tools/list, rejected if a client calls a cached schema directly, and
removed from get_capabilities. Historical counters remain visible through
sym usage.
SymbolPeek does not replace reading files or text search. It replaces the most expensive pattern an agent hits on a real codebase: find a symbol, find everyone who touches it, and understand its type — across import aliases and re-exports.
Where it genuinely saves an agent work and tokens
read_symbol / read_symbol_context
return a single declaration instead of a whole file. On large files this is
the bulk of the token saving.find_references returns resolved
locations, while find_calls with direction: "callers" also identifies the
enclosing functions in one call. Both use the project's module resolution, including path aliases
(@app/...) and barrel re-exports, which text search follows unreliably.get_type returns the instantiated signature (for
example useAsync<FeedPermission, Error>), which text search cannot produce.search_symbols finds declarations by name and kind
(for example "hooks matching conversation") without the noise of string
matches in comments and unrelated code.Where an agent should still use ordinary tools
grep is faster.grep can win for a single lookup. Rust, Python, Java, Go, and JSON
requests never start Node and stay fast regardless of project size.What makes the results trustworthy
hook and
react_component are conventions applied on top of that syntax tree, based on
naming and JSX usage.tsconfig.json they use its configured source set; without one they
cover the target file and recursively resolved static imports, exports, and
require(...) calls. Compiler options come from the project tsconfig.json.analysis: { backend, analysis_level, complete } trust metadata, where
complete: false means the parser recovered from a syntax error.TypeScript and JavaScript — function declarations, async functions, generators, and arrow functions; exported and nested functions; React components and hooks; classes and class methods; object methods; interfaces, type aliases, enums and qualified enum members, variables, and constants.
Enum members are addressed by qualified name, for example
Screens.PUBLISH_ACKNOWLEDGEMENT. Symbol names are indexed; assigned string
values remain literals and require text search.
Rust — functions, structs, unions, enums and variants, traits, impl blocks
and methods, modules, constants, statics, type declarations, and macros. Impl
methods use qualified names such as Client.send, and trait impl methods use
<Client as Transport>.send.
JSON — object properties are indexed as RFC 6901 JSON Pointers, for example
/checkout/errors/payment_failed. Array-valued properties remain single
addressable branches instead of expanding every element, which keeps large
locale and data files token-efficient. .jsonc and JSON5 are not supported.
Markdown — headings are the symbols, nested by level, and a symbol spans the
whole section rather than the heading line. read_symbol with
Quick start.Connect your client returns that section alone; on this README
that is 839 bytes instead of 20 KB. Both # and underline (setext) headings are
indexed, # inside a fenced code block is not, and repeated headings such as
Options under several commands get @line:column selectors so each stays
addressable. Prose, lists, and code blocks are not indexed separately — this
finds sections, not full-text matches.
Absolute file paths are the canonical, most reliable input. Relative paths first
use an explicit SYMBOLPEEK_WORKSPACE_ROOT, then filesystem roots supplied by a
compatible MCP client; multi-root workspaces resolve only when exactly one root
contains the requested path.
Supported files are parsed from their current contents on every request — there is no index to rebuild and no stale cache to invalidate.
Unsupported extensions return { "supported": false }. Missing files, parser
failures, unknown symbols, and paths that are not usable source files (a
directory, a bare module specifier) are returned as MCP invalid-parameter
errors that name the mistake.
Two mechanisms nudge a model toward targeted reads:
symbolpeek skill
is a stronger, always-loaded hint for Codex and Claude Code, with a trigger
description covering code exploration and large JSON locale/configuration
files. Install it with
install-skills if you want it.No MCP server can force a client model to call a tool, but these mechanisms make the intended workflow part of the model's default context. For another agent that consumes neither, copy the short workflow from the bundled skill into that client's global agent instructions.
The CLI reports lifetime context-avoidance statistics:
symbolpeek stats
symbolpeek stats --reset
symbolpeek stat is accepted as a shorter alias for stats.
Tool-call frequency is persisted separately in the same statistics file:
symbolpeek usage
symbolpeek usage --reset
usage lists every current MCP tool, including zero-call tools, ordered by
descending call count. Calls rejected for invalid parameters still count because
they show attempted use; unknown tool names do not. Each --reset clears only
the selected report, so stats --reset preserves usage history and vice versa.
Concurrent Codex, Claude, and Copilot MCP processes merge their increments into
the same file without overwriting one another. After either reset command,
already-running servers add only post-reset deltas and cannot restore old
totals.
All numbers compare SymbolPeek with a counterfactual full-source baseline:
find_calls request can count several files);Treat these as directional context-reduction estimates, not exact model-token counts or billing data.
Prebuilt binaries detect their bundled TypeScript runtime automatically. These variables are for advanced setups only:
| Variable | Purpose |
|---|---|
SYMBOLPEEK_WORKSPACE_ROOT | Workspace root used to resolve relative source paths. |
SYMBOLPEEK_ALLOW_CWD_FALLBACK | Allow relative paths to fall back to the process working directory (default true). |
SYMBOLPEEK_TYPESCRIPT_ROOT | Directory containing the TypeScript runtime. |
SYMBOLPEEK_NODE | Explicit Node.js executable for the parser worker. |
SYMBOLPEEK_STATS_PATH | Override the lifetime statistics JSON path. |
SYMBOLPEEK_CONFIG_PATH | Override the disabled-tool configuration JSON path. |
For a global MCP installation, do not set SYMBOLPEEK_WORKSPACE_ROOT to a
fixed project — use absolute paths, or let the client provide filesystem roots.
Set SYMBOLPEEK_ALLOW_CWD_FALLBACK=false if relative paths must never resolve
against the server's working directory.
The client shows no SymbolPeek tools.
Confirm registration with codex mcp list or /mcp in Claude Code, and restart
the client — MCP servers are discovered at startup. If registration itself
failed, re-run the mcp add command using the absolute binary path.
TypeScript/JavaScript calls fail, other languages work.
Node.js 20+ is missing or not visible to the server process. Check with
node --version; if Node is installed but not on the client's PATH, set
SYMBOLPEEK_NODE to the absolute Node executable.
symbolpeek: command not found after installing on macOS/Linux.
~/.local/bin is not on your PATH:
export PATH="$HOME/.local/bin:$PATH" # add to your shell profile
The absolute path ~/.local/share/symbolpeek/symbolpeek always works.
Windows: the command is not recognized.
The installer updates the user PATH; open a new terminal so the change is
picked up. If irm ... | iex is blocked, run
Set-ExecutionPolicy -Scope Process RemoteSigned first, or download the archive
manually.
macOS blocks the binary. Release binaries are currently unsigned. If a browser-added quarantine flag blocks a manually downloaded package, clear it:
xattr -dr com.apple.quarantine <package-directory>
A relative path resolves to the wrong project.
Use absolute paths, or set SYMBOLPEEK_WORKSPACE_ROOT for a deliberately
project-scoped launch. SYMBOLPEEK_ALLOW_CWD_FALLBACK=false disables working
directory fallback entirely.
An operation returns an unsupported-operation error. Check the language support matrix — semantic operations are TypeScript/JavaScript only.
Still stuck? Open an issue
with your OS, client, SymbolPeek version (symbolpeek --version), and the failing
call.
# macOS / Linux
rm -rf ~/.local/share/symbolpeek ~/.local/bin/symbolpeek ~/.local/bin/sym
rm -rf ~/.config/symbolpeek "$HOME/Library/Application Support/SymbolPeek"
# Windows
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\SymbolPeek", "$env:APPDATA\SymbolPeek"
Then remove the server from your client: codex mcp remove symbolpeek or
claude mcp remove symbolpeek. On Windows, also drop the SymbolPeek entry from
your user PATH.
If you installed the optional agent guidance, remove it too:
rm -rf ~/.codex/skills/symbolpeek ~/.claude/skills/symbolpeek
Prefer to install manually? Every package contains symbolpeek, the sym
alias, and the locked TypeScript runtime.
| Platform | Release package |
|---|---|
| Linux x86-64 | Download |
| Linux ARM64 | Download |
| macOS Apple Silicon | Download |
| macOS Intel | Download |
| Windows x86-64 | Download |
Every package has a matching .sha256 asset. All versions and release notes are
on the GitHub Releases page.
A manually extracted archive behaves exactly like an installer-placed one: run
the binary directly, register it with your client, and optionally run
install-skills.
SymbolPeek communicates over stdio when used as an MCP server. It normally does not print a terminal interface; an MCP client starts it and exchanges JSON-RPC messages through stdin/stdout.
| Document | Contents |
|---|---|
| MCP_TOOLS.md | Every tool's request shape, options, and response format |
| ARCHITECTURE.md | Internal design, provider boundary, request lifecycle |
| CONTRIBUTING.md | Reporting bugs, source builds, tests, releases |
| CHANGELOG.md | Release history |
| SECURITY.md | Reporting a vulnerability |
The current foundation is intentionally focused. Natural next capabilities include:
get_type hover signatures (fully resolved nested
and generic types);MIT © Alex Shumihin
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots
Google's universal MCP server supporting PostgreSQL, MySQL, MongoDB, Redis, and 10+ databases
Official GitHub integration for repos, issues, PRs, and CI/CD workflows