Skip to content

fix(streamable_http): stop sending a spec-incorrect Origin header - #154

Merged
patvice merged 2 commits into
patvice:mainfrom
guizaols:fix/drop-origin-header
Oct 8, 2026
Merged

patvice merged 2 commits into
patvice:mainfrom
guizaols:fix/drop-origin-header

Conversation

@guizaols

Copy link
Copy Markdown
Contributor

Problem

StreamableHTTP#build_common_headers sets Origin to the MCP endpoint's own URL, path included — e.g. Origin: https://api.githubcopilot.com/mcp/.

  • RFC 6454 §7 defines the Origin value as scheme "://" host [ ":" port ]. A path is never part of it, so no server allowlist can match what the gem sends.
  • The MCP Streamable HTTP transport spec tells servers to validate Origin to prevent DNS rebinding. Servers that do so (GitHub's remote MCP server, Metabase's MCP endpoint, Grafana, …) reject every request with 403 / "Origin not allowed", regardless of how the server-side allowlist is configured.
  • A server-to-server client has no browser origin to report. The reference TypeScript and Python SDKs send no Origin header at all.

Reproduction and sources are in #140. The prepend workaround posted there (removing Origin from build_common_headers) is what affected users are running in production today; this PR makes it unnecessary.

Fix

Remove the one line that sets the header. Nothing else changes:

  • An Origin passed explicitly via the headers option is still forwarded untouched, for anyone who genuinely needs one.
  • The SSE transport never sent Origin, so it is unaffected.

Tests

Two specs added to streamable_http_spec.rb:

  • default headers contain no Origin
  • a caller-supplied Origin is preserved

The first spec fails on main and passes with this change. bundle exec rspec spec/ruby_llm/mcp/native/transports/streamable_http_spec.rb is green (142 examples), rubocop clean.

Fixes #140

guizaols and others added 2 commits August 25, 2026 08:34
build_common_headers set `Origin` to the MCP endpoint's own URL, path
included. RFC 6454 §7 defines Origin as scheme + host [+ port] only, so
that value can never match a server allowlist. The MCP Streamable HTTP
spec asks servers to validate Origin against DNS rebinding, and servers
that do (GitHub's remote MCP, Metabase, Grafana...) reject every request
with 403. A server-to-server client has no browser origin to report, and
the reference TypeScript and Python SDKs send none.

Drop the automatic header. An Origin passed explicitly through the
`headers` option is still forwarded untouched.

Fixes patvice#140
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@patvice

patvice commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Heads up @guizaols: I pushed an empty commit (a48e800 Trigger CI) to this branch. The original CI run from August failed before any jobs started (a GitHub-side issue, not your change), and GitHub won't re-run workflows older than a month, so the empty commit was the only way to get a fresh run. No code changes, so no action needed on your end. Thanks for the fix!

@patvice

patvice commented Oct 8, 2026

Copy link
Copy Markdown
Owner

CI passes and this change looks good. Thanks for the contribution @guizaols

@patvice
patvice merged commit db6ba40 into patvice:main Oct 8, 2026
6 checks passed
@guizaols
guizaols deleted the fix/drop-origin-header branch October 9, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: StreamableHTTP transport sends spec-incorrect Origin header, causing 403 from GitHub's remote MCP server

2 participants