| 284 | } |
| 285 | |
| 286 | export const invokeMcpTool = ( |
| 287 | input: InvokeMcpToolInput, |
| 288 | ): Effect.Effect< |
| 289 | unknown, |
| 290 | McpConnectionError | McpInvocationError | McpOAuthReauthorizationRequired |
| 291 | > => |
| 292 | Effect.gen(function* () { |
| 293 | const args = argsRecord(input.args); |
| 294 | const use = (connection: McpConnection) => |
| 295 | useConnection(connection, input.toolName, args, input.elicit, input.onToolListChanged); |
| 296 | |
| 297 | if (input.connectionPool && input.connectionPoolKey) { |
| 298 | return yield* input.connectionPool.withConnection( |
| 299 | input.connectionPoolKey, |
| 300 | input.connector.pipe( |
| 301 | Effect.withSpan("plugin.mcp.connection.acquire", { |
| 302 | attributes: { "plugin.mcp.transport": input.transport }, |
| 303 | }), |
| 304 | ), |
| 305 | use, |
| 306 | ); |
| 307 | } |
| 308 | |
| 309 | const connection = yield* Effect.acquireRelease( |
| 310 | input.connector.pipe( |
| 311 | Effect.withSpan("plugin.mcp.connection.acquire", { |
| 312 | attributes: { "plugin.mcp.transport": input.transport }, |
| 313 | }), |
| 314 | ), |
| 315 | (conn) => |
| 316 | Effect.ignore( |
| 317 | Effect.tryPromise({ |
| 318 | try: () => conn.close(), |
| 319 | catch: () => |
| 320 | new McpConnectionError({ |
| 321 | transport: input.transport, |
| 322 | message: "Failed to close MCP connection", |
| 323 | }), |
| 324 | }), |
| 325 | ), |
| 326 | ); |
| 327 | |
| 328 | return yield* use(connection); |
| 329 | }).pipe( |
| 330 | Effect.scoped, |
| 331 | Effect.withSpan("plugin.mcp.invoke", { |
| 332 | attributes: { |
| 333 | "mcp.tool.name": input.toolName, |
| 334 | "plugin.mcp.tool_id": input.toolId, |
| 335 | "plugin.mcp.transport": input.transport, |
| 336 | }, |
| 337 | }), |
| 338 | ); |