@genkit-ai/mcp 1.30.1 → 1.31.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/lib/index.d.mts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/server.d.mts +1 -1
- package/lib/server.d.ts +1 -1
- package/lib/util/message.d.mts +1 -1
- package/lib/util/message.d.ts +1 -1
- package/lib/util/message.js +1 -1
- package/lib/util/message.js.map +1 -1
- package/lib/util/message.mjs +1 -1
- package/lib/util/message.mjs.map +1 -1
- package/lib/util/prompts.js +2 -2
- package/lib/util/prompts.js.map +1 -1
- package/lib/util/prompts.mjs +2 -2
- package/lib/util/prompts.mjs.map +1 -1
- package/lib/util/resource.js +3 -3
- package/lib/util/resource.js.map +1 -1
- package/lib/util/resource.mjs +3 -3
- package/lib/util/resource.mjs.map +1 -1
- package/lib/util/tools.js +2 -2
- package/lib/util/tools.js.map +1 -1
- package/lib/util/tools.mjs +2 -2
- package/lib/util/tools.mjs.map +1 -1
- package/package.json +3 -3
- package/src/util/message.ts +1 -1
- package/src/util/resource.ts +3 -3
- package/src/util/tools.ts +2 -2
package/lib/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import 'genkit';
|
|
2
2
|
export { GenkitMcpClient, McpClientOptions, McpClientOptionsWithCache, McpServerConfig, McpStdioServerConfig } from './client/client.mjs';
|
|
3
3
|
export { GenkitMcpHost, McpHostOptions, McpHostOptionsWithCache } from './client/host.mjs';
|
|
4
|
-
export { M as McpServerOptions,
|
|
4
|
+
export { M as McpServerOptions, c as createMcpClient, a as createMcpHost, b as createMcpServer, d as defineMcpClient, e as defineMcpHost } from './server.mjs';
|
|
5
5
|
import '@modelcontextprotocol/sdk/client/index.js';
|
|
6
6
|
import '@modelcontextprotocol/sdk/client/stdio.js';
|
|
7
7
|
import '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import 'genkit';
|
|
2
2
|
export { GenkitMcpClient, McpClientOptions, McpClientOptionsWithCache, McpServerConfig, McpStdioServerConfig } from './client/client.js';
|
|
3
3
|
export { GenkitMcpHost, McpHostOptions, McpHostOptionsWithCache } from './client/host.js';
|
|
4
|
-
export { M as McpServerOptions,
|
|
4
|
+
export { M as McpServerOptions, c as createMcpClient, a as createMcpHost, b as createMcpServer, d as defineMcpClient, e as defineMcpHost } from './server.js';
|
|
5
5
|
import '@modelcontextprotocol/sdk/client/index.js';
|
|
6
6
|
import '@modelcontextprotocol/sdk/client/stdio.js';
|
|
7
7
|
import '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
package/lib/server.d.mts
CHANGED
|
@@ -258,4 +258,4 @@ declare function defineMcpClient(ai: Genkit, options: McpClientOptionsWithCache)
|
|
|
258
258
|
*/
|
|
259
259
|
declare function createMcpServer(ai: Genkit, options: McpServerOptions): GenkitMcpServer;
|
|
260
260
|
|
|
261
|
-
export { GenkitMcpServer, type McpServerOptions as M,
|
|
261
|
+
export { GenkitMcpServer, type McpServerOptions as M, createMcpHost as a, createMcpServer as b, createMcpClient as c, defineMcpClient as d, defineMcpHost as e };
|
package/lib/server.d.ts
CHANGED
|
@@ -258,4 +258,4 @@ declare function defineMcpClient(ai: Genkit, options: McpClientOptionsWithCache)
|
|
|
258
258
|
*/
|
|
259
259
|
declare function createMcpServer(ai: Genkit, options: McpServerOptions): GenkitMcpServer;
|
|
260
260
|
|
|
261
|
-
export { GenkitMcpServer, type McpServerOptions as M,
|
|
261
|
+
export { GenkitMcpServer, type McpServerOptions as M, createMcpHost as a, createMcpServer as b, createMcpClient as c, defineMcpClient as d, defineMcpHost as e };
|
package/lib/util/message.d.mts
CHANGED
package/lib/util/message.d.ts
CHANGED
package/lib/util/message.js
CHANGED
package/lib/util/message.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/message.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PromptMessage } from '@modelcontextprotocol/sdk/types.js' with { 'resolution-mode': 'import' };\nimport { type MessageData, type Part } from 'genkit';\n\nconst ROLE_MAP = {\n user: 'user',\n assistant: 'model',\n} as const;\n\n/**\n * Converts an MCP (Model Context Protocol) PromptMessage into Genkit's\n * MessageData format. This involves mapping MCP roles (user, assistant) to\n * Genkit roles (user, model) and transforming the MCP content part into a\n * Genkit Part.\n *\n * @param message The MCP PromptMessage to convert.\n * @returns The corresponding Genkit MessageData object.\n */\nexport function fromMcpPromptMessage(message: PromptMessage): MessageData {\n return {\n role: ROLE_MAP[message.role],\n content: [fromMcpPart(message.content)],\n };\n}\n\n/**\n * Converts an MCP message content part (text, image, or resource) into a Genkit\n * Part.\n * - Text parts are directly mapped.\n * - Image parts are converted to Genkit media parts with a data URL.\n * - Resource parts currently result in an empty Genkit Part (further\n * implementation may be needed).\n *\n * @param part The MCP PromptMessage content part to convert.\n * @returns The corresponding Genkit Part.\n */\nexport function fromMcpPart(part: PromptMessage['content']): Part {\n switch (part.type) {\n case 'text':\n return { text: part.text };\n case 'image':\n return {\n media: {\n contentType: part.mimeType,\n url: `data:${part.mimeType};base64,${part.data}`,\n },\n };\n case 'resource':\n return {\n resource: {\n uri: part.uri
|
|
1
|
+
{"version":3,"sources":["../../src/util/message.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PromptMessage } from '@modelcontextprotocol/sdk/types.js' with { 'resolution-mode': 'import' };\nimport { type MessageData, type Part } from 'genkit';\n\nconst ROLE_MAP = {\n user: 'user',\n assistant: 'model',\n} as const;\n\n/**\n * Converts an MCP (Model Context Protocol) PromptMessage into Genkit's\n * MessageData format. This involves mapping MCP roles (user, assistant) to\n * Genkit roles (user, model) and transforming the MCP content part into a\n * Genkit Part.\n *\n * @param message The MCP PromptMessage to convert.\n * @returns The corresponding Genkit MessageData object.\n */\nexport function fromMcpPromptMessage(message: PromptMessage): MessageData {\n return {\n role: ROLE_MAP[message.role],\n content: [fromMcpPart(message.content)],\n };\n}\n\n/**\n * Converts an MCP message content part (text, image, or resource) into a Genkit\n * Part.\n * - Text parts are directly mapped.\n * - Image parts are converted to Genkit media parts with a data URL.\n * - Resource parts currently result in an empty Genkit Part (further\n * implementation may be needed).\n *\n * @param part The MCP PromptMessage content part to convert.\n * @returns The corresponding Genkit Part.\n */\nexport function fromMcpPart(part: PromptMessage['content']): Part {\n switch (part.type) {\n case 'text':\n return { text: part.text };\n case 'image':\n return {\n media: {\n contentType: part.mimeType,\n url: `data:${part.mimeType};base64,${part.data}`,\n },\n };\n case 'resource':\n return {\n resource: {\n uri: part.resource.uri,\n },\n };\n default:\n return {};\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBA,MAAM,WAAW;AAAA,EACf,MAAM;AAAA,EACN,WAAW;AACb;AAWO,SAAS,qBAAqB,SAAqC;AACxE,SAAO;AAAA,IACL,MAAM,SAAS,QAAQ,IAAI;AAAA,IAC3B,SAAS,CAAC,YAAY,QAAQ,OAAO,CAAC;AAAA,EACxC;AACF;AAaO,SAAS,YAAY,MAAsC;AAChE,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,EAAE,MAAM,KAAK,KAAK;AAAA,IAC3B,KAAK;AACH,aAAO;AAAA,QACL,OAAO;AAAA,UACL,aAAa,KAAK;AAAA,UAClB,KAAK,QAAQ,KAAK,QAAQ,WAAW,KAAK,IAAI;AAAA,QAChD;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,UAAU;AAAA,UACR,KAAK,KAAK,SAAS;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AACE,aAAO,CAAC;AAAA,EACZ;AACF;","names":[]}
|
package/lib/util/message.mjs
CHANGED
package/lib/util/message.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/message.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PromptMessage } from '@modelcontextprotocol/sdk/types.js' with { 'resolution-mode': 'import' };\nimport { type MessageData, type Part } from 'genkit';\n\nconst ROLE_MAP = {\n user: 'user',\n assistant: 'model',\n} as const;\n\n/**\n * Converts an MCP (Model Context Protocol) PromptMessage into Genkit's\n * MessageData format. This involves mapping MCP roles (user, assistant) to\n * Genkit roles (user, model) and transforming the MCP content part into a\n * Genkit Part.\n *\n * @param message The MCP PromptMessage to convert.\n * @returns The corresponding Genkit MessageData object.\n */\nexport function fromMcpPromptMessage(message: PromptMessage): MessageData {\n return {\n role: ROLE_MAP[message.role],\n content: [fromMcpPart(message.content)],\n };\n}\n\n/**\n * Converts an MCP message content part (text, image, or resource) into a Genkit\n * Part.\n * - Text parts are directly mapped.\n * - Image parts are converted to Genkit media parts with a data URL.\n * - Resource parts currently result in an empty Genkit Part (further\n * implementation may be needed).\n *\n * @param part The MCP PromptMessage content part to convert.\n * @returns The corresponding Genkit Part.\n */\nexport function fromMcpPart(part: PromptMessage['content']): Part {\n switch (part.type) {\n case 'text':\n return { text: part.text };\n case 'image':\n return {\n media: {\n contentType: part.mimeType,\n url: `data:${part.mimeType};base64,${part.data}`,\n },\n };\n case 'resource':\n return {\n resource: {\n uri: part.uri
|
|
1
|
+
{"version":3,"sources":["../../src/util/message.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PromptMessage } from '@modelcontextprotocol/sdk/types.js' with { 'resolution-mode': 'import' };\nimport { type MessageData, type Part } from 'genkit';\n\nconst ROLE_MAP = {\n user: 'user',\n assistant: 'model',\n} as const;\n\n/**\n * Converts an MCP (Model Context Protocol) PromptMessage into Genkit's\n * MessageData format. This involves mapping MCP roles (user, assistant) to\n * Genkit roles (user, model) and transforming the MCP content part into a\n * Genkit Part.\n *\n * @param message The MCP PromptMessage to convert.\n * @returns The corresponding Genkit MessageData object.\n */\nexport function fromMcpPromptMessage(message: PromptMessage): MessageData {\n return {\n role: ROLE_MAP[message.role],\n content: [fromMcpPart(message.content)],\n };\n}\n\n/**\n * Converts an MCP message content part (text, image, or resource) into a Genkit\n * Part.\n * - Text parts are directly mapped.\n * - Image parts are converted to Genkit media parts with a data URL.\n * - Resource parts currently result in an empty Genkit Part (further\n * implementation may be needed).\n *\n * @param part The MCP PromptMessage content part to convert.\n * @returns The corresponding Genkit Part.\n */\nexport function fromMcpPart(part: PromptMessage['content']): Part {\n switch (part.type) {\n case 'text':\n return { text: part.text };\n case 'image':\n return {\n media: {\n contentType: part.mimeType,\n url: `data:${part.mimeType};base64,${part.data}`,\n },\n };\n case 'resource':\n return {\n resource: {\n uri: part.resource.uri,\n },\n };\n default:\n return {};\n }\n}\n"],"mappings":"AAmBA,MAAM,WAAW;AAAA,EACf,MAAM;AAAA,EACN,WAAW;AACb;AAWO,SAAS,qBAAqB,SAAqC;AACxE,SAAO;AAAA,IACL,MAAM,SAAS,QAAQ,IAAI;AAAA,IAC3B,SAAS,CAAC,YAAY,QAAQ,OAAO,CAAC;AAAA,EACxC;AACF;AAaO,SAAS,YAAY,MAAsC;AAChE,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,EAAE,MAAM,KAAK,KAAK;AAAA,IAC3B,KAAK;AACH,aAAO;AAAA,QACL,OAAO;AAAA,UACL,aAAa,KAAK;AAAA,UAClB,KAAK,QAAQ,KAAK,QAAQ,WAAW,KAAK,IAAI;AAAA,QAChD;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,UAAU;AAAA,UACR,KAAK,KAAK,SAAS;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AACE,aAAO,CAAC;AAAA,EACZ;AACF;","names":[]}
|
package/lib/util/prompts.js
CHANGED
|
@@ -61,10 +61,10 @@ function registerPrompt(ai, client, prompt, params) {
|
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
function createExecutablePrompt(client, prompt, params) {
|
|
64
|
-
const callPrompt = async (input, opts) => {
|
|
64
|
+
const callPrompt = (async (input, opts) => {
|
|
65
65
|
import_logging.logger.debug(`[MCP] Calling MCP prompt ${params.name}/${prompt.name}`);
|
|
66
66
|
return params.ai.generate(callPrompt.render(input, opts));
|
|
67
|
-
};
|
|
67
|
+
});
|
|
68
68
|
callPrompt.ref = {
|
|
69
69
|
name: prompt.name,
|
|
70
70
|
metadata: {
|
package/lib/util/prompts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/prompts.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport type { Prompt } from '@modelcontextprotocol/sdk/types.js';\nimport {\n GenkitError,\n z,\n type ExecutablePrompt,\n type GenerateOptions,\n type GenerateResponse,\n type GenerateStreamResponse,\n type Genkit,\n type JSONSchema,\n type PromptGenerateOptions,\n type ToolAction,\n} from 'genkit';\nimport { logger } from 'genkit/logging';\nimport { fromMcpPromptMessage } from './message.js';\n\nfunction toSchema(args: Prompt['arguments']) {\n if (!args) return {};\n const schema: JSONSchema = { type: 'object', properties: {}, required: [] };\n for (const arg of args) {\n schema.properties[arg.name] = {\n type: 'string',\n description: arg.description,\n };\n if (arg.required) schema.required.push(arg.name);\n }\n return schema;\n}\n\n/**\n * Registers a single MCP prompt as a Genkit prompt.\n * It defines a new Genkit prompt action that, when called, will\n * interact with the MCP client to fetch and render the corresponding MCP prompt.\n *\n * @param ai The Genkit instance to define the prompt on.\n * @param client The MCP client instance used to interact with the MCP server.\n * @param prompt The MCP Prompt object to register.\n * @param params Contains the Genkit client name and the MCP server name for namespacing and logging.\n */\nfunction registerPrompt(\n ai: Genkit,\n client: Client,\n prompt: Prompt,\n params: { name: string; serverName: string }\n) {\n logger.debug(`[MCP] Registering MCP prompt ${params.name}/${prompt.name}`);\n ai.definePrompt({\n name: prompt.name,\n description: prompt.description || '',\n input: { jsonSchema: toSchema(prompt.arguments) },\n output: { format: 'text' },\n metadata: { mcp: { _meta: prompt._meta || {} } },\n messages: async (args, { context }) => {\n logger.debug(\n `[MCP] Calling MCP prompt ${params.name}/${prompt.name} with arguments`,\n JSON.stringify(args)\n );\n const result = await client.getPrompt({\n name: prompt.name,\n arguments: args,\n _meta: context?.mcp?._meta,\n });\n return result.messages.map(fromMcpPromptMessage);\n },\n });\n}\n\nfunction createExecutablePrompt<\n I extends z.ZodTypeAny = z.ZodTypeAny,\n O extends z.ZodTypeAny = z.ZodTypeAny,\n CustomOptions extends z.ZodTypeAny = z.ZodTypeAny,\n>(\n client: Client,\n prompt: Prompt,\n params: {\n ai: Genkit;\n name: string;\n serverName: string;\n promptName: string;\n options?: PromptGenerateOptions<any, any>;\n }\n): ExecutablePrompt<z.infer<I>, O, CustomOptions> {\n const callPrompt = (async (\n input?: z.infer<I>,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): Promise<GenerateResponse<z.infer<O>>> => {\n logger.debug(`[MCP] Calling MCP prompt ${params.name}/${prompt.name}`);\n return params.ai.generate(callPrompt.render(input, opts));\n }) as ExecutablePrompt<z.infer<I>, O, CustomOptions>;\n\n callPrompt.ref = {\n name: prompt.name,\n metadata: {\n description: prompt.description,\n arguments: prompt.arguments,\n mcp: { _meta: prompt._meta || {} },\n },\n };\n\n callPrompt.stream = (\n input?: z.infer<I>,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): GenerateStreamResponse<z.infer<O>> => {\n logger.debug(`[MCP] Streaming MCP prompt ${params.name}/${prompt.name}`);\n return params.ai.generateStream(callPrompt.render(input, opts));\n };\n\n callPrompt.render = async (\n input?: I,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): Promise<GenerateOptions<O, CustomOptions>> => {\n logger.debug(`[MCP] Rendering MCP prompt ${params.name}/${prompt.name}`);\n const result = await client.getPrompt({\n name: prompt.name,\n arguments: input as any,\n _meta: opts?.context?.mcp?._meta,\n });\n const messages = result.messages.map(fromMcpPromptMessage);\n return {\n ...params.options,\n ...opts,\n messages,\n };\n };\n\n callPrompt.asTool = async (): Promise<ToolAction> => {\n throw new GenkitError({\n status: 'UNIMPLEMENTED',\n message: `[MCP] prompt.asTool not supported with MCP`,\n });\n };\n\n return callPrompt;\n}\n\n/**\n * Lookup all prompts available in the server and register each as a Genkit\n * prompt.\n */\nexport async function registerAllPrompts(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string }\n): Promise<void> {\n let cursor: string | undefined;\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n prompts.forEach((p) => registerPrompt(ai, client, p, params));\n cursor = nextCursor;\n if (!cursor) break;\n }\n}\n\n/**\n * Lookup a specified prompt from the server and return as an ExecutablePrompt.\n */\nexport async function getExecutablePrompt(\n client: Client,\n params: {\n name: string;\n serverName: string;\n promptName: string;\n ai: Genkit;\n options?: PromptGenerateOptions;\n }\n): Promise<ExecutablePrompt | undefined> {\n let cursor: string | undefined;\n\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n const maybePrompt = prompts.find(\n (p: Prompt) => p.name === params.promptName\n );\n if (maybePrompt) {\n return createExecutablePrompt(client, maybePrompt, params);\n }\n cursor = nextCursor;\n if (!cursor) break;\n }\n return undefined;\n}\n\nexport async function fetchAllPrompts(\n client: Client,\n params: {\n name: string;\n serverName: string;\n ai: Genkit;\n options?: PromptGenerateOptions;\n }\n): Promise<ExecutablePrompt[]> {\n let cursor: string | undefined;\n const out: ExecutablePrompt[] = [];\n\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n for (const p of prompts) {\n out.push(\n createExecutablePrompt(client, p, { ...params, promptName: p.name })\n );\n }\n cursor = nextCursor;\n if (!cursor) break;\n }\n return out;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBA,oBAWO;AACP,qBAAuB;AACvB,qBAAqC;AAErC,SAAS,SAAS,MAA2B;AAC3C,MAAI,CAAC,KAAM,QAAO,CAAC;AACnB,QAAM,SAAqB,EAAE,MAAM,UAAU,YAAY,CAAC,GAAG,UAAU,CAAC,EAAE;AAC1E,aAAW,OAAO,MAAM;AACtB,WAAO,WAAW,IAAI,IAAI,IAAI;AAAA,MAC5B,MAAM;AAAA,MACN,aAAa,IAAI;AAAA,IACnB;AACA,QAAI,IAAI,SAAU,QAAO,SAAS,KAAK,IAAI,IAAI;AAAA,EACjD;AACA,SAAO;AACT;AAYA,SAAS,eACP,IACA,QACA,QACA,QACA;AACA,wBAAO,MAAM,gCAAgC,OAAO,IAAI,IAAI,OAAO,IAAI,EAAE;AACzE,KAAG,aAAa;AAAA,IACd,MAAM,OAAO;AAAA,IACb,aAAa,OAAO,eAAe;AAAA,IACnC,OAAO,EAAE,YAAY,SAAS,OAAO,SAAS,EAAE;AAAA,IAChD,QAAQ,EAAE,QAAQ,OAAO;AAAA,IACzB,UAAU,EAAE,KAAK,EAAE,OAAO,OAAO,SAAS,CAAC,EAAE,EAAE;AAAA,IAC/C,UAAU,OAAO,MAAM,EAAE,QAAQ,MAAM;AACrC,4BAAO;AAAA,QACL,4BAA4B,OAAO,IAAI,IAAI,OAAO,IAAI;AAAA,QACtD,KAAK,UAAU,IAAI;AAAA,MACrB;AACA,YAAM,SAAS,MAAM,OAAO,UAAU;AAAA,QACpC,MAAM,OAAO;AAAA,QACb,WAAW;AAAA,QACX,OAAO,SAAS,KAAK;AAAA,MACvB,CAAC;AACD,aAAO,OAAO,SAAS,IAAI,mCAAoB;AAAA,IACjD;AAAA,EACF,CAAC;AACH;AAEA,SAAS,uBAKP,QACA,QACA,QAOgD;AAChD,QAAM,
|
|
1
|
+
{"version":3,"sources":["../../src/util/prompts.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport type { Prompt } from '@modelcontextprotocol/sdk/types.js';\nimport {\n GenkitError,\n z,\n type ExecutablePrompt,\n type GenerateOptions,\n type GenerateResponse,\n type GenerateStreamResponse,\n type Genkit,\n type JSONSchema,\n type PromptGenerateOptions,\n type ToolAction,\n} from 'genkit';\nimport { logger } from 'genkit/logging';\nimport { fromMcpPromptMessage } from './message.js';\n\nfunction toSchema(args: Prompt['arguments']) {\n if (!args) return {};\n const schema: JSONSchema = { type: 'object', properties: {}, required: [] };\n for (const arg of args) {\n schema.properties[arg.name] = {\n type: 'string',\n description: arg.description,\n };\n if (arg.required) schema.required.push(arg.name);\n }\n return schema;\n}\n\n/**\n * Registers a single MCP prompt as a Genkit prompt.\n * It defines a new Genkit prompt action that, when called, will\n * interact with the MCP client to fetch and render the corresponding MCP prompt.\n *\n * @param ai The Genkit instance to define the prompt on.\n * @param client The MCP client instance used to interact with the MCP server.\n * @param prompt The MCP Prompt object to register.\n * @param params Contains the Genkit client name and the MCP server name for namespacing and logging.\n */\nfunction registerPrompt(\n ai: Genkit,\n client: Client,\n prompt: Prompt,\n params: { name: string; serverName: string }\n) {\n logger.debug(`[MCP] Registering MCP prompt ${params.name}/${prompt.name}`);\n ai.definePrompt({\n name: prompt.name,\n description: prompt.description || '',\n input: { jsonSchema: toSchema(prompt.arguments) },\n output: { format: 'text' },\n metadata: { mcp: { _meta: prompt._meta || {} } },\n messages: async (args, { context }) => {\n logger.debug(\n `[MCP] Calling MCP prompt ${params.name}/${prompt.name} with arguments`,\n JSON.stringify(args)\n );\n const result = await client.getPrompt({\n name: prompt.name,\n arguments: args,\n _meta: context?.mcp?._meta,\n });\n return result.messages.map(fromMcpPromptMessage);\n },\n });\n}\n\nfunction createExecutablePrompt<\n I extends z.ZodTypeAny = z.ZodTypeAny,\n O extends z.ZodTypeAny = z.ZodTypeAny,\n CustomOptions extends z.ZodTypeAny = z.ZodTypeAny,\n>(\n client: Client,\n prompt: Prompt,\n params: {\n ai: Genkit;\n name: string;\n serverName: string;\n promptName: string;\n options?: PromptGenerateOptions<any, any>;\n }\n): ExecutablePrompt<z.infer<I>, O, CustomOptions> {\n const callPrompt = (async (\n input?: z.infer<I>,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): Promise<GenerateResponse<z.infer<O>>> => {\n logger.debug(`[MCP] Calling MCP prompt ${params.name}/${prompt.name}`);\n return params.ai.generate(callPrompt.render(input, opts));\n }) as ExecutablePrompt<z.infer<I>, O, CustomOptions>;\n\n callPrompt.ref = {\n name: prompt.name,\n metadata: {\n description: prompt.description,\n arguments: prompt.arguments,\n mcp: { _meta: prompt._meta || {} },\n },\n };\n\n callPrompt.stream = (\n input?: z.infer<I>,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): GenerateStreamResponse<z.infer<O>> => {\n logger.debug(`[MCP] Streaming MCP prompt ${params.name}/${prompt.name}`);\n return params.ai.generateStream(callPrompt.render(input, opts));\n };\n\n callPrompt.render = async (\n input?: I,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): Promise<GenerateOptions<O, CustomOptions>> => {\n logger.debug(`[MCP] Rendering MCP prompt ${params.name}/${prompt.name}`);\n const result = await client.getPrompt({\n name: prompt.name,\n arguments: input as any,\n _meta: opts?.context?.mcp?._meta,\n });\n const messages = result.messages.map(fromMcpPromptMessage);\n return {\n ...params.options,\n ...opts,\n messages,\n };\n };\n\n callPrompt.asTool = async (): Promise<ToolAction> => {\n throw new GenkitError({\n status: 'UNIMPLEMENTED',\n message: `[MCP] prompt.asTool not supported with MCP`,\n });\n };\n\n return callPrompt;\n}\n\n/**\n * Lookup all prompts available in the server and register each as a Genkit\n * prompt.\n */\nexport async function registerAllPrompts(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string }\n): Promise<void> {\n let cursor: string | undefined;\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n prompts.forEach((p) => registerPrompt(ai, client, p, params));\n cursor = nextCursor;\n if (!cursor) break;\n }\n}\n\n/**\n * Lookup a specified prompt from the server and return as an ExecutablePrompt.\n */\nexport async function getExecutablePrompt(\n client: Client,\n params: {\n name: string;\n serverName: string;\n promptName: string;\n ai: Genkit;\n options?: PromptGenerateOptions;\n }\n): Promise<ExecutablePrompt | undefined> {\n let cursor: string | undefined;\n\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n const maybePrompt = prompts.find(\n (p: Prompt) => p.name === params.promptName\n );\n if (maybePrompt) {\n return createExecutablePrompt(client, maybePrompt, params);\n }\n cursor = nextCursor;\n if (!cursor) break;\n }\n return undefined;\n}\n\nexport async function fetchAllPrompts(\n client: Client,\n params: {\n name: string;\n serverName: string;\n ai: Genkit;\n options?: PromptGenerateOptions;\n }\n): Promise<ExecutablePrompt[]> {\n let cursor: string | undefined;\n const out: ExecutablePrompt[] = [];\n\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n for (const p of prompts) {\n out.push(\n createExecutablePrompt(client, p, { ...params, promptName: p.name })\n );\n }\n cursor = nextCursor;\n if (!cursor) break;\n }\n return out;\n}\n"],"mappings":"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","names":[]}
|
package/lib/util/prompts.mjs
CHANGED
|
@@ -38,10 +38,10 @@ function registerPrompt(ai, client, prompt, params) {
|
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
function createExecutablePrompt(client, prompt, params) {
|
|
41
|
-
const callPrompt = async (input, opts) => {
|
|
41
|
+
const callPrompt = (async (input, opts) => {
|
|
42
42
|
logger.debug(`[MCP] Calling MCP prompt ${params.name}/${prompt.name}`);
|
|
43
43
|
return params.ai.generate(callPrompt.render(input, opts));
|
|
44
|
-
};
|
|
44
|
+
});
|
|
45
45
|
callPrompt.ref = {
|
|
46
46
|
name: prompt.name,
|
|
47
47
|
metadata: {
|
package/lib/util/prompts.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/prompts.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport type { Prompt } from '@modelcontextprotocol/sdk/types.js';\nimport {\n GenkitError,\n z,\n type ExecutablePrompt,\n type GenerateOptions,\n type GenerateResponse,\n type GenerateStreamResponse,\n type Genkit,\n type JSONSchema,\n type PromptGenerateOptions,\n type ToolAction,\n} from 'genkit';\nimport { logger } from 'genkit/logging';\nimport { fromMcpPromptMessage } from './message.js';\n\nfunction toSchema(args: Prompt['arguments']) {\n if (!args) return {};\n const schema: JSONSchema = { type: 'object', properties: {}, required: [] };\n for (const arg of args) {\n schema.properties[arg.name] = {\n type: 'string',\n description: arg.description,\n };\n if (arg.required) schema.required.push(arg.name);\n }\n return schema;\n}\n\n/**\n * Registers a single MCP prompt as a Genkit prompt.\n * It defines a new Genkit prompt action that, when called, will\n * interact with the MCP client to fetch and render the corresponding MCP prompt.\n *\n * @param ai The Genkit instance to define the prompt on.\n * @param client The MCP client instance used to interact with the MCP server.\n * @param prompt The MCP Prompt object to register.\n * @param params Contains the Genkit client name and the MCP server name for namespacing and logging.\n */\nfunction registerPrompt(\n ai: Genkit,\n client: Client,\n prompt: Prompt,\n params: { name: string; serverName: string }\n) {\n logger.debug(`[MCP] Registering MCP prompt ${params.name}/${prompt.name}`);\n ai.definePrompt({\n name: prompt.name,\n description: prompt.description || '',\n input: { jsonSchema: toSchema(prompt.arguments) },\n output: { format: 'text' },\n metadata: { mcp: { _meta: prompt._meta || {} } },\n messages: async (args, { context }) => {\n logger.debug(\n `[MCP] Calling MCP prompt ${params.name}/${prompt.name} with arguments`,\n JSON.stringify(args)\n );\n const result = await client.getPrompt({\n name: prompt.name,\n arguments: args,\n _meta: context?.mcp?._meta,\n });\n return result.messages.map(fromMcpPromptMessage);\n },\n });\n}\n\nfunction createExecutablePrompt<\n I extends z.ZodTypeAny = z.ZodTypeAny,\n O extends z.ZodTypeAny = z.ZodTypeAny,\n CustomOptions extends z.ZodTypeAny = z.ZodTypeAny,\n>(\n client: Client,\n prompt: Prompt,\n params: {\n ai: Genkit;\n name: string;\n serverName: string;\n promptName: string;\n options?: PromptGenerateOptions<any, any>;\n }\n): ExecutablePrompt<z.infer<I>, O, CustomOptions> {\n const callPrompt = (async (\n input?: z.infer<I>,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): Promise<GenerateResponse<z.infer<O>>> => {\n logger.debug(`[MCP] Calling MCP prompt ${params.name}/${prompt.name}`);\n return params.ai.generate(callPrompt.render(input, opts));\n }) as ExecutablePrompt<z.infer<I>, O, CustomOptions>;\n\n callPrompt.ref = {\n name: prompt.name,\n metadata: {\n description: prompt.description,\n arguments: prompt.arguments,\n mcp: { _meta: prompt._meta || {} },\n },\n };\n\n callPrompt.stream = (\n input?: z.infer<I>,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): GenerateStreamResponse<z.infer<O>> => {\n logger.debug(`[MCP] Streaming MCP prompt ${params.name}/${prompt.name}`);\n return params.ai.generateStream(callPrompt.render(input, opts));\n };\n\n callPrompt.render = async (\n input?: I,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): Promise<GenerateOptions<O, CustomOptions>> => {\n logger.debug(`[MCP] Rendering MCP prompt ${params.name}/${prompt.name}`);\n const result = await client.getPrompt({\n name: prompt.name,\n arguments: input as any,\n _meta: opts?.context?.mcp?._meta,\n });\n const messages = result.messages.map(fromMcpPromptMessage);\n return {\n ...params.options,\n ...opts,\n messages,\n };\n };\n\n callPrompt.asTool = async (): Promise<ToolAction> => {\n throw new GenkitError({\n status: 'UNIMPLEMENTED',\n message: `[MCP] prompt.asTool not supported with MCP`,\n });\n };\n\n return callPrompt;\n}\n\n/**\n * Lookup all prompts available in the server and register each as a Genkit\n * prompt.\n */\nexport async function registerAllPrompts(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string }\n): Promise<void> {\n let cursor: string | undefined;\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n prompts.forEach((p) => registerPrompt(ai, client, p, params));\n cursor = nextCursor;\n if (!cursor) break;\n }\n}\n\n/**\n * Lookup a specified prompt from the server and return as an ExecutablePrompt.\n */\nexport async function getExecutablePrompt(\n client: Client,\n params: {\n name: string;\n serverName: string;\n promptName: string;\n ai: Genkit;\n options?: PromptGenerateOptions;\n }\n): Promise<ExecutablePrompt | undefined> {\n let cursor: string | undefined;\n\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n const maybePrompt = prompts.find(\n (p: Prompt) => p.name === params.promptName\n );\n if (maybePrompt) {\n return createExecutablePrompt(client, maybePrompt, params);\n }\n cursor = nextCursor;\n if (!cursor) break;\n }\n return undefined;\n}\n\nexport async function fetchAllPrompts(\n client: Client,\n params: {\n name: string;\n serverName: string;\n ai: Genkit;\n options?: PromptGenerateOptions;\n }\n): Promise<ExecutablePrompt[]> {\n let cursor: string | undefined;\n const out: ExecutablePrompt[] = [];\n\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n for (const p of prompts) {\n out.push(\n createExecutablePrompt(client, p, { ...params, promptName: p.name })\n );\n }\n cursor = nextCursor;\n if (!cursor) break;\n }\n return out;\n}\n"],"mappings":"AAkBA;AAAA,EACE;AAAA,OAUK;AACP,SAAS,cAAc;AACvB,SAAS,4BAA4B;AAErC,SAAS,SAAS,MAA2B;AAC3C,MAAI,CAAC,KAAM,QAAO,CAAC;AACnB,QAAM,SAAqB,EAAE,MAAM,UAAU,YAAY,CAAC,GAAG,UAAU,CAAC,EAAE;AAC1E,aAAW,OAAO,MAAM;AACtB,WAAO,WAAW,IAAI,IAAI,IAAI;AAAA,MAC5B,MAAM;AAAA,MACN,aAAa,IAAI;AAAA,IACnB;AACA,QAAI,IAAI,SAAU,QAAO,SAAS,KAAK,IAAI,IAAI;AAAA,EACjD;AACA,SAAO;AACT;AAYA,SAAS,eACP,IACA,QACA,QACA,QACA;AACA,SAAO,MAAM,gCAAgC,OAAO,IAAI,IAAI,OAAO,IAAI,EAAE;AACzE,KAAG,aAAa;AAAA,IACd,MAAM,OAAO;AAAA,IACb,aAAa,OAAO,eAAe;AAAA,IACnC,OAAO,EAAE,YAAY,SAAS,OAAO,SAAS,EAAE;AAAA,IAChD,QAAQ,EAAE,QAAQ,OAAO;AAAA,IACzB,UAAU,EAAE,KAAK,EAAE,OAAO,OAAO,SAAS,CAAC,EAAE,EAAE;AAAA,IAC/C,UAAU,OAAO,MAAM,EAAE,QAAQ,MAAM;AACrC,aAAO;AAAA,QACL,4BAA4B,OAAO,IAAI,IAAI,OAAO,IAAI;AAAA,QACtD,KAAK,UAAU,IAAI;AAAA,MACrB;AACA,YAAM,SAAS,MAAM,OAAO,UAAU;AAAA,QACpC,MAAM,OAAO;AAAA,QACb,WAAW;AAAA,QACX,OAAO,SAAS,KAAK;AAAA,MACvB,CAAC;AACD,aAAO,OAAO,SAAS,IAAI,oBAAoB;AAAA,IACjD;AAAA,EACF,CAAC;AACH;AAEA,SAAS,uBAKP,QACA,QACA,QAOgD;AAChD,QAAM,
|
|
1
|
+
{"version":3,"sources":["../../src/util/prompts.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport type { Prompt } from '@modelcontextprotocol/sdk/types.js';\nimport {\n GenkitError,\n z,\n type ExecutablePrompt,\n type GenerateOptions,\n type GenerateResponse,\n type GenerateStreamResponse,\n type Genkit,\n type JSONSchema,\n type PromptGenerateOptions,\n type ToolAction,\n} from 'genkit';\nimport { logger } from 'genkit/logging';\nimport { fromMcpPromptMessage } from './message.js';\n\nfunction toSchema(args: Prompt['arguments']) {\n if (!args) return {};\n const schema: JSONSchema = { type: 'object', properties: {}, required: [] };\n for (const arg of args) {\n schema.properties[arg.name] = {\n type: 'string',\n description: arg.description,\n };\n if (arg.required) schema.required.push(arg.name);\n }\n return schema;\n}\n\n/**\n * Registers a single MCP prompt as a Genkit prompt.\n * It defines a new Genkit prompt action that, when called, will\n * interact with the MCP client to fetch and render the corresponding MCP prompt.\n *\n * @param ai The Genkit instance to define the prompt on.\n * @param client The MCP client instance used to interact with the MCP server.\n * @param prompt The MCP Prompt object to register.\n * @param params Contains the Genkit client name and the MCP server name for namespacing and logging.\n */\nfunction registerPrompt(\n ai: Genkit,\n client: Client,\n prompt: Prompt,\n params: { name: string; serverName: string }\n) {\n logger.debug(`[MCP] Registering MCP prompt ${params.name}/${prompt.name}`);\n ai.definePrompt({\n name: prompt.name,\n description: prompt.description || '',\n input: { jsonSchema: toSchema(prompt.arguments) },\n output: { format: 'text' },\n metadata: { mcp: { _meta: prompt._meta || {} } },\n messages: async (args, { context }) => {\n logger.debug(\n `[MCP] Calling MCP prompt ${params.name}/${prompt.name} with arguments`,\n JSON.stringify(args)\n );\n const result = await client.getPrompt({\n name: prompt.name,\n arguments: args,\n _meta: context?.mcp?._meta,\n });\n return result.messages.map(fromMcpPromptMessage);\n },\n });\n}\n\nfunction createExecutablePrompt<\n I extends z.ZodTypeAny = z.ZodTypeAny,\n O extends z.ZodTypeAny = z.ZodTypeAny,\n CustomOptions extends z.ZodTypeAny = z.ZodTypeAny,\n>(\n client: Client,\n prompt: Prompt,\n params: {\n ai: Genkit;\n name: string;\n serverName: string;\n promptName: string;\n options?: PromptGenerateOptions<any, any>;\n }\n): ExecutablePrompt<z.infer<I>, O, CustomOptions> {\n const callPrompt = (async (\n input?: z.infer<I>,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): Promise<GenerateResponse<z.infer<O>>> => {\n logger.debug(`[MCP] Calling MCP prompt ${params.name}/${prompt.name}`);\n return params.ai.generate(callPrompt.render(input, opts));\n }) as ExecutablePrompt<z.infer<I>, O, CustomOptions>;\n\n callPrompt.ref = {\n name: prompt.name,\n metadata: {\n description: prompt.description,\n arguments: prompt.arguments,\n mcp: { _meta: prompt._meta || {} },\n },\n };\n\n callPrompt.stream = (\n input?: z.infer<I>,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): GenerateStreamResponse<z.infer<O>> => {\n logger.debug(`[MCP] Streaming MCP prompt ${params.name}/${prompt.name}`);\n return params.ai.generateStream(callPrompt.render(input, opts));\n };\n\n callPrompt.render = async (\n input?: I,\n opts?: PromptGenerateOptions<O, CustomOptions>\n ): Promise<GenerateOptions<O, CustomOptions>> => {\n logger.debug(`[MCP] Rendering MCP prompt ${params.name}/${prompt.name}`);\n const result = await client.getPrompt({\n name: prompt.name,\n arguments: input as any,\n _meta: opts?.context?.mcp?._meta,\n });\n const messages = result.messages.map(fromMcpPromptMessage);\n return {\n ...params.options,\n ...opts,\n messages,\n };\n };\n\n callPrompt.asTool = async (): Promise<ToolAction> => {\n throw new GenkitError({\n status: 'UNIMPLEMENTED',\n message: `[MCP] prompt.asTool not supported with MCP`,\n });\n };\n\n return callPrompt;\n}\n\n/**\n * Lookup all prompts available in the server and register each as a Genkit\n * prompt.\n */\nexport async function registerAllPrompts(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string }\n): Promise<void> {\n let cursor: string | undefined;\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n prompts.forEach((p) => registerPrompt(ai, client, p, params));\n cursor = nextCursor;\n if (!cursor) break;\n }\n}\n\n/**\n * Lookup a specified prompt from the server and return as an ExecutablePrompt.\n */\nexport async function getExecutablePrompt(\n client: Client,\n params: {\n name: string;\n serverName: string;\n promptName: string;\n ai: Genkit;\n options?: PromptGenerateOptions;\n }\n): Promise<ExecutablePrompt | undefined> {\n let cursor: string | undefined;\n\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n const maybePrompt = prompts.find(\n (p: Prompt) => p.name === params.promptName\n );\n if (maybePrompt) {\n return createExecutablePrompt(client, maybePrompt, params);\n }\n cursor = nextCursor;\n if (!cursor) break;\n }\n return undefined;\n}\n\nexport async function fetchAllPrompts(\n client: Client,\n params: {\n name: string;\n serverName: string;\n ai: Genkit;\n options?: PromptGenerateOptions;\n }\n): Promise<ExecutablePrompt[]> {\n let cursor: string | undefined;\n const out: ExecutablePrompt[] = [];\n\n while (true) {\n const { nextCursor, prompts } = await client.listPrompts({ cursor });\n for (const p of prompts) {\n out.push(\n createExecutablePrompt(client, p, { ...params, promptName: p.name })\n );\n }\n cursor = nextCursor;\n if (!cursor) break;\n }\n return out;\n}\n"],"mappings":"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","names":[]}
|
package/lib/util/resource.js
CHANGED
|
@@ -69,10 +69,10 @@ function createDynamicResourceTemplate(client, template, params) {
|
|
|
69
69
|
);
|
|
70
70
|
}
|
|
71
71
|
function fromMcpResourcePart(part) {
|
|
72
|
-
if (part.text) {
|
|
72
|
+
if ("text" in part && part.text) {
|
|
73
73
|
return { text: part.text, metadata: part._meta };
|
|
74
74
|
}
|
|
75
|
-
if (part.blob) {
|
|
75
|
+
if ("blob" in part && part.blob) {
|
|
76
76
|
return {
|
|
77
77
|
media: {
|
|
78
78
|
contentType: part.mimeType,
|
|
@@ -83,7 +83,7 @@ function fromMcpResourcePart(part) {
|
|
|
83
83
|
}
|
|
84
84
|
throw new import_genkit.GenkitError({
|
|
85
85
|
status: "UNIMPLEMENTED",
|
|
86
|
-
message: `Part type ${part.type} is not currently supported.`
|
|
86
|
+
message: `Part type ${"type" in part ? part.type : "unknown"} is not currently supported.`
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
async function fetchDynamicResources(ai, client, params) {
|
package/lib/util/resource.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/resource.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n ReadResourceResult,\n Resource,\n ResourceTemplate,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n GenkitError,\n dynamicResource,\n type DynamicResourceAction,\n type Genkit,\n type Part,\n} from 'genkit';\nimport { logger } from 'genkit/logging';\n\nfunction createDynamicResource(\n client: Client,\n resource: Resource,\n params: { serverName: string; name: string }\n): DynamicResourceAction {\n return dynamicResource(\n {\n name: `${params.serverName}/${resource.name}`,\n description: resource.description || undefined,\n metadata: { mcp: { _meta: resource._meta || {} } },\n uri: resource.uri,\n },\n async (args, { context }) => {\n logger.debug(\n `[MCP] calling resource '${params.serverName}/${resource.name}' in host '${params.name}'`\n );\n const result = await client.readResource({\n uri: args.uri,\n _meta: context?.mcp?._meta,\n });\n return {\n content: result.contents.map((p) => fromMcpResourcePart(p)),\n };\n }\n );\n}\n\nfunction createDynamicResourceTemplate(\n client: Client,\n template: ResourceTemplate,\n params: { serverName: string; name: string }\n): DynamicResourceAction {\n return dynamicResource(\n {\n name: `${params.serverName}/${template.name}`,\n description: template.description || undefined,\n metadata: { mcp: { _meta: template._meta || {} } },\n template: template.uriTemplate,\n },\n async (args, { context }) => {\n logger.debug(\n `[MCP] calling resource template '${params.serverName}/${template.name}' in host '${params.name}'`\n );\n const result = await client.readResource({\n uri: args.uri,\n _meta: context?.mcp?._meta,\n });\n return {\n content: result.contents.map((p) => fromMcpResourcePart(p)),\n metadata: result._meta,\n };\n }\n );\n}\n\ntype ArrayElement<ArrayType extends readonly unknown[]> =\n ArrayType extends readonly (infer ElementType)[] ? ElementType : never;\n\nfunction fromMcpResourcePart(\n part: ArrayElement<ReadResourceResult['contents']>\n): Part {\n if (part.text) {\n return { text: part.text as string, metadata: part._meta };\n }\n if (part.blob) {\n return {\n media: {\n contentType: part.mimeType,\n url: `data:${part.mimeType};base64,${part.blob}`,\n },\n metadata: part._meta,\n };\n }\n throw new GenkitError({\n status: 'UNIMPLEMENTED',\n message: `Part type ${part.type} is not currently supported.`,\n });\n}\n\n/**\n * Lookup all resources available in the server and fetches as a Genkit dynamic resource.\n */\nexport async function fetchDynamicResources(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string }\n): Promise<DynamicResourceAction[]> {\n let cursor: string | undefined;\n let allResources: DynamicResourceAction[] = [];\n while (true) {\n const { nextCursor, resources } = await client.listResources({ cursor });\n allResources.push(\n ...resources.map((r) => createDynamicResource(client, r, params))\n );\n cursor = nextCursor;\n if (!cursor) break;\n }\n while (true) {\n const { nextCursor, resourceTemplates } =\n await client.listResourceTemplates({ cursor });\n allResources.push(\n ...resourceTemplates.map((r) =>\n createDynamicResourceTemplate(client, r, params)\n )\n );\n cursor = nextCursor;\n if (!cursor) break;\n }\n return allResources;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBA,oBAMO;AACP,qBAAuB;AAEvB,SAAS,sBACP,QACA,UACA,QACuB;AACvB,aAAO;AAAA,IACL;AAAA,MACE,MAAM,GAAG,OAAO,UAAU,IAAI,SAAS,IAAI;AAAA,MAC3C,aAAa,SAAS,eAAe;AAAA,MACrC,UAAU,EAAE,KAAK,EAAE,OAAO,SAAS,SAAS,CAAC,EAAE,EAAE;AAAA,MACjD,KAAK,SAAS;AAAA,IAChB;AAAA,IACA,OAAO,MAAM,EAAE,QAAQ,MAAM;AAC3B,4BAAO;AAAA,QACL,2BAA2B,OAAO,UAAU,IAAI,SAAS,IAAI,cAAc,OAAO,IAAI;AAAA,MACxF;AACA,YAAM,SAAS,MAAM,OAAO,aAAa;AAAA,QACvC,KAAK,KAAK;AAAA,QACV,OAAO,SAAS,KAAK;AAAA,MACvB,CAAC;AACD,aAAO;AAAA,QACL,SAAS,OAAO,SAAS,IAAI,CAAC,MAAM,oBAAoB,CAAC,CAAC;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,8BACP,QACA,UACA,QACuB;AACvB,aAAO;AAAA,IACL;AAAA,MACE,MAAM,GAAG,OAAO,UAAU,IAAI,SAAS,IAAI;AAAA,MAC3C,aAAa,SAAS,eAAe;AAAA,MACrC,UAAU,EAAE,KAAK,EAAE,OAAO,SAAS,SAAS,CAAC,EAAE,EAAE;AAAA,MACjD,UAAU,SAAS;AAAA,IACrB;AAAA,IACA,OAAO,MAAM,EAAE,QAAQ,MAAM;AAC3B,4BAAO;AAAA,QACL,oCAAoC,OAAO,UAAU,IAAI,SAAS,IAAI,cAAc,OAAO,IAAI;AAAA,MACjG;AACA,YAAM,SAAS,MAAM,OAAO,aAAa;AAAA,QACvC,KAAK,KAAK;AAAA,QACV,OAAO,SAAS,KAAK;AAAA,MACvB,CAAC;AACD,aAAO;AAAA,QACL,SAAS,OAAO,SAAS,IAAI,CAAC,MAAM,oBAAoB,CAAC,CAAC;AAAA,QAC1D,UAAU,OAAO;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,oBACP,MACM;AACN,MAAI,KAAK,MAAM;
|
|
1
|
+
{"version":3,"sources":["../../src/util/resource.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n ReadResourceResult,\n Resource,\n ResourceTemplate,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n GenkitError,\n dynamicResource,\n type DynamicResourceAction,\n type Genkit,\n type Part,\n} from 'genkit';\nimport { logger } from 'genkit/logging';\n\nfunction createDynamicResource(\n client: Client,\n resource: Resource,\n params: { serverName: string; name: string }\n): DynamicResourceAction {\n return dynamicResource(\n {\n name: `${params.serverName}/${resource.name}`,\n description: resource.description || undefined,\n metadata: { mcp: { _meta: resource._meta || {} } },\n uri: resource.uri,\n },\n async (args, { context }) => {\n logger.debug(\n `[MCP] calling resource '${params.serverName}/${resource.name}' in host '${params.name}'`\n );\n const result = await client.readResource({\n uri: args.uri,\n _meta: context?.mcp?._meta,\n });\n return {\n content: result.contents.map((p) => fromMcpResourcePart(p)),\n };\n }\n );\n}\n\nfunction createDynamicResourceTemplate(\n client: Client,\n template: ResourceTemplate,\n params: { serverName: string; name: string }\n): DynamicResourceAction {\n return dynamicResource(\n {\n name: `${params.serverName}/${template.name}`,\n description: template.description || undefined,\n metadata: { mcp: { _meta: template._meta || {} } },\n template: template.uriTemplate,\n },\n async (args, { context }) => {\n logger.debug(\n `[MCP] calling resource template '${params.serverName}/${template.name}' in host '${params.name}'`\n );\n const result = await client.readResource({\n uri: args.uri,\n _meta: context?.mcp?._meta,\n });\n return {\n content: result.contents.map((p) => fromMcpResourcePart(p)),\n metadata: result._meta,\n };\n }\n );\n}\n\ntype ArrayElement<ArrayType extends readonly unknown[]> =\n ArrayType extends readonly (infer ElementType)[] ? ElementType : never;\n\nfunction fromMcpResourcePart(\n part: ArrayElement<ReadResourceResult['contents']>\n): Part {\n if ('text' in part && part.text) {\n return { text: part.text as string, metadata: part._meta };\n }\n if ('blob' in part && part.blob) {\n return {\n media: {\n contentType: part.mimeType,\n url: `data:${part.mimeType};base64,${part.blob}`,\n },\n metadata: part._meta,\n };\n }\n throw new GenkitError({\n status: 'UNIMPLEMENTED',\n message: `Part type ${'type' in part ? part.type : 'unknown'} is not currently supported.`,\n });\n}\n\n/**\n * Lookup all resources available in the server and fetches as a Genkit dynamic resource.\n */\nexport async function fetchDynamicResources(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string }\n): Promise<DynamicResourceAction[]> {\n let cursor: string | undefined;\n let allResources: DynamicResourceAction[] = [];\n while (true) {\n const { nextCursor, resources } = await client.listResources({ cursor });\n allResources.push(\n ...resources.map((r) => createDynamicResource(client, r, params))\n );\n cursor = nextCursor;\n if (!cursor) break;\n }\n while (true) {\n const { nextCursor, resourceTemplates } =\n await client.listResourceTemplates({ cursor });\n allResources.push(\n ...resourceTemplates.map((r) =>\n createDynamicResourceTemplate(client, r, params)\n )\n );\n cursor = nextCursor;\n if (!cursor) break;\n }\n return allResources;\n}\n"],"mappings":"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","names":[]}
|
package/lib/util/resource.mjs
CHANGED
|
@@ -49,10 +49,10 @@ function createDynamicResourceTemplate(client, template, params) {
|
|
|
49
49
|
);
|
|
50
50
|
}
|
|
51
51
|
function fromMcpResourcePart(part) {
|
|
52
|
-
if (part.text) {
|
|
52
|
+
if ("text" in part && part.text) {
|
|
53
53
|
return { text: part.text, metadata: part._meta };
|
|
54
54
|
}
|
|
55
|
-
if (part.blob) {
|
|
55
|
+
if ("blob" in part && part.blob) {
|
|
56
56
|
return {
|
|
57
57
|
media: {
|
|
58
58
|
contentType: part.mimeType,
|
|
@@ -63,7 +63,7 @@ function fromMcpResourcePart(part) {
|
|
|
63
63
|
}
|
|
64
64
|
throw new GenkitError({
|
|
65
65
|
status: "UNIMPLEMENTED",
|
|
66
|
-
message: `Part type ${part.type} is not currently supported.`
|
|
66
|
+
message: `Part type ${"type" in part ? part.type : "unknown"} is not currently supported.`
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
async function fetchDynamicResources(ai, client, params) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/resource.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n ReadResourceResult,\n Resource,\n ResourceTemplate,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n GenkitError,\n dynamicResource,\n type DynamicResourceAction,\n type Genkit,\n type Part,\n} from 'genkit';\nimport { logger } from 'genkit/logging';\n\nfunction createDynamicResource(\n client: Client,\n resource: Resource,\n params: { serverName: string; name: string }\n): DynamicResourceAction {\n return dynamicResource(\n {\n name: `${params.serverName}/${resource.name}`,\n description: resource.description || undefined,\n metadata: { mcp: { _meta: resource._meta || {} } },\n uri: resource.uri,\n },\n async (args, { context }) => {\n logger.debug(\n `[MCP] calling resource '${params.serverName}/${resource.name}' in host '${params.name}'`\n );\n const result = await client.readResource({\n uri: args.uri,\n _meta: context?.mcp?._meta,\n });\n return {\n content: result.contents.map((p) => fromMcpResourcePart(p)),\n };\n }\n );\n}\n\nfunction createDynamicResourceTemplate(\n client: Client,\n template: ResourceTemplate,\n params: { serverName: string; name: string }\n): DynamicResourceAction {\n return dynamicResource(\n {\n name: `${params.serverName}/${template.name}`,\n description: template.description || undefined,\n metadata: { mcp: { _meta: template._meta || {} } },\n template: template.uriTemplate,\n },\n async (args, { context }) => {\n logger.debug(\n `[MCP] calling resource template '${params.serverName}/${template.name}' in host '${params.name}'`\n );\n const result = await client.readResource({\n uri: args.uri,\n _meta: context?.mcp?._meta,\n });\n return {\n content: result.contents.map((p) => fromMcpResourcePart(p)),\n metadata: result._meta,\n };\n }\n );\n}\n\ntype ArrayElement<ArrayType extends readonly unknown[]> =\n ArrayType extends readonly (infer ElementType)[] ? ElementType : never;\n\nfunction fromMcpResourcePart(\n part: ArrayElement<ReadResourceResult['contents']>\n): Part {\n if (part.text) {\n return { text: part.text as string, metadata: part._meta };\n }\n if (part.blob) {\n return {\n media: {\n contentType: part.mimeType,\n url: `data:${part.mimeType};base64,${part.blob}`,\n },\n metadata: part._meta,\n };\n }\n throw new GenkitError({\n status: 'UNIMPLEMENTED',\n message: `Part type ${part.type} is not currently supported.`,\n });\n}\n\n/**\n * Lookup all resources available in the server and fetches as a Genkit dynamic resource.\n */\nexport async function fetchDynamicResources(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string }\n): Promise<DynamicResourceAction[]> {\n let cursor: string | undefined;\n let allResources: DynamicResourceAction[] = [];\n while (true) {\n const { nextCursor, resources } = await client.listResources({ cursor });\n allResources.push(\n ...resources.map((r) => createDynamicResource(client, r, params))\n );\n cursor = nextCursor;\n if (!cursor) break;\n }\n while (true) {\n const { nextCursor, resourceTemplates } =\n await client.listResourceTemplates({ cursor });\n allResources.push(\n ...resourceTemplates.map((r) =>\n createDynamicResourceTemplate(client, r, params)\n )\n );\n cursor = nextCursor;\n if (!cursor) break;\n }\n return allResources;\n}\n"],"mappings":"AAsBA;AAAA,EACE;AAAA,EACA;AAAA,OAIK;AACP,SAAS,cAAc;AAEvB,SAAS,sBACP,QACA,UACA,QACuB;AACvB,SAAO;AAAA,IACL;AAAA,MACE,MAAM,GAAG,OAAO,UAAU,IAAI,SAAS,IAAI;AAAA,MAC3C,aAAa,SAAS,eAAe;AAAA,MACrC,UAAU,EAAE,KAAK,EAAE,OAAO,SAAS,SAAS,CAAC,EAAE,EAAE;AAAA,MACjD,KAAK,SAAS;AAAA,IAChB;AAAA,IACA,OAAO,MAAM,EAAE,QAAQ,MAAM;AAC3B,aAAO;AAAA,QACL,2BAA2B,OAAO,UAAU,IAAI,SAAS,IAAI,cAAc,OAAO,IAAI;AAAA,MACxF;AACA,YAAM,SAAS,MAAM,OAAO,aAAa;AAAA,QACvC,KAAK,KAAK;AAAA,QACV,OAAO,SAAS,KAAK;AAAA,MACvB,CAAC;AACD,aAAO;AAAA,QACL,SAAS,OAAO,SAAS,IAAI,CAAC,MAAM,oBAAoB,CAAC,CAAC;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,8BACP,QACA,UACA,QACuB;AACvB,SAAO;AAAA,IACL;AAAA,MACE,MAAM,GAAG,OAAO,UAAU,IAAI,SAAS,IAAI;AAAA,MAC3C,aAAa,SAAS,eAAe;AAAA,MACrC,UAAU,EAAE,KAAK,EAAE,OAAO,SAAS,SAAS,CAAC,EAAE,EAAE;AAAA,MACjD,UAAU,SAAS;AAAA,IACrB;AAAA,IACA,OAAO,MAAM,EAAE,QAAQ,MAAM;AAC3B,aAAO;AAAA,QACL,oCAAoC,OAAO,UAAU,IAAI,SAAS,IAAI,cAAc,OAAO,IAAI;AAAA,MACjG;AACA,YAAM,SAAS,MAAM,OAAO,aAAa;AAAA,QACvC,KAAK,KAAK;AAAA,QACV,OAAO,SAAS,KAAK;AAAA,MACvB,CAAC;AACD,aAAO;AAAA,QACL,SAAS,OAAO,SAAS,IAAI,CAAC,MAAM,oBAAoB,CAAC,CAAC;AAAA,QAC1D,UAAU,OAAO;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,oBACP,MACM;AACN,MAAI,KAAK,MAAM;
|
|
1
|
+
{"version":3,"sources":["../../src/util/resource.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n ReadResourceResult,\n Resource,\n ResourceTemplate,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n GenkitError,\n dynamicResource,\n type DynamicResourceAction,\n type Genkit,\n type Part,\n} from 'genkit';\nimport { logger } from 'genkit/logging';\n\nfunction createDynamicResource(\n client: Client,\n resource: Resource,\n params: { serverName: string; name: string }\n): DynamicResourceAction {\n return dynamicResource(\n {\n name: `${params.serverName}/${resource.name}`,\n description: resource.description || undefined,\n metadata: { mcp: { _meta: resource._meta || {} } },\n uri: resource.uri,\n },\n async (args, { context }) => {\n logger.debug(\n `[MCP] calling resource '${params.serverName}/${resource.name}' in host '${params.name}'`\n );\n const result = await client.readResource({\n uri: args.uri,\n _meta: context?.mcp?._meta,\n });\n return {\n content: result.contents.map((p) => fromMcpResourcePart(p)),\n };\n }\n );\n}\n\nfunction createDynamicResourceTemplate(\n client: Client,\n template: ResourceTemplate,\n params: { serverName: string; name: string }\n): DynamicResourceAction {\n return dynamicResource(\n {\n name: `${params.serverName}/${template.name}`,\n description: template.description || undefined,\n metadata: { mcp: { _meta: template._meta || {} } },\n template: template.uriTemplate,\n },\n async (args, { context }) => {\n logger.debug(\n `[MCP] calling resource template '${params.serverName}/${template.name}' in host '${params.name}'`\n );\n const result = await client.readResource({\n uri: args.uri,\n _meta: context?.mcp?._meta,\n });\n return {\n content: result.contents.map((p) => fromMcpResourcePart(p)),\n metadata: result._meta,\n };\n }\n );\n}\n\ntype ArrayElement<ArrayType extends readonly unknown[]> =\n ArrayType extends readonly (infer ElementType)[] ? ElementType : never;\n\nfunction fromMcpResourcePart(\n part: ArrayElement<ReadResourceResult['contents']>\n): Part {\n if ('text' in part && part.text) {\n return { text: part.text as string, metadata: part._meta };\n }\n if ('blob' in part && part.blob) {\n return {\n media: {\n contentType: part.mimeType,\n url: `data:${part.mimeType};base64,${part.blob}`,\n },\n metadata: part._meta,\n };\n }\n throw new GenkitError({\n status: 'UNIMPLEMENTED',\n message: `Part type ${'type' in part ? part.type : 'unknown'} is not currently supported.`,\n });\n}\n\n/**\n * Lookup all resources available in the server and fetches as a Genkit dynamic resource.\n */\nexport async function fetchDynamicResources(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string }\n): Promise<DynamicResourceAction[]> {\n let cursor: string | undefined;\n let allResources: DynamicResourceAction[] = [];\n while (true) {\n const { nextCursor, resources } = await client.listResources({ cursor });\n allResources.push(\n ...resources.map((r) => createDynamicResource(client, r, params))\n );\n cursor = nextCursor;\n if (!cursor) break;\n }\n while (true) {\n const { nextCursor, resourceTemplates } =\n await client.listResourceTemplates({ cursor });\n allResources.push(\n ...resourceTemplates.map((r) =>\n createDynamicResourceTemplate(client, r, params)\n )\n );\n cursor = nextCursor;\n if (!cursor) break;\n }\n return allResources;\n}\n"],"mappings":"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","names":[]}
|
package/lib/util/tools.js
CHANGED
|
@@ -24,10 +24,10 @@ __export(tools_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(tools_exports);
|
|
25
25
|
var import_genkit = require("genkit");
|
|
26
26
|
var import_logging = require("genkit/logging");
|
|
27
|
-
const toText = (c) => c.map((p) => p.text
|
|
27
|
+
const toText = (c) => c.map((p) => p.type === "text" ? p.text : "").join("");
|
|
28
28
|
function processResult(result) {
|
|
29
29
|
if (result.isError) return { error: toText(result.content) };
|
|
30
|
-
if (result.content.every((c) => !!c.text)) {
|
|
30
|
+
if (result.content.every((c) => c.type === "text" && !!c.text)) {
|
|
31
31
|
const text = toText(result.content);
|
|
32
32
|
if (text.trim().startsWith("{") || text.trim().startsWith("[")) {
|
|
33
33
|
try {
|
package/lib/util/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/tools.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport type {\n CallToolResult,\n Tool,\n} from '@modelcontextprotocol/sdk/types.js' with { 'resolution-mode': 'import' };\nimport { JSONSchema7, z, type Genkit, type ToolAction } from 'genkit';\nimport { logger } from 'genkit/logging';\n\nconst toText = (c: CallToolResult['content']) =>\n c.map((p) => p.text
|
|
1
|
+
{"version":3,"sources":["../../src/util/tools.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport type {\n CallToolResult,\n Tool,\n} from '@modelcontextprotocol/sdk/types.js' with { 'resolution-mode': 'import' };\nimport { JSONSchema7, z, type Genkit, type ToolAction } from 'genkit';\nimport { logger } from 'genkit/logging';\n\nconst toText = (c: CallToolResult['content']) =>\n c.map((p) => (p.type === 'text' ? p.text : '')).join('');\n\nfunction processResult(result: CallToolResult) {\n if (result.isError) return { error: toText(result.content) };\n if (result.content.every((c) => c.type === 'text' && !!c.text)) {\n const text = toText(result.content);\n if (text.trim().startsWith('{') || text.trim().startsWith('[')) {\n try {\n return JSON.parse(text);\n } catch (e) {\n return text;\n }\n }\n return text;\n }\n if (result.content.length === 1) return result.content[0];\n return result;\n}\n\n/**\n * Registers a single MCP tool as a Genkit tool.\n * It defines a new Genkit tool action that, when called, will\n * interact with the MCP client to execute the corresponding MCP tool.\n *\n * @param ai The Genkit instance to define the tool on.\n * @param client The MCP client instance used to interact with the MCP server.\n * @param tool The MCP Tool object to register.\n * @param params Contains the Genkit client name, MCP server name for namespacing,\n * and a flag for raw tool responses.\n */\nfunction registerTool(\n ai: Genkit,\n client: Client,\n tool: Tool,\n params: { serverName: string; name: string; rawToolResponses?: boolean }\n) {\n logger.debug(\n `[MCP] Registering tool '${params.name}/${tool.name}'' from server '${params.serverName}'`\n );\n ai.defineTool(\n {\n name: `${params.serverName}/${tool.name}`,\n description: tool.description || '',\n inputJsonSchema: tool.inputSchema as JSONSchema7,\n outputSchema: z.any(),\n metadata: { mcp: { _meta: tool._meta || {} } },\n },\n async (args) => {\n logger.debug(\n `[MCP] Calling MCP tool '${params.serverName}/${tool.name}' with arguments`,\n JSON.stringify(args)\n );\n const result = await client.callTool({\n name: tool.name,\n arguments: args,\n });\n if (params.rawToolResponses) return result;\n return processResult(result as CallToolResult);\n }\n );\n}\n\n/**\n * Creates a Genkit dynamic tool action for a given MCP tool.\n * This is similar to `registerTool` but returns the `ToolAction` directly\n * instead of defining it on the Genkit instance.\n *\n * @param ai The Genkit instance, used for creating the dynamic tool.\n * @param client The MCP client instance.\n * @param tool The MCP Tool object.\n * @param params Configuration parameters including namespacing and raw response flag.\n * @returns A Genkit `ToolAction` representing the MCP tool.\n */\nfunction createDynamicTool(\n ai: Genkit,\n client: Client,\n tool: Tool,\n params: { serverName: string; name: string; rawToolResponses?: boolean }\n): ToolAction {\n return ai.dynamicTool(\n {\n name: `${params.serverName}/${tool.name}`,\n description: tool.description || '',\n inputJsonSchema: tool.inputSchema as JSONSchema7,\n outputSchema: z.any(),\n metadata: { mcp: { _meta: tool._meta || {} } },\n },\n async (args, { context }) => {\n logger.debug(\n `[MCP] calling tool '${params.serverName}/${tool.name}' in host '${params.name}'`\n );\n const result = await client.callTool({\n name: tool.name,\n arguments: args,\n _meta: context?.mcp?._meta,\n });\n if (params.rawToolResponses) return result;\n return processResult(result as CallToolResult);\n }\n );\n}\n\n/**\n * Lookup all tools available in the server and register each as a Genkit tool.\n */\nexport async function registerAllTools(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string; rawToolResponses?: boolean }\n): Promise<void> {\n let cursor: string | undefined;\n while (true) {\n const { nextCursor, tools } = await client.listTools({ cursor });\n tools.forEach((t) => registerTool(ai, client, t, params));\n cursor = nextCursor;\n if (!cursor) break;\n }\n}\n\n/**\n * Lookup all tools available in the server and fetches as a Genkit dynamic tool.\n */\nexport async function fetchDynamicTools(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string; rawToolResponses?: boolean }\n): Promise<ToolAction[]> {\n let cursor: string | undefined;\n let allTools: ToolAction[] = [];\n while (true) {\n const { nextCursor, tools } = await client.listTools({ cursor });\n allTools.push(\n ...tools.map((t) => createDynamicTool(ai, client, t, params))\n );\n cursor = nextCursor;\n if (!cursor) break;\n }\n return allTools;\n}\n"],"mappings":"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","names":[]}
|
package/lib/util/tools.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { z } from "genkit";
|
|
2
2
|
import { logger } from "genkit/logging";
|
|
3
|
-
const toText = (c) => c.map((p) => p.text
|
|
3
|
+
const toText = (c) => c.map((p) => p.type === "text" ? p.text : "").join("");
|
|
4
4
|
function processResult(result) {
|
|
5
5
|
if (result.isError) return { error: toText(result.content) };
|
|
6
|
-
if (result.content.every((c) => !!c.text)) {
|
|
6
|
+
if (result.content.every((c) => c.type === "text" && !!c.text)) {
|
|
7
7
|
const text = toText(result.content);
|
|
8
8
|
if (text.trim().startsWith("{") || text.trim().startsWith("[")) {
|
|
9
9
|
try {
|
package/lib/util/tools.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/tools.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport type {\n CallToolResult,\n Tool,\n} from '@modelcontextprotocol/sdk/types.js' with { 'resolution-mode': 'import' };\nimport { JSONSchema7, z, type Genkit, type ToolAction } from 'genkit';\nimport { logger } from 'genkit/logging';\n\nconst toText = (c: CallToolResult['content']) =>\n c.map((p) => p.text
|
|
1
|
+
{"version":3,"sources":["../../src/util/tools.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport type {\n CallToolResult,\n Tool,\n} from '@modelcontextprotocol/sdk/types.js' with { 'resolution-mode': 'import' };\nimport { JSONSchema7, z, type Genkit, type ToolAction } from 'genkit';\nimport { logger } from 'genkit/logging';\n\nconst toText = (c: CallToolResult['content']) =>\n c.map((p) => (p.type === 'text' ? p.text : '')).join('');\n\nfunction processResult(result: CallToolResult) {\n if (result.isError) return { error: toText(result.content) };\n if (result.content.every((c) => c.type === 'text' && !!c.text)) {\n const text = toText(result.content);\n if (text.trim().startsWith('{') || text.trim().startsWith('[')) {\n try {\n return JSON.parse(text);\n } catch (e) {\n return text;\n }\n }\n return text;\n }\n if (result.content.length === 1) return result.content[0];\n return result;\n}\n\n/**\n * Registers a single MCP tool as a Genkit tool.\n * It defines a new Genkit tool action that, when called, will\n * interact with the MCP client to execute the corresponding MCP tool.\n *\n * @param ai The Genkit instance to define the tool on.\n * @param client The MCP client instance used to interact with the MCP server.\n * @param tool The MCP Tool object to register.\n * @param params Contains the Genkit client name, MCP server name for namespacing,\n * and a flag for raw tool responses.\n */\nfunction registerTool(\n ai: Genkit,\n client: Client,\n tool: Tool,\n params: { serverName: string; name: string; rawToolResponses?: boolean }\n) {\n logger.debug(\n `[MCP] Registering tool '${params.name}/${tool.name}'' from server '${params.serverName}'`\n );\n ai.defineTool(\n {\n name: `${params.serverName}/${tool.name}`,\n description: tool.description || '',\n inputJsonSchema: tool.inputSchema as JSONSchema7,\n outputSchema: z.any(),\n metadata: { mcp: { _meta: tool._meta || {} } },\n },\n async (args) => {\n logger.debug(\n `[MCP] Calling MCP tool '${params.serverName}/${tool.name}' with arguments`,\n JSON.stringify(args)\n );\n const result = await client.callTool({\n name: tool.name,\n arguments: args,\n });\n if (params.rawToolResponses) return result;\n return processResult(result as CallToolResult);\n }\n );\n}\n\n/**\n * Creates a Genkit dynamic tool action for a given MCP tool.\n * This is similar to `registerTool` but returns the `ToolAction` directly\n * instead of defining it on the Genkit instance.\n *\n * @param ai The Genkit instance, used for creating the dynamic tool.\n * @param client The MCP client instance.\n * @param tool The MCP Tool object.\n * @param params Configuration parameters including namespacing and raw response flag.\n * @returns A Genkit `ToolAction` representing the MCP tool.\n */\nfunction createDynamicTool(\n ai: Genkit,\n client: Client,\n tool: Tool,\n params: { serverName: string; name: string; rawToolResponses?: boolean }\n): ToolAction {\n return ai.dynamicTool(\n {\n name: `${params.serverName}/${tool.name}`,\n description: tool.description || '',\n inputJsonSchema: tool.inputSchema as JSONSchema7,\n outputSchema: z.any(),\n metadata: { mcp: { _meta: tool._meta || {} } },\n },\n async (args, { context }) => {\n logger.debug(\n `[MCP] calling tool '${params.serverName}/${tool.name}' in host '${params.name}'`\n );\n const result = await client.callTool({\n name: tool.name,\n arguments: args,\n _meta: context?.mcp?._meta,\n });\n if (params.rawToolResponses) return result;\n return processResult(result as CallToolResult);\n }\n );\n}\n\n/**\n * Lookup all tools available in the server and register each as a Genkit tool.\n */\nexport async function registerAllTools(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string; rawToolResponses?: boolean }\n): Promise<void> {\n let cursor: string | undefined;\n while (true) {\n const { nextCursor, tools } = await client.listTools({ cursor });\n tools.forEach((t) => registerTool(ai, client, t, params));\n cursor = nextCursor;\n if (!cursor) break;\n }\n}\n\n/**\n * Lookup all tools available in the server and fetches as a Genkit dynamic tool.\n */\nexport async function fetchDynamicTools(\n ai: Genkit,\n client: Client,\n params: { name: string; serverName: string; rawToolResponses?: boolean }\n): Promise<ToolAction[]> {\n let cursor: string | undefined;\n let allTools: ToolAction[] = [];\n while (true) {\n const { nextCursor, tools } = await client.listTools({ cursor });\n allTools.push(\n ...tools.map((t) => createDynamicTool(ai, client, t, params))\n );\n cursor = nextCursor;\n if (!cursor) break;\n }\n return allTools;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"genai",
|
|
10
10
|
"generative-ai"
|
|
11
11
|
],
|
|
12
|
-
"version": "1.
|
|
12
|
+
"version": "1.31.0",
|
|
13
13
|
"description": "A Genkit plugin that provides interoperability between Genkit and Model Context Protocol (MCP). Both client and server use cases are supported.",
|
|
14
14
|
"main": "./lib/index.js",
|
|
15
15
|
"types": "./lib/index.d.ts",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"license": "Apache-2.0",
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@modelcontextprotocol/sdk": "^1.13.0",
|
|
34
|
-
"genkit": "^1.
|
|
34
|
+
"genkit": "^1.31.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"get-port": "^5.1.0",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"ts-jest": "^29.1.2",
|
|
45
45
|
"tsup": "^8.3.5",
|
|
46
46
|
"tsx": "^4.19.2",
|
|
47
|
-
"typescript": "^5.3
|
|
47
|
+
"typescript": "^5.9.3"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"check": "tsc",
|
package/src/util/message.ts
CHANGED
package/src/util/resource.ts
CHANGED
|
@@ -90,10 +90,10 @@ type ArrayElement<ArrayType extends readonly unknown[]> =
|
|
|
90
90
|
function fromMcpResourcePart(
|
|
91
91
|
part: ArrayElement<ReadResourceResult['contents']>
|
|
92
92
|
): Part {
|
|
93
|
-
if (part.text) {
|
|
93
|
+
if ('text' in part && part.text) {
|
|
94
94
|
return { text: part.text as string, metadata: part._meta };
|
|
95
95
|
}
|
|
96
|
-
if (part.blob) {
|
|
96
|
+
if ('blob' in part && part.blob) {
|
|
97
97
|
return {
|
|
98
98
|
media: {
|
|
99
99
|
contentType: part.mimeType,
|
|
@@ -104,7 +104,7 @@ function fromMcpResourcePart(
|
|
|
104
104
|
}
|
|
105
105
|
throw new GenkitError({
|
|
106
106
|
status: 'UNIMPLEMENTED',
|
|
107
|
-
message: `Part type ${part.type} is not currently supported.`,
|
|
107
|
+
message: `Part type ${'type' in part ? part.type : 'unknown'} is not currently supported.`,
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
|
package/src/util/tools.ts
CHANGED
|
@@ -23,11 +23,11 @@ import { JSONSchema7, z, type Genkit, type ToolAction } from 'genkit';
|
|
|
23
23
|
import { logger } from 'genkit/logging';
|
|
24
24
|
|
|
25
25
|
const toText = (c: CallToolResult['content']) =>
|
|
26
|
-
c.map((p) => p.text
|
|
26
|
+
c.map((p) => (p.type === 'text' ? p.text : '')).join('');
|
|
27
27
|
|
|
28
28
|
function processResult(result: CallToolResult) {
|
|
29
29
|
if (result.isError) return { error: toText(result.content) };
|
|
30
|
-
if (result.content.every((c) => !!c.text)) {
|
|
30
|
+
if (result.content.every((c) => c.type === 'text' && !!c.text)) {
|
|
31
31
|
const text = toText(result.content);
|
|
32
32
|
if (text.trim().startsWith('{') || text.trim().startsWith('[')) {
|
|
33
33
|
try {
|