Releases: Ostico/bruno-mcp-studio
Releases · Ostico/bruno-mcp-studio
Release list
v2.5.0
What's Changed
- fix: mask a token minted under a CSRF header, and keep both cookies by @Ostico in #206
- feat: read messages back, bound reported headers, and let a script assert a session's outcome by @Ostico in #207
- fix: keep the test suite out of the real registry, and let a caller remove a collection by @Ostico in #208
- fix: stop blaming pacing for a handshake failure, and reconcile captureVariables warnings by @Ostico in #209
- fix: make a WebSocket ping interval writable, and stop taking form fields that are dropped by @Ostico in #210
- docs: claim what this server is better at, and name what it is not by @Ostico in #211
- perf: cut the tool surface by a quarter, and merge four tools into write_request by @Ostico in #212
- chore: release 2.5.0 by @Ostico in #213
Full Changelog: v2.4.0...v2.5.0
v2.4.0
What's Changed
- fix: keep the registry description inside the length the registry accepts by @Ostico in #180
- docs: close E1, and correct the summary line that still listed B1 as open by @Ostico in #181
- docs: record what the aggregators actually list, and draft the upstream comment by @Ostico in #182
- feat: let a lost registry listing be republished without cutting a release by @Ostico in #183
- chore: move the working notes into a private submodule by @Ostico in #186
- docs: explain how grouping and parallelism actually work by @Ostico in #187
- docs: say how to assert on a transport, and what includePayloads gates by @Ostico in #188
- fix: keep the oauth2 credential when a pre-request script sets a variable by @Ostico in #189
- fix: run pre-request scripts on gRPC and WebSocket requests by @Ostico in #190
- fix: say that a created collection is not in the registry list_collections reads by @Ostico in #191
- feat: let modify_request rename a request's file by @Ostico in #192
- docs: say that an SSRF allowlist entry matches one spelling of a target by @Ostico in #193
- feat: move a request to another folder or collection by @Ostico in #194
- feat: stop a run at the first failure, and report what it did not reach by @Ostico in #195
- fix: stop the SSRF allowlist depending on how a target is spelled by @Ostico in #199
- fix: register a created collection, and say so either way by @Ostico in #201
- feat: give the script sandbox atob and btoa by @Ostico in #196
- feat: report each request's URL in collection stats, and let a caller ask for less by @Ostico in #197
- docs: say where simultaneity comes from, and prove two runs overlap by @Ostico in #198
- feat: let a group wait for another to reach a given point by @Ostico in #200
- docs: keep the changelog out of feature branches, and write it at release by @Ostico in #202
- test: drive the socket.io recipe against socket.io itself by @Ostico in #203
- fix: send a .bru WebSocket message only when it says it is selected by @Ostico in #204
- chore: release 2.4.0 by @Ostico in #205
Full Changelog: v2.3.0...v2.4.0
v2.3.0
What's Changed
- fix: stop five ways a request could fail while reporting success by @Ostico in #154
- fix: send the payload the file authored, or say why not by @Ostico in #155
- docs: the standing gaps list and the transport authoring tasks by @Ostico in #156
- feat: let a gRPC call and a WebSocket session fail by @Ostico in #157
- fix: give each request kind the settings block Bruno writes for it by @Ostico in #158
- Funding by @Ostico in #160
- fix: operate on a dialect-mismatched request, and say Bruno will not by @Ostico in #159
- fix: keep an authored timeout of inherit, and an unreadable tls block by @Ostico in #161
- fix: report the reason a .bru file will not parse, not just its position by @Ostico in #162
- feat: return response headers on every result by @Ostico in #163
- feat: read a WebSocket session, and end it when it goes quiet by @Ostico in #164
- feat: pace a WebSocket session's messages, and negotiate a subprotocol by @Ostico in #165
- feat: write JUnit and HTML report files from a run by @Ostico in #166
- test: read the WebSocket handshake off the wire, and the paths nothing triggered by @Ostico in #167
- feat: author WebSocket requests, and carry a message's selected flag in .bru by @Ostico in #168
- feat: author gRPC requests, and refuse an escaping proto import at both ends by @Ostico in #169
- feat: edit a WebSocket or gRPC request by @Ostico in #170
- fix: warn where a request is listed, not only where it is read by @Ostico in #171
- docs: close B1 as delivered, and Task 7 as not executable by @Ostico in #172
- fix: refuse a request whose oauth2 token could not be fetched by @Ostico in #173
- docs: stop claiming the category, and name the copyright holders by @Ostico in #174
- feat: read CSV data rows, refusing the files that would bind the wrong column by @Ostico in #175
- test: wait for the close a WebSocket test asserts, instead of assuming it by @Ostico in #177
- chore: ship only the server in a source archive by @Ostico in #176
- feat: run a group once per row of a data table by @Ostico in #178
- chore: release 2.3.0 by @Ostico in #179
Full Changelog: v2.2.1...v2.3.0
v2.2.1
What's Changed
- feat: list the server on the MCP registry, updated by the release itself by @Ostico in #152
- chore(release): 2.2.1 by @Ostico in #153
Full Changelog: v2.2.0...v2.2.1
v2.2.0
What's Changed
- chore: follow the repository rename to bruno-mcp-studio by @Ostico in #147
- fix: stop destroying gRPC and WebSocket requests on every write by @Ostico in #148
- feat: run gRPC and WebSocket requests by @Ostico in #149
- docs: record the gRPC and WebSocket work in the changelog by @Ostico in #150
- chore(release): 2.2.0 by @Ostico in #151
Full Changelog: v2.1.1...v2.2.0
v2.1.1
What's Changed
- docs: retire the defect register by @Ostico in #142
- docs: make the README findable and comparable by @Ostico in #143
- docs: write down how a release is actually cut by @Ostico in #141
- docs: correct the comparison, and fix the npm card by @Ostico in #144
- feat: make npx work, which meant fixing an entry point that never started by @Ostico in #145
- chore(release): 2.1.1 by @Ostico in #146
Full Changelog: v2.1.0...v2.1.1
v2.1.0
What's Changed
- docs: rewrite the README for 2.0 by @Ostico in #123
- docs: put the features list back by @Ostico in #124
- docs: shrink the defect register to the three items still open by @Ostico in #125
- test: close the two execution-groups spec test gaps by @Ostico in #126
- fix: refuse a queryless graphql body when authoring it, warn when running it by @Ostico in #127
- docs: file L17, comments are not stripped from JSON or graphql variables by @Ostico in #129
- fix: model tags as a list in both formats, so a rewrite keeps them by @Ostico in #128
- fix: strip comments from a JSON body before sending it (L17) by @Ostico in #130
- docs: lead the README with why this server exists by @Ostico in #132
- fix: match Bruno's graphql envelope byte for byte by @Ostico in #131
- test: read our own output back with Bruno's reader by @Ostico in #133
- feat: make res callable, with Bruno's own query language by @Ostico in #134
- fix: resolve a variable built out of other variables, as bru run does by @Ostico in #135
- fix: expand Bruno's dynamic variables instead of sending them literally by @Ostico in #137
- fix: cap redirects where Bruno caps them, and close M9 by @Ostico in #138
- fix: send a file body, and agree with Bruno on what
selectedmeans by @Ostico in #139 - chore(release): 2.1.0 by @Ostico in #140
Full Changelog: v2.0.0...v2.1.0
v2.0.0
What's Changed
- fix(scripts): document that res.getBody() is already parsed, warn on double parse by @Ostico in #7
- feat(discoverability): actionable SSRF refusal, environment visibility, honest list_collections by @Ostico in #8
- feat(errors): make network failures actionable, record blind round 4 by @Ostico in #9
- docs: record blind discoverability round 5 by @Ostico in #10
- fix(tsconfig): NodeNext resolution to stop tsc running out of memory by @Ostico in #11
- fix(test-runner): make property-style assertions actually assert by @Ostico in #12
- fix(request-executor): stop parallel mode from hiding a failed folder by @Ostico in #13
- fix(test-runner): await async test callbacks instead of passing them blind by @Ostico in #14
- fix(test-runner): close sandbox escape via host-realm bru closures by @Ostico in #15
- fix(server): keep the MCP server alive through script-triggered rejections and crashes by @Ostico in #16
- fix(server): do not file a non-Error rejection as sandbox noise by @Ostico in #17
- refactor(test-runner): extract the sandbox into a pure, forkable worker (PR-a of child-process migration) by @Ostico in #18
- feat(sandbox): forked, env-scrubbed, killable worker (PR-b of child-process migration) by @Ostico in #19
- feat(sandbox): run collection scripts behind the process boundary in production (PR-c) by @Ostico in #20
- fix(executor): apply request auth on the wire instead of dropping it (A7) by @Ostico in #21
- fix(sandbox): preserve test results recorded before a top-level throw (A4) by @Ostico in #22
- fix(request-executor): warn on unresolved {{var}} placeholders (X8) by @Ostico in #25
- fix(sandbox): project non-serializable request bodies over IPC instead of losing them (S19) by @Ostico in #24
- fix(variable-store): treat setVar(name, undefined|null) as unset (X9) by @Ostico in #23
- fix(dispatcher): deny collection-supplied TLS/proxy overrides by default, host-scoped opt-in (S10/S11/S12) by @Ostico in #26
- fix(ssrf): block cloud-metadata/CGNAT/broadcast/multicast ranges (S18) by @Ostico in #27
- fix(executor): confine multipart file-part reads to the collection root (S05) by @Ostico in #29
- fix(server): confine create_* folder arg to the collection root (S08) by @Ostico in #28
- refine(executor): widen S05 upload confinement (home/tmp/BRUNO_UPLOAD_DIRS) + deny hidden paths by @Ostico in #30
- fix(executor): strip credential headers on cross-origin redirects (S06/S07) by @Ostico in #31
- fix(executor): redact secrets from URLs returned to the caller (S22) by @Ostico in #32
- fix(executor): correct redirect count boundary + 301/302/303 POST->GET (X1/X2) by @Ostico in #33
- fix(request): preserve auth credentials on modify_request instead of dropping them (D1) by @Ostico in #34
- fix(response): cap the response body read + preserve all Set-Cookie (X3/X7) by @Ostico in #35
- fix(executor): skip disabled form parts, halt on pre-request error (X13/X15/X12) by @Ostico in #38
- fix(response): honor Content-Type charset when decoding the body (X4) by @Ostico in #36
- fix(bru-parser): preserve the env secret flag across parse/generate (D7) by @Ostico in #37
- fix(response-wrapper): unify JSON content-type detection (X6) by @Ostico in #39
- fix(env-loader): dispatch by format, load native .bru environments (X11) by @Ostico in #40
- fix(bru-parser): preserve non-string bodies (D2) and disabled headers (D3) by @Ostico in #41
- fix(sandbox): let bru.getVar read env/collection variables (X10) by @Ostico in #42
- fix(network-error): correct the timeout-overrun explanation (X17) by @Ostico in #43
- fix(url-validator): bound the SSRF pre-flight DNS lookup (S19) by @Ostico in #44
- chore(gitignore): ignore the evidence/ QA-artifact dir (S23) by @Ostico in #45
- fix(deps): patch runtime security advisories — undici + MCP SDK transitives (S15/S16/S17) by @Ostico in #46
- fix(security): pin validated addresses at connect time to close DNS rebinding (S20/S21) by @Ostico in #47
- fix(reliability): atomic durable writes and per-path locking (D9/S24/D8) by @Ostico in #48
- fix(fidelity): preserve params, assertions, settings, vars and oauth2 extras on round-trip (D5/D6/D11) by @Ostico in #49
- chore(ci): make the lint, coverage and integration gates real (Q5/Q3/Q6/Q12) by @Ostico in #50
- refactor: remove the unreachable generator module (Q1) by @Ostico in #51
- ci: make the coverage gate actually gate, and split the test lanes by @Ostico in #52
- test: add MCP stdio end-to-end harness by @Ostico in #53
- test: general round-trip fidelity guard for .bru and .yml (D10) by @Ostico in #54
- fix(security): stop re-arming a switched-off .yml header or multipart part (D13/D14) by @Ostico in #55
- chore(ci): adopt *.helper.ts convention for non-suite test support files by @Ostico in #56
- test: build dist/ once in a jest globalSetup instead of per-suite (Q18) by @Ostico in #57
- ci: make test-guard's source scoping real (Q20) and drop the duplicate build (Q21) by @Ostico in #58
- fix: send duplicate request headers instead of dropping all but the last (D4) by @Ostico in #59
- fix: warn when a request repeats a single-value header (D15) by @Ostico in #60
- refactor: split server.ts into per-domain tool modules (Q14) by @Ostico in #61
- fix: check the parse boundary instead of asserting past it (Q17a) by @Ostico in #62
- docs: make code comments self-contained instead of citing a tracker by @Ostico in #63
- docs: keep config, CI and doc comments self-contained by @Ostico in #64
- fix: send form-urlencoded and graphql bodies from .bru requests by @Ostico in #65
- fix: derive Content-Type from the body type by @Ostico in #66
- fix: apply declared query and path parameters to the request by @Ostico in #67
- fix: persist query parameters and honour .bru request settings by @Ostico in #68
- fix: honour settings.encodeUrl and match Bruno's URL encoding by @Ostico in #69
- feat: evaluate declared assert blocks by @Ostico in #70
- fix: close two false passes and restore Bruno's assert semantics by @Ostico in #71
- feat: apply vars:pre-request and vars:post-response by @Ostico in #72
- feat: author assert, vars and path params from the MCP tools by @Ostico in #73
- fix: write .bru files Bruno can actually read by @Ostico in #74
- fix: keep form-urlencoded bodies readable by Bruno by @Ostico in #75
- docs: 2026-07-29 adversarial review findings by @Ostico in #76
- fix: adversarial review batch 1 — unverified-run signal, plaintext secrets, SSRF bypass by @Ostico in #77
- fix: adversarial sweep batch 2 — authoring fidelity, .yml tests slot, assert ordering by @Ostico in #78
- fix: stop reporting Bruno's own metadata files as requests by @Ostico in #79
- fix: keep the body payload when loading a .yml request by @Ostico in #80
- fix: treat inherit as an auth mode, not as absent auth by @Ostico in #81
- fix: take the per-file lock on the create and delete write paths by @Ostico in #82
- docs: consolidate the defect findings into a single regist...
v1.2.4
What's Changed
- fix: close the script lifecycle gaps (silent-green assertions, append-vs-replace, no deletion) by @Ostico in #5
- ci(release): derive the published version from the tag by @Ostico in #6
Full Changelog: v1.2.3...v1.2.4
v1.2.3
Draft — publishing this release creates & pushes the v1.2.3 tag, which triggers the npm publish workflow.
⚠️ Restores work missing from 1.2.2
Commit 3e9adb2 (pre-request scripts, parallel folder execution, HTTPS/proxy dispatcher) was committed locally but never reached the published 1.2.2 — that release forked before it. 1.2.3 reconciles it back in, and actually wires the TLS/proxy settings (they were previously unreachable from a request file).
✨ Features
- Multipart / form-data & file uploads —
create_request/modify_requestform-data items supportcontentTypeandvalueas a string or array (multi-file); requests are sent as realmultipart/form-datawith per-partContent-Typehonored. (Previously form fields were silently dropped and the executor had no multipart support → the source of 415s.) run_collectionreturns the response body —response_body(byte-capped, UTF-8 safe),response_body_truncated,response_content_type; optionsincludeResponseBody(default true),maxResponseBodyBytes(default 10240).- Environment merge tools —
update_environment,set_environment_variable,remove_environment_variable— merge without clobbering unlisted (incl. disabled) variables.create_environmentstill replaces. - Inline scripts on
create_request/modify_request(pre-request/post-response/tests, withbefore-request/after-responseaccepted as aliases). - TLS/proxy + redirect settings wired —
settings.tls/settings.proxynow read from request files;followRedirects/maxRedirectshonored instead of a hardcoded 10-hop follow. - Pre-request scripts & parallel folder execution (restored via
3e9adb2).
🔒 Security
- SSRF guard (DNS-resolution +
BRUNO_SSRF_ALLOWLIST, shipped in 1.2.2) verified intact: pre-request URL mutations are re-validated before fetch; every redirect hop re-validated. - Review fix: env merge no longer deletes disabled variables.
✅ Quality
- Coverage raised to 100% lines / 94.6% branches (801 tests).
- New CI test-guard adequacy gate (threshold 95) on PRs, enforced via branch protection.
Notes
secretonset_environment_variableis accepted but not persisted (documented).- Known residual: DNS-rebinding on the SSRF guard (needs connect-time IP pinning) — tracked follow-up.
What's Changed
- v1.2.3: reconcile 3e9adb2 + multipart, response body, env merge tools, inline scripts, TLS/proxy wiring by @Ostico in #2
- ci: add test-guard adequacy gate + coverage artifact by @Ostico in #3
Full Changelog: v1.2.2...v1.2.3