Skip to content

Commit 760030f

Browse files
authored
fix(mcp): preserve headers during auth and debug (anomalyco#31802)
1 parent 1ae8d25 commit 760030f

3 files changed

Lines changed: 15 additions & 5 deletions

File tree

‎packages/opencode/src/cli/cmd/mcp.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ export const McpDebugCommand = effectCmd({
744744
const response = await fetch(serverConfig.url, {
745745
method: "POST",
746746
headers: {
747+
...serverConfig.headers,
747748
"Content-Type": "application/json",
748749
Accept: "application/json, text/event-stream",
749750
},
@@ -792,6 +793,7 @@ export const McpDebugCommand = effectCmd({
792793
// Try creating transport with auth provider to trigger discovery
793794
const transport = new StreamableHTTPClientTransport(new URL(serverConfig.url), {
794795
authProvider,
796+
requestInit: serverConfig.headers ? { headers: serverConfig.headers } : undefined,
795797
})
796798

797799
try {

‎packages/opencode/src/mcp/index.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,10 @@ export const layer = Layer.effect(
741741
auth,
742742
)
743743

744-
const transport = new StreamableHTTPClientTransport(url, { authProvider })
744+
const transport = new StreamableHTTPClientTransport(url, {
745+
authProvider,
746+
requestInit: mcpConfig.headers ? { headers: mcpConfig.headers } : undefined,
747+
})
745748

746749
return yield* Effect.tryPromise({
747750
try: () => {

‎packages/opencode/test/mcp/oauth-browser.test.ts‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,18 @@ class MockUnauthorizedError extends Error {
3838
const transportCalls: Array<{
3939
type: "streamable" | "sse"
4040
url: string
41-
options: { authProvider?: unknown }
41+
options: { authProvider?: unknown; requestInit?: RequestInit }
4242
}> = []
4343

4444
// Mock the transport constructors
4545
void mock.module("@modelcontextprotocol/sdk/client/streamableHttp.js", () => ({
4646
StreamableHTTPClientTransport: class MockStreamableHTTP {
4747
url: string
4848
authProvider: { redirectToAuthorization?: (url: URL) => Promise<void> } | undefined
49-
constructor(url: URL, options?: { authProvider?: { redirectToAuthorization?: (url: URL) => Promise<void> } }) {
49+
constructor(
50+
url: URL,
51+
options?: { authProvider?: { redirectToAuthorization?: (url: URL) => Promise<void> }; requestInit?: RequestInit },
52+
) {
5053
this.url = url.toString()
5154
this.authProvider = options?.authProvider
5255
transportCalls.push({
@@ -127,11 +130,12 @@ const mcpTest = testEffect(
127130
)
128131
const service = MCP.Service as unknown as Effect.Effect<MCPNS.Interface, never, never>
129132

130-
const config = (name: string) => ({
133+
const config = (name: string, headers?: Record<string, string>) => ({
131134
mcp: {
132135
[name]: {
133136
type: "remote" as const,
134137
url: "https://example.com/mcp",
138+
headers,
135139
},
136140
},
137141
})
@@ -227,6 +231,7 @@ mcpTest.instance(
227231
expect(failure).toEqual(Option.none())
228232
expect(typeof url).toBe("string")
229233
expect(url).toContain("https://")
234+
expect(transportCalls.at(-1)?.options.requestInit?.headers).toEqual({ "X-Custom-Header": "custom-value" })
230235
}),
231-
{ config: config("test-oauth-server-3") },
236+
{ config: config("test-oauth-server-3", { "X-Custom-Header": "custom-value" }) },
232237
)

0 commit comments

Comments
 (0)