fix(mcp): bound oauth refresh timeout
This commit is contained in:
parent
c5fff9fb68
commit
ee5ee61db5
2 changed files with 40 additions and 2 deletions
|
|
@ -210,6 +210,7 @@ export const layer = Layer.effect(
|
||||||
status: { status: "failed" as const, error: `Invalid MCP URL for "${key}"` },
|
status: { status: "failed" as const, error: `Invalid MCP URL for "${key}"` },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const connectTimeout = mcp.timeout ?? DEFAULT_TIMEOUT
|
||||||
let authProvider: McpOAuthProvider | undefined
|
let authProvider: McpOAuthProvider | undefined
|
||||||
|
|
||||||
if (!oauthDisabled) {
|
if (!oauthDisabled) {
|
||||||
|
|
@ -230,7 +231,10 @@ export const layer = Layer.effect(
|
||||||
)
|
)
|
||||||
authProvider = provider
|
authProvider = provider
|
||||||
yield* Effect.tryPromise(() =>
|
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)
|
).pipe(Effect.ignore)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,7 +255,6 @@ export const layer = Layer.effect(
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const connectTimeout = mcp.timeout ?? DEFAULT_TIMEOUT
|
|
||||||
let lastStatus: Status | undefined
|
let lastStatus: Status | undefined
|
||||||
|
|
||||||
for (const { name, transport } of transports) {
|
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(
|
it.instance(
|
||||||
"local mcp cwd resolves relative paths against instance directory",
|
"local mcp cwd resolves relative paths against instance directory",
|
||||||
() =>
|
() =>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue