@onivoro/server-mcp-llm-adapter 24.38.2 → 25.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,8 +10,8 @@ npm install @onivoro/server-mcp-llm-adapter
10
10
 
11
11
  ### Peer dependencies
12
12
 
13
- | Package | Version |
14
- |---------|---------|
13
+ | Package | Version |
14
+ | ---------------- | ---------------------- |
15
15
  | `@nestjs/common` | `^10.0.0 \|\| ^11.0.0` |
16
16
 
17
17
  `@onivoro/server-mcp` is a hard dependency — installed automatically.
@@ -20,27 +20,27 @@ npm install @onivoro/server-mcp-llm-adapter
20
20
 
21
21
  Configs map to **the API you are calling**, not the model or hosting platform. A model hosted on AWS Bedrock can be called through different APIs, each with its own tool format.
22
22
 
23
- | API you are calling | Config | Module method |
24
- |---------------------|--------|---------------|
25
- | AWS Bedrock **Converse / ConverseStream** | `BEDROCK_CONVERSE_CONFIG` | `forBedrockConverse()` |
26
- | AWS Bedrock **Mantle** (Anthropic Messages format) | `BEDROCK_MANTLE_CONFIG` | `forBedrockMantle()` |
27
- | AWS Bedrock **OpenAI-compatible** | `BEDROCK_OPENAI_CONFIG` | `forBedrockOpenAi()` |
28
- | OpenAI **Chat Completions** (also xAI, Groq, Together) | `OPENAI_CONFIG` | `forOpenAi()` |
29
- | Anthropic **Messages** | `CLAUDE_CONFIG` | `forClaude()` |
30
- | Google **Gemini** | `GEMINI_CONFIG` | `forGemini()` |
31
- | Mistral **La Plateforme** | `MISTRAL_CONFIG` | `forMistral()` |
23
+ | API you are calling | Config | Module method |
24
+ | ------------------------------------------------------ | ------------------------- | ---------------------- |
25
+ | AWS Bedrock **Converse / ConverseStream** | `BEDROCK_CONVERSE_CONFIG` | `forBedrockConverse()` |
26
+ | AWS Bedrock **Mantle** (Anthropic Messages format) | `BEDROCK_MANTLE_CONFIG` | `forBedrockMantle()` |
27
+ | AWS Bedrock **OpenAI-compatible** | `BEDROCK_OPENAI_CONFIG` | `forBedrockOpenAi()` |
28
+ | OpenAI **Chat Completions** (also xAI, Groq, Together) | `OPENAI_CONFIG` | `forOpenAi()` |
29
+ | Anthropic **Messages** | `CLAUDE_CONFIG` | `forClaude()` |
30
+ | Google **Gemini** | `GEMINI_CONFIG` | `forGemini()` |
31
+ | Mistral **La Plateforme** | `MISTRAL_CONFIG` | `forMistral()` |
32
32
 
33
33
  ### Bedrock examples
34
34
 
35
35
  Bedrock exposes multiple API surfaces. Each has its own tool format — pick the config that matches the API you are calling:
36
36
 
37
- | Scenario | Config |
38
- |----------|--------|
37
+ | Scenario | Config |
38
+ | --------------------------------------------------- | ------------------------- |
39
39
  | Any model via Bedrock **Converse / ConverseStream** | `BEDROCK_CONVERSE_CONFIG` |
40
- | Bedrock **Mantle** (Anthropic Messages format) | `BEDROCK_MANTLE_CONFIG` |
41
- | Bedrock **OpenAI-compatible** endpoint | `BEDROCK_OPENAI_CONFIG` |
42
- | Claude on Bedrock via **InvokeModel** | `CLAUDE_CONFIG` |
43
- | Mistral on Bedrock via **InvokeModel** | `MISTRAL_CONFIG` |
40
+ | Bedrock **Mantle** (Anthropic Messages format) | `BEDROCK_MANTLE_CONFIG` |
41
+ | Bedrock **OpenAI-compatible** endpoint | `BEDROCK_OPENAI_CONFIG` |
42
+ | Claude on Bedrock via **InvokeModel** | `CLAUDE_CONFIG` |
43
+ | Mistral on Bedrock via **InvokeModel** | `MISTRAL_CONFIG` |
44
44
 
45
45
  Mantle and Converse are mutually exclusive access paths — never mix them. `BEDROCK_MANTLE_CONFIG` uses the Anthropic Messages tool format (`input_schema`) while `BEDROCK_CONVERSE_CONFIG` uses the Converse `toolSpec` envelope. Similarly, `BEDROCK_OPENAI_CONFIG` uses the OpenAI function-calling format independently from `OPENAI_CONFIG` — each has its own alias key for per-provider name overrides.
46
46
 
@@ -48,7 +48,7 @@ The same principle applies outside Bedrock — pick the config that matches the
48
48
 
49
49
  ## Usage
50
50
 
51
- Import `McpLlmAdapterModule` alongside whichever MCP module provides the tool registry:
51
+ `McpLlmAdapterModule.forProvider()` (and every `for*()` shortcut) imports `McpRegistryModule.registerOnly()` itself and injects that module's `McpToolRegistry`. Listing `McpRegistryModule.registerOnly()` in your own imports as well, as below, resolves to the same module:
52
52
 
53
53
  ```typescript
54
54
  import { Module } from '@nestjs/common';
@@ -58,15 +58,14 @@ import { EmojiToolService } from './services/emoji-tool.service';
58
58
  import { ChatService } from './services/chat.service';
59
59
 
60
60
  @Module({
61
- imports: [
62
- McpRegistryModule.registerOnly(),
63
- McpLlmAdapterModule.forBedrockConverse(),
64
- ],
61
+ imports: [McpRegistryModule.registerOnly(), McpLlmAdapterModule.forBedrockConverse()],
65
62
  providers: [EmojiToolService, ChatService],
66
63
  })
67
64
  export class AppModule {}
68
65
  ```
69
66
 
67
+ If the same app also imports `McpHttpModule` or `McpStdioModule`, those modules have their own `McpToolRegistry` instance. Tools are discovered into both, but an `authStrategy` or interceptors registered on the transport's registry do not apply to calls made through the adapter.
68
+
70
69
  Then inject `McpLlmToolAdapter` wherever you need provider-specific functionality:
71
70
 
72
71
  ```typescript
@@ -84,10 +83,7 @@ export class ChatService {
84
83
  // ... call the LLM provider with tools ...
85
84
 
86
85
  // When the provider returns a tool call:
87
- const result = await this.adapter.executeToolForProvider(
88
- toolCall.name,
89
- toolCall.input,
90
- );
86
+ const result = await this.adapter.executeToolForProvider(toolCall.name, toolCall.input);
91
87
  }
92
88
  }
93
89
  ```
@@ -101,10 +97,10 @@ LLM providers can return multiple tool calls in a single turn — OpenAI returns
101
97
  ```typescript
102
98
  // LLM returned multiple tool calls in one turn
103
99
  const results = await this.adapter.executeToolsForProvider(
104
- toolCalls.map(tc => ({
100
+ toolCalls.map((tc) => ({
105
101
  providerName: tc.name,
106
102
  params: tc.input,
107
- id: tc.id, // OpenAI tool_call.id, Claude tool_use.id, Bedrock toolUseId
103
+ id: tc.id, // OpenAI tool_call.id, Claude tool_use.id, Bedrock toolUseId
108
104
  })),
109
105
  authInfo,
110
106
  );
@@ -119,7 +115,7 @@ for (const r of results) {
119
115
  }
120
116
  ```
121
117
 
122
- Each tool call goes through the full `@onivoro/server-mcp` execution pipeline independently (guards, validation, interceptors, handler) via `registry.executeToolRaw()`. The core MCP library is unchanged — the batch coordination lives entirely in the adapter.
118
+ Each tool call goes through the full `@onivoro/server-mcp` execution pipeline independently (auth strategy, guards, validation, interceptors, handler) via `registry.executeToolRaw()`. Non-string results are `JSON.stringify`-ed. An unknown provider name, a thrown error, a result the tool marked `isError: true`, or a tool asking for user input with `inputRequired(...)` (which needs an MCP client to answer it) becomes `{ success: false, error: message }` for that call only. For an `isError` result, `message` is the result's text content (or `Tool execution failed` when it has none). Error messages are passed on as thrown: unlike an MCP transport, the adapter runs in your process, so it does not hide them. The core MCP library is unchanged — the batch coordination lives entirely in the adapter.
123
119
 
124
120
  ## Output schemas
125
121
 
@@ -142,11 +138,16 @@ For custom providers that support per-tool output schemas, use `formatToolWithOu
142
138
  const MY_CONFIG: LlmAdapterConfig<MyToolDef> = {
143
139
  aliasKey: 'myProvider',
144
140
  formatTool: (name, description, inputSchema) => ({
145
- name, description, inputSchema,
141
+ name,
142
+ description,
143
+ inputSchema,
146
144
  }),
147
145
  // Called instead of formatTool when the tool has an outputSchema
148
146
  formatToolWithOutput: (name, description, inputSchema, outputSchema) => ({
149
- name, description, inputSchema, outputSchema,
147
+ name,
148
+ description,
149
+ inputSchema,
150
+ outputSchema,
150
151
  }),
151
152
  };
152
153
  ```
@@ -181,72 +182,112 @@ McpLlmAdapterModule.forProvider(MY_CONFIG);
181
182
 
182
183
  ## McpLlmToolAdapter API
183
184
 
184
- | Method | Description |
185
- |--------|-------------|
186
- | `toProviderTools()` | Returns `T[]` — tool definitions in the provider's format |
187
- | `getOutputSchemas()` | Returns `Map<string, Record<string, unknown>>` — provider tool names to output JSON Schemas (only tools with `outputSchema`) |
188
- | `resolveProviderToolName(providerName)` | Maps a provider-specific tool name back to the MCP tool name, or `undefined` |
189
- | `executeToolForProvider(providerName, params, authInfo?)` | Resolves name, executes tool, returns stringified result |
190
- | `executeToolCallForProvider(toolCall, authInfo?)` | Executes a single `ProviderToolCall`, returns `ProviderToolCallResult` with id passthrough |
191
- | `executeToolsForProvider(toolCalls, authInfo?)` | Executes multiple tool calls in parallel. Returns `ProviderToolCallResult[]` with per-call success/error |
185
+ | Method | Description |
186
+ | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
187
+ | `toProviderTools()` | Returns `T[]` — tool definitions in the provider's format |
188
+ | `getOutputSchemas()` | Returns `Map<string, Record<string, unknown>>` — provider tool names to output JSON Schemas (only tools with `outputSchema`) |
189
+ | `resolveProviderToolName(providerName)` | Maps a provider-specific tool name back to the MCP tool name, or `undefined` |
190
+ | `executeToolForProvider(providerName, params, authInfo?, extra?)` | Resolves name, executes tool, returns stringified result. Throws if the name is unknown, the tool throws, or it returns `isError: true` or `inputRequired(...)` |
191
+ | `executeToolCallForProvider(toolCall, authInfo?, extra?)` | Executes a single `ProviderToolCall`, returns `ProviderToolCallResult` with id passthrough (never throws) |
192
+ | `executeToolsForProvider(toolCalls, authInfo?, extra?)` | Executes multiple tool calls in parallel. Returns `ProviderToolCallResult[]` with per-call success/error |
193
+
194
+ The provider-name map is cached and rebuilt when the registry reports a registration change.
195
+
196
+ ### Execution context (`extra`)
197
+
198
+ Every execute method takes an optional `McpToolExecutionExtra`, forwarded to the tool as part of its `McpToolContext`:
199
+
200
+ ```typescript
201
+ import type { McpToolExecutionExtra } from '@onivoro/server-mcp-llm-adapter';
202
+
203
+ const controller = new AbortController();
204
+ const extra: McpToolExecutionExtra = {
205
+ sessionId: conversationId,
206
+ signal: controller.signal, // the tool sees context.signal and can stop when the turn is cancelled
207
+ sendProgress: async (progress, total, message) => emitProgress({ progress, total, message }),
208
+ sendLog: async (level, data) => logger.log({ level, data }),
209
+ };
210
+
211
+ const results = await this.adapter.executeToolsForProvider(calls, authInfo, extra);
212
+ ```
192
213
 
193
214
  ## Name handling
194
215
 
195
- Each config has an `aliasKey` (e.g., `'bedrock'`, `'bedrock-mantle'`, `'bedrock-openai'`, `'openai'`) used to look up per-provider name overrides from the `@McpTool` decorator's `aliases` parameter.
216
+ Each config has an `aliasKey` used to look up per-provider name overrides from the `@McpTool` decorator's `aliases` parameter:
217
+
218
+ | Config | `aliasKey` | Sanitizer |
219
+ | ------------------------- | -------------------- | ----------------------------------- |
220
+ | `BEDROCK_CONVERSE_CONFIG` | `'bedrock-converse'` | non `[a-zA-Z0-9_]` characters → `_` |
221
+ | `BEDROCK_MANTLE_CONFIG` | `'bedrock-mantle'` | none |
222
+ | `BEDROCK_OPENAI_CONFIG` | `'bedrock-openai'` | none |
223
+ | `OPENAI_CONFIG` | `'openai'` | none |
224
+ | `CLAUDE_CONFIG` | `'claude'` | none |
225
+ | `GEMINI_CONFIG` | `'gemini'` | non `[a-zA-Z0-9_]` characters → `_` |
226
+ | `MISTRAL_CONFIG` | `'mistral'` | none |
196
227
 
197
228
  Resolution order:
229
+
198
230
  1. **Explicit alias** — `aliases[aliasKey]` if present
199
231
  2. **Sanitized name** — `sanitizeName(mcpName)` if the config defines a sanitizer
200
232
  3. **MCP name as-is** — used directly when no alias or sanitizer applies
201
233
 
202
234
  ```typescript
203
235
  // Explicit alias for Bedrock Converse
204
- @McpTool({ name: 'insert-emojis', description: 'Insert emojis', schema, aliases: { bedrock: 'insertEmojis' } })
236
+ @McpTool({ name: 'insert-emojis', description: 'Insert emojis', schema, aliases: { 'bedrock-converse': 'insertEmojis' } })
205
237
 
206
238
  // No alias needed for OpenAI (hyphens are valid)
207
239
  @McpTool({ name: 'insert-emojis', description: 'Insert emojis', schema })
208
240
  ```
209
241
 
210
- Providers that require name sanitization (Bedrock Converse, Gemini) apply it automatically — hyphens are replaced with underscores.
242
+ Providers that require name sanitization (Bedrock Converse, Gemini) apply it automatically — every character outside `[a-zA-Z0-9_]` (hyphens, dots, and so on) becomes an underscore. An alias is used as-is, without sanitizing.
243
+
244
+ `resolveProviderName(metadata, config)` applies this same resolution and is exported for custom code:
245
+
246
+ ```typescript
247
+ import { resolveProviderName, GEMINI_CONFIG } from '@onivoro/server-mcp-llm-adapter';
248
+
249
+ resolveProviderName({ name: 'insert-emojis', description: 'Insert emojis' }, GEMINI_CONFIG); // 'insert_emojis'
250
+ ```
211
251
 
212
252
  ## Exports
213
253
 
214
254
  ```typescript
215
255
  // Module
216
- McpLlmAdapterModule // NestJS module — forProvider(), forBedrockConverse(), forBedrockMantle(), forBedrockOpenAi(), forOpenAi(), forClaude(), forGemini(), forMistral()
256
+ McpLlmAdapterModule; // NestJS module — forProvider(), forBedrockConverse(), forBedrockMantle(), forBedrockOpenAi(), forOpenAi(), forClaude(), forGemini(), forMistral()
217
257
 
218
258
  // Adapter
219
- McpLlmToolAdapter // Injectable — toProviderTools(), getOutputSchemas(), resolveProviderToolName(), executeToolForProvider(), executeToolCallForProvider(), executeToolsForProvider()
220
- ProviderToolCall // Input type for single/batch execution — { providerName, params, id? }
221
- ProviderToolCallResult // Output type for single/batch execution — { providerName, id?, result?, error?, success }
259
+ McpLlmToolAdapter; // Injectable — toProviderTools(), getOutputSchemas(), resolveProviderToolName(), executeToolForProvider(), executeToolCallForProvider(), executeToolsForProvider()
260
+ ProviderToolCall; // Input type for single/batch execution — { providerName, params, id? }
261
+ ProviderToolCallResult; // Output type for single/batch execution — { providerName, id?, result?, error?, success }
262
+ McpToolExecutionExtra; // Optional execution context — { sessionId?, signal?, sendProgress?, sendLog? }
222
263
 
223
264
  // Config
224
- LlmAdapterConfig // Interface for custom provider configs
225
- LLM_ADAPTER_CONFIG // Injection token
226
- resolveProviderName // Utility: resolves provider name from metadata + config
265
+ LlmAdapterConfig; // Interface for custom provider configs
266
+ LLM_ADAPTER_CONFIG; // Injection token
267
+ resolveProviderName; // Utility: resolves provider name from metadata + config
227
268
 
228
269
  // Prebuilt configs
229
- BEDROCK_CONVERSE_CONFIG // AWS Bedrock Converse API
230
- BEDROCK_MANTLE_CONFIG // AWS Bedrock Mantle (Anthropic Messages format)
231
- BEDROCK_OPENAI_CONFIG // AWS Bedrock OpenAI-compatible endpoint
232
- OPENAI_CONFIG // OpenAI Chat Completions API
233
- CLAUDE_CONFIG // Anthropic Messages API
234
- GEMINI_CONFIG // Google Gemini API
235
- MISTRAL_CONFIG // Mistral La Plateforme API
270
+ BEDROCK_CONVERSE_CONFIG; // AWS Bedrock Converse API
271
+ BEDROCK_MANTLE_CONFIG; // AWS Bedrock Mantle (Anthropic Messages format)
272
+ BEDROCK_OPENAI_CONFIG; // AWS Bedrock OpenAI-compatible endpoint
273
+ OPENAI_CONFIG; // OpenAI Chat Completions API
274
+ CLAUDE_CONFIG; // Anthropic Messages API
275
+ GEMINI_CONFIG; // Google Gemini API
276
+ MISTRAL_CONFIG; // Mistral La Plateforme API
236
277
 
237
278
  // Shared formatters (used internally by prebuilt configs, also available for custom configs)
238
- formatAnthropicTool // Anthropic Messages format — { name, description, input_schema }
239
- formatOpenAiTool // OpenAI function format — { type: 'function', function: { name, description, parameters } }
279
+ formatAnthropicTool; // Anthropic Messages format — { name, description, input_schema }
280
+ formatOpenAiTool; // OpenAI function format — { type: 'function', function: { name, description, parameters } }
240
281
 
241
282
  // Types
242
- BedrockConverseToolDefinition // { toolSpec: { name, description, inputSchema: { json } } }
243
- OpenAiToolDefinition // { type: 'function', function: { name, description, parameters } }
244
- ClaudeToolDefinition // { name, description, input_schema }
245
- GeminiToolDefinition // { name, description, parameters }
283
+ BedrockConverseToolDefinition; // { toolSpec: { name, description, inputSchema: { json } } }
284
+ OpenAiToolDefinition; // { type: 'function', function: { name, description, parameters } }
285
+ ClaudeToolDefinition; // { name, description, input_schema }
286
+ GeminiToolDefinition; // { name, description, parameters }
246
287
  ```
247
288
 
248
289
  ## Related libraries
249
290
 
250
- | Library | Purpose |
251
- |---------|---------|
291
+ | Library | Purpose |
292
+ | -------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
252
293
  | [`@onivoro/server-mcp`](https://www.npmjs.com/package/@onivoro/server-mcp) | Transport-agnostic MCP tool registry, decorators, HTTP and stdio transports |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onivoro/server-mcp-llm-adapter",
3
- "version": "24.38.2",
3
+ "version": "25.0.2",
4
4
  "description": "LLM provider tool format adapter for MCP — supports OpenAI, Claude, Bedrock, Gemini, and Mistral",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -31,7 +31,7 @@
31
31
  "adapter"
32
32
  ],
33
33
  "dependencies": {
34
- "@onivoro/server-mcp": "^24.38.2",
34
+ "@onivoro/server-mcp": "^25.0.2",
35
35
  "tslib": "^2.3.0"
36
36
  },
37
37
  "peerDependencies": {
package/src/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { McpLlmToolAdapter } from './lib/mcp-llm-tool-adapter';
1
+ export { McpLlmToolAdapter, McpToolExecutionExtra, } from './lib/mcp-llm-tool-adapter';
2
2
  export { ProviderToolCall } from './lib/provider-tool-call';
3
3
  export { ProviderToolCallResult } from './lib/provider-tool-call-result';
4
4
  export { McpLlmAdapterModule } from './lib/mcp-llm-adapter.module';
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/server/mcp-llm-adapter/src/index.ts"],"names":[],"mappings":";;;AAAA,mEAA+D;AAAtD,yHAAA,iBAAiB,OAAA;AAG1B,uEAAmE;AAA1D,6HAAA,mBAAmB,OAAA;AAC5B,2EAAoE;AAA3D,8HAAA,kBAAkB,OAAA;AAE3B,qEAAkE;AAAzD,4HAAA,mBAAmB,OAAA;AAE5B,yEAAwE;AAA/D,kIAAA,uBAAuB,OAAA;AAEhC,qDAAoD;AAA3C,8GAAA,aAAa,OAAA;AAEtB,qDAAoD;AAA3C,8GAAA,aAAa,OAAA;AAEtB,qDAAoD;AAA3C,8GAAA,aAAa,OAAA;AACtB,uDAAsD;AAA7C,gHAAA,cAAc,OAAA;AACvB,qEAAoE;AAA3D,8HAAA,qBAAqB,OAAA;AAC9B,qEAAoE;AAA3D,8HAAA,qBAAqB,OAAA;AAC9B,qEAAkE;AAAzD,4HAAA,mBAAmB,OAAA;AAC5B,+DAA4D;AAAnD,sHAAA,gBAAgB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/server/mcp-llm-adapter/src/index.ts"],"names":[],"mappings":";;;AAAA,mEAGoC;AAFlC,yHAAA,iBAAiB,OAAA;AAKnB,uEAAmE;AAA1D,6HAAA,mBAAmB,OAAA;AAC5B,2EAAoE;AAA3D,8HAAA,kBAAkB,OAAA;AAE3B,qEAAkE;AAAzD,4HAAA,mBAAmB,OAAA;AAE5B,yEAAwE;AAA/D,kIAAA,uBAAuB,OAAA;AAEhC,qDAAoD;AAA3C,8GAAA,aAAa,OAAA;AAEtB,qDAAoD;AAA3C,8GAAA,aAAa,OAAA;AAEtB,qDAAoD;AAA3C,8GAAA,aAAa,OAAA;AACtB,uDAAsD;AAA7C,gHAAA,cAAc,OAAA;AACvB,qEAAoE;AAA3D,8HAAA,qBAAqB,OAAA;AAC9B,qEAAoE;AAA3D,8HAAA,qBAAqB,OAAA;AAC9B,qEAAkE;AAAzD,4HAAA,mBAAmB,OAAA;AAC5B,+DAA4D;AAAnD,sHAAA,gBAAgB,OAAA"}
@@ -3,6 +3,12 @@ import { McpToolRegistry, McpAuthInfo } from '@onivoro/server-mcp';
3
3
  import type { LlmAdapterConfig } from './llm-adapter-config';
4
4
  import type { ProviderToolCall } from './provider-tool-call';
5
5
  import type { ProviderToolCallResult } from './provider-tool-call-result';
6
+ export type McpToolExecutionExtra = {
7
+ sessionId?: string;
8
+ signal?: AbortSignal;
9
+ sendProgress?: (progress: number, total?: number, message?: string) => Promise<void>;
10
+ sendLog?: (level: any, data: unknown, logger?: string) => Promise<void>;
11
+ };
6
12
  export declare class McpLlmToolAdapter<T = unknown> implements OnModuleInit {
7
13
  private readonly registry;
8
14
  private readonly config;
@@ -14,8 +20,8 @@ export declare class McpLlmToolAdapter<T = unknown> implements OnModuleInit {
14
20
  toProviderTools(): T[];
15
21
  getOutputSchemas(): Map<string, Record<string, unknown>>;
16
22
  resolveProviderToolName(providerName: string): string | undefined;
17
- executeToolForProvider(providerName: string, params: Record<string, unknown>, authInfo?: McpAuthInfo): Promise<string>;
18
- executeToolCallForProvider(toolCall: ProviderToolCall, authInfo?: McpAuthInfo): Promise<ProviderToolCallResult>;
19
- executeToolsForProvider(toolCalls: ProviderToolCall[], authInfo?: McpAuthInfo): Promise<ProviderToolCallResult[]>;
23
+ executeToolForProvider(providerName: string, params: Record<string, unknown>, authInfo?: McpAuthInfo, extra?: McpToolExecutionExtra): Promise<string>;
24
+ executeToolCallForProvider(toolCall: ProviderToolCall, authInfo?: McpAuthInfo, extra?: McpToolExecutionExtra): Promise<ProviderToolCallResult>;
25
+ executeToolsForProvider(toolCalls: ProviderToolCall[], authInfo?: McpAuthInfo, extra?: McpToolExecutionExtra): Promise<ProviderToolCallResult[]>;
20
26
  }
21
27
  //# sourceMappingURL=mcp-llm-tool-adapter.d.ts.map
@@ -54,28 +54,39 @@ let McpLlmToolAdapter = class McpLlmToolAdapter {
54
54
  resolveProviderToolName(providerName) {
55
55
  return this.getNameMap().get(providerName);
56
56
  }
57
- async executeToolForProvider(providerName, params, authInfo) {
57
+ async executeToolForProvider(providerName, params, authInfo, extra) {
58
58
  const mcpName = this.getNameMap().get(providerName);
59
59
  if (!mcpName) {
60
60
  throw new Error(`No MCP tool found for provider name "${providerName}".`);
61
61
  }
62
- const result = await this.registry.executeToolRaw(mcpName, params, authInfo);
62
+ const result = await this.registry.executeToolRaw(mcpName, params, authInfo, extra);
63
+ const errorText = toolErrorText(result);
64
+ if (errorText !== undefined)
65
+ throw new Error(errorText);
63
66
  return typeof result === 'string' ? result : JSON.stringify(result);
64
67
  }
65
- async executeToolCallForProvider(toolCall, authInfo) {
66
- const [result] = await this.executeToolsForProvider([toolCall], authInfo);
68
+ async executeToolCallForProvider(toolCall, authInfo, extra) {
69
+ const [result] = await this.executeToolsForProvider([toolCall], authInfo, extra);
67
70
  return result;
68
71
  }
69
- async executeToolsForProvider(toolCalls, authInfo) {
72
+ async executeToolsForProvider(toolCalls, authInfo, extra) {
70
73
  const nameMap = this.getNameMap();
71
74
  const settled = await Promise.allSettled(toolCalls.map(async ({ providerName, params, id }) => {
72
75
  const mcpName = nameMap.get(providerName);
73
76
  if (!mcpName) {
74
77
  throw new Error(`No MCP tool found for provider name "${providerName}".`);
75
78
  }
76
- const rawResult = await this.registry.executeToolRaw(mcpName, params, authInfo);
79
+ const rawResult = await this.registry.executeToolRaw(mcpName, params, authInfo, extra);
80
+ const errorText = toolErrorText(rawResult);
81
+ if (errorText !== undefined)
82
+ throw new Error(errorText);
77
83
  const result = typeof rawResult === 'string' ? rawResult : JSON.stringify(rawResult);
78
- return { providerName, id, result, success: true };
84
+ return {
85
+ providerName,
86
+ id,
87
+ result,
88
+ success: true,
89
+ };
79
90
  }));
80
91
  return settled.map((outcome, i) => {
81
92
  if (outcome.status === 'fulfilled') {
@@ -85,7 +96,9 @@ let McpLlmToolAdapter = class McpLlmToolAdapter {
85
96
  return {
86
97
  providerName: call.providerName,
87
98
  id: call.id,
88
- error: outcome.reason instanceof Error ? outcome.reason.message : String(outcome.reason),
99
+ error: outcome.reason instanceof Error
100
+ ? outcome.reason.message
101
+ : String(outcome.reason),
89
102
  success: false,
90
103
  };
91
104
  });
@@ -97,4 +110,24 @@ exports.McpLlmToolAdapter = McpLlmToolAdapter = tslib_1.__decorate([
97
110
  tslib_1.__param(1, (0, common_1.Inject)(llm_adapter_config_token_1.LLM_ADAPTER_CONFIG)),
98
111
  tslib_1.__metadata("design:paramtypes", [server_mcp_1.McpToolRegistry, Object])
99
112
  ], McpLlmToolAdapter);
113
+ function toolErrorText(result) {
114
+ if (!!result &&
115
+ typeof result === 'object' &&
116
+ result.resultType === 'input_required') {
117
+ return 'The tool needs input from the user (inputRequired), which is only available to MCP clients.';
118
+ }
119
+ if (!result ||
120
+ typeof result !== 'object' ||
121
+ result.isError !== true) {
122
+ return undefined;
123
+ }
124
+ const content = result.content;
125
+ const text = Array.isArray(content)
126
+ ? content
127
+ .filter((block) => !!block && block.type === 'text' && typeof block.text === 'string')
128
+ .map((block) => block.text)
129
+ .join('\n')
130
+ : '';
131
+ return text || 'Tool execution failed';
132
+ }
100
133
  //# sourceMappingURL=mcp-llm-tool-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-llm-tool-adapter.js","sourceRoot":"","sources":["../../../../../../libs/server/mcp-llm-adapter/src/lib/mcp-llm-tool-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-llm-tool-adapter.js","sourceRoot":"","sources":["../../../../../../libs/server/mcp-llm-adapter/src/lib/mcp-llm-tool-adapter.ts"],"names":[],"mappings":"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"}