Unified · Split
| @@ -1,4 +1,4 @@ | |||
| 1 | import { Schema } from "effect"; | 1 | import { Option, Schema } from "effect"; |
| 2 | 2 | ||
| 3 | import { McpToolAnnotations } from "./types"; | 3 | import { McpToolAnnotations } from "./types"; |
| 4 | 4 | ||
| @@ -51,7 +51,7 @@ const decodeListToolsResult = Schema.decodeUnknownOption(ListToolsResult); · 46 unmodified lines | |||
| 51 | const decodeServerInfo = Schema.decodeUnknownOption(ServerInfo); | 51 | const decodeServerInfo = Schema.decodeUnknownOption(ServerInfo); |
| 52 | 52 | ||
| 53 | export const isListToolsResult = (value: unknown): boolean => | 53 | export const isListToolsResult = (value: unknown): boolean => |
| 54 | decodeListToolsResult(value)._tag === "Some"; | 54 | Option.isSome(decodeListToolsResult(value)); |
| 55 | 55 | ||
| 56 | // --------------------------------------------------------------------------- | 56 | // --------------------------------------------------------------------------- |
| 57 | // Tool ID sanitization | 57 | // Tool ID sanitization |
| @@ -86,14 +86,19 @@ export const extractManifestFromListToolsResult = ( · 28 unmodified lines | |||
| 86 | ): McpToolManifest => { | 86 | ): McpToolManifest => { |
| 87 | const seen = new Map<string, number>(); | 87 | const seen = new Map<string, number>(); |
| 88 | 88 | ||
| 89 | const listed = decodeListToolsResult(listToolsResult).pipe((opt) => | 89 | const listed = decodeListToolsResult(listToolsResult).pipe( |
| 90 | opt._tag === "Some" ? opt.value.tools : [], | 90 | Option.map((result) => result.tools), |
| 91 | Option.getOrElse(() => []), | ||
| 91 | ); | 92 | ); |
| 92 | 93 | ||
| 93 | const server = decodeServerInfo(metadata?.serverInfo).pipe((opt): McpServerMetadata | null => | 94 | const server = decodeServerInfo(metadata?.serverInfo).pipe( |
| 94 | opt._tag === "Some" | 95 | Option.map( |
| 95 | ? { name: opt.value.name ?? null, version: opt.value.version ?? null } | 96 | (info): McpServerMetadata => ({ |
| 96 | : null, | 97 | name: info.name ?? null, |
| 98 | version: info.version ?? null, | ||
| 99 | }), | ||
| 100 | ), | ||
| 101 | Option.getOrNull, | ||
| 97 | ); | 102 | ); |
| 98 | 103 | ||
| 99 | const tools = listed.flatMap((tool): McpToolManifestEntry[] => { | 104 | const tools = listed.flatMap((tool): McpToolManifestEntry[] => { |
| @@ -126,11 +131,8 @@ const slugify = (value: string): string => · 26 unmodified lines | |||
| 126 | .replace(/^_+|_+$/g, ""); | 131 | .replace(/^_+|_+$/g, ""); |
| 127 | 132 | ||
| 128 | const hostnameOf = (url: string): string | null => { | 133 | const hostnameOf = (url: string): string | null => { |
| 129 | try { | 134 | if (!URL.canParse(url)) return null; |
| 130 | return new URL(url).hostname; | 135 | return new URL(url).hostname; |
| 131 | } catch { | ||
| 132 | return null; | ||
| 133 | } | ||
| 134 | }; | 136 | }; |
| 135 | 137 | ||
| 136 | const basenameOf = (path: string): string => path.trim().split(/[\\/]/).pop() ?? path.trim(); | 138 | const basenameOf = (path: string): string => path.trim().split(/[\\/]/).pop() ?? path.trim(); |