(input: string | McpProbeEndpointInput)
| 984 | const httpClientLayer = options?.httpClientLayer ?? ctx.httpClientLayer; |
| 985 | |
| 986 | const probeEndpoint = (input: string | McpProbeEndpointInput) => |
| 987 | Effect.gen(function* () { |
| 988 | const endpoint = typeof input === "string" ? input : input.endpoint; |
| 989 | const trimmed = endpoint.trim(); |
| 990 | if (!trimmed) { |
| 991 | return yield* new McpConnectionError({ |
| 992 | transport: "remote", |
| 993 | message: "Endpoint URL is required", |
| 994 | }); |
| 995 | } |
| 996 | |
| 997 | const name = yield* Effect.try({ |
| 998 | try: () => new URL(trimmed).hostname, |
| 999 | catch: () => "mcp", |
| 1000 | }).pipe(Effect.orElseSucceed(() => "mcp")); |
| 1001 | const slug = deriveMcpNamespace({ endpoint: trimmed }); |
| 1002 | |
| 1003 | const probeHeaders = typeof input === "string" ? undefined : input.headers; |
| 1004 | const probeQueryParams = typeof input === "string" ? undefined : input.queryParams; |
| 1005 | |
| 1006 | const result = yield* discoverToolsFromInput({ |
| 1007 | transport: "remote", |
| 1008 | endpoint: trimmed, |
| 1009 | headers: probeHeaders, |
| 1010 | queryParams: probeQueryParams, |
| 1011 | httpClientLayer, |
| 1012 | }).pipe( |
| 1013 | Effect.map((d) => ({ ok: true as const, ...d })), |
| 1014 | Effect.catch(() => |
| 1015 | Effect.succeed({ ok: false as const, manifest: null, versionNegotiation: null }), |
| 1016 | ), |
| 1017 | Effect.withSpan("mcp.plugin.discover_tools"), |
| 1018 | ); |
| 1019 | |
| 1020 | if (result.ok && result.manifest) { |
| 1021 | return { |
| 1022 | connected: true, |
| 1023 | requiresAuthentication: false, |
| 1024 | requiresOAuth: false, |
| 1025 | supportsDynamicRegistration: false, |
| 1026 | name: result.manifest.server?.name ?? name, |
| 1027 | slug, |
| 1028 | toolCount: result.manifest.tools.length, |
| 1029 | serverName: result.manifest.server?.name ?? null, |
| 1030 | instructions: result.manifest.server?.instructions ?? null, |
| 1031 | ...(result.versionNegotiation === "legacy" |
| 1032 | ? { versionNegotiation: "legacy" as const } |
| 1033 | : {}), |
| 1034 | } satisfies McpProbeResult; |
| 1035 | } |
| 1036 | |
| 1037 | // Confirm the endpoint actually speaks MCP before classifying it as |
| 1038 | // OAuth-protected (an OAuth-protected non-MCP service would |
| 1039 | // otherwise be misclassified). |
| 1040 | const shape = yield* probeMcpEndpointShape(trimmed, { |
| 1041 | httpClientLayer, |
| 1042 | headers: probeHeaders, |
| 1043 | queryParams: probeQueryParams, |
nothing calls this directly
no test coverage detected