(envelope: JsonRpcEnvelope)
| 161 | }; |
| 162 | |
| 163 | const methodAttrs = (envelope: JsonRpcEnvelope): Record<string, unknown> => { |
| 164 | const params = envelope.params ?? {}; |
| 165 | return Match.value(envelope.method).pipe( |
| 166 | Match.when("initialize", () => |
| 167 | Option.match(decodeInitializeParams(params), { |
| 168 | onNone: () => ({}) as Record<string, unknown>, |
| 169 | onSome: (init) => ({ |
| 170 | ...(init.protocolVersion && { "mcp.client.protocol_version": init.protocolVersion }), |
| 171 | ...(init.clientInfo?.name && { "mcp.client.name": init.clientInfo.name }), |
| 172 | ...(init.clientInfo?.version && { "mcp.client.version": init.clientInfo.version }), |
| 173 | ...(init.clientInfo?.title && { "mcp.client.title": init.clientInfo.title }), |
| 174 | "mcp.client.capability.keys": Object.keys(init.capabilities ?? {}) |
| 175 | .sort() |
| 176 | .join(","), |
| 177 | }), |
| 178 | }), |
| 179 | ), |
| 180 | Match.when("tools/call", () => |
| 181 | Option.match(decodeNamedParams(params), { |
| 182 | onNone: () => ({}) as Record<string, unknown>, |
| 183 | onSome: ({ name, arguments: args }) => ({ |
| 184 | ...(name ? { "mcp.tool.name": name } : {}), |
| 185 | ...executeCodeAttrs(name, args), |
| 186 | }), |
| 187 | }), |
| 188 | ), |
| 189 | Match.whenOr("resources/read", "resources/subscribe", () => |
| 190 | Option.match(decodeUriParams(params), { |
| 191 | onNone: () => ({}) as Record<string, unknown>, |
| 192 | onSome: ({ uri }) => (uri ? { "mcp.resource.uri": uri } : {}), |
| 193 | }), |
| 194 | ), |
| 195 | Match.when("prompts/get", () => |
| 196 | Option.match(decodeNamedParams(params), { |
| 197 | onNone: () => ({}) as Record<string, unknown>, |
| 198 | onSome: ({ name }) => (name ? { "mcp.prompt.name": name } : {}), |
| 199 | }), |
| 200 | ), |
| 201 | Match.when("notifications/cancelled", () => |
| 202 | Option.match(decodeCancelledParams(params), { |
| 203 | onNone: () => ({}) as Record<string, unknown>, |
| 204 | onSome: ({ requestId, reason }) => ({ |
| 205 | ...(requestId !== undefined && { "mcp.rpc.cancelled_id": String(requestId) }), |
| 206 | ...(reason && { "mcp.rpc.cancelled_reason": reason }), |
| 207 | }), |
| 208 | }), |
| 209 | ), |
| 210 | Match.option, |
| 211 | Option.getOrElse(() => ({}) as Record<string, unknown>), |
| 212 | ); |
| 213 | }; |
| 214 | |
| 215 | const replyAttrs = (envelope: JsonRpcEnvelope): Record<string, unknown> => { |
| 216 | if (!envelope.result || envelope.method) return {}; |
no test coverage detected