bun mcp runs a Model Context Protocol server from the bun binary itself. Coding agents (Claude Code, Codex, Antigravity/Gemini CLI and any MCP client) get Bun's documentation, agent skills, a persistent memory, a code graph of the project, file search and bulk edits, language-server answers and bounded bun run / bun test, with no package to install and no Node.js process.
bun mcp install # register it in Claude Code, Codex and Antigravity
bun mcp install claude # or one agent: claude, codex, agy
bun mcp install adds a bun server entry and leaves every other server and setting in place:
| Agent | File | Entry |
|---|---|---|
| Claude Code | ~/.claude.json (with --project: .mcp.json of the folder) | mcpServers.bun |
| Codex | $CODEX_HOME/config.toml (default ~/.codex/config.toml) | [mcp_servers.bun] |
| Antigravity | ~/.gemini/config/mcp_config.json | mcpServers.bun |
bun mcp uninstall [agent] removes the entry. The install also writes ~/.bun/agent/mcp/manifest.json (version, executable and tool list). When bun upgrade replaces that executable, the next bun mcp start rewrites the manifest and the agent entries, so the agents follow the new version.
To configure a client by hand, run bun mcp as a stdio server:
{
"mcpServers": {
"bun": { "type": "stdio", "command": "bun", "args": ["mcp"] }
}
}
Transports
- stdio (default): one JSON-RPC message per line on stdin and stdout.
- Streamable HTTP:
bun mcp --http <port>listens on127.0.0.1:<port>/mcp(--http 0picks a free port and prints it on stderr).POSTcarries a JSON-RPC message and gets anapplication/jsonreply, or202for a notification. Requests with a non-localOriginare refused.
The server speaks protocol revisions 2025-06-18, 2025-03-26 and 2024-11-05. It starts before the JavaScript runtime, so it answers initialize in a few milliseconds.
Response budget
Every tool result is capped at a token budget that depends on the agent (8000 tokens for Claude Code and Antigravity, 6000 for Codex and others), roughly 4 bytes per token. A longer result ends with a cursor:
… [truncated at byte 31994 of 81520; call docs_read with {"cursor":"3.31994"} for the rest]
Calling the same tool with {"cursor": "3.31994"} returns the next page. The cursor is also in the result's _meta.cursor. Every tool takes max_tokens (256 to 50000) to change the budget of one call; lists (tools/list, resources/list, prompts/list) are paginated with nextCursor.
Agent profile
bun mcp detects the agent that started it from its environment (CLAUDECODE, CODEX_*, GEMINI_CLI / ANTIGRAVITY_CLI), then from clientInfo in initialize. The profile sets the default budget. Override it with --profile claude|codex|agy|generic or BUN_MCP_PROFILE.
Tools
| Tool | Description | Arguments | Kind |
|---|---|---|---|
docs_search | Search the Bun documentation embedded in this binary (runtime APIs, bundler, package manager, test runner, guides). Returns ranked page paths with a description and a matching line; read a page with docs_read. | query, limit?, offset? | read-only |
docs_read | Read one page of the embedded Bun documentation as Markdown, whole or one section. path is a docs_search result (runtime/http/server), a docs URL, or "llms.txt" for the index of every page. | path, heading? | read-only |
skills_list | List the agent skills available here: Bun repository skills (embedded), user skills (~/.claude/skills, ~/.codex/skills, ~/.bun/agent/skills), installed Bun plugin skills and the project's .claude/skills. Filter with query. | query?, limit?, offset? | read-only |
skill_read | Read a skill's instructions (SKILL.md) or one of its files, then follow them for the task at hand. | name, file? | read-only |
memory_search | Full-text search (SQLite FTS5) of the persistent agent memory for this project: decisions, conventions, references saved by memory_write or imported from Markdown notes. Empty query lists the most recent entries. | query?, project?, limit?, offset? | read-only |
memory_read | Read one memory entry in full by name. | name, project? | read-only |
memory_write | Create or replace a memory entry (keyed by project and name) in ~/.bun/agent/memory.db, for facts worth keeping across sessions. | name, body, description?, type?, project? | write |
memory_import | Import Markdown notes with YAML frontmatter (name, description, type) from a file or a directory of *.md files (MEMORY.md and README.md are skipped); existing entries with the same name are replaced. | path, project? | write |
graph_query | Answer a question about the code of the working directory from its native code graph (Rust, TypeScript/JavaScript, Markdown): finds the best-matching symbols and walks their neighbourhood within a token budget. | question, depth?, budget_tokens?, relations?, path?, max_files?, refresh? | read-only |
graph_symbols | Find functions, types, modules and other graph nodes by name in the working directory, with their file and line. | query, kind?, limit?, offset?, path?, max_files?, refresh? | read-only |
graph_callers | List the call sites of a symbol (or what it calls, with direction "callees") from the native code graph. | symbol, direction?, relations?, limit?, path?, max_files?, refresh? | read-only |
graph_path | Shortest path between two symbols or files of the code graph, with the relation and location of every hop: how A reaches B. | from, to, directed?, relations?, path?, max_files?, refresh? | read-only |
graph_community | Modules of the code found by community detection (Louvain) on the code graph: the largest communities with their main members and the most connected nodes, or with node the community of that symbol. | node?, top?, path?, max_files?, refresh? | read-only |
graph_impact | What depends on a symbol, transitively (callers, importers, references) up to a depth: the nodes and files a change to it can affect. | symbol, depth?, relations?, limit?, path?, max_files?, refresh? | read-only |
host_inventory | Resources of the machines of the mesh (CPU, RAM, GPU and free VRAM, disks, kernel, OS, WireGuard IPs), from the shared registry of bun host. Cards are merged from ~/.bun/host (override: BUN_HOST_DIR); refresh adds a fresh card of this machine. | host?, refresh?, max_age_s? | read-only |
host_find | Which host has the resources: at least N GiB of free VRAM, N GiB of available RAM or of free disk, a GPU name, CUDA, an OS. Returns the matches, most free VRAM first, so inference and builds can pick a machine. | min_vram_free_gb?, min_ram_gb?, min_disk_free_gb?, gpu?, os?, cuda?, max_age_s?, refresh? | read-only |
vfs_find | Find files and directories by name or path (substring terms, glob, regex or exact name) on an index of the working directory that stays warm for the session (.gitignore honoured). Paged with offset/limit. | query, mode?, kind?, extensions?, under?, case_sensitive?, sort?, offset?, limit?, path? | read-only |
vfs_grep | Search file contents for a literal or a regular expression (.gitignore honoured, hidden files skipped), in path order, with optional context lines. Paged with offset/limit. | pattern, regex?, case_sensitive?, paths?, globs?, context?, files_only?, hidden?, max_per_file?, offset?, limit?, path? | read-only |
vfs_edit | Plan a bulk edit and return its diff without writing anything: literal or regex replacements over files, directories and globs, file writes, deletions and renames. Returns a plan id for vfs_apply. | ops, max_diff_lines?, max_files?, hidden?, path? | read-only |
vfs_apply | Apply a plan previewed by vfs_edit, as one transaction: every file is written or none (rolled back on any failure). | plan | destructive |
lsp_diagnostics | Type errors and lint diagnostics of a file. TypeScript/JavaScript, Python, Rust and C/C++, through bun lsp. | file, line?, column?, limit?, timeout_ms? | read-only |
lsp_definition | Where the symbol at a position is defined. TypeScript/JavaScript, Python, Rust and C/C++, through bun lsp. | file, line, column, limit?, timeout_ms? | read-only |
lsp_references | Every reference to the symbol at a position. TypeScript/JavaScript, Python, Rust and C/C++, through bun lsp. | file, line, column, limit?, timeout_ms? | read-only |
lsp_hover | Type and documentation of the symbol at a position. TypeScript/JavaScript, Python, Rust and C/C++, through bun lsp. | file, line, column, limit?, timeout_ms? | read-only |
lsp_rename | Rename the symbol at a position across the project: lists the edits, and writes them with apply: true. TypeScript/JavaScript, Python, Rust and C/C++, through bun lsp. | file, line, column, limit?, timeout_ms?, new_name, apply? | destructive |
lsp_symbols | Outline of a file, or with query the workspace symbols matching it. TypeScript/JavaScript, Python, Rust and C/C++, through bun lsp. | file, line?, column?, limit?, timeout_ms?, query? | read-only |
run | Run a package.json script or a file with bun run, with a timeout. Returns the exit code and a digest of stdout/stderr (head, error lines, tail). | target, args?, cwd?, env?, timeout_ms?, max_lines? | destructive |
test | Run bun test (optionally on some files and with a -t name filter), with a timeout. Returns the exit code and a digest of the output that keeps failures. | files?, filter?, args?, cwd?, env?, timeout_ms?, max_lines? | destructive |
html_parse | Parse supplied HTML using Bun's native browser DOM, query a selector and return bounded node/text previews. No network, scripts, navigation or persistent session. Input up to 2 MiB UTF-8; 1-100 results; output at most 48 KiB before MCP pagination. | html, selector?, limit?, include_html? | read-only |
css_parse | Parse supplied CSS using Bun's shared browser/bundler CSS AST with author-style recovery. Return bounded ordered rule preludes and bodies; no minifier, cascade evaluation, layout, network or session. Input up to 2 MiB UTF-8; 1-100 rules; output at most 48 KiB before MCP pagination. | css, limit? | read-only |
git_ingest | Turn a local directory or a subpath of it into a prompt-ready digest in the GitIngest layout: a summary, the directory tree and the content of every text file. Honors .gitignore, skips binary files and files over max_file_size. | source?, subpath?, include_patterns?, exclude_patterns?, max_file_size?, max_total_bytes? | read-only |
deps_list | List the dependencies of a project whose sources are on disk: npm packages from package.json resolved through node_modules, Cargo packages from Cargo.lock resolved in the Cargo registry and git checkouts, and directories under vendor/. Each entry has its ecosystem, version and local path. | root?, ecosystem?, filter?, limit? | read-only |
deps_info | Facts about one dependency read from its installed manifest: version, local path, license, repository, homepage, description and the documentation files it ships. | name, root?, ecosystem? | read-only |
deps_tree | List a directory of a dependency's installed sources. | name, path?, depth?, root?, ecosystem? | read-only |
deps_read | Read one file of a dependency's installed sources. Text past max_bytes is cut and the result is flagged truncated. | name, path, offset?, max_bytes?, root?, ecosystem? | read-only |
deps_search | Regular-expression search over the installed sources of one or more dependencies, in parallel. Returns file, line and the matching line. | query, names, glob?, case_insensitive?, max_results?, root?, ecosystem? | read-only |
deps_docs | Rank the documentation shipped by installed dependencies (README, *.md, *.mdx, docs/, *.d.ts) against a query and return the best sections. Offline counterpart of a web documentation search, pinned to the installed versions. | query, names?, max_results?, root? | read-only |
- Docs come from the
docs/folder of the Bun version that runs, compressed into the binary;docs_readwith"path": "llms.txt"returns the index. - Skills are the skills of the Bun repository and the agent plugin, plus those installed in
~/.claude/skills,~/.codex/skills,~/.bun/agent/skills,$BUN_MCP_SKILLS_PATHand the project's.claude/skills. They are also MCP prompts andbun://skills/<name>resources. - Memory is a SQLite database with full-text search,
~/.bun/agent/memory.db(BUN_MCP_MEMORY_DBto change it). Entries belong to the git repository they were written in;memory_importloads a folder of Markdown notes with front matter. - Graph tools build a code graph (Rust, TypeScript/JavaScript, Markdown) of the working directory on first use and keep it for the session; with
REDIS_URLorVALKEY_URLset, built graphs are shared between sessions through Valkey, otherwise through the SQLite database. - vfs_edit never writes: it returns the diff and a plan id. vfs_apply applies that exact plan as one transaction, rolled back on any failure.
- lsp_* tools go through
bun lspand its language servers. - run and test run
bun run/bun testwith a timeout and return the exit code with a digest of the output (head, error lines, tail).
Resources and prompts
| URI | Content |
|---|---|
bun://docs/llms.txt | Index of the documentation |
bun://docs/<path> | A documentation page (Markdown) |
bun://skills/<name> | The SKILL.md of a skill |
Each skill is also a prompt, with an optional task argument.
Options
| Flag | Environment | Default |
|---|---|---|
--http <port> | stdio | |
--max-tokens <n> | BUN_MCP_MAX_TOKENS | by profile (6000-8000) |
--page-size <n> | BUN_MCP_PAGE_SIZE | 100 tools per page |
--profile <agent> | BUN_MCP_PROFILE | detected |
--cwd <dir> | the current directory |
bun mcp tools lists the tools; --json prints their MCP descriptors and --markdown the table above.
Adding tools
Tools are Rust values registered in the bun_mcp crate (src/mcp/registry.rs): a name, a description, a JSON Schema of the arguments, behaviour annotations and a function. A module exposes a TOOLS: &[Tool] slice; the same descriptors produce tools/list, the install manifest and the table on this page.