Bowire MCP
OfficialAllows running GraphQL requests against any service URL, enabling discovery and invocation of GraphQL endpoints through the embedded API workbench.
Allows running MQTT interactions against any service URL, enabling publish/subscribe messaging through the embedded API workbench.
Allows running Socket.IO interactions against any service URL, enabling real-time event-based communication through the embedded API workbench.
Bowire
The API workbench that embeds in your own service. gRPC, REST, GraphQL, JSON-RPC, SignalR, WebSocket, SSE, MQTT, Socket.IO, MCP, OData, AsyncAPI, AMQP, Kafka, Akka.NET, NATS, SOAP, Pulsar — run against any service URL with zero code changes.
Quickstart · Features · Why Bowire · Docs · Downloads · Bootcamp

Install
# .NET tool (cross-platform, recommended)
dotnet tool install -g Kuestenlogik.Bowire.ToolWindows MSIs, portable ZIPs, Docker images, winget install Kuestenlogik.Bowire, and choco install bowire — with a Homebrew tap still pending — all listed on the Downloads page. It's the source of truth for what's available right now.
→ 5-minute Quickstart for the first call against your own service.
Related MCP server: api-test-mcp
Embedded mode
Mount the workbench inside an existing ASP.NET host:
dotnet add package Kuestenlogik.Bowirevar app = WebApplication.Create(args);
app.MapBowire(); // workbench at /bowire
app.Run();Discovery picks services off the host's IServiceProvider — REST routes, gRPC reflection, SignalR hubs, custom protocols. See Setup → Embedded.
On a shared or production host, set options.LockServerUrl = true (standalone: --url) and, if needed, options.AllowedServerUrls (--allowed-server-url) and options.AllowedAuthUrls for identity providers (--allowed-auth-url). They are enforced server-side: the workbench then refuses to dial any target outside the configured set with 403, so it can't be used as a relay into your network. See Options → LockServerUrl.
Documentation
Everything user-facing lives at bowire.io. The most-asked entries:
Quickstart — zero to first call
Bootcamp — hands-on walkthrough, six units + capstone
Features — workbench surfaces, recordings, mock, MCP
Protocols — per-protocol setup and conventions
Architecture — plugin model, host packages, ALC isolation
API reference — DocFX-generated reference
Roadmap & Community
ROADMAP.md — what shipped, what's planned, what's deliberately out of scope
Community — Discord, Discussions, Issues
CONTRIBUTING.md — plugin authoring, smoke tests, PR workflow
License
Available Tools
28 toolsbowire.allowlist.permitA
Record that a URL is now allowed for bowire.invoke / bowire.subscribe — appends to ~/.bowire/typed-urls.json (the same file --allow-invoke seeds from) and adds the URL to the in-memory allowlist for the rest of this session. Use to surface "the user just typed this URL into the workbench" without re-reading the file. Returns whether the URL was new + the resulting list size.
Inputs: url (required).
bowire.allowlist.showA
Diagnostic: show the URLs the agent is currently allowed to call via bowire.invoke / bowire.subscribe, plus the toggles that fed the list (environments seed, typed-URLs seed, --allow-arbitrary-urls).
Inputs: no named parameters.
bowire.assertA
Append a test assertion onto a step inside an on-disk recording. Targets either ~/.bowire/recordings.json (when recordingId is set) or the supplied recordingPath. The assertion shape matches the Newman-style probe Bowire runs after replay: { path, op, expected }. Supported ops: eq, ne, gt, gte, lt, lte, contains, matches, exists, notexists, type. Use path="status" to assert on the HTTP/gRPC status name; otherwise path is a JSONPath rooted at the response body. Returns the assertion id + the step it was attached to.
Inputs: op (required), path (required), expected (required), stepIndex (required), +2 more.
bowire.auth-recording.captureA
Store a credential as a named auth recording so a mock's auth requirement can resolve it by id — parity with bowire auth-recording capture and the workbench picker. Two-step by default: the first call returns { pending, confirmationToken, plan }; re-invoke with confirm=true or the token to store it. The credential is written to the local store only and is never echoed back.
Inputs: id (required), credential (required), name, header, +4 more.
bowire.auth-recording.capture-flowA
Run an auth flow (a scriptable login → token chain) and store the captured token as a named auth recording. Bowire EXECUTES the flow — an outbound HTTP call — so this is two-step by default (confirm=true / confirmationToken). Secrets in the flow are read from {{env.NAME}}, never inlined. Requires a host with flow-capture enabled; returns an error otherwise. Parity with bowire auth-recording capture --flow and the workbench's flow-capture.
Inputs: id (required), flow (required), name, confirm, +2 more.
bowire.auth-recording.listA
List captured auth recordings (credential-free) that a mock's auth requirement can resolve by id. Returns { workspace, recordings: [{ id, name, scheme, capturedAt }] }. The credential value is never returned.
Inputs: workspace.
bowire.auth-recording.removeA
Delete a captured auth recording. Idempotent — reports whether a file was removed. Two-step by default (confirm=true or confirmationToken).
Inputs: id (required), confirm, workspace, confirmationToken.
bowire.contract.matrixA
Read the contract-verification results stored under .bowire/contract-results (written by bowire contract verify) and roll them up into the same consumer x provider matrix the workbench Contracts rail and bowire contract matrix render. Purely local: it reports stored verdicts and never calls a provider itself. Returns { consumers: [...], providers: [...], cells: [{ consumer, provider, status: pass|fail|notRun, lastRun, passedInteractions, totalInteractions, failures: [{ description, method, error }] }], summary: { passed, failed } }.
Inputs: no named parameters.
bowire.cookies.clearA
Clear a cookie jar (#681): an environment's whole jar, or one domain in it. Two-step by default: the first call returns { pending, confirmationToken, plan }; re-invoke with confirm=true or pass the token back.
Inputs: env (required), domain, confirm, workspaceId, +1 more.
bowire.cookies.listB
List the cookie jars (#681): per environment, the cookies Bowire's calls send and keep — domain, path, name, expiry, Secure / HttpOnly / SameSite. Values are credentials and are masked.
Inputs: env, workspaceId.
bowire.discoverA
Run discovery against a server URL and return the discovered services and methods. Optional protocol filters to one plugin (grpc, rest, graphql, signalr, mqtt, ws, sse, mcp, odata, socketio); without it every registered protocol that handles the URL gets a turn. The attempts array reports what each plugin did — outcome is ok / empty / partial / error / timeout — so an empty services list always comes with an explanation instead of leaving you to guess. partial means that plugin returned services AND hit a fault while producing them, so its contribution is incomplete; the optional details array breaks the message down step by step.
Inputs: url (required), protocol, grpcDescriptorSet.
bowire.env.listA
List Bowire environments stored under ~/.bowire/environments.json — names, server URLs, variables.
Inputs: no named parameters.
bowire.export.httpA
Write Bowire collections as a .http file the IDEs run (Rider, IntelliJ, Visual Studio 2022, VS Code REST Client) plus http-client.env.json (#673). Reads a .bww workspace file, a workspace's collections.json or an array of collections. Secrets are never written: {{secret.x}} references become names to fill into http-client.private.env.json. Returns { http, envJson, report }.
Inputs: path (required), dialect.
bowire.har.importA
Convert a HAR 1.2 trace into a Bowire recording. Reads the HAR file at harPath, optionally writes the recording JSON to outPath (use "-" or omit to return the JSON inline), and returns a summary { recordingId, stepCount, authHeaders, redacted, outPath?, recording? }. Set redactSecrets to strip credential headers (Authorization, Cookie, X-Api-Key, …) before import. Pair with bowire.mock.start { recording: } to serve the trace back.
Inputs: harPath (required), name, outPath, redactSecrets.
bowire.importA
Import an Insomnia export (v4 JSON/YAML or v5 YAML), a Bruno collection (a directory of .bru files or OpenCollection YAML, or a bundled OpenCollection file) or .http files (one file, or a directory of them with http-client.env.json) into Bowire collections and environments (#674). Returns { format, collections, environments, report } where report lists what was approximated or skipped and which credentials sit in clear text. With outPath, also writes a .bww workspace file the workbench or bowire workspace import reads.
Inputs: path (required), name, format, outPath.
bowire.invokeA
Invoke a unary method discovered via bowire.discover. body is a JSON string; metadata is a flat object of header / gRPC metadata key-value pairs.
Inputs: url (required), method (required), service (required), body, +2 more.
bowire.lintA
Discover a server URL and run Bowire's design-time linter over the API surface — the same rules bowire lint and the workbench Lint rail use. Flags design smells (secrets or PII in responses, unbounded list responses, missing versioning, string-typed timestamps, ...) each with a severity, honouring the workspace's .bowire/rules.json. Returns { findings: [{ ruleId, severity, service, method, field, message }], summary: { total, high, medium, low, info } }.
Inputs: url (required), protocol, grpcDescriptorSet.
bowire.mock.listA
List currently running mock servers spawned via bowire.mock.start. Includes handle, port, and a connect URL per mock.
Inputs: no named parameters.
bowire.mock.startA
Spin up a local Bowire mock server that replays a recording (or synthesises responses from a schema). Returns a handle the agent uses with bowire.mock.stop. Multiple mocks can run concurrently on different ports. Two-step by default (controlled by RequireConfirmationForMutations): the first call returns { pending: true, confirmationToken, plan }; re-invoke with confirm=true or pass the token back as confirmationToken to actually start the mock.
Inputs: host, port, schema, confirm, +4 more.
bowire.mock.stopA
Stop a mock server previously started by bowire.mock.start. Idempotent — returns false if the handle is unknown or already stopped.
Inputs: handle (required).
bowire.network.getA
Show how Bowire's outbound connections leave the machine (#680): proxy mode and URL, bypass list, CA bundle, which layer set each value, what is misconfigured, and which protocol plugins can use the proxy. Passwords are shown only as their reference, never the value.
Inputs: workspaceId.
bowire.record.listA
List Bowire recordings stored under ~/.bowire/recordings.json — id, name, step count, captured at. Step bodies omitted; ask for details via the (planned) record.replay tool.
Inputs: no named parameters.
bowire.record.replayA
Switch the active server-side recording session into replay mode for the given recording id (#285); a session that belongs to another recording is left alone and the call is refused. When no session is open, opens a fresh one bound to the supplied recording id so the workbench can drive replay. Returns the resulting session state. Two-step by default; pass confirm=true to skip the confirmation gate.
Inputs: confirm, recordingId, workspaceId, confirmationToken.
bowire.record.startA
Begin a new server-side recording (#285). Subsequent capture-mode invocations on the same workspace land in the buffer until bowire.record.stop. Two-step by default: the first call returns { pending, confirmationToken, plan }; re-invoke with confirm=true or pass the token back. Mode: capture (default, record live invokes), proxy (record proxied flows), replay (drive replay from a pre-existing recording). One active session per process — start fails with a 409-equivalent message when a session is already open.
Inputs: mode, name, confirm, recordingId, +2 more.
bowire.record.stopA
Stop the active server-side recording (#285) and flush the buffer into ~/.bowire/recordings.json. Returns { stopped, recordingId, stepCount }. When that file is not a {"recordings":[…]} store the call is refused and the session stays open. Idempotent — returns { stopped: false, reason: "no-active-session" } when no session is open. Two-step by default; pass confirm=true to skip the confirmation gate.
Inputs: confirm, confirmationToken.
bowire.report.rollupA
Roll the reports Bowire writes up into one view across services — the portfolio question. Reads lint findings, contract-verification results, benchmark run histories, k6 summaries, scan SARIF and test JUnit from the given paths (directories are walked recursively) and returns one row per service. Purely local: it reads files that already exist and never calls a service. Returns { services: [{ service, worst: high|medium|low|info|null, lint, contracts, tests, benchmark, scanErrors, lastReportAt, sources }], summary: { services, atHigh, clean, skipped } }.
Inputs: from, service.
bowire.subscribeA
Subscribe to a streaming method (server-streaming, SSE, MQTT topic, websocket) and return collected frames after the sample window elapses. Frames are returned as raw strings; the agent decodes them in follow-up reasoning.
Inputs: url (required), method (required), service (required), body, +3 more.
bowire.test.runA
Run a Bowire test collection or flow, as bowire test does: invoke every test, evaluate its assertions, and report what passed and failed. With data (a CSV or JSON file), the collection runs once per row, with the row's columns as variables; failures name the iteration and the source row. Runs as an MCP task for clients that declare the tasks extension (status messages report each step; tasks/cancel stops before the next step). Returns { exitCode, passed, output, errors } — exitCode 0 when everything passed, 1 when a test failed, 2 when the input was refused.
Inputs: path (required), data, failFast, junitPath, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
TDQS
Scored across 28 tools
Most tools map to clearly distinct resources/actions (invoke vs subscribe, mock.start/stop/list, record.start/stop/replay/list). A few boundaries blur: bowire.discover vs bowire.lint (lint also discovers), bowire.test.run vs bowire.assert, and bowire.import vs bowire.har.import both parse external formats. Descriptions disambiguate these well, but note record.list's text calls record.replay '(planned)' even though it exists, which could confuse an agent.
Consistent dotted namespacing (bowire.<resource>.<verb>, e.g. mock.start, auth-recording.list, cookies.clear) throughout. A handful of domain-level verbs sit at the top level (invoke, subscribe, assert, discover, lint, import), which is a reasonable but slightly different convention. Easily readable and predictable overall.
28 tools is on the heavy side; even for a full API-testing platform some are niche diagnostics (contract.matrix, report.rollup, network.get, allowlist.show) that broaden the surface considerably. Each maps to a real capability from the underlying CLI, so it's not bloat for bloat's sake, but the set is at the upper end of comfortably navigable.
Strong lifecycle coverage: discover/invoke/subscribe, mock start/stop/list, record start/stop/replay/list, import/export, assertions, test runs, contract matrix, lint, auth recordings, cookies, allowlist. Gaps remain around mutating stored artifacts — no delete/rename for recordings, no collection/workspace CRUD or env mutation, and no way to inspect or edit assertions or collections after creation. Agents can work around most of these but will hit dead ends for cleanup/management tasks.
Maintenance
Related MCP Connectors
AI-callable tools for API mocking, testing, monitoring, security, and automation.
Webhook, email, WebSocket and tunnel testing for AI agents: capture, wait, verify, replay.
Email inboxes, webhooks, mock APIs, 2FA codes, approvals and 170 tools for AI agents.
Capture, inspect, send and assert on webhooks and inbound email from your coding agent.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to inspect, test, validate, compare, and debug HTTP APIs through a structured toolkit, with features such as secret redaction, response contract validation, regression comparison, health checks, and incident investigation workflows.MIT
- AlicenseAqualityCmaintenanceEnables AI agents to call real API endpoints and verify responses against OpenAPI specs, supporting contract testing, auth presets, spec diffing, and health checks.852 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to discover and call existing OpenAPI services through governed tools, enforcing policy, approval for destructive operations, and credential handling before requests execute.1Apache 2.0
- AlicenseNot gradedqualityBmaintenanceTurns existing REST/OpenAPI APIs into governed MCP tools for AI agents without modifying the APIs themselves, generating agent-friendly tools from specs, Postman collections, HAR files or cURL commands. Owners enable tools and set policies, while every call injects upstream credentials, redacts PII, projects responses to fit context limits, and produces a full audit trail.46 npm5Apache 2.0