@genkit-ai/mcp 1.14.1-rc.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/LICENSE +203 -0
- package/README.md +205 -0
- package/examples/client/index.js +36 -0
- package/examples/client/package.json +25 -0
- package/examples/server/index.js +46 -0
- package/examples/server/package.json +18 -0
- package/examples/server/prompts/port_code.prompt +13 -0
- package/lib/client/client.d.mts +177 -0
- package/lib/client/client.d.ts +177 -0
- package/lib/client/client.js +282 -0
- package/lib/client/client.js.map +1 -0
- package/lib/client/client.mjs +267 -0
- package/lib/client/client.mjs.map +1 -0
- package/lib/client/host.d.mts +202 -0
- package/lib/client/host.d.ts +202 -0
- package/lib/client/host.js +392 -0
- package/lib/client/host.js.map +1 -0
- package/lib/client/host.mjs +368 -0
- package/lib/client/host.mjs.map +1 -0
- package/lib/client/index.d.mts +9 -0
- package/lib/client/index.d.ts +9 -0
- package/lib/client/index.js +32 -0
- package/lib/client/index.js.map +1 -0
- package/lib/client/index.mjs +7 -0
- package/lib/client/index.mjs.map +1 -0
- package/lib/index.d.mts +12 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.js +48 -0
- package/lib/index.js.map +1 -0
- package/lib/index.mjs +22 -0
- package/lib/index.mjs.map +1 -0
- package/lib/server.d.mts +188 -0
- package/lib/server.d.ts +188 -0
- package/lib/server.js +280 -0
- package/lib/server.js.map +1 -0
- package/lib/server.mjs +249 -0
- package/lib/server.mjs.map +1 -0
- package/lib/util/index.d.mts +11 -0
- package/lib/util/index.d.ts +11 -0
- package/lib/util/index.js +29 -0
- package/lib/util/index.js.map +1 -0
- package/lib/util/index.mjs +5 -0
- package/lib/util/index.mjs.map +1 -0
- package/lib/util/message.d.mts +43 -0
- package/lib/util/message.d.ts +43 -0
- package/lib/util/message.js +61 -0
- package/lib/util/message.js.map +1 -0
- package/lib/util/message.mjs +36 -0
- package/lib/util/message.mjs.map +1 -0
- package/lib/util/prompts.d.mts +45 -0
- package/lib/util/prompts.d.ts +45 -0
- package/lib/util/prompts.js +147 -0
- package/lib/util/prompts.js.map +1 -0
- package/lib/util/prompts.mjs +123 -0
- package/lib/util/prompts.mjs.map +1 -0
- package/lib/util/resource.d.mts +28 -0
- package/lib/util/resource.d.ts +28 -0
- package/lib/util/resource.js +116 -0
- package/lib/util/resource.js.map +1 -0
- package/lib/util/resource.mjs +95 -0
- package/lib/util/resource.mjs.map +1 -0
- package/lib/util/tools.d.mts +37 -0
- package/lib/util/tools.d.ts +37 -0
- package/lib/util/tools.js +120 -0
- package/lib/util/tools.js.map +1 -0
- package/lib/util/tools.mjs +95 -0
- package/lib/util/tools.mjs.map +1 -0
- package/lib/util/transport.d.mts +39 -0
- package/lib/util/transport.d.ts +39 -0
- package/lib/util/transport.js +63 -0
- package/lib/util/transport.js.map +1 -0
- package/lib/util/transport.mjs +29 -0
- package/lib/util/transport.mjs.map +1 -0
- package/package.json +57 -0
- package/src/client/client.ts +414 -0
- package/src/client/host.ts +485 -0
- package/src/client/index.ts +29 -0
- package/src/index.ts +114 -0
- package/src/server.ts +330 -0
- package/src/util/index.ts +20 -0
- package/src/util/message.ts +72 -0
- package/src/util/prompts.ts +223 -0
- package/src/util/resource.ts +141 -0
- package/src/util/tools.ts +164 -0
- package/src/util/transport.ts +67 -0
- package/tests/fakes.ts +221 -0
- package/tests/host_test.ts +609 -0
- package/tests/server_test.ts +165 -0
package/lib/server.d.mts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { Genkit, PromptAction } from 'genkit';
|
|
2
|
+
import { McpClientOptions, GenkitMcpClient } from './client/client.mjs';
|
|
3
|
+
import { McpHostOptions, GenkitMcpHost } from './client/host.mjs';
|
|
4
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
5
|
+
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
6
|
+
import { ListToolsRequest, ListToolsResult, CallToolRequest, CallToolResult, ListPromptsRequest, ListPromptsResult, GetPromptRequest, GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
import { ToolAction } from 'genkit/tool';
|
|
8
|
+
import '@modelcontextprotocol/sdk/client/index.js';
|
|
9
|
+
import '@modelcontextprotocol/sdk/client/stdio.js';
|
|
10
|
+
import '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
11
|
+
import '@modelcontextprotocol/sdk/client/sse.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Copyright 2024 Google LLC
|
|
15
|
+
*
|
|
16
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
17
|
+
* you may not use this file except in compliance with the License.
|
|
18
|
+
* You may obtain a copy of the License at
|
|
19
|
+
*
|
|
20
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
21
|
+
*
|
|
22
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
23
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
24
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
25
|
+
* See the License for the specific language governing permissions and
|
|
26
|
+
* limitations under the License.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Represents an MCP (Model Context Protocol) server that exposes Genkit tools
|
|
31
|
+
* and prompts. This class wraps a Genkit instance and makes its registered
|
|
32
|
+
* actions (tools, prompts) available to MCP clients. It handles the translation
|
|
33
|
+
* between Genkit's action definitions and MCP's expected formats.
|
|
34
|
+
*/
|
|
35
|
+
declare class GenkitMcpServer {
|
|
36
|
+
ai: Genkit;
|
|
37
|
+
options: McpServerOptions;
|
|
38
|
+
server?: Server;
|
|
39
|
+
actionsResolved: boolean;
|
|
40
|
+
toolActions: ToolAction[];
|
|
41
|
+
promptActions: PromptAction[];
|
|
42
|
+
/**
|
|
43
|
+
* Creates an instance of GenkitMcpServer.
|
|
44
|
+
* @param ai The Genkit instance whose actions will be exposed.
|
|
45
|
+
* @param options Configuration options for the MCP server, like its name and version.
|
|
46
|
+
*/
|
|
47
|
+
constructor(ai: Genkit, options: McpServerOptions);
|
|
48
|
+
/**
|
|
49
|
+
* Initializes the MCP server instance and registers request handlers. It
|
|
50
|
+
* dynamically imports MCP SDK components and sets up handlers for listing
|
|
51
|
+
* tools, calling tools, listing prompts, and getting prompts. It also
|
|
52
|
+
* resolves and stores all tool and prompt actions from the Genkit instance.
|
|
53
|
+
*
|
|
54
|
+
* This method is called by the constructor and ensures the server is ready
|
|
55
|
+
* before any requests are handled. It's idempotent.
|
|
56
|
+
*/
|
|
57
|
+
setup(): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Handles MCP requests to list available tools.
|
|
60
|
+
* It maps the resolved Genkit tool actions to the MCP Tool format.
|
|
61
|
+
* @param req The MCP ListToolsRequest.
|
|
62
|
+
* @returns A Promise resolving to an MCP ListToolsResult.
|
|
63
|
+
*/
|
|
64
|
+
listTools(req: ListToolsRequest): Promise<ListToolsResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Handles MCP requests to call a specific tool. It finds the corresponding
|
|
67
|
+
* Genkit tool action and executes it with the provided arguments. The result
|
|
68
|
+
* is then formatted as an MCP CallToolResult.
|
|
69
|
+
* @param req The MCP CallToolRequest containing the tool name and arguments.
|
|
70
|
+
* @returns A Promise resolving to an MCP CallToolResult.
|
|
71
|
+
* @throws GenkitError if the requested tool is not found.
|
|
72
|
+
*/
|
|
73
|
+
callTool(req: CallToolRequest): Promise<CallToolResult>;
|
|
74
|
+
/**
|
|
75
|
+
* Handles MCP requests to list available prompts.
|
|
76
|
+
* It maps the resolved Genkit prompt actions to the MCP Prompt format,
|
|
77
|
+
* including converting input schemas to MCP argument definitions.
|
|
78
|
+
* @param req The MCP ListPromptsRequest.
|
|
79
|
+
* @returns A Promise resolving to an MCP ListPromptsResult.
|
|
80
|
+
*/
|
|
81
|
+
listPrompts(req: ListPromptsRequest): Promise<ListPromptsResult>;
|
|
82
|
+
/**
|
|
83
|
+
* Handles MCP requests to get (render) a specific prompt. It finds the
|
|
84
|
+
* corresponding Genkit prompt action, executes it with the provided
|
|
85
|
+
* arguments, and then formats the resulting messages into the MCP
|
|
86
|
+
* PromptMessage format.
|
|
87
|
+
* @param req The MCP GetPromptRequest containing the prompt name and
|
|
88
|
+
* arguments.
|
|
89
|
+
* @returns A Promise resolving to an MCP GetPromptResult.
|
|
90
|
+
* @throws GenkitError if the requested prompt is not found.
|
|
91
|
+
*/
|
|
92
|
+
getPrompt(req: GetPromptRequest): Promise<GetPromptResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Starts the MCP server with the specified transport or a default
|
|
95
|
+
* StdioServerTransport. Ensures the server is set up before connecting the
|
|
96
|
+
* transport.
|
|
97
|
+
* @param transport Optional MCP transport instance. If not provided, a
|
|
98
|
+
* StdioServerTransport will be created and used.
|
|
99
|
+
*/
|
|
100
|
+
start(transport?: Transport): Promise<void>;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Copyright 2024 Google LLC
|
|
105
|
+
*
|
|
106
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
107
|
+
* you may not use this file except in compliance with the License.
|
|
108
|
+
* You may obtain a copy of the License at
|
|
109
|
+
*
|
|
110
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
111
|
+
*
|
|
112
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
113
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
114
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
115
|
+
* See the License for the specific language governing permissions and
|
|
116
|
+
* limitations under the License.
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
interface McpServerOptions {
|
|
120
|
+
/** The name you want to give your server for MCP inspection. */
|
|
121
|
+
name: string;
|
|
122
|
+
/** The version you want the server to advertise to clients. Defaults to
|
|
123
|
+
* 1.0.0. */
|
|
124
|
+
version?: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Creates an MCP Client Host that connects to one or more MCP servers.
|
|
128
|
+
* Each server is defined in the `mcpClients` option, where the key is a
|
|
129
|
+
* client-side name for the server and the value is the server's configuration.
|
|
130
|
+
*
|
|
131
|
+
* By default, all servers in the config will be attempted to connect unless
|
|
132
|
+
* their configuration includes `{disabled: true}`.
|
|
133
|
+
*
|
|
134
|
+
* ```ts
|
|
135
|
+
* const clientHost = createMcpHost({
|
|
136
|
+
* name: "my-mcp-client-host", // Name for the host itself
|
|
137
|
+
* mcpServers: {
|
|
138
|
+
* // Each key is a name for this client/server configuration
|
|
139
|
+
* // Each value is an McpServerConfig object
|
|
140
|
+
* gitToolServer: { command: "uvx", args: ["mcp-server-git"] },
|
|
141
|
+
* customApiServer: { url: "http://localhost:1234/mcp" }
|
|
142
|
+
* }
|
|
143
|
+
* });
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
146
|
+
* @param options Configuration for the MCP Client Host, including the definitions of MCP servers to connect to.
|
|
147
|
+
* @returns A new instance of GenkitMcpHost.
|
|
148
|
+
*/
|
|
149
|
+
declare function createMcpHost(options: McpHostOptions): GenkitMcpHost;
|
|
150
|
+
/**
|
|
151
|
+
* Creates an MCP Client that connects to a single MCP server.
|
|
152
|
+
* This is useful when you only need to interact with one MCP server,
|
|
153
|
+
* or if you want to manage client instances individually.
|
|
154
|
+
*
|
|
155
|
+
* ```ts
|
|
156
|
+
* const client = createMcpClient({
|
|
157
|
+
* name: "mySingleMcpClient", // A name for this client instance
|
|
158
|
+
* command: "npx", // Example: Launching a local server
|
|
159
|
+
* args: ["-y", "@modelcontextprotocol/server-everything", "/path/to/allowed/dir"],
|
|
160
|
+
* });
|
|
161
|
+
*
|
|
162
|
+
* // To get tools from this client:
|
|
163
|
+
* // const tools = await client.getActiveTools(ai);
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* @param options Configuration for the MCP Client, defining how it connects
|
|
167
|
+
* to the MCP server and its behavior.
|
|
168
|
+
* @returns A new instance of GenkitMcpClient.
|
|
169
|
+
*/
|
|
170
|
+
declare function createMcpClient(options: McpClientOptions): GenkitMcpClient;
|
|
171
|
+
/**
|
|
172
|
+
* Creates an MCP server based on the supplied Genkit instance. All tools and prompts
|
|
173
|
+
* will be automatically converted to MCP compatibility.
|
|
174
|
+
*
|
|
175
|
+
* ```ts
|
|
176
|
+
* const mcpServer = createMcpServer(ai, {name: 'my-mcp-server', version: '0.1.0'});
|
|
177
|
+
*
|
|
178
|
+
* await mcpServer.start(); // starts a stdio transport, OR
|
|
179
|
+
* await mcpServer.start(customMcpTransport); // starts server using supplied transport
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @param ai Your Genkit instance with registered tools and prompts.
|
|
183
|
+
* @param options Configuration metadata for the server.
|
|
184
|
+
* @returns GenkitMcpServer instance.
|
|
185
|
+
*/
|
|
186
|
+
declare function createMcpServer(ai: Genkit, options: McpServerOptions): GenkitMcpServer;
|
|
187
|
+
|
|
188
|
+
export { GenkitMcpServer, type McpServerOptions as M, createMcpClient as a, createMcpServer as b, createMcpHost as c };
|
package/lib/server.d.ts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { Genkit, PromptAction } from 'genkit';
|
|
2
|
+
import { McpClientOptions, GenkitMcpClient } from './client/client.js';
|
|
3
|
+
import { McpHostOptions, GenkitMcpHost } from './client/host.js';
|
|
4
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
5
|
+
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
6
|
+
import { ListToolsRequest, ListToolsResult, CallToolRequest, CallToolResult, ListPromptsRequest, ListPromptsResult, GetPromptRequest, GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
import { ToolAction } from 'genkit/tool';
|
|
8
|
+
import '@modelcontextprotocol/sdk/client/index.js';
|
|
9
|
+
import '@modelcontextprotocol/sdk/client/stdio.js';
|
|
10
|
+
import '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
11
|
+
import '@modelcontextprotocol/sdk/client/sse.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Copyright 2024 Google LLC
|
|
15
|
+
*
|
|
16
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
17
|
+
* you may not use this file except in compliance with the License.
|
|
18
|
+
* You may obtain a copy of the License at
|
|
19
|
+
*
|
|
20
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
21
|
+
*
|
|
22
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
23
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
24
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
25
|
+
* See the License for the specific language governing permissions and
|
|
26
|
+
* limitations under the License.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Represents an MCP (Model Context Protocol) server that exposes Genkit tools
|
|
31
|
+
* and prompts. This class wraps a Genkit instance and makes its registered
|
|
32
|
+
* actions (tools, prompts) available to MCP clients. It handles the translation
|
|
33
|
+
* between Genkit's action definitions and MCP's expected formats.
|
|
34
|
+
*/
|
|
35
|
+
declare class GenkitMcpServer {
|
|
36
|
+
ai: Genkit;
|
|
37
|
+
options: McpServerOptions;
|
|
38
|
+
server?: Server;
|
|
39
|
+
actionsResolved: boolean;
|
|
40
|
+
toolActions: ToolAction[];
|
|
41
|
+
promptActions: PromptAction[];
|
|
42
|
+
/**
|
|
43
|
+
* Creates an instance of GenkitMcpServer.
|
|
44
|
+
* @param ai The Genkit instance whose actions will be exposed.
|
|
45
|
+
* @param options Configuration options for the MCP server, like its name and version.
|
|
46
|
+
*/
|
|
47
|
+
constructor(ai: Genkit, options: McpServerOptions);
|
|
48
|
+
/**
|
|
49
|
+
* Initializes the MCP server instance and registers request handlers. It
|
|
50
|
+
* dynamically imports MCP SDK components and sets up handlers for listing
|
|
51
|
+
* tools, calling tools, listing prompts, and getting prompts. It also
|
|
52
|
+
* resolves and stores all tool and prompt actions from the Genkit instance.
|
|
53
|
+
*
|
|
54
|
+
* This method is called by the constructor and ensures the server is ready
|
|
55
|
+
* before any requests are handled. It's idempotent.
|
|
56
|
+
*/
|
|
57
|
+
setup(): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Handles MCP requests to list available tools.
|
|
60
|
+
* It maps the resolved Genkit tool actions to the MCP Tool format.
|
|
61
|
+
* @param req The MCP ListToolsRequest.
|
|
62
|
+
* @returns A Promise resolving to an MCP ListToolsResult.
|
|
63
|
+
*/
|
|
64
|
+
listTools(req: ListToolsRequest): Promise<ListToolsResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Handles MCP requests to call a specific tool. It finds the corresponding
|
|
67
|
+
* Genkit tool action and executes it with the provided arguments. The result
|
|
68
|
+
* is then formatted as an MCP CallToolResult.
|
|
69
|
+
* @param req The MCP CallToolRequest containing the tool name and arguments.
|
|
70
|
+
* @returns A Promise resolving to an MCP CallToolResult.
|
|
71
|
+
* @throws GenkitError if the requested tool is not found.
|
|
72
|
+
*/
|
|
73
|
+
callTool(req: CallToolRequest): Promise<CallToolResult>;
|
|
74
|
+
/**
|
|
75
|
+
* Handles MCP requests to list available prompts.
|
|
76
|
+
* It maps the resolved Genkit prompt actions to the MCP Prompt format,
|
|
77
|
+
* including converting input schemas to MCP argument definitions.
|
|
78
|
+
* @param req The MCP ListPromptsRequest.
|
|
79
|
+
* @returns A Promise resolving to an MCP ListPromptsResult.
|
|
80
|
+
*/
|
|
81
|
+
listPrompts(req: ListPromptsRequest): Promise<ListPromptsResult>;
|
|
82
|
+
/**
|
|
83
|
+
* Handles MCP requests to get (render) a specific prompt. It finds the
|
|
84
|
+
* corresponding Genkit prompt action, executes it with the provided
|
|
85
|
+
* arguments, and then formats the resulting messages into the MCP
|
|
86
|
+
* PromptMessage format.
|
|
87
|
+
* @param req The MCP GetPromptRequest containing the prompt name and
|
|
88
|
+
* arguments.
|
|
89
|
+
* @returns A Promise resolving to an MCP GetPromptResult.
|
|
90
|
+
* @throws GenkitError if the requested prompt is not found.
|
|
91
|
+
*/
|
|
92
|
+
getPrompt(req: GetPromptRequest): Promise<GetPromptResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Starts the MCP server with the specified transport or a default
|
|
95
|
+
* StdioServerTransport. Ensures the server is set up before connecting the
|
|
96
|
+
* transport.
|
|
97
|
+
* @param transport Optional MCP transport instance. If not provided, a
|
|
98
|
+
* StdioServerTransport will be created and used.
|
|
99
|
+
*/
|
|
100
|
+
start(transport?: Transport): Promise<void>;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Copyright 2024 Google LLC
|
|
105
|
+
*
|
|
106
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
107
|
+
* you may not use this file except in compliance with the License.
|
|
108
|
+
* You may obtain a copy of the License at
|
|
109
|
+
*
|
|
110
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
111
|
+
*
|
|
112
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
113
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
114
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
115
|
+
* See the License for the specific language governing permissions and
|
|
116
|
+
* limitations under the License.
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
interface McpServerOptions {
|
|
120
|
+
/** The name you want to give your server for MCP inspection. */
|
|
121
|
+
name: string;
|
|
122
|
+
/** The version you want the server to advertise to clients. Defaults to
|
|
123
|
+
* 1.0.0. */
|
|
124
|
+
version?: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Creates an MCP Client Host that connects to one or more MCP servers.
|
|
128
|
+
* Each server is defined in the `mcpClients` option, where the key is a
|
|
129
|
+
* client-side name for the server and the value is the server's configuration.
|
|
130
|
+
*
|
|
131
|
+
* By default, all servers in the config will be attempted to connect unless
|
|
132
|
+
* their configuration includes `{disabled: true}`.
|
|
133
|
+
*
|
|
134
|
+
* ```ts
|
|
135
|
+
* const clientHost = createMcpHost({
|
|
136
|
+
* name: "my-mcp-client-host", // Name for the host itself
|
|
137
|
+
* mcpServers: {
|
|
138
|
+
* // Each key is a name for this client/server configuration
|
|
139
|
+
* // Each value is an McpServerConfig object
|
|
140
|
+
* gitToolServer: { command: "uvx", args: ["mcp-server-git"] },
|
|
141
|
+
* customApiServer: { url: "http://localhost:1234/mcp" }
|
|
142
|
+
* }
|
|
143
|
+
* });
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
146
|
+
* @param options Configuration for the MCP Client Host, including the definitions of MCP servers to connect to.
|
|
147
|
+
* @returns A new instance of GenkitMcpHost.
|
|
148
|
+
*/
|
|
149
|
+
declare function createMcpHost(options: McpHostOptions): GenkitMcpHost;
|
|
150
|
+
/**
|
|
151
|
+
* Creates an MCP Client that connects to a single MCP server.
|
|
152
|
+
* This is useful when you only need to interact with one MCP server,
|
|
153
|
+
* or if you want to manage client instances individually.
|
|
154
|
+
*
|
|
155
|
+
* ```ts
|
|
156
|
+
* const client = createMcpClient({
|
|
157
|
+
* name: "mySingleMcpClient", // A name for this client instance
|
|
158
|
+
* command: "npx", // Example: Launching a local server
|
|
159
|
+
* args: ["-y", "@modelcontextprotocol/server-everything", "/path/to/allowed/dir"],
|
|
160
|
+
* });
|
|
161
|
+
*
|
|
162
|
+
* // To get tools from this client:
|
|
163
|
+
* // const tools = await client.getActiveTools(ai);
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* @param options Configuration for the MCP Client, defining how it connects
|
|
167
|
+
* to the MCP server and its behavior.
|
|
168
|
+
* @returns A new instance of GenkitMcpClient.
|
|
169
|
+
*/
|
|
170
|
+
declare function createMcpClient(options: McpClientOptions): GenkitMcpClient;
|
|
171
|
+
/**
|
|
172
|
+
* Creates an MCP server based on the supplied Genkit instance. All tools and prompts
|
|
173
|
+
* will be automatically converted to MCP compatibility.
|
|
174
|
+
*
|
|
175
|
+
* ```ts
|
|
176
|
+
* const mcpServer = createMcpServer(ai, {name: 'my-mcp-server', version: '0.1.0'});
|
|
177
|
+
*
|
|
178
|
+
* await mcpServer.start(); // starts a stdio transport, OR
|
|
179
|
+
* await mcpServer.start(customMcpTransport); // starts server using supplied transport
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @param ai Your Genkit instance with registered tools and prompts.
|
|
183
|
+
* @param options Configuration metadata for the server.
|
|
184
|
+
* @returns GenkitMcpServer instance.
|
|
185
|
+
*/
|
|
186
|
+
declare function createMcpServer(ai: Genkit, options: McpServerOptions): GenkitMcpServer;
|
|
187
|
+
|
|
188
|
+
export { GenkitMcpServer, type McpServerOptions as M, createMcpClient as a, createMcpServer as b, createMcpHost as c };
|
package/lib/server.js
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var server_exports = {};
|
|
30
|
+
__export(server_exports, {
|
|
31
|
+
GenkitMcpServer: () => GenkitMcpServer
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(server_exports);
|
|
34
|
+
var import_genkit = require("genkit");
|
|
35
|
+
var import_logging = require("genkit/logging");
|
|
36
|
+
var import_schema = require("genkit/schema");
|
|
37
|
+
var import_tool = require("genkit/tool");
|
|
38
|
+
class GenkitMcpServer {
|
|
39
|
+
ai;
|
|
40
|
+
options;
|
|
41
|
+
server;
|
|
42
|
+
actionsResolved = false;
|
|
43
|
+
toolActions = [];
|
|
44
|
+
promptActions = [];
|
|
45
|
+
/**
|
|
46
|
+
* Creates an instance of GenkitMcpServer.
|
|
47
|
+
* @param ai The Genkit instance whose actions will be exposed.
|
|
48
|
+
* @param options Configuration options for the MCP server, like its name and version.
|
|
49
|
+
*/
|
|
50
|
+
constructor(ai, options) {
|
|
51
|
+
this.ai = ai;
|
|
52
|
+
this.options = options;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Initializes the MCP server instance and registers request handlers. It
|
|
56
|
+
* dynamically imports MCP SDK components and sets up handlers for listing
|
|
57
|
+
* tools, calling tools, listing prompts, and getting prompts. It also
|
|
58
|
+
* resolves and stores all tool and prompt actions from the Genkit instance.
|
|
59
|
+
*
|
|
60
|
+
* This method is called by the constructor and ensures the server is ready
|
|
61
|
+
* before any requests are handled. It's idempotent.
|
|
62
|
+
*/
|
|
63
|
+
async setup() {
|
|
64
|
+
if (this.actionsResolved) return;
|
|
65
|
+
const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
|
|
66
|
+
this.server = new Server(
|
|
67
|
+
{ name: this.options.name, version: this.options.version || "1.0.0" },
|
|
68
|
+
{
|
|
69
|
+
capabilities: {
|
|
70
|
+
prompts: {},
|
|
71
|
+
tools: {}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
const {
|
|
76
|
+
CallToolRequestSchema,
|
|
77
|
+
GetPromptRequestSchema,
|
|
78
|
+
ListPromptsRequestSchema,
|
|
79
|
+
ListToolsRequestSchema
|
|
80
|
+
} = await import("@modelcontextprotocol/sdk/types.js");
|
|
81
|
+
this.server.setRequestHandler(
|
|
82
|
+
ListToolsRequestSchema,
|
|
83
|
+
this.listTools.bind(this)
|
|
84
|
+
);
|
|
85
|
+
this.server.setRequestHandler(
|
|
86
|
+
CallToolRequestSchema,
|
|
87
|
+
this.callTool.bind(this)
|
|
88
|
+
);
|
|
89
|
+
this.server.setRequestHandler(
|
|
90
|
+
ListPromptsRequestSchema,
|
|
91
|
+
this.listPrompts.bind(this)
|
|
92
|
+
);
|
|
93
|
+
this.server.setRequestHandler(
|
|
94
|
+
GetPromptRequestSchema,
|
|
95
|
+
this.getPrompt.bind(this)
|
|
96
|
+
);
|
|
97
|
+
const allActions = await this.ai.registry.listActions();
|
|
98
|
+
const toolList = [];
|
|
99
|
+
const promptList = [];
|
|
100
|
+
for (const k in allActions) {
|
|
101
|
+
if (k.startsWith("/tool/")) {
|
|
102
|
+
toolList.push(allActions[k]);
|
|
103
|
+
} else if (k.startsWith("/prompt/")) {
|
|
104
|
+
promptList.push(allActions[k]);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
this.toolActions = toolList;
|
|
108
|
+
this.promptActions = promptList;
|
|
109
|
+
this.actionsResolved = true;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Handles MCP requests to list available tools.
|
|
113
|
+
* It maps the resolved Genkit tool actions to the MCP Tool format.
|
|
114
|
+
* @param req The MCP ListToolsRequest.
|
|
115
|
+
* @returns A Promise resolving to an MCP ListToolsResult.
|
|
116
|
+
*/
|
|
117
|
+
async listTools(req) {
|
|
118
|
+
await this.setup();
|
|
119
|
+
return {
|
|
120
|
+
tools: this.toolActions.map((t) => {
|
|
121
|
+
const def = (0, import_tool.toToolDefinition)(t);
|
|
122
|
+
return {
|
|
123
|
+
name: def.name,
|
|
124
|
+
inputSchema: def.inputSchema || { type: "object" },
|
|
125
|
+
description: def.description,
|
|
126
|
+
_meta: t.__action.metadata?.mcp?._meta
|
|
127
|
+
};
|
|
128
|
+
})
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Handles MCP requests to call a specific tool. It finds the corresponding
|
|
133
|
+
* Genkit tool action and executes it with the provided arguments. The result
|
|
134
|
+
* is then formatted as an MCP CallToolResult.
|
|
135
|
+
* @param req The MCP CallToolRequest containing the tool name and arguments.
|
|
136
|
+
* @returns A Promise resolving to an MCP CallToolResult.
|
|
137
|
+
* @throws GenkitError if the requested tool is not found.
|
|
138
|
+
*/
|
|
139
|
+
async callTool(req) {
|
|
140
|
+
await this.setup();
|
|
141
|
+
const tool = this.toolActions.find(
|
|
142
|
+
(t) => t.__action.name === req.params.name
|
|
143
|
+
);
|
|
144
|
+
if (!tool)
|
|
145
|
+
throw new import_genkit.GenkitError({
|
|
146
|
+
status: "NOT_FOUND",
|
|
147
|
+
message: `Tried to call tool '${req.params.name}' but it could not be found.`
|
|
148
|
+
});
|
|
149
|
+
const result = await tool(req.params.arguments);
|
|
150
|
+
return {
|
|
151
|
+
content: [
|
|
152
|
+
{
|
|
153
|
+
type: "text",
|
|
154
|
+
text: typeof result === "string" ? result : JSON.stringify(result)
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Handles MCP requests to list available prompts.
|
|
161
|
+
* It maps the resolved Genkit prompt actions to the MCP Prompt format,
|
|
162
|
+
* including converting input schemas to MCP argument definitions.
|
|
163
|
+
* @param req The MCP ListPromptsRequest.
|
|
164
|
+
* @returns A Promise resolving to an MCP ListPromptsResult.
|
|
165
|
+
*/
|
|
166
|
+
async listPrompts(req) {
|
|
167
|
+
await this.setup();
|
|
168
|
+
return {
|
|
169
|
+
prompts: this.promptActions.map((p) => {
|
|
170
|
+
return {
|
|
171
|
+
name: p.__action.name,
|
|
172
|
+
description: p.__action.description,
|
|
173
|
+
arguments: toMcpPromptArguments(p),
|
|
174
|
+
_meta: p.__action.metadata?.mcp?._meta
|
|
175
|
+
};
|
|
176
|
+
})
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Handles MCP requests to get (render) a specific prompt. It finds the
|
|
181
|
+
* corresponding Genkit prompt action, executes it with the provided
|
|
182
|
+
* arguments, and then formats the resulting messages into the MCP
|
|
183
|
+
* PromptMessage format.
|
|
184
|
+
* @param req The MCP GetPromptRequest containing the prompt name and
|
|
185
|
+
* arguments.
|
|
186
|
+
* @returns A Promise resolving to an MCP GetPromptResult.
|
|
187
|
+
* @throws GenkitError if the requested prompt is not found.
|
|
188
|
+
*/
|
|
189
|
+
async getPrompt(req) {
|
|
190
|
+
await this.setup();
|
|
191
|
+
const prompt = this.promptActions.find(
|
|
192
|
+
(p) => p.__action.name === req.params.name
|
|
193
|
+
);
|
|
194
|
+
if (!prompt)
|
|
195
|
+
throw new import_genkit.GenkitError({
|
|
196
|
+
status: "NOT_FOUND",
|
|
197
|
+
message: `[MCP Server] Tried to call prompt '${req.params.name}' but it could not be found.`
|
|
198
|
+
});
|
|
199
|
+
const result = await prompt(req.params.arguments);
|
|
200
|
+
return {
|
|
201
|
+
description: prompt.__action.description,
|
|
202
|
+
messages: result.messages.map(toMcpPromptMessage)
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Starts the MCP server with the specified transport or a default
|
|
207
|
+
* StdioServerTransport. Ensures the server is set up before connecting the
|
|
208
|
+
* transport.
|
|
209
|
+
* @param transport Optional MCP transport instance. If not provided, a
|
|
210
|
+
* StdioServerTransport will be created and used.
|
|
211
|
+
*/
|
|
212
|
+
async start(transport) {
|
|
213
|
+
if (!transport) {
|
|
214
|
+
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
215
|
+
transport = new StdioServerTransport();
|
|
216
|
+
}
|
|
217
|
+
await this.setup();
|
|
218
|
+
await this.server.connect(transport);
|
|
219
|
+
import_logging.logger.info(
|
|
220
|
+
`[MCP Server] MCP server '${this.options.name}' started successfully.`
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function toMcpPromptArguments(p) {
|
|
225
|
+
const jsonSchema = (0, import_schema.toJsonSchema)({
|
|
226
|
+
schema: p.__action.inputSchema,
|
|
227
|
+
jsonSchema: p.__action.inputJsonSchema
|
|
228
|
+
});
|
|
229
|
+
if (!jsonSchema) return void 0;
|
|
230
|
+
if (!jsonSchema.properties)
|
|
231
|
+
throw new import_genkit.GenkitError({
|
|
232
|
+
status: "FAILED_PRECONDITION",
|
|
233
|
+
message: "[MCP Server] MCP prompts must take objects as input schema."
|
|
234
|
+
});
|
|
235
|
+
const args = [];
|
|
236
|
+
for (const k in jsonSchema.properties) {
|
|
237
|
+
const { type, description } = jsonSchema.properties[k];
|
|
238
|
+
if (type !== "string" && (!Array.isArray(type) || !type.includes("string"))) {
|
|
239
|
+
throw new import_genkit.GenkitError({
|
|
240
|
+
status: "FAILED_PRECONDITION",
|
|
241
|
+
message: `[MCP Server] MCP prompts may only take string arguments, but ${p.__action.name} has property '${k}' of type '${type}'.`
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
args.push({
|
|
245
|
+
name: k,
|
|
246
|
+
description,
|
|
247
|
+
required: jsonSchema.required?.includes(k)
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
return args;
|
|
251
|
+
}
|
|
252
|
+
const ROLE_MAP = { model: "assistant", user: "user" };
|
|
253
|
+
function toMcpPromptMessage(messageData) {
|
|
254
|
+
if (messageData.role !== "model" && messageData.role !== "user") {
|
|
255
|
+
throw new import_genkit.GenkitError({
|
|
256
|
+
status: "UNIMPLEMENTED",
|
|
257
|
+
message: `[MCP Server] MCP prompt messages do not support role '${messageData.role}'. Only 'user' and 'model' messages are supported.`
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
const message = new import_genkit.Message(messageData);
|
|
261
|
+
const common = { role: ROLE_MAP[messageData.role] };
|
|
262
|
+
if (message.media) {
|
|
263
|
+
const { url, contentType } = message.media;
|
|
264
|
+
if (!url.startsWith("data:"))
|
|
265
|
+
throw new import_genkit.GenkitError({
|
|
266
|
+
status: "UNIMPLEMENTED",
|
|
267
|
+
message: `[MCP Server] MCP prompt messages only support base64 data images.`
|
|
268
|
+
});
|
|
269
|
+
const mimeType = contentType || url.substring(url.indexOf(":") + 1, url.indexOf(";"));
|
|
270
|
+
const data = url.substring(url.indexOf(",") + 1);
|
|
271
|
+
return { ...common, content: { type: "image", mimeType, data } };
|
|
272
|
+
} else {
|
|
273
|
+
return { ...common, content: { type: "text", text: message.text } };
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
277
|
+
0 && (module.exports = {
|
|
278
|
+
GenkitMcpServer
|
|
279
|
+
});
|
|
280
|
+
//# sourceMappingURL=server.js.map
|