Back to all posts

Bruno MCP: Complete Guide (2026)

The Bruno MCP server lets an AI agent run your Bruno API collections — execute a single request or a whole test suite, switch environments, validate before sending, and emit CI-ready reports — all from a chat window. Because Bruno stores collections as plain .bru text files in your repo, the agent tests the same requests your team already versions in Git. This guide covers what Bruno is, what the MCP server adds, the crowded field of community implementations (there is no official one yet), install for every client, all nine tools, real recipes, and the sharp edges we hit.

Updated July 2026 ~14 min read3,200 words
Editorial illustration: a luminous warm-amber stack-of-documents glyph at center representing an API collection, thin glowing request arcs curving outward to orbiting circular endpoint nodes, a faint branching git motif and small checkmark glyphs threading between them, on a deep midnight navy backdrop.

TL;DR + what you actually need

  • One package: bruno-mcp-server — the implementation by Juan Ruiz that our /servers/bruno catalog entry tracks. MIT-licensed, runs via npx, needs Node.js 20+, and drives Bruno’s bru CLI under the hood.
  • No credentials to configure: unlike a SaaS MCP server, there is no API token for Bruno itself. Authentication lives inside your requests (the .bru files carry their own bearer tokens, API keys, and OAuth config). You point the server at a folder; it runs what’s there.
  • One prerequisite people miss: you need an existing Bruno collection — a directory of .bru files with a bruno.json at its root. This server runs collections; it does not author them.
  • Nine tools: run a request, run a collection or folder, list requests, inspect a request without sending it, discover collections, list and validate environments, validate a collection, and a health check.

The copy-paste, if that’s all you came for:

claude mcp add --transport stdio bruno -- npx -y bruno-mcp-server

The --transport stdio flag and the -- separator are both required — leave either out and the CLI errors with a missing required argument complaint. The rest of this guide explains the pieces, disambiguates the several servers that all call themselves “Bruno MCP,” and shows where the wrapper ends and raw Bruno CLI begins.

What Bruno is (read this if you found Bruno second)

Quick disambiguation first, because “Bruno” is an overloaded name and “Bruno MCP” is overloaded twice over. This guide is about Bruno the API client — the git-native alternative to Postman and Insomnia at usebruno.com — and the MCP server that runs its collections. It is not about people, pop culture, or other tools that share the name.

Bruno is an open-source API client whose defining choice is storage: instead of syncing your requests to a vendor’s cloud, it saves each request as a human-readable .bru file on your filesystem, in a plain-text markup called Bru. A collection is just a folder of those files plus a bruno.json. The project’s own framing is “Git-native, local-first, developer-first”: there is no login, no account, and by design no cloud sync — you version and share collections with Git like any other source. It is developed in the open at github.com/usebruno/bruno, one of the most-starred API tools on GitHub, and it ships a headless bru CLI (docs.usebruno.com/cli) for running collections without the GUI.

That last part is the hook. Because Bruno already has a real CLI that runs .bru files, produces pass/fail results, and writes reports, an MCP server doesn’t have to reimplement an HTTP client — it just has to expose the CLI to the model. That is exactly what bruno-mcp-server does, and it’s why the surface is small and the behavior is predictable: the agent is running the same tool your CI would.

What the MCP server adds

The Bruno MCP server is a stdio process — a local subprocess your MCP client launches — that turns tool calls from the model into bru invocations against a collection on disk. You say “run the Get User request in my users API using the dev environment” and the agent calls bruno_run_request with the collection path, request name, and environment, then reads back real status codes, timings, and test assertions — not a guess about what the API might return.

Three design points from the README are worth internalizing before you install. First, it reads, runs, and reports — it does not author. Every tool takes a collectionPath to something that already exists. Second, dry-run is first-class: bruno_run_request and bruno_run_collection accept dryRun: true, which validates the request (method, URL, headers, body, auth, test count) and returns a summary without sending an HTTP call. That makes it safe to point an agent at a collection full of destructive POSTs and ask “is this configured correctly” before anything fires. Third, reports are the payoff for teams: any run can emit JSON, JUnit XML, and HTML simultaneously, and the JUnit output drops straight into Jenkins, GitHub Actions, or GitLab CI.

It also ships operational niceties you don’t strictly need but will appreciate: a bruno-mcp.config.json for timeouts, retry with exponential backoff, response caching, and a security block (allowedPaths, maskSecrets, custom secretPatterns). Secret masking is on by default, so tokens in your .bru files don’t leak into the model’s view of the logs.

The Bruno MCP landscape: pick the right one

“Bruno MCP” is not one project. At least four community servers exist, and they split along one axis: do you want the agent to run collections or to write them? There is no official, first-party server — native MCP support is an open feature request on the Bruno repo (#4806), filed in May 2025 and still unshipped as of writing. Until it lands, you are choosing among community implementations.

ServerWhat it doesDesign stance
jcr82/bruno-mcp-server (this guide, our catalog)Runs requests & collections via the bru CLI; reports; dry-runNine named tools, config file, secret masking
hungthai1401/bruno-mcpRuns Bruno collectionsLeaner runner; the other popular execution option
djkz/bruno-api-mcpExposes each .bru request as its own MCP toolPer-request tools instead of one run tool
macarthy/bruno-mcpGenerates .bru files: collections, environments, requests, testsAuthoring, the opposite direction

How to choose, in one line each. Use jcr82 (this guide) when you have collections and want an agent to run them and read results with CI-shaped reports. Use djkz if you’d rather each request show up as a distinct tool the model can call by name — nicer discoverability, more tools in the context window. Use macarthy when the job is building a collection from a chat, not running one. The two runners (jcr82 and hungthai1401) overlap the most; we default to jcr82 because of the dry-run mode, the config file, and the three report formats, and because it’s the entry our directory keeps in sync. If you’re coming from a dedicated test-management tool and weighing MCP options, the same “run vs author” split shows up there too — see our TestRail MCP alternatives roundup.

Install (every client)

The server is stdio-only — there is no hosted endpoint. Every install path runs npx -y bruno-mcp-server as a subprocess. The install panel below pulls its config from the canonical /servers/bruno catalog entry, so the command and JSON stay in sync as the package evolves. Pick your client, copy, paste, restart.

One-line install · Bruno

Open server page

Install

Client-specific notes:

  • Claude Code — the one-liner from the TL;DR: claude mcp add --transport stdio bruno -- npx -y bruno-mcp-server. Add --scope project to register it in the repo’s .mcp.json so the whole team shares it — a natural fit here, since the Bruno collection usually lives in that same repo. Full flag reference at /clients/claude-code.
  • Claude Desktop — paste the JSON block from the install card into claude_desktop_config.json (on macOS: ~/Library/Application Support/Claude/), then restart the app.
  • Cursor — same JSON shape in ~/.cursor/mcp.json. See /clients/cursor.
  • VS Code / Windsurf — the snippet goes in the client’s MCP config (~/.codeium/windsurf/mcp_config.json for Windsurf).

Before you blame the MCP layer, confirm Bruno’s CLI resolves on the same machine — the server shells out to it:

# Bruno's CLI ships as @usebruno/cli (command: bru)
npx bru --version

# If that prints a version, the MCP server will find it too.

Codex CLI

Codex reads MCP servers from ~/.codex/config.toml:

[mcp_servers.bruno]
command = "npx"
args = ["-y", "bruno-mcp-server"]

Restart Codex and confirm with codex mcp list. Browse every supported client and its config path at mcp.directory/clients.

Tools walkthrough

Nine tools, grouped by what an agent actually does with a collection. Every tool that touches a collection takes an absolute collectionPath; the run tools add optional environment, envVariables, reporter paths, and dryRun.

Discover & inspect (read-only)

  • bruno_discover_collections — recursively finds Bruno collections under a searchPath (default depth 5, max 10). The natural first call: “what collections do I have?”
  • bruno_list_requests — lists every request in a collection so the agent knows the exact names to run.
  • bruno_get_request_details — returns method, URL, headers, body, auth, and tests for one request without executing it. This is how the model answers “what does the Create User request send?” safely.

Environments

  • bruno_list_environments — lists the environments defined in the collection (dev, staging, production, whatever you named them).
  • bruno_validate_environment — checks a named environment file for problems before you run against it. Catches the “wrong base URL” class of mistake early.

Validate (dry-run)

  • bruno_validate_collection — validates the collection’s structure and configuration. Run it after generating or editing .bru files by hand.

The dry-run path is the one to remember. Ask the agent to validate before it fires anything, and you get a summary like this — no HTTP call sent:

=== DRY RUN: Request Validation ===

✅ Request validated successfully (HTTP call not executed)

Request: Create User
Method: POST
URL: {{baseUrl}}/api/users

Configuration Summary:
  Headers: 2
  Body: json
  Auth: bearer
  Tests: 3

Run & report

  • bruno_run_request — runs a single named request, optionally with an environment, inline envVariablesoverrides, and any of the three reporters.
  • bruno_run_collection — runs a whole collection, or scope it to one folderPath. This is the tool that produces a JUnit report for CI.
  • bruno_health_check — confirms the server and the underlying Bruno CLI are healthy, optionally with execution metrics and cache stats. First thing to call when tools behave oddly.

Recipes

Four workflows where pointing an agent at Bruno pays off. Each assumes the server is registered and a collection exists on disk.

Recipe 1 — Run a suite and triage failures

“Run all tests in the collection at ./api-tests against the staging environment, write an HTML and JSON report to ./reports, then summarize which requests failed and why.” The agent calls bruno_run_collection with environment: "staging" and the two reporter paths, reads the JSON result in-context, and hands you a summary plus a shareable HTML report. This is the recipe that replaces “run the suite, squint at the terminal, scroll.”

Recipe 2 — Validate before a risky run

“Before you send anything, dry-run every request in the payments folder and tell me which ones are missing auth or have empty required variables.” bruno_run_collection with dryRun: true scoped to folderPath: "payments". Nothing fires; you get a configuration audit. Pair it with bruno_validate_environment so a wrong baseUrl in staging never becomes a production call.

Recipe 3 — Explain an API from its collection

“List the requests in this collection, then show me exactly what the Refund Order request sends — method, headers, body, and any test assertions.” bruno_list_requests then bruno_get_request_details. No HTTP call, no live data — just the collection as documentation. Useful when you inherit a repo and want the API surface explained without reading every .bru file yourself.

Recipe 4 — Post-change regression check

“I just changed the auth middleware. Run the auth folder against dev, and if anything fails, show me the failing request’s details.” A scoped bruno_run_collection plus a conditional bruno_get_request_details on failures. It turns a code change into an immediate, targeted API check — the kind of loop that pairs well with agent-driven QA. If your regression surface is a live web app rather than an API, our Claude web-app testing skill guide covers the browser-automation side of the same idea.

Limits + what we got wrong

Honest constraints, including the assumptions that bit us while testing.

  • It runs, it doesn’t author. We assumed “Bruno MCP” would let an agent create a new request from a description. It won’t — not this server. Every tool needs an existing collection. Authoring is a separate project (macarthy). Know which problem you have before you install.
  • You still need the Bruno CLI on the machine. We hit “Bruno CLI not found” because the bru binary wasn’t resolvable in the environment the MCP client launched. The server looks for a local node_modules/.bin/bru; verify with npx bru --version in the same shell context before debugging the MCP layer.
  • Absolute paths, always. Relative collectionPath values are the most common “collection not found.” The MCP subprocess doesn’t share your shell’s working directory. Use full paths, and make sure a bruno.json sits at the collection root.
  • Node 20+ is a hard floor. The package targets Node.js 20 or higher; older runtimes fail at startup, and the failure shows up as “tools never appeared” rather than a clear error. Check node --version first.
  • It’s an early, single-maintainer project. This is a young community server, not a first-party one. It’s well-tested (the repo advertises a large passing test suite) but small and one-person-maintained. For anything mission critical, pin a version and read the release notes before upgrading.

Troubleshooting

“missing required argument ‘commandOrUrl’” on install

You dropped the --transport stdio flag or the -- separator. The correct form is claude mcp add --transport stdio bruno -- npx -y bruno-mcp-server. Everything after -- is the command Claude Code runs; without it the CLI reads bruno-mcp-server as its own argument.

Bruno tools don’t appear in the client

Verify the entry landed in your config (cat ~/.claude.json, or the project’s .claude.json if you used --scope project), confirm node --version is 20+, then restart the client — MCP servers are loaded once at session start, so edits don’t hot-reload.

“Bruno CLI not found”

The server couldn’t locate the bru binary. Confirm it independently with npx bru --version; if that fails, install Bruno’s CLI (npm i -g @usebruno/cli) or add it to the collection’s project so a local node_modules/.bin/bru exists.

“Collection not found”

Three usual causes: a relative path (use an absolute one), a missing bruno.json at the collection root, or a folder the process can’t read. If you set allowedPaths in bruno-mcp.config.json, make sure the collection sits inside one of them.

Runs work locally but env values look wrong

The agent is likely using the collection’s default environment. Pass the environment explicitly ("staging"), or override single values with the envVariables map on the run call. Run bruno_validate_environment to confirm what’s actually defined.

Community signal

Bruno the API client has a large, opinionated following. Its original Show HN and a steady run of follow-ups (the v1.35 release thread, and the more recent “Reinventing the API Client” discussion) show the same appeal repeated: developers who wanted to test APIs without a cloud account or a “platform” found the git-native, local-first model and stuck with it.

The contrarian notes are worth hearing before you commit. On Hacker News, a recurring gripe is that Bruno only persists changes when you explicitly save — some users, used to Insomnia writing edits immediately, have lost work to it. That is about the app, not the MCP server, but it colors the collections your agent will run: if a request looks stale, someone may have edited it without saving.

On the MCP side, the honest signal is that the space is fragmented and early. Four community servers, no official one, and the native-integration request (usebruno/bruno #4806) still open means today’s pick may not be tomorrow’s. We default to jcr82 because of its dry-run mode, report formats, and config file — but treat any Bruno MCP server as a young project, pin versions, and check the catalog entry for the current recommendation.

Embed note: we found no verifiable first-party X/Twitter post from the server’s maintainer announcing it (candidate links 404’d on verification), so this guide cites the repository, the Bruno project, and Hacker News threads rather than embedding an unverifiable social post — no fabrication.

The verdict

Our Take

Install Bruno MCP if you already keep .bru collections in Git and want an agent to run them, validate before firing, and hand back CI-shaped reports — that’s a genuinely useful loop, and the dry-run mode makes it safe to try against real endpoints. Skip it if you don’t use Bruno yet (the setup cost isn’t worth it for one server), if you need the agent to write new requests (use macarthy’s generator instead), or if you want unattended CI (call the bru CLI directly). It’s a thin, well-scoped wrapper over a tool you already trust — which is exactly what a good MCP server should be.

FAQ

What is the Bruno MCP server?

It is a local stdio process that lets an AI agent like Claude run your Bruno API collections. The implementation our catalog tracks, jcr82/bruno-mcp-server (npm bruno-mcp-server), wraps Bruno's bru CLI and exposes nine tools: run a single request, run a whole collection or folder, list and validate requests and environments, discover collections, and generate JSON, JUnit, or HTML reports.

How do I install the Bruno MCP server?

Use the install card on this page, or run claude mcp add --transport stdio bruno -- npx -y bruno-mcp-server. The --transport stdio flag and the -- separator are both required. Prerequisites: Node.js 20+, Bruno's bru CLI reachable, and at least one Bruno collection (.bru files with a bruno.json). Restart your client and the nine bruno_* tools appear.

Does Bruno MCP create API requests, or only run them?

The jcr82 server only runs and inspects collections you already have — it never authors requests. If you want an agent to generate .bru files (new collections, environments, requests, test scripts), that is a different server: macarthy/bruno-mcp. Pick the runner (this guide) for CI-style test execution; pick the generator for scaffolding collections from a chat.

Is there an official Bruno MCP server?

Not yet. Native MCP support is an open feature request on the Bruno project itself (usebruno/bruno issue #4806, filed May 2025). Until it ships, every Bruno MCP server is community-built — jcr82 and hungthai1401 both run collections, djkz exposes each request as its own tool, and macarthy generates files. There is no first-party server.

Do I need the Bruno desktop app installed?

No. The MCP server drives Bruno's command-line runner, not the GUI. What you need is the collection itself — the folder of .bru text files plus a bruno.json — and the bru CLI on the machine. Most people author those files in the Bruno desktop app, but the app is optional at run time; the files and the CLI are what matter.

Can I use Bruno MCP in a CI/CD pipeline?

The reporters can: bruno_run_collection writes JUnit XML that Jenkins, GitHub Actions, and GitLab CI parse natively, plus JSON and HTML. But the MCP server is built for interactive agent use. For unattended CI you would normally call the bru CLI directly; use the MCP server when a human or agent is in the loop triaging results.

How does it protect my API secrets?

Three built-in guards: secret masking scrubs values matching patterns like password, api_key, and token from logs; path validation blocks directory-traversal; and input sanitization guards against command injection. You can also pin an allowedPaths list in bruno-mcp.config.json so the server can only touch collection folders you name. Environment values still come from your own .bru files on disk.

Sources

Found an issue?

If something in this guide is out of date — a new tool name, a change to the config schema, or an official Bruno MCP server finally shipping — email [email protected] or read more on our about page. We keep these guides current.