AphrodyBun GitHub

Runtime docs · Runtime · Core Runtime

MCP server

bun mcp is a Model Context Protocol server built into Bun, for coding agents

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:

AgentFileEntry
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.jsonmcpServers.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:

.mcp.json
{
  "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 on 127.0.0.1:<port>/mcp (--http 0 picks a free port and prints it on stderr). POST carries a JSON-RPC message and gets an application/json reply, or 202 for a notification. Requests with a non-local Origin are 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

ToolDescriptionArgumentsKind
docs_searchSearch 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_readRead 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_listList 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_readRead a skill's instructions (SKILL.md) or one of its files, then follow them for the task at hand.name, file?read-only
memory_searchFull-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_readRead one memory entry in full by name.name, project?read-only
memory_writeCreate 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_importImport 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_queryAnswer 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_symbolsFind 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_callersList 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_pathShortest 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_communityModules 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_impactWhat 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_inventoryResources 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_findWhich 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_findFind 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_grepSearch 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_editPlan 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_applyApply a plan previewed by vfs_edit, as one transaction: every file is written or none (rolled back on any failure).plandestructive
lsp_diagnosticsType 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_definitionWhere 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_referencesEvery 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_hoverType 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_renameRename 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_symbolsOutline 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
runRun 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
testRun 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_parseParse 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_parseParse 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_ingestTurn 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_listList 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_infoFacts 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_treeList a directory of a dependency's installed sources.name, path?, depth?, root?, ecosystem?read-only
deps_readRead 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_searchRegular-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_docsRank 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_read with "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_PATH and the project's .claude/skills. They are also MCP prompts and bun://skills/<name> resources.
  • Memory is a SQLite database with full-text search, ~/.bun/agent/memory.db (BUN_MCP_MEMORY_DB to change it). Entries belong to the git repository they were written in; memory_import loads 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_URL or VALKEY_URL set, 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 lsp and its language servers.
  • run and test run bun run / bun test with a timeout and return the exit code with a digest of the output (head, error lines, tail).

Resources and prompts

URIContent
bun://docs/llms.txtIndex 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

FlagEnvironmentDefault
--http <port>stdio
--max-tokens <n>BUN_MCP_MAX_TOKENSby profile (6000-8000)
--page-size <n>BUN_MCP_PAGE_SIZE100 tools per page
--profile <agent>BUN_MCP_PROFILEdetected
--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.