Bruno MCP Studio
NPM · @OSTICO/BRUNO-MCP · SCANNED SEP 28
Author, edit and run Bruno collections as files: HTTP, WebSocket, gRPC, per-request pass/fail.
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 → Why this is hard to 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
- 46 of 140 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 39 days ago).Pass
- Disclosure check failed: no security disclosure policy was found in the source repository. See how to fix → Fail
Schema Quality & AI Usability59
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 7591 tokens (~421/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 Management87
- Stability observed for 26 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage96
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 88% of tool parameters carry a description.Partial
Tool Safety75
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- 0 of 5 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "remove_environment_variable" implies "remove" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
- An AI judge read all 19 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the Bruno MCP Studio server?
Bruno MCP Studio runs locally as an npm package, launched with npx -y @ostico/bruno-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
npm · @ostico/bruno-mcp
claude mcp add ostico-bruno-mcp-studio -- npx -y @ostico/bruno-mcp
{
"mcpServers": {
"ostico-bruno-mcp-studio": {
"command": "npx",
"args": [
"-y",
"@ostico/bruno-mcp"
]
}
}
} {
"servers": {
"ostico-bruno-mcp-studio": {
"command": "npx",
"args": [
"-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": {
"Transport": "stdio",
"Command": "npx",
"Arguments": [
"-y",
"@ostico/bruno-mcp"
]
}
}
} assistant mcp add ostico-bruno-mcp-studio -t stdio -c npx -a -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.
- 28 Sept 26 +1
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 26 Sept 26 −3
- Stability: pass → 0.80 functional
- 25 Sept 26 +1
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 23 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.
- 21 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.
- 20 Sept 26 −3
- Stability: pass → 0.83 functional
- 19 Sept 26 +1
- Stability: 0.97 → pass security
- 17 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.
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 28 Sept 2026 · Analysed npm/@ostico/bruno-mcp@2.5.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.5.0 |
| Rekor log index | 2522695218 |
| Predicate type | SLSA build provenance https://slsa.dev/provenance/v1 |
| Subject digest | sha512:3bd789645ef7557cc69e2373d50e56ab503a83021cd9931165412345e359662594e09be7a7d64e51ea628badb01de615fe979b4efd31dadfd94439792 |
Background: How many MCP packages publish verified provenance →
Dependencies 140 packages
| Packages resolved | 140 |
|---|---|
| Stale | 43 |
| No linked repository | 4 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
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. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
add_test_script Add Test Script ~387
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 spend the script timeout (settings.timeout, default 5000ms), which write_request's settings argument raises.
| 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 script type has its own slot in both .bru and .yml, so replacing one leav… |
| 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 ~294
Create a new Bruno API testing collection with configuration. outputPath is the PARENT directory and name is appended to it: outputPath "/work/apis" with name "Billing" creates the collection at /work/apis/Billing. Do not put the collection name in outputPath as well. The new collection is also added to the workspace registry that `list_collections` reads rather than the disk, so a collection missing from it is invisible to that tool and to the Bruno app. The result says whether it was registered and, if not, why.
| Name | Type | Req | Description |
|---|---|---|---|
| baseUrl | string | – | – |
| description | string | – | – |
| format | string | – | – |
| ignore | array | – | – |
| name | string | yes | – |
| outputPath | string | yes | Absolute path of the PARENT directory to create the collection directory in. name is appended: "/work/apis" with name "Billing" creates /work/apis/Billing, and passing "/work/apis/Billing" here would… |
| registerInWorkspace | boolean | – | Set false to create the collection without touching any workspace file. It will not appear in list_collections until something else registers it. |
| workspacePath | string | – | Absolute path of the workspace.yml to register the new collection in. Defaults to the same one list_collections reads: BRUNO_WORKSPACE_PATH, or the Bruno app's workspace for this platform. |
No output schema declared.
No examples provided.
create_environment Create Bruno Environment ~190
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 which ones a replace would delete, so you can merge with update_environment, pick another name, or retry 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.
delete_collection Delete Collection ~178
Permanently delete a Bruno collection: the collection directory and everything inside it is removed from disk, and its workspace registry entry with it. Nothing here can be recovered through this server. Only a directory that is itself a collection root — one holding opencollection.yml or bruno.json — can be deleted. To keep the files and only stop the collection being listed, use unregister_collection instead.
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path of the collection directory to delete. Use the path from list_collections. |
| confirm | boolean | yes | Must be true. Explicit acknowledgement that the directory and every request in it are deleted permanently. |
| workspacePath | string | – | Absolute path of the workspace.yml holding its entry. Defaults to the same one list_collections reads: BRUNO_WORKSPACE_PATH, or the Bruno app's workspace for this platform. |
No output schema declared.
No examples provided.
delete_request Delete Requests ~148
Permanently delete request files from a Bruno collection. One confirm covers the whole list. Each file is unlinked and cannot be recovered through this server. Only .yml/.bru files inside a detected collection can be deleted. Every path is checked before the first unlink, so one unusable path deletes nothing. The result names each file's outcome. To clear a script and keep the request, use remove_script.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | yes | Must be true. Every file in filePaths is deleted permanently. |
| filePaths | array | yes | Absolute paths to the .yml or .bru request files to delete, from list_requests or get_collection_stats. A one-element list deletes one request. |
No output schema declared.
No examples provided.
get_collection_stats Get Collection Statistics ~305
Get statistics about a Bruno collection — request counts by method, folders, environments, and per-request details including each request's file path and URL. environmentDetails lists each environment with the NAMES of the variables it declares, values withheld, so what an environment already defines is visible before merging into it with set_environment_variable. Use filePath values as entries in the requests list of run_collection. SIZE: the per-request array is the bulk of the response and grows with the collection — a few hundred requests run to tens of kilobytes. Narrow it with folder, method or nameContains, or pass includeRequests: false for counts only. The counts always describe the WHOLE collection; a filtered call adds matchedRequests so the two cannot be confused.
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path to collection directory. Use the path returned by list_collections. |
| folder | string | – | Report only requests in this folder, path relative to the collection root. Nested folders are included, so "auth" also matches "auth/oauth2". |
| includeRequests | boolean | – | Set false to drop the per-request array and return only the counts, folders and environments. |
| method | string | – | Report only requests with this method, case-insensitive. A request that has no method is bucketed under its kind, so "GRPC" and "WS" work here too. |
| nameContains | string | – | Report only requests whose name contains this text, case-insensitive. |
No output schema declared.
No examples provided.
list_collections List Collections ~110
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. A known absolute path works in the other tools without appearing here. Use the returned path as collectionPath in get_collection_stats, list_requests and 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.
move_request Move Request ~231
Relocate a request file to another folder, or to another collection entirely. Pass copy:true to duplicate it instead of moving it. The bytes are moved verbatim, nothing is parsed and rewritten, so seq arrives unchanged and may tie with a request already there; that is reported, and Bruno breaks such a tie by filename. The file keeps its name: use write_request with filename to rename it. The new path comes back in the response.
| Name | Type | Req | Description |
|---|---|---|---|
| copy | boolean | – | Leave the original in place and write a duplicate at the destination. Since the file keeps its name, a copy needs a different folder or collection. |
| filePath | string | yes | Absolute path to the .yml or .bru request file to move. Get from list_requests or get_collection_stats. |
| targetCollectionPath | string | – | Absolute path to the collection it should land in. Omit to move within the request's own collection. |
| targetFolder | string | – | Folder inside the target collection, relative to its root, e.g. "auth/login". Omit for the collection root. Created if it does not exist. |
No output schema declared.
No examples provided.
read_environment Read Bruno Environment ~101
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 — no file format stores a secret's value, 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 ~191
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. Both .bru and .yml return the same shape, so the on-disk format stays invisible. Use this before write_request to see current state, and after it to confirm what was written. A websocket or grpc request also carries its stored messages in full — title, content, and for a websocket the type and whether the runner will send it — under websocket.messages or grpc.messages, keyed as write_request accepts them. 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 write_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 ~150
Delete a pre-request, post-response, or tests script from a Bruno request, leaving the rest of the request intact, 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,938
Execute requests in a Bruno collection and run their test scripts. SUBSET: requests is an ORDERED list of .yml/.bru paths, absolute or relative to collectionPath; a directory expands recursively. Duplicates allowed, and run twice. Omit to run the whole collection. Pass requests OR groups, never both. GROUPS: one call, 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. ITERATIONS: data or dataFile runs a group once per row, the row bound as variables. Each row is its own group — same name, own index, own iterationIndex — with that same isolation. Rows are independent: a failing row does not stop later rows. Ceiling 1000 rows per scope. PARALLELISM: parallel on the run fans groups out; parallel on a group fans that group's requests out. A group is serial unless it says otherwise, whatever the run does. seq no longer constrains execution — default order and reporting order only — so two requests in one parallel group run at the same moment and may contend on the store they share. startAfter holds a group until a named group has completed a given number of its requests, connecting a listener before a trigger fires; needs parallel on the run. Chains allowed; cycles, and gates that can never open, are refused before anything runs. If the group waited on ends early, the waiting group reports that as its error instead of starting. RESULTS are group-shaped: each groups[] entry carries its own summary, results, capturedVariableNames and capturedVariables; the top-level summary is the run. Run-wide warnings are top-level, so a captureVariables name is reported unset only when NO group set it. There is no top-level results array, not even with no groups. A crashed group reports error and counts as one failure. RESPONSE DATA: every result carries the response…
| Name | Type | Req | Description |
|---|---|---|---|
| bail | boolean | – | Stop at the first request that errors or fails a test, instead of running the rest. Bruno's --bail. Requests not yet started come back as results with skipped:true, in the failing group and every gro… |
| captureVariables | array | – | Names of variables set by bru.setVar during the run whose values you want back, e.g. ["token"]. This is the only way to see one: without it the value exists only inside the run. Every name a script s… |
| 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. |
| includeResponseHeaders | boolean | – | Include the response headers of each request in the results, credential values masked. Default: true. Turn it OFF for a run whose results you read in bulk: the same headers repeat per result and a fe… |
| 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. |
| maxResponseHeaderBytes | integer | – | Maximum size (bytes) of one header VALUE to return; a longer value is cut and response_headers_truncated is set on that result. Default: 2048. Per value, not per map, so it never changes which header… |
| 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 as well as 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, because… |
| 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 every websocket request in this call; there is no per-request form. Omit for the defaults below. A session always ends on one of these bounds or on the peer closing, and nothing is held op… |
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.
unregister_collection Unregister Collection ~148
Remove a collection from the workspace registry, leaving every file on disk untouched. list_collections reads that registry, so this is how an entry stops being listed, including a stale entry whose directory is gone. To delete the collection itself, use delete_collection.
| Name | Type | Req | Description |
|---|---|---|---|
| collectionPath | string | yes | Absolute path of the collection as it is listed. Use the path from list_collections: matching is by path, not by name, because two entries are allowed to share a name. |
| workspacePath | string | – | Absolute path of the workspace.yml to remove the entry from. Defaults to the same one list_collections reads: BRUNO_WORKSPACE_PATH, or the Bruno app's workspace for this platform. |
No output schema declared.
No examples provided.
update_environment Update Bruno Environment ~91
Partially update an existing Bruno environment by MERGING the provided variables into the existing ones. 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.
write_request Write Bruno Request ~1,633
Create a request file or change an existing one (.bru and .yml). The locator decides which: collectionPath plus name creates, filePath changes what is already there. Creating never overwrites — an existing file is refused, so address it by filePath. Changing is a partial merge: only provided fields are updated and every other field is preserved. Pass requests to write a whole set in ONE call, not one call per request. 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 spend the script timeout (settings.timeout, default 5000ms) — raise it via the settings argument. Inline scripts REPLACE the existing script of the same type by default, so repeated calls do not accumulate duplicate blocks; scriptMode:"append" concatenates instead, and remove_script clears one. RENAMING: name and filename are independent, as they are in Bruno itself — name changes the request's name inside the file and filename moves the file. Pass both to keep them in step, and read the new path back from the response.
| Name | Type | Req | Description |
|---|---|---|---|
| assert | array | – | Declared assertions, evaluated on every run without needing a test() block. On an existing request this replaces the whole assert block; omit to leave existing assertions untouched. |
| auth | object | – | – |
| body | object | – | – |
| collectionPath | string | – | Absolute path to existing collection directory. Passing it, with name, creates a new request; pass filePath instead to change an existing one. |
| filePath | string | – | Absolute path to the .yml or .bru request file to change. Get from list_requests or get_collection_stats. Only provided fields are updated; every other field is kept. |
| filename | string | – | Renames the file, keeping it in its own folder. Basename only, no path separators. The extension is optional and must match the collection's format if given. Refused if another file of that name alre… |
| folder | string | – | Subfolder within the collection to create the request in. Only valid when creating. |
| 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. Set only when creating: an existing request cannot change tr… |
| 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 | – | The request's name. Required when creating. On an existing request this changes the name inside the file and does NOT rename the file — pass filename for that. |
| pathParams | object | – | Values for :name segments in the URL, e.g. { id: "42" } for /users/:id. On an existing request this replaces the declared path parameters; query parameters are left alone. |
| query | object | – | – |
| requests | array | – | Write several requests in one call. Each item takes the same fields as a single write and means the same thing: name creates one in the collection named at the top level, filePath edits an existing o… |
| scriptMode | string | – | How to write the scripts field. "replace" (the default) overwrites the existing script of each provided type, so repeating the same call is idempotent. "append" concatenates onto the existing script,… |
| scripts | object | – | Inline scripts to persist with the request. Keys: pre-request, post-response, tests (aliases before-request/after-response accepted). IMPORTANT for tests/post-response: only assertions inside a test(… |
| sequence | number | – | Run order within the folder. Defaults to after the folder's other requests. Only valid when creating. |
| 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 | – | Required when creating a request. On an existing one it replaces the URL. |
| vars | object | – | – |
| websocket | object | – | WebSocket-only fields. Applies to kind "websocket" and is refused otherwise. |
No output schema declared.
No examples provided.
What is the Bruno MCP Studio server?
Bruno MCP Studio is listed in the public MCP registry as io.github.Ostico/bruno-mcp-studio. Author, edit and run Bruno collections as files: HTTP, WebSocket, gRPC, per-request pass/fail. This page covers its npm package (@ostico/bruno-mcp).
Is the Bruno MCP Studio server safe to use?
Bruno MCP Studio scores 88 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 28 September 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the Bruno MCP Studio server expose?
Bruno MCP Studio exposes 18 tools: create_collection, create_environment, update_environment, set_environment_variable, remove_environment_variable, and 13 more. Their descriptions and schemas cost roughly 7,446 tokens of context every time the server is loaded.
Is the Bruno MCP Studio server still maintained?
Bruno MCP Studio is still listed as active in the MCP registry. We last reached this channel on 28 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the Bruno MCP Studio server under?
Bruno MCP Studio declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.