Bruno MCP Studio
NPM · @OSTICO/BRUNO-MCP · SCANNED AUG 13
Author, edit and run Bruno collections non-destructively: both dialects, groups, gRPC, WebSocket.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score →
Supply Chain Security98
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- No install/post-install scripts declared.Pass
- 44 of 143 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency97
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Cryptographically verified build provenance (signed, bound to Ostico/bruno-mcp-studio). View diagnostics → Pass
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 0 days ago).Pass
- Disclosure check failed: no security disclosure policy was found in the source repository. See how to fix → Fail
Schema Quality & AI Usability57
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 6497 tokens (~360/item across 18 items; 18 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management20
- Stability observed for 6 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage90
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 69% of tool parameters carry a description.Partial
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Add this component to your MCP client. Where a client-specific snippet is available, pick your client below and copy it straight into your config; otherwise use the connection detail shown.
npm · @ostico/bruno-mcp
claude mcp add ostico-bruno-mcp-studio -- npx -y @ostico/bruno-mcp
codex mcp add ostico-bruno-mcp-studio -- npx -y @ostico/bruno-mcp
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"ostico-bruno-mcp-studio": {
"type": "local",
"command": [
"npx",
"-y",
"@ostico/bruno-mcp"
],
"enabled": true
}
}
} openclaw mcp add ostico-bruno-mcp-studio --command npx --arg -y --arg @ostico/bruno-mcp
mcp_servers:
ostico-bruno-mcp-studio:
command: "npx"
args: ["-y", "@ostico/bruno-mcp"] {
"mcpServers": {
"ostico-bruno-mcp-studio": {
"command": "npx",
"args": [
"-y",
"@ostico/bruno-mcp"
]
}
}
} Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 12 Aug 26 +2
- Schema quality: 301 → 360 ▼ functional
- Security disclosure: unverified → fail ▼ functional
- Stability: unverified → 0.17 ▲ functional
- Package version: 2.2.1 → 2.3.0 functional
- 11 Aug 26 +3
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 7 Aug 26 72
First indexed and scored.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 13 Aug 2026 · Analysed npm/@ostico/bruno-mcp@2.3.0
Provenance Verified
A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.
| Result | Verified |
|---|---|
| Ecosystem | npm |
| Reason | Verified |
| Discovered via | Registry attestation endpoint |
| Source repo | Ostico/bruno-mcp-studio |
| Certificate issuer | https://token.actions.githubusercontent.com |
| Certificate SAN | https://github.com/Ostico/bruno-mcp-studio/.github/workflows/release.yml@refs/tags/v2.3.0 |
| Rekor log index | 2438989943 |
| Predicate type | https://slsa.dev/provenance/v1 |
| Subject digest | sha512:6c92a4ffe4644698fcc28d6b68020a1fa7c9e9a58dc9800d658f62b486a14497a2faa179848bd0fcbda7cfed8fa0f547df9f3c14ca4dcba95a8fd6c2c |
Dependencies 143 packages
| Packages resolved | 143 |
|---|---|
| Stale | 41 |
| No linked repository | 4 |
| Tree resolution | Complete |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability.
add_test_script Add Test Script ~407
Add pre-request, post-response, or tests scripts to a Bruno request. Canonical scriptType values are pre-request/post-response/tests; the aliases before-request (→ pre-request) and after-response (→ post-response) are also accepted. Appends to any existing script of that type by default — pass scriptMode:"replace" to overwrite it, or use remove_script to clear it. Assertions must be wrapped in test("name", function() { ... }) to be reported. Scripts run as async functions: top-level await works, and bru.sleep(ms), setTimeout and setInterval are available. Time spent waiting counts against the script timeout (settings.timeout, default 5000ms); raise it with modify_request's settings argument.
| Name | Type | Req | Description |
|---|---|---|---|
| bruFilePath | string | yes | Absolute path to the .yml or .bru request file. Get from list_requests or get_collection_stats. |
| script | string | yes | Script body. For post-response/tests, wrap every assertion in a test() block — test("status is 200", function() { expect(res.getStatus()).to.equal(200); }); — because only test() blocks are recorded… |
| scriptMode | string | – | How to write the script. "append" (default) concatenates onto any existing script of this type; "replace" overwrites it. Each of the three script types has its own slot in both .bru and .yml, so repl… |
| scriptType | string | yes | Script type. Canonical: pre-request, post-response, tests. Aliases: before-request (→ pre-request), after-response (→ post-response). |
No output schema declared.
No examples provided.
create_collection Create Bruno Collection ~72
Create a new Bruno API testing collection with configuration
| Name | Type | Req | Description |
|---|---|---|---|
| baseUrl | string | – | – |
| description | string | – | – |
| format | string | – | – |
| ignore | array | – | – |
| name | string | yes | – |
| outputPath | string | yes | Absolute path where the new collection directory will be created. |
No output schema declared.
No examples provided.
create_crud_requests Create CRUD Requests ~131
Generate a complete set of CRUD operations for an entity: list, get by id, create, update, delete. All five inherit the collection or folder auth block unless you pass auth.
| Name | Type | Req | Description |
|---|---|---|---|
| auth | object | – | Defaults to inherit, matching what Bruno itself gives a new request. Passing "none" is an opt-OUT that stops the collection auth block from applying to these five files, not an absence of opinion. |
| baseUrl | string | yes | – |
| collectionPath | string | yes | Absolute path to existing collection directory. |
| entityName | string | yes | – |
| folder | string | – | – |
No output schema declared.
No examples provided.
create_environment Create Bruno Environment ~194
Create an environment file for a Bruno collection. Writes the WHOLE file, so it REFUSES a name that already exists rather than overwriting it — the error names the existing variables and says which ones a replace would delete, so you can choose between merging with update_environment, picking another name, and retrying with overwrite: true.
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path to existing collection directory. |
| name | string | yes | – |
| overwrite | boolean | – | Replace an environment that already exists. Without this an existing name is refused. Keys in the file that this tool does not model are preserved either way. |
| variables | – | yes | Either a flat name-to-value map, or a list of variable objects when you need flags. Use the list form to declare a secret at create time: a secret variable is stored as a name only (no format persist… |
No output schema declared.
No examples provided.
create_request Create Bruno Request ~889
Generate request files for API testing (supports .bru and .yml formats). Authors HTTP requests by default, WebSocket requests with kind "websocket" (url plus websocket.messages) and gRPC requests with kind "grpc" (url plus grpc.method, grpc.protoPath and grpc.messages); neither takes an HTTP method or a body. Supports multipart/form-data with file uploads and per-part contentType (body.type "form-data" with formData entries of type "file"), and inline scripts (pre-request/post-response/tests) so no separate add_test_script call is needed. Scripts run as async functions: top-level await works, and bru.sleep(ms)/setTimeout/setInterval are available, spending the script timeout (settings.timeout, default 5000ms) — raise it via the settings argument.
| Name | Type | Req | Description |
|---|---|---|---|
| assert | array | – | Declared assertions, evaluated on every run without needing a test() block. |
| auth | object | – | – |
| body | object | – | – |
| collectionPath | string | yes | Absolute path to existing collection directory. |
| folder | string | – | – |
| grpc | object | – | gRPC-only fields. Applies to kind "grpc" and is refused otherwise. Headers given for a gRPC request are written as metadata, which is that transport's only header surface. |
| headers | object | – | – |
| kind | string | – | Transport. Defaults to "http". "websocket" and "grpc" take no method and no body; their payloads are websocket.messages and grpc.messages. |
| method | string | – | Required for kind "http", refused for "websocket" and "grpc", which have no HTTP method. A gRPC request names its RPC method in grpc.method. |
| name | string | yes | – |
| pathParams | object | – | Values for :name segments in the URL, e.g. { id: "42" } for /users/:id. |
| query | object | – | – |
| scripts | object | – | Inline scripts to persist with the request. Keys: pre-request, post-response, tests (aliases before-request/after-response accepted). Avoids a separate add_test_script call. IMPORTANT for tests/post-… |
| sequence | number | – | – |
| settings | object | – | Request-level settings: transport behaviour (timeouts, redirects, URL encoding), not payload. What reaches the file depends on the dialect, because Bruno's own two writers differ: a .yml request alwa… |
| url | string | yes | – |
| vars | object | – | – |
| websocket | object | – | WebSocket-only fields. Applies to kind "websocket" and is refused otherwise. |
No output schema declared.
No examples provided.
create_test_suite Create Test Suite ~54
Generate comprehensive test collections with multiple related requests
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path to existing collection directory. |
| dependencies | array | – | – |
| requests | array | yes | – |
| suiteName | string | yes | – |
No output schema declared.
No examples provided.
delete_request Delete Request ~125
Permanently delete a Bruno request file from a collection. Use this to remove a request created by mistake; the file is unlinked from disk and cannot be recovered through this server. Only .yml/.bru files inside a detected Bruno collection can be deleted. To clear just a script and keep the request, use remove_script instead.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | yes | Must be true. Explicit acknowledgement that the file is deleted permanently. |
| filePath | string | yes | Absolute path to the .yml or .bru request file to delete. Get from list_requests or get_collection_stats. |
No output schema declared.
No examples provided.
get_collection_stats Get Collection Statistics ~106
Get statistics about a Bruno collection — request counts by method, folders, environments, and per-request details including file paths. environmentDetails lists each environment with the NAMES of the variables it declares (values are withheld), so you can see what an environment already defines before merging into it with set_environment_variable. Use filePath values as entries in the requests list of run_collection.
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path to collection directory. Use the path returned by list_collections. |
No output schema declared.
No examples provided.
list_collections List Collections ~126
List the Bruno collections REGISTERED IN workspace.yml, with their names and paths. This is a registry listing, not a filesystem scan: a collection that exists on disk but is not registered will NOT appear, and registered entries that no longer exist are returned with "exists": false. If you already know a collection's absolute path, pass it directly to the other tools — it does not need to appear here. Use the returned path as collectionPath in other tools (get_collection_stats, list_requests, run_collection).
| Name | Type | Req | Description |
|---|---|---|---|
| workspacePath | string | – | Optional explicit path to workspace.yml |
No output schema declared.
No examples provided.
list_requests List Requests ~70
List all request files (.yml/.bru) in a Bruno collection. Returns absolute file paths, each usable as an entry in the requests list of run_collection, or of one of its groups.
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path to collection directory. Use the path returned by list_collections. |
No output schema declared.
No examples provided.
modify_request Modify Request ~854
Update an existing Bruno request file with partial-merge semantics. Only provided fields are updated; all other fields are preserved. Supports multipart/form-data with file uploads and per-part contentType. Inline scripts REPLACE the existing script of the same type by default (idempotent — repeated calls do not accumulate duplicate blocks); pass scriptMode:"append" to concatenate instead. Use remove_script to clear a script entirely.
| Name | Type | Req | Description |
|---|---|---|---|
| assert | array | – | Replaces the whole assert block. Omit to leave existing assertions untouched. |
| auth | object | – | – |
| body | object | – | – |
| filePath | string | yes | Absolute path to the .yml or .bru request file to modify. Get from list_requests or get_collection_stats. |
| grpc | object | – | gRPC-only fields. Applies to kind "grpc" and is refused otherwise. Headers given for a gRPC request are written as metadata, which is that transport's only header surface. |
| headers | object | – | – |
| method | string | – | – |
| name | string | – | – |
| pathParams | object | – | Replaces the declared path parameters; query parameters are left alone. |
| query | object | – | – |
| scriptMode | string | – | How to write the scripts field. "replace" (default) overwrites the existing script of each provided type, so calling modify_request repeatedly is idempotent. "append" concatenates onto the existing s… |
| scripts | object | – | Inline scripts to persist with the request. Keys: pre-request, post-response, tests (aliases before-request/after-response accepted). Avoids a separate add_test_script call. IMPORTANT for tests/post-… |
| settings | object | – | Request-level settings: transport behaviour (timeouts, redirects, URL encoding), not payload. What reaches the file depends on the dialect, because Bruno's own two writers differ: a .yml request alwa… |
| url | string | – | – |
| vars | object | – | – |
| websocket | object | – | WebSocket-only fields. Applies to kind "websocket" and is refused otherwise. |
No output schema declared.
No examples provided.
read_environment Read Bruno Environment ~104
Read an environment back as structured JSON: every variable with its value, plus its disabled and secret flags. Omit "name" to list the collection's environments instead. Secret variables are returned by name only — Bruno stores no value for a secret in either file format, so there is none to return.
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path to the collection directory. |
| name | string | – | Environment name, without extension. Omit to list the available environment names. |
No output schema declared.
No examples provided.
read_request Read Bruno Request ~152
Read a single request file back as structured JSON: method, url, headers, query and path params, body, auth mode, scripts, assertions, vars, settings and docs. Works on both .bru and .yml and returns the same shape for each, so the on-disk format stays invisible. Use this before modify_request to see current state, and after create_request to confirm what was written. A "notes" array reports anything the file declares that the runner will not act on.
| Name | Type | Req | Description |
|---|---|---|---|
| filePath | string | yes | Absolute path to the .bru or .yml request file. Use the path returned by create_request or list_requests rather than rebuilding it: request filenames are lowercased on write. |
No output schema declared.
No examples provided.
remove_environment_variable Remove Environment Variable ~68
Remove a single variable from an existing Bruno environment. MERGES into the environment — all other variables are preserved.
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path to existing collection directory. |
| environment | string | yes | Name of the existing environment. |
| name | string | yes | Variable key to remove. |
No output schema declared.
No examples provided.
remove_script Remove Script ~170
Delete a pre-request, post-response, or tests script from a Bruno request, leaving the rest of the request intact. Use this to undo or clean up a script written by create_request/modify_request/add_test_script — including duplicate blocks accumulated by appending. Canonical scriptType values are pre-request/post-response/tests; the aliases before-request and after-response are accepted. Removing all scripts also drops the now-empty script container.
| Name | Type | Req | Description |
|---|---|---|---|
| bruFilePath | string | yes | Absolute path to the .yml or .bru request file. Get from list_requests or get_collection_stats. |
| scriptType | string | yes | Which script to remove. Both .bru and .yml keep the three script types in separate slots, so removal is precise: clearing tests leaves a post-response script in place, and vice versa. |
No output schema declared.
No examples provided.
run_collection Run Collection ~2,609
Execute requests in a Bruno collection and run test scripts. HOW TO RUN A SUBSET: requests takes an ORDERED list of entries, each a .yml/.bru request file or a directory (which expands to every request under it, recursively). Absolute, or relative to collectionPath. Order is yours and duplicates are allowed — naming the same request twice runs it twice. Omit requests to run the whole collection. GROUPS: pass groups instead when one call needs more than one identity or configuration. Each group owns its OWN variable store and cookie jar, so nothing a group sets — a bru.setVar, a session cookie — is visible to any other group. That is what makes running the same five requests as alice and as bob in one call safe. Passing both requests and groups is REJECTED rather than resolved for you. ITERATIONS: data or dataFile runs a group once per row of a table, with the row bound as variables — one call to check the same requests against 50 accounts, or one login against 50 credential pairs. Each row is reported as its own group, with the same name, its own index and an iterationIndex, because each row IS a separate group: it gets that isolation, so two rows differing only in a password authenticate separately instead of one silently reusing the other's token. Rows are independent, so a failing row does not stop the rows after it. Ceiling of 1000 rows per scope. PARALLELISM: parallel on the RUN fans the groups out against each other; parallel on a GROUP fans that group's own requests out. A group is serial unless it says otherwise, whatever the run does. seq no longer constrains execution — it is the default order and the reporting order only, so two requests in one parallel group genuinely run at the same time and may contend on the store they share. RESULTS are group-shaped: groups[] each carry their own summary, results, capturedVariableNames, capturedVariables and warnings, and the top-level summary is the run. There is no top-level results array, in the no-groups case ei…
| Name | Type | Req | Description |
|---|---|---|---|
| captureVariables | array | – | Names of variables set by bru.setVar during the run whose values you want back, e.g. ["token"]. A script that captures a value out of a response — bru.setVar("token", res.body.token) — makes it avail… |
| collectionPath | string | yes | Absolute path to collection root directory. Use the path returned by list_collections. |
| collectionRoot | string | – | The collection that collectionPath belongs to, when running a subfolder of one: environments and the collection- and folder-level scripts are resolved from here. Must be collectionPath itself or an a… |
| cookieJar | boolean | – | Keep cookies from each response and send them on later requests in the same run, so a login carries into the requests after it. Scoped to the group — nothing crosses from one group to another, at any… |
| data | array | – | Rows every group iterates over, as the group-level data but applied to all of them. A group that gives its own data or dataFile REPLACES this rather than adding to it, the same rule environment follo… |
| dataFile | string | – | A CSV inside the collection whose rows every group iterates over. Same rules as the group-level dataFile, and likewise replaced by a group that names its own rows. Ceiling of 1000 rows, because every… |
| environment | string | – | Environment name to use (e.g. "dev", "staging"). Get available names from get_collection_stats. |
| groups | array | – | Run the same collection under more than one identity or configuration in one call. Each group owns its OWN variable store and cookie jar: nothing a group sets is visible to any other group, in either… |
| includeResponseBody | boolean | – | Include the response body of each request in the results. Default: true. |
| maxConcurrency | integer | – | Ceiling on requests in flight across the whole run. Omit to derive one from this machine's cores and memory, held below capacity. 0 lifts it entirely, at your own risk. Applies to THIS run and is giv… |
| maxResponseBodyBytes | number | – | Maximum response body size (bytes) to return per request; longer bodies are truncated and response_body_truncated is set. Default: 10240. |
| parallel | boolean | – | Fan out. At the run level this runs the GROUPS concurrently; a group's own requests are serial unless that group sets its own parallel. With no groups given the run is one group, so parallel here run… |
| report | object | – | Write the run to a file, in addition to returning it here. Name at least one format. Paths are CONFINED TO THE COLLECTION: a path resolving outside it is refused, with the reason as a run warning, be… |
| requests | array | – | The requests to run, IN THE ORDER GIVEN. Each entry is a .yml or .bru request file, or a directory, which expands to every request under it, recursively. Absolute, or relative to collectionPath. Get… |
| variables | object | – | Variables for this run only, as {name: value}. They override the environment file and work without one. Held in memory and never written to any file — this is the only correct way to supply a secret,… |
| websocket | object | – | Bounds for websocket requests in this run. Applies to every websocket request in the call; there is no per-request form. Omit and the defaults below apply. A session always ends on one of these bound… |
No output schema declared.
No examples provided.
set_environment_variable Set Environment Variable ~213
Set (add or update) a single variable in an existing Bruno environment. MERGES into the environment — all other variables are preserved.
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path to existing collection directory. |
| enabled | boolean | – | Whether the variable is enabled. Persisted: enabled=false is written as a disabled variable. |
| environment | string | yes | Name of the existing environment. |
| name | string | yes | Variable key to set. |
| secret | boolean | – | Whether the variable is a secret. Persisted. IMPORTANT: marking a variable secret means its VALUE IS NOT SAVED — Bruno stores a secret variable as a name only (.bru lists it under vars:secret, .yml w… |
| value | string|number|boolean | yes | Variable value. |
No output schema declared.
No examples provided.
update_environment Update Bruno Environment ~94
Partially update an existing Bruno environment by MERGING the provided variables into the existing ones. Pre-existing variables not listed are preserved (unlike create_environment, which replaces the whole file).
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path to existing collection directory. |
| name | string | yes | Name of the existing environment to update. |
| variables | object | yes | Variables to merge into the environment. Existing variables not listed here are kept. |
No output schema declared.
No examples provided.