Skip to content
Buy · $14.99 Opens the GitHub repository in a new tab. The signed build is a separate download; see the README for what is in each.
Changelog

Bastion 1.9.0

Version 1.9.0 ·

Added

  • Progress on a long call, streamed to the client that asked for it. A POST to /s/<profile>/<server> can now be answered with text/event-stream carrying the child's notifications/progress ahead of the result, instead of going silent until the whole thing finishes. This is the current transport rather than the deprecated one: still one POST and one response, no Mcp-Session-Id, no replay, and GET/DELETE are still 405.

    It is opted into twice — the request must carry a progressToken and an Accept: text/event-stream. Every conforming client already sends that header unconditionally, so gating on it alone would have changed the shape of every response in the product overnight for no gain on the calls that emit nothing. The token requirement is also what keeps the status codes intact: an unknown method carries no token, so it never streams and is still a 404 with -32601. The stream head is written on the first frame, so a call that emits no progress is answered byte-for-byte as it was before.

    The token is remapped on the way out, for the same reason ids already were. One pipe carries every client of a child and two clients are free to have picked token 1; the token Bastion sends upstream is the internal request id, so pending is the token table too and there is no second numbering to keep in step. The client's own token, and its type, come back unchanged.

    bastion-bridge reads the stream as well, writing each frame to stdout as its own line — so Claude Desktop, the one client that cannot be handed a URL, is not left out.

    Still gaps, and now for a sharper reason: list_changed and subscriptions/listen name no request, so a per-request channel cannot carry them. Remote servers still collapse their stream, because RemoteEndpoint.verify refuses a rebinding answer only while the body is buffered.

  • A search field on the catalog tab. Thirty-three entries had no way in but scrolling. It filters over the id, the display name, the summary, the npm package and the endpoint, because the title is the one field somebody searching may not know: sentry finds the entry by name, issues finds it by what it does, and @sentry/mcp-server finds it when a package name is what was pasted in. Pinned above the list rather than scrolling with it, and the text survives a trip to the Custom tab and back — switching tabs to check a package name is not a reason to retype it.