fix(mcp): bound oauth refresh timeout

This commit is contained in:
opencode-agent[bot]
2026-06-13 02:48:13 +00:00
parent c5fff9fb68
commit ee5ee61db5
2 changed files with 40 additions and 2 deletions
+5 -2
View File
@@ -210,6 +210,7 @@ export const layer = Layer.effect(
status: { status: "failed" as const, error: `Invalid MCP URL for "${key}"` },
}
}
const connectTimeout = mcp.timeout ?? DEFAULT_TIMEOUT
let authProvider: McpOAuthProvider | undefined
if (!oauthDisabled) {
@@ -230,7 +231,10 @@ export const layer = Layer.effect(
)
authProvider = provider
yield* Effect.tryPromise(() =>
provider.refreshTokensIfExpired(mcp.headers ? createFetchWithInit(fetch, { headers: mcp.headers }) : undefined),
withTimeout(
provider.refreshTokensIfExpired(mcp.headers ? createFetchWithInit(fetch, { headers: mcp.headers }) : undefined),
connectTimeout,
),
).pipe(Effect.ignore)
}
@@ -251,7 +255,6 @@ export const layer = Layer.effect(
},
]
const connectTimeout = mcp.timeout ?? DEFAULT_TIMEOUT
let lastStatus: Status | undefined
for (const { name, transport } of transports) {
@@ -306,6 +306,41 @@ it.live("McpOAuthProvider refreshes expired stored tokens", () =>
}),
)
it.instance(
"remote connect bounds expired token refresh by mcp timeout",
() =>
Effect.acquireUseRelease(
Effect.sync(() => {
const original = McpOAuthProvider.prototype.refreshTokensIfExpired
McpOAuthProvider.prototype.refreshTokensIfExpired = () => {
refreshAuthorizationCalls++
return new Promise(() => {})
}
return original
}),
() =>
MCP.Service.use((mcp: MCPNS.Interface) =>
Effect.gen(function* () {
lastCreatedClientName = "remote-timeout"
const result = yield* mcp.add("remote-timeout", {
type: "remote",
url: "https://mcp.example.com/mcp",
timeout: 20,
})
expect(statusName(result.status, "remote-timeout")).toBe("connected")
expect(refreshAuthorizationCalls).toBe(1)
}),
),
(original) =>
Effect.sync(() => {
McpOAuthProvider.prototype.refreshTokensIfExpired = original
}),
),
{ config: { mcp: {} } },
)
it.instance(
"local mcp cwd resolves relative paths against instance directory",
() =>