@onivoro/server-mcp-llm-adapter 24.34.0

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 ADDED
@@ -0,0 +1,242 @@
1
+ # @onivoro/server-mcp-llm-adapter
2
+
3
+ Generic adapter for [`@onivoro/server-mcp`](https://www.npmjs.com/package/@onivoro/server-mcp). Converts MCP tool registry entries to any LLM provider's tool definition format and provides a unified execution path. Ships with prebuilt configs for AWS Bedrock Converse, OpenAI, Anthropic, Google Gemini, and Mistral.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @onivoro/server-mcp-llm-adapter
9
+ ```
10
+
11
+ ### Peer dependencies
12
+
13
+ | Package | Version |
14
+ |---------|---------|
15
+ | `@nestjs/common` | `^10.0.0 \|\| ^11.0.0` |
16
+
17
+ `@onivoro/server-mcp` is a hard dependency — installed automatically.
18
+
19
+ ## Choosing the right config
20
+
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
+
23
+ | API you are calling | Config | Module method |
24
+ |---------------------|--------|---------------|
25
+ | AWS Bedrock **Converse / ConverseStream** | `BEDROCK_CONVERSE_CONFIG` | `forBedrockConverse()` |
26
+ | OpenAI **Chat Completions** (also xAI, Groq, Together) | `OPENAI_CONFIG` | `forOpenAi()` |
27
+ | Anthropic **Messages** | `CLAUDE_CONFIG` | `forClaude()` |
28
+ | Google **Gemini** | `GEMINI_CONFIG` | `forGemini()` |
29
+ | Mistral **La Plateforme** | `MISTRAL_CONFIG` | `forMistral()` |
30
+
31
+ ### Bedrock examples
32
+
33
+ If you use Bedrock's **Converse API**, all models (Claude, Mistral, Llama, etc.) share the same `toolSpec` envelope — use `BEDROCK_CONVERSE_CONFIG`.
34
+
35
+ If you use Bedrock's **InvokeModel API** (passing the raw request body), the tool format is model-specific:
36
+
37
+ | Scenario | Config |
38
+ |----------|--------|
39
+ | Any model via Bedrock **Converse** | `BEDROCK_CONVERSE_CONFIG` |
40
+ | Claude on Bedrock via **InvokeModel** | `CLAUDE_CONFIG` |
41
+ | Mistral on Bedrock via **InvokeModel** | `MISTRAL_CONFIG` |
42
+
43
+ The same principle applies outside Bedrock — pick the config that matches the API format, not where the model is hosted.
44
+
45
+ ## Usage
46
+
47
+ Import `LlmAdapterModule` alongside whichever MCP module provides the tool registry:
48
+
49
+ ```typescript
50
+ import { Module } from '@nestjs/common';
51
+ import { McpRegistryModule } from '@onivoro/server-mcp';
52
+ import { LlmAdapterModule } from '@onivoro/server-mcp-llm-adapter';
53
+ import { EmojiToolService } from './services/emoji-tool.service';
54
+ import { ChatService } from './services/chat.service';
55
+
56
+ @Module({
57
+ imports: [
58
+ McpRegistryModule.registerOnly(),
59
+ LlmAdapterModule.forBedrockConverse(),
60
+ ],
61
+ providers: [EmojiToolService, ChatService],
62
+ })
63
+ export class AppModule {}
64
+ ```
65
+
66
+ Then inject `LlmToolAdapter` wherever you need provider-specific functionality:
67
+
68
+ ```typescript
69
+ import { Injectable } from '@nestjs/common';
70
+ import { LlmToolAdapter } from '@onivoro/server-mcp-llm-adapter';
71
+
72
+ @Injectable()
73
+ export class ChatService {
74
+ constructor(private readonly adapter: LlmToolAdapter) {}
75
+
76
+ async chat(userMessage: string) {
77
+ // Build provider tool definitions from the registry
78
+ const tools = this.adapter.toProviderTools();
79
+
80
+ // ... call the LLM provider with tools ...
81
+
82
+ // When the provider returns a tool call:
83
+ const result = await this.adapter.executeToolForProvider(
84
+ toolCall.name,
85
+ toolCall.input,
86
+ );
87
+ }
88
+ }
89
+ ```
90
+
91
+ ## Batch execution
92
+
93
+ LLM providers can return multiple tool calls in a single turn — OpenAI returns an array of `tool_calls`, Claude returns multiple `tool_use` content blocks, Bedrock returns multiple `toolUse` entries. This is not an MCP spec concept (the MCP protocol's `tools/call` is always a single tool per request), but it's a universal pattern at the LLM API layer that this adapter sits in front of.
94
+
95
+ `executeToolsForProvider` handles the boilerplate: parallel execution via `Promise.allSettled`, independent per-call error handling (one failure doesn't block siblings), and `id` passthrough for the correlation every provider requires.
96
+
97
+ ```typescript
98
+ // LLM returned multiple tool calls in one turn
99
+ const results = await this.adapter.executeToolsForProvider(
100
+ toolCalls.map(tc => ({
101
+ providerName: tc.name,
102
+ params: tc.input,
103
+ id: tc.id, // OpenAI tool_call.id, Claude tool_use.id, Bedrock toolUseId
104
+ })),
105
+ authInfo,
106
+ );
107
+
108
+ // Build tool result messages for the next LLM turn
109
+ for (const r of results) {
110
+ messages.push({
111
+ role: 'tool',
112
+ tool_call_id: r.id,
113
+ content: r.success ? r.result : `Error: ${r.error}`,
114
+ });
115
+ }
116
+ ```
117
+
118
+ 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.
119
+
120
+ ## Output schemas
121
+
122
+ MCP tools can declare an `outputSchema` for structured result validation. No current LLM provider API supports per-tool output schemas in their tool definition format, so the built-in configs don't forward them. However, the adapter exposes them for consumers that need output schemas at the API call level (e.g., OpenAI `response_format`) or for custom result validation.
123
+
124
+ ```typescript
125
+ // Get output schemas for tools that define them
126
+ const outputSchemas = this.adapter.getOutputSchemas();
127
+ // Map<string, Record<string, unknown>> — provider tool name → JSON Schema
128
+
129
+ // Use with OpenAI response_format, your own validation, etc.
130
+ for (const [toolName, schema] of outputSchemas) {
131
+ console.log(`${toolName} returns:`, schema);
132
+ }
133
+ ```
134
+
135
+ For custom providers that support per-tool output schemas, use `formatToolWithOutput` in your config:
136
+
137
+ ```typescript
138
+ const MY_CONFIG: LlmAdapterConfig<MyToolDef> = {
139
+ aliasKey: 'myProvider',
140
+ formatTool: (name, description, inputSchema) => ({
141
+ name, description, inputSchema,
142
+ }),
143
+ // Called instead of formatTool when the tool has an outputSchema
144
+ formatToolWithOutput: (name, description, inputSchema, outputSchema) => ({
145
+ name, description, inputSchema, outputSchema,
146
+ }),
147
+ };
148
+ ```
149
+
150
+ When `formatToolWithOutput` is defined and the tool has an `outputSchema`, it is called instead of `formatTool`. Otherwise `formatTool` is used — existing configs are unaffected.
151
+
152
+ ## Custom providers
153
+
154
+ Use `LlmAdapterModule.forProvider()` with a custom config for any provider not included out of the box:
155
+
156
+ ```typescript
157
+ import { LlmAdapterModule, LlmAdapterConfig } from '@onivoro/server-mcp-llm-adapter';
158
+
159
+ interface MyToolDef {
160
+ name: string;
161
+ desc: string;
162
+ params: Record<string, unknown>;
163
+ }
164
+
165
+ const MY_CONFIG: LlmAdapterConfig<MyToolDef> = {
166
+ aliasKey: 'myProvider',
167
+ sanitizeName: (name) => name.toUpperCase(),
168
+ formatTool: (name, description, jsonSchema) => ({
169
+ name,
170
+ desc: description,
171
+ params: jsonSchema,
172
+ }),
173
+ };
174
+
175
+ LlmAdapterModule.forProvider(MY_CONFIG);
176
+ ```
177
+
178
+ ## LlmToolAdapter API
179
+
180
+ | Method | Description |
181
+ |--------|-------------|
182
+ | `toProviderTools()` | Returns `T[]` — tool definitions in the provider's format |
183
+ | `getOutputSchemas()` | Returns `Map<string, Record<string, unknown>>` — provider tool names to output JSON Schemas (only tools with `outputSchema`) |
184
+ | `resolveProviderToolName(providerName)` | Maps a provider-specific tool name back to the MCP tool name, or `undefined` |
185
+ | `executeToolForProvider(providerName, params, authInfo?)` | Resolves name, executes tool, returns stringified result |
186
+ | `executeToolCallForProvider(toolCall, authInfo?)` | Executes a single `ProviderToolCall`, returns `ProviderToolCallResult` with id passthrough |
187
+ | `executeToolsForProvider(toolCalls, authInfo?)` | Executes multiple tool calls in parallel. Returns `ProviderToolCallResult[]` with per-call success/error |
188
+
189
+ ## Name handling
190
+
191
+ Each config has an `aliasKey` (e.g., `'bedrock'`, `'openai'`) used to look up per-provider name overrides from the `@McpTool` decorator's `aliases` parameter.
192
+
193
+ Resolution order:
194
+ 1. **Explicit alias** — `aliases[aliasKey]` if present
195
+ 2. **Sanitized name** — `sanitizeName(mcpName)` if the config defines a sanitizer
196
+ 3. **MCP name as-is** — used directly when no alias or sanitizer applies
197
+
198
+ ```typescript
199
+ // Explicit alias for Bedrock Converse
200
+ @McpTool('insert-emojis', 'Insert emojis', schema, { bedrock: 'insertEmojis' })
201
+
202
+ // No alias needed for OpenAI (hyphens are valid)
203
+ @McpTool('insert-emojis', 'Insert emojis', schema)
204
+ ```
205
+
206
+ Providers that require name sanitization (Bedrock Converse, Gemini) apply it automatically — hyphens are replaced with underscores.
207
+
208
+ ## Exports
209
+
210
+ ```typescript
211
+ // Module
212
+ LlmAdapterModule // NestJS module — forProvider(), forBedrockConverse(), forOpenAi(), forClaude(), forGemini(), forMistral()
213
+
214
+ // Adapter
215
+ LlmToolAdapter // Injectable — toProviderTools(), getOutputSchemas(), resolveProviderToolName(), executeToolForProvider(), executeToolCallForProvider(), executeToolsForProvider()
216
+ ProviderToolCall // Input type for single/batch execution — { providerName, params, id? }
217
+ ProviderToolCallResult // Output type for single/batch execution — { providerName, id?, result?, error?, success }
218
+
219
+ // Config
220
+ LlmAdapterConfig // Interface for custom provider configs
221
+ LLM_ADAPTER_CONFIG // Injection token
222
+ resolveProviderName // Utility: resolves provider name from metadata + config
223
+
224
+ // Prebuilt configs
225
+ BEDROCK_CONVERSE_CONFIG // AWS Bedrock Converse API
226
+ OPENAI_CONFIG // OpenAI Chat Completions API
227
+ CLAUDE_CONFIG // Anthropic Messages API
228
+ GEMINI_CONFIG // Google Gemini API
229
+ MISTRAL_CONFIG // Mistral La Plateforme API
230
+
231
+ // Types
232
+ BedrockConverseToolDefinition // { toolSpec: { name, description, inputSchema: { json } } }
233
+ OpenAiToolDefinition // { type: 'function', function: { name, description, parameters } }
234
+ ClaudeToolDefinition // { name, description, input_schema }
235
+ GeminiToolDefinition // { name, description, parameters }
236
+ ```
237
+
238
+ ## Related libraries
239
+
240
+ | Library | Purpose |
241
+ |---------|---------|
242
+ | [`@onivoro/server-mcp`](https://www.npmjs.com/package/@onivoro/server-mcp) | Transport-agnostic MCP tool registry, decorators, HTTP and stdio transports |
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@onivoro/server-mcp-llm-adapter",
3
+ "version": "24.34.0",
4
+ "license": "MIT",
5
+ "type": "commonjs",
6
+ "main": "./src/index.js",
7
+ "types": "./src/index.d.ts",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/onivoro/monorepo.git"
11
+ },
12
+ "dependencies": {
13
+ "@onivoro/server-mcp": "^24.34.0",
14
+ "tslib": "^2.3.0"
15
+ },
16
+ "peerDependencies": {
17
+ "@nestjs/common": "^10.0.0 || ^11.0.0"
18
+ },
19
+ "files": [
20
+ "**/*.js",
21
+ "**/*.d.ts",
22
+ "**/*.js.map",
23
+ "README.md"
24
+ ]
25
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { LlmToolAdapter, ProviderToolCall, ProviderToolCallResult } from './lib/llm-tool-adapter';
2
+ export { LlmAdapterModule } from './lib/llm-adapter.module';
3
+ export { LlmAdapterConfig, LLM_ADAPTER_CONFIG, resolveProviderName, } from './lib/llm-adapter.config';
4
+ export { BEDROCK_CONVERSE_CONFIG, BedrockConverseToolDefinition, OPENAI_CONFIG, OpenAiToolDefinition, CLAUDE_CONFIG, ClaudeToolDefinition, GEMINI_CONFIG, GeminiToolDefinition, MISTRAL_CONFIG, } from './lib/provider-configs';
5
+ //# sourceMappingURL=index.d.ts.map
package/src/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MISTRAL_CONFIG = exports.GEMINI_CONFIG = exports.CLAUDE_CONFIG = exports.OPENAI_CONFIG = exports.BEDROCK_CONVERSE_CONFIG = exports.resolveProviderName = exports.LLM_ADAPTER_CONFIG = exports.LlmAdapterModule = exports.LlmToolAdapter = void 0;
4
+ var llm_tool_adapter_1 = require("./lib/llm-tool-adapter");
5
+ Object.defineProperty(exports, "LlmToolAdapter", { enumerable: true, get: function () { return llm_tool_adapter_1.LlmToolAdapter; } });
6
+ var llm_adapter_module_1 = require("./lib/llm-adapter.module");
7
+ Object.defineProperty(exports, "LlmAdapterModule", { enumerable: true, get: function () { return llm_adapter_module_1.LlmAdapterModule; } });
8
+ var llm_adapter_config_1 = require("./lib/llm-adapter.config");
9
+ Object.defineProperty(exports, "LLM_ADAPTER_CONFIG", { enumerable: true, get: function () { return llm_adapter_config_1.LLM_ADAPTER_CONFIG; } });
10
+ Object.defineProperty(exports, "resolveProviderName", { enumerable: true, get: function () { return llm_adapter_config_1.resolveProviderName; } });
11
+ var provider_configs_1 = require("./lib/provider-configs");
12
+ Object.defineProperty(exports, "BEDROCK_CONVERSE_CONFIG", { enumerable: true, get: function () { return provider_configs_1.BEDROCK_CONVERSE_CONFIG; } });
13
+ Object.defineProperty(exports, "OPENAI_CONFIG", { enumerable: true, get: function () { return provider_configs_1.OPENAI_CONFIG; } });
14
+ Object.defineProperty(exports, "CLAUDE_CONFIG", { enumerable: true, get: function () { return provider_configs_1.CLAUDE_CONFIG; } });
15
+ Object.defineProperty(exports, "GEMINI_CONFIG", { enumerable: true, get: function () { return provider_configs_1.GEMINI_CONFIG; } });
16
+ Object.defineProperty(exports, "MISTRAL_CONFIG", { enumerable: true, get: function () { return provider_configs_1.MISTRAL_CONFIG; } });
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/server/mcp-llm-adapter/src/index.ts"],"names":[],"mappings":";;;AAAA,2DAAkG;AAAzF,kHAAA,cAAc,OAAA;AACvB,+DAA4D;AAAnD,sHAAA,gBAAgB,OAAA;AACzB,+DAIkC;AAFhC,wHAAA,kBAAkB,OAAA;AAClB,yHAAA,mBAAmB,OAAA;AAErB,2DAUgC;AAT9B,2HAAA,uBAAuB,OAAA;AAEvB,iHAAA,aAAa,OAAA;AAEb,iHAAA,aAAa,OAAA;AAEb,iHAAA,aAAa,OAAA;AAEb,kHAAA,cAAc,OAAA"}
@@ -0,0 +1,10 @@
1
+ import type { McpToolMetadata } from '@onivoro/server-mcp';
2
+ export declare const LLM_ADAPTER_CONFIG: unique symbol;
3
+ export interface LlmAdapterConfig<T = unknown> {
4
+ aliasKey: string;
5
+ sanitizeName?: (name: string) => string;
6
+ formatTool: (name: string, description: string, jsonSchema: Record<string, unknown>) => T;
7
+ formatToolWithOutput?: (name: string, description: string, inputSchema: Record<string, unknown>, outputSchema: Record<string, unknown>) => T;
8
+ }
9
+ export declare function resolveProviderName(metadata: McpToolMetadata, config: LlmAdapterConfig): string;
10
+ //# sourceMappingURL=llm-adapter.config.d.ts.map
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LLM_ADAPTER_CONFIG = void 0;
4
+ exports.resolveProviderName = resolveProviderName;
5
+ exports.LLM_ADAPTER_CONFIG = Symbol('LLM_ADAPTER_CONFIG');
6
+ function resolveProviderName(metadata, config) {
7
+ const alias = metadata.aliases?.[config.aliasKey];
8
+ if (alias)
9
+ return alias;
10
+ return config.sanitizeName
11
+ ? config.sanitizeName(metadata.name)
12
+ : metadata.name;
13
+ }
14
+ //# sourceMappingURL=llm-adapter.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-adapter.config.js","sourceRoot":"","sources":["../../../../../../libs/server/mcp-llm-adapter/src/lib/llm-adapter.config.ts"],"names":[],"mappings":";;;AA6BA,kDASC;AApCY,QAAA,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AA2B/D,SAAgB,mBAAmB,CACjC,QAAyB,EACzB,MAAwB;IAExB,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,OAAO,MAAM,CAAC,YAAY;QACxB,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC;QACpC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AACpB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { LlmAdapterConfig } from './llm-adapter.config';
3
+ export declare class LlmAdapterModule {
4
+ static forProvider<T>(config: LlmAdapterConfig<T>): DynamicModule;
5
+ static forBedrockConverse(): DynamicModule;
6
+ static forOpenAi(): DynamicModule;
7
+ static forClaude(): DynamicModule;
8
+ static forGemini(): DynamicModule;
9
+ static forMistral(): DynamicModule;
10
+ }
11
+ //# sourceMappingURL=llm-adapter.module.d.ts.map
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var LlmAdapterModule_1;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.LlmAdapterModule = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const common_1 = require("@nestjs/common");
7
+ const llm_tool_adapter_1 = require("./llm-tool-adapter");
8
+ const llm_adapter_config_1 = require("./llm-adapter.config");
9
+ const provider_configs_1 = require("./provider-configs");
10
+ let LlmAdapterModule = LlmAdapterModule_1 = class LlmAdapterModule {
11
+ static forProvider(config) {
12
+ return {
13
+ module: LlmAdapterModule_1,
14
+ providers: [
15
+ llm_tool_adapter_1.LlmToolAdapter,
16
+ { provide: llm_adapter_config_1.LLM_ADAPTER_CONFIG, useValue: config },
17
+ ],
18
+ exports: [llm_tool_adapter_1.LlmToolAdapter],
19
+ };
20
+ }
21
+ static forBedrockConverse() {
22
+ return this.forProvider(provider_configs_1.BEDROCK_CONVERSE_CONFIG);
23
+ }
24
+ static forOpenAi() {
25
+ return this.forProvider(provider_configs_1.OPENAI_CONFIG);
26
+ }
27
+ static forClaude() {
28
+ return this.forProvider(provider_configs_1.CLAUDE_CONFIG);
29
+ }
30
+ static forGemini() {
31
+ return this.forProvider(provider_configs_1.GEMINI_CONFIG);
32
+ }
33
+ static forMistral() {
34
+ return this.forProvider(provider_configs_1.MISTRAL_CONFIG);
35
+ }
36
+ };
37
+ exports.LlmAdapterModule = LlmAdapterModule;
38
+ exports.LlmAdapterModule = LlmAdapterModule = LlmAdapterModule_1 = tslib_1.__decorate([
39
+ (0, common_1.Module)({})
40
+ ], LlmAdapterModule);
41
+ //# sourceMappingURL=llm-adapter.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-adapter.module.js","sourceRoot":"","sources":["../../../../../../libs/server/mcp-llm-adapter/src/lib/llm-adapter.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAAuD;AACvD,yDAAoD;AACpD,6DAA4E;AAC5E,yDAM4B;AAGrB,IAAM,gBAAgB,wBAAtB,MAAM,gBAAgB;IAC3B,MAAM,CAAC,WAAW,CAAI,MAA2B;QAC/C,OAAO;YACL,MAAM,EAAE,kBAAgB;YACxB,SAAS,EAAE;gBACT,iCAAc;gBACd,EAAE,OAAO,EAAE,uCAAkB,EAAE,QAAQ,EAAE,MAAM,EAAE;aAClD;YACD,OAAO,EAAE,CAAC,iCAAc,CAAC;SAC1B,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,kBAAkB;QACvB,OAAO,IAAI,CAAC,WAAW,CAAC,0CAAuB,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,CAAC,SAAS;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,gCAAa,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,SAAS;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,gCAAa,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,SAAS;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,gCAAa,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,UAAU;QACf,OAAO,IAAI,CAAC,WAAW,CAAC,iCAAc,CAAC,CAAC;IAC1C,CAAC;CACF,CAAA;AA/BY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,gBAAgB,CA+B5B"}
@@ -0,0 +1,31 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { McpToolRegistry, McpAuthInfo } from '@onivoro/server-mcp';
3
+ import { LlmAdapterConfig } from './llm-adapter.config';
4
+ export interface ProviderToolCall {
5
+ providerName: string;
6
+ params: Record<string, unknown>;
7
+ id?: string;
8
+ }
9
+ export interface ProviderToolCallResult {
10
+ providerName: string;
11
+ id?: string;
12
+ result?: string;
13
+ error?: string;
14
+ success: boolean;
15
+ }
16
+ export declare class LlmToolAdapter<T = unknown> implements OnModuleInit {
17
+ private readonly registry;
18
+ private readonly config;
19
+ private nameMapCache;
20
+ private unsubscribe?;
21
+ constructor(registry: McpToolRegistry, config: LlmAdapterConfig<T>);
22
+ onModuleInit(): void;
23
+ private getNameMap;
24
+ toProviderTools(): T[];
25
+ getOutputSchemas(): Map<string, Record<string, unknown>>;
26
+ resolveProviderToolName(providerName: string): string | undefined;
27
+ executeToolForProvider(providerName: string, params: Record<string, unknown>, authInfo?: McpAuthInfo): Promise<string>;
28
+ executeToolCallForProvider(toolCall: ProviderToolCall, authInfo?: McpAuthInfo): Promise<ProviderToolCallResult>;
29
+ executeToolsForProvider(toolCalls: ProviderToolCall[], authInfo?: McpAuthInfo): Promise<ProviderToolCallResult[]>;
30
+ }
31
+ //# sourceMappingURL=llm-tool-adapter.d.ts.map
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LlmToolAdapter = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const server_mcp_1 = require("@onivoro/server-mcp");
7
+ const llm_adapter_config_1 = require("./llm-adapter.config");
8
+ let LlmToolAdapter = class LlmToolAdapter {
9
+ registry;
10
+ config;
11
+ nameMapCache = null;
12
+ unsubscribe;
13
+ constructor(registry, config) {
14
+ this.registry = registry;
15
+ this.config = config;
16
+ }
17
+ onModuleInit() {
18
+ this.unsubscribe = this.registry.onRegistrationChange(() => {
19
+ this.nameMapCache = null;
20
+ });
21
+ }
22
+ getNameMap() {
23
+ if (!this.nameMapCache) {
24
+ const map = new Map();
25
+ for (const { metadata } of this.registry.getTools()) {
26
+ map.set((0, llm_adapter_config_1.resolveProviderName)(metadata, this.config), metadata.name);
27
+ }
28
+ this.nameMapCache = map;
29
+ }
30
+ return this.nameMapCache;
31
+ }
32
+ toProviderTools() {
33
+ return this.registry.getTools().map(({ metadata }) => {
34
+ const name = (0, llm_adapter_config_1.resolveProviderName)(metadata, this.config);
35
+ const inputSchema = (0, server_mcp_1.mcpSchemaToJsonSchema)(metadata.schema);
36
+ if (this.config.formatToolWithOutput && metadata.outputSchema) {
37
+ const outputSchema = (0, server_mcp_1.mcpSchemaToJsonSchema)(metadata.outputSchema);
38
+ return this.config.formatToolWithOutput(name, metadata.description, inputSchema, outputSchema);
39
+ }
40
+ return this.config.formatTool(name, metadata.description, inputSchema);
41
+ });
42
+ }
43
+ getOutputSchemas() {
44
+ const result = new Map();
45
+ for (const { metadata } of this.registry.getTools()) {
46
+ if (metadata.outputSchema) {
47
+ const providerName = (0, llm_adapter_config_1.resolveProviderName)(metadata, this.config);
48
+ result.set(providerName, (0, server_mcp_1.mcpSchemaToJsonSchema)(metadata.outputSchema));
49
+ }
50
+ }
51
+ return result;
52
+ }
53
+ resolveProviderToolName(providerName) {
54
+ return this.getNameMap().get(providerName);
55
+ }
56
+ async executeToolForProvider(providerName, params, authInfo) {
57
+ const mcpName = this.getNameMap().get(providerName);
58
+ if (!mcpName) {
59
+ throw new Error(`No MCP tool found for provider name "${providerName}".`);
60
+ }
61
+ const result = await this.registry.executeToolRaw(mcpName, params, authInfo);
62
+ return typeof result === 'string' ? result : JSON.stringify(result);
63
+ }
64
+ async executeToolCallForProvider(toolCall, authInfo) {
65
+ const [result] = await this.executeToolsForProvider([toolCall], authInfo);
66
+ return result;
67
+ }
68
+ async executeToolsForProvider(toolCalls, authInfo) {
69
+ const nameMap = this.getNameMap();
70
+ const settled = await Promise.allSettled(toolCalls.map(async ({ providerName, params, id }) => {
71
+ const mcpName = nameMap.get(providerName);
72
+ if (!mcpName) {
73
+ throw new Error(`No MCP tool found for provider name "${providerName}".`);
74
+ }
75
+ const rawResult = await this.registry.executeToolRaw(mcpName, params, authInfo);
76
+ const result = typeof rawResult === 'string' ? rawResult : JSON.stringify(rawResult);
77
+ return { providerName, id, result, success: true };
78
+ }));
79
+ return settled.map((outcome, i) => {
80
+ if (outcome.status === 'fulfilled') {
81
+ return outcome.value;
82
+ }
83
+ const call = toolCalls[i];
84
+ return {
85
+ providerName: call.providerName,
86
+ id: call.id,
87
+ error: outcome.reason instanceof Error ? outcome.reason.message : String(outcome.reason),
88
+ success: false,
89
+ };
90
+ });
91
+ }
92
+ };
93
+ exports.LlmToolAdapter = LlmToolAdapter;
94
+ exports.LlmToolAdapter = LlmToolAdapter = tslib_1.__decorate([
95
+ (0, common_1.Injectable)(),
96
+ tslib_1.__param(1, (0, common_1.Inject)(llm_adapter_config_1.LLM_ADAPTER_CONFIG)),
97
+ tslib_1.__metadata("design:paramtypes", [server_mcp_1.McpToolRegistry, Object])
98
+ ], LlmToolAdapter);
99
+ //# sourceMappingURL=llm-tool-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-tool-adapter.js","sourceRoot":"","sources":["../../../../../../libs/server/mcp-llm-adapter/src/lib/llm-tool-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { LlmAdapterConfig } from './llm-adapter.config';
2
+ export interface BedrockConverseToolDefinition {
3
+ toolSpec: {
4
+ name: string;
5
+ description: string;
6
+ inputSchema: {
7
+ json: Record<string, unknown>;
8
+ };
9
+ };
10
+ }
11
+ export declare const BEDROCK_CONVERSE_CONFIG: LlmAdapterConfig<BedrockConverseToolDefinition>;
12
+ export interface OpenAiToolDefinition {
13
+ type: 'function';
14
+ function: {
15
+ name: string;
16
+ description: string;
17
+ parameters: Record<string, unknown>;
18
+ };
19
+ }
20
+ export declare const OPENAI_CONFIG: LlmAdapterConfig<OpenAiToolDefinition>;
21
+ export interface ClaudeToolDefinition {
22
+ name: string;
23
+ description: string;
24
+ input_schema: Record<string, unknown>;
25
+ }
26
+ export declare const CLAUDE_CONFIG: LlmAdapterConfig<ClaudeToolDefinition>;
27
+ export interface GeminiToolDefinition {
28
+ name: string;
29
+ description: string;
30
+ parameters: Record<string, unknown>;
31
+ }
32
+ export declare const GEMINI_CONFIG: LlmAdapterConfig<GeminiToolDefinition>;
33
+ export declare const MISTRAL_CONFIG: LlmAdapterConfig<OpenAiToolDefinition>;
34
+ //# sourceMappingURL=provider-configs.d.ts.map
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MISTRAL_CONFIG = exports.GEMINI_CONFIG = exports.CLAUDE_CONFIG = exports.OPENAI_CONFIG = exports.BEDROCK_CONVERSE_CONFIG = void 0;
4
+ exports.BEDROCK_CONVERSE_CONFIG = {
5
+ aliasKey: 'bedrock',
6
+ sanitizeName: (name) => name.replace(/[^a-zA-Z0-9_]/g, '_'),
7
+ formatTool: (name, description, jsonSchema) => ({
8
+ toolSpec: { name, description, inputSchema: { json: jsonSchema } },
9
+ }),
10
+ };
11
+ exports.OPENAI_CONFIG = {
12
+ aliasKey: 'openai',
13
+ formatTool: (name, description, jsonSchema) => ({
14
+ type: 'function',
15
+ function: { name, description, parameters: jsonSchema },
16
+ }),
17
+ };
18
+ exports.CLAUDE_CONFIG = {
19
+ aliasKey: 'claude',
20
+ formatTool: (name, description, jsonSchema) => ({
21
+ name,
22
+ description,
23
+ input_schema: jsonSchema,
24
+ }),
25
+ };
26
+ exports.GEMINI_CONFIG = {
27
+ aliasKey: 'gemini',
28
+ sanitizeName: (name) => name.replace(/[^a-zA-Z0-9_]/g, '_'),
29
+ formatTool: (name, description, jsonSchema) => ({
30
+ name,
31
+ description,
32
+ parameters: jsonSchema,
33
+ }),
34
+ };
35
+ exports.MISTRAL_CONFIG = {
36
+ aliasKey: 'mistral',
37
+ formatTool: (name, description, jsonSchema) => ({
38
+ type: 'function',
39
+ function: { name, description, parameters: jsonSchema },
40
+ }),
41
+ };
42
+ //# sourceMappingURL=provider-configs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-configs.js","sourceRoot":"","sources":["../../../../../../libs/server/mcp-llm-adapter/src/lib/provider-configs.ts"],"names":[],"mappings":";;;AAYa,QAAA,uBAAuB,GAAoD;IACtF,QAAQ,EAAE,SAAS;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;IAC3D,UAAU,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAC9C,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;KACnE,CAAC;CACH,CAAC;AAaW,QAAA,aAAa,GAA2C;IACnE,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAC9C,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE;KACxD,CAAC;CACH,CAAC;AAUW,QAAA,aAAa,GAA2C;IACnE,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAC9C,IAAI;QACJ,WAAW;QACX,YAAY,EAAE,UAAU;KACzB,CAAC;CACH,CAAC;AAUW,QAAA,aAAa,GAA2C;IACnE,QAAQ,EAAE,QAAQ;IAClB,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;IAC3D,UAAU,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAC9C,IAAI;QACJ,WAAW;QACX,UAAU,EAAE,UAAU;KACvB,CAAC;CACH,CAAC;AAIW,QAAA,cAAc,GAA2C;IACpE,QAAQ,EAAE,SAAS;IACnB,UAAU,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAC9C,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE;KACxD,CAAC;CACH,CAAC"}