* test(core): backfill coverage on inspectorClient + remote server Resolves #1310. Drops the two TODO(#1310) exclusions from clients/web/vite.config.ts (coverage.exclude); both files now pass the per-file gate (lines >=90, statements >=85, functions >=80, branches >=50). core/mcp/remote/node/server.ts (88.15 / 78.37 -> 97.29 / 100): - Extract createTokenAuthProvider to its own file (core/mcp/remote/node/tokenAuthProvider.ts) so the 7 no-op OAuthClientProvider stubs can be unit-tested directly. - Add focused integration tests covering the remaining gaps: * createTransportNode failure path on POST /api/mcp/connect * /api/mcp/send when transport is dead * /api/log non-JSON body (catch fallback) * forwardLogEvent unknown-level / no-messages / string-first-message fallbacks (lines 232, 240-242, 257-265 in the original) * /api/fetch missing-url + upstream-throw paths * /api/storage POST invalid storeId + invalid JSON body * /api/storage GET when the on-disk store is unparseable core/mcp/inspectorClient.ts (73.48 / 72.09 -> 91.16 / 89.92): Added a single "Coverage backfill (#1310)" describe block to the existing integration test, plus a few unit-style cases: - OAuth getters / setOAuthConfig / authenticate when oauthManager is unset. - Simple session, roots, subscription, and instructions accessors. - subscribe / unsubscribe error paths against a server without the subscribe capability; happy path against one with it. - getPrompt + readResourceFromTemplate happy path + expansion-failure. - setLoggingLevel "Server does not support logging" guard. - getAppRendererClient (null before connect, cached proxy after). - OAuth + stdio: authenticate() throws via getServerUrl()'s stdio check. - listChanged notifications: tools/resources/prompts handlers via the fixture add_tool / add_resource / add_prompt tools. - Misc tiny branches: re-connect no-op, elicit form mode, getTaskCapabilities on a tasks-less server, receiver-task TTL cleanup + cancel via the private surface (the focused-unit pass the issue describes). - defensive `if (!this.client) throw` guards: one nullify-and-call test exercises 16 of them via a single instance, plus the connect() entry guard. The receiver-task internals test uses (instance as unknown as { private fields... }) to drive createReceiverTask / cancelReceiverTask / TTL cleanup directly; per the issue, refactoring private helpers to be testable from a unit test was authorized. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(core): address #1317 PR review feedback - Rename the misnamed "listChanged notifications" describe in inspectorClient.test.ts to "capability detection after connect", since the test asserts only on getCapabilities() round-tripping and never triggers or observes a notification dispatch. Real dispatch coverage lives in the adjacent "list_changed + resourceUpdated notifications" block. Kept the resources/prompts fixtures with a note explaining why they are required for the server to advertise the matching capabilities. - Expand the comment on the 250ms wait in remote-transport.test.ts' /api/mcp/send dead-transport test so it is clear the >= 500 assertion is intentionally permissive across both the dead-transport short- circuit and the downstream send-failure branches. - Add a "keep this in sync" pointer on the nullify() helper so a future cleanup that removes any of the defensive `if (!this.client) throw` guards in inspectorClient.ts is reminded to drop the matching call here rather than silently under-covering. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
import type { OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
import type { RemoteConnectRequest } from "../types.js";
|
|
|
|
/**
|
|
* Simple OAuth client provider that just returns tokens.
|
|
* Used by the remote server to inject Bearer tokens into transport requests.
|
|
* The other OAuthClientProvider methods are required by the interface but never
|
|
* exercised in the remote-server path (the SDK only calls `tokens()` for Bearer
|
|
* injection); they are kept as no-op stubs.
|
|
*/
|
|
export function createTokenAuthProvider(
|
|
tokens: RemoteConnectRequest["oauthTokens"],
|
|
): OAuthClientProvider | undefined {
|
|
if (!tokens) return undefined;
|
|
|
|
return {
|
|
async tokens(): Promise<OAuthTokens | undefined> {
|
|
return tokens as OAuthTokens;
|
|
},
|
|
async clientInformation() {
|
|
return undefined;
|
|
},
|
|
async saveTokens() {
|
|
// No-op
|
|
},
|
|
codeVerifier() {
|
|
return undefined;
|
|
},
|
|
async saveCodeVerifier() {
|
|
// No-op
|
|
},
|
|
clear() {
|
|
// No-op
|
|
},
|
|
redirectToAuthorization() {
|
|
// No-op
|
|
},
|
|
state() {
|
|
return "";
|
|
},
|
|
} as unknown as OAuthClientProvider;
|
|
}
|