MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / classify

Function classify

packages/plugins/mcp/src/sdk/probe-shape.ts:263–368  ·  view source on GitHub ↗
(
        response: {
          readonly status: number;
          readonly headers: Readonly<Record<string, string>>;
          readonly text: Effect.Effect<string, unknown>;
        },
        method: "GET" | "POST",
      )

Source from the content-addressed store, hash-verified

261 );
262
263 const classify = (
264 response: {
265 readonly status: number;
266 readonly headers: Readonly<Record<string, string>>;
267 readonly text: Effect.Effect<string, unknown>;
268 },
269 method: "GET" | "POST",
270 ): Effect.Effect<McpShapeProbeResult | null> =>
271 Effect.gen(function* () {
272 const contentType = readHeader(response.headers, "content-type") ?? "";
273 const isSse = /^\s*text\/event-stream\b/i.test(contentType);
274
275 if (response.status === 401) {
276 const wwwAuth = readHeader(response.headers, "www-authenticate");
277 if (!wwwAuth || !/^\s*bearer\b/i.test(wwwAuth)) {
278 // Spec-non-compliant 401 (no `Bearer` challenge). Before
279 // giving up, check whether the server still publishes
280 // RFC 9728 protected-resource metadata for this path —
281 // some real MCP servers (Datadog) do exactly this.
282 if (yield* probeProtectedResourceMetadata(client, url, timeoutMs)) {
283 return { kind: "mcp", requiresAuth: true } as const;
284 }
285 return {
286 kind: "not-mcp",
287 category: "auth-required",
288 reason: "401 without Bearer WWW-Authenticate — not an MCP auth challenge",
289 } as const;
290 }
291 // Spec-compliant MCP signal: the auth spec mandates a
292 // `resource_metadata=` attribute pointing at the server's
293 // RFC 9728 document. Real OAuth-protected MCP servers
294 // (sentry.dev, etc.) include it. This attribute is rare on
295 // unrelated OAuth services and is the cleanest accept signal
296 // we have when the 401 body is RFC 6750 OAuth-shape rather
297 // than JSON-RPC.
298 if (/(?:^|[\s,])resource_metadata\s*=/i.test(wwwAuth)) {
299 return { kind: "mcp", requiresAuth: true } as const;
300 }
301 // Looser RFC 6750 §3.1 signal: the Bearer challenge carries
302 // `error=` / `error_description=` auth-params. Real MCP
303 // servers (Supabase, GitHub Copilot, Vercel, Neon, Tavily,
304 // Replicate, ...) include this even when they omit
305 // `resource_metadata=`. The body alone isn't enough for
306 // those — Supabase, e.g., returns `{"message":"Unauthorized"}`
307 // which is neither JSON-RPC nor RFC 6750. The `error=`
308 // auth-param is the tiebreaker.
309 if (/(?:^|[\s,])error\s*=/i.test(wwwAuth)) {
310 return { kind: "mcp", requiresAuth: true } as const;
311 }
312 // SSE responses can't carry a JSON-RPC error envelope; accept the
313 // Bearer challenge alone in that case (rare but spec-permissible).
314 if (isSse) return { kind: "mcp", requiresAuth: true } as const;
315 // Fallback for MCP servers whose 401 omits
316 // `resource_metadata=`. Two body shapes count:
317 // - JSON-RPC error (cubic.dev: API-key auth, JSON-RPC
318 // errors end-to-end).
319 // - RFC 6750 OAuth Bearer error envelope `{error:
320 // "invalid_token", ...}` without GraphQL `{errors:[...]}`

Callers 1

probeMcpEndpointShapeFunction · 0.85

Calls 5

readHeaderFunction · 0.85
isJsonRpcEnvelopeFunction · 0.85
isOAuthErrorBodyFunction · 0.85
readBodyFunction · 0.70

Tested by

no test coverage detected