
整合生成式人工智能协议:MCP和A2A的单服务器解决方案

摘要
新的统一Google Apps脚本现在将模型上下文协议(MCP)和Agent2Agent(A2A)网络部署为单个服务器,简化了Google Workspace用户的AI模型集成。
引言
生成式人工智能的快速增长导致了人工智能模型之间的集成越来越多,例如模型上下文协议(MCP)和Agent2Agent(A2A)协议等协议。最近,我发布了MCPApp和A2AApp,它们使用Google Apps脚本建立了MCP和A2A网络。 参考 和 参考 这种方法为Google Workspace和Google API的用户提供了显著的优势,因为它可以直接在应用程序中无缝授权和集成这些资源。
传统上,部署单独的MCP和A2A服务器需要设置和开发两个不同的项目。本报告通过提供一个能够将MCP和A2A服务器创建为单个集成服务器的统一脚本来解决这种低效问题。这种整合允许MCP和A2A客户端访问一个公共服务器,简化了操作。此外,它促进了MCP和A2A服务器之间共享公共功能,显著降低了开发成本,提高了整体效率。
流动
其流程图如下。
flowchart TD
subgraph Server
direction TB
functions[Functions] --> mvp[MCP server] & a2a[A2A server]
end
A[MCP Client] -- Protocol for MCP --> Server
B[A2A Client] -- Protocol for A2A --> Server仓库
用法
1.Ger API密钥
为了使用本报告中的脚本,请使用您的API密钥。 参考 此API密钥用于访问Gemini API。
2.复制演示脚本
您可以使用以下Google Apps脚本复制演示脚本。请将以下脚本复制并粘贴到Google Apps脚本的脚本编辑器中,然后运行该功能 myFunction。通过此操作,演示Google Apps脚本项目将复制到您的Google Drive的根文件夹中。
function myFunction() {
const fileId = "1N1eg3vEgi_eVAiPB1SrPG9NIfEEQ5qohZED9haQQ7VbOKnMfLkPkYkUe";
const file = DriveApp.getFileById(fileId);
file.makeCopy(file.getName());
}当然,您也可以直接从存储库复制和粘贴脚本。
3.部署Web应用程序
为了允许MCP和A2A客户端访问,该项目使用使用Google Apps Script构建的Web Apps作为服务器。两个客户端都可以使用HTTP GET和HTTP POST请求访问此服务器。因此,Web Apps可以作为一个统一的服务器,集成MCP和A2A功能。
详细信息可以在 官方文件.
请按照以下步骤在脚本编辑器中部署Web App。
- 在脚本编辑器的右上角,单击“部署”->“新建部署”。
- 点击“选择类型”->“Web App”。
- 在“部署配置”下的字段中输入有关Web App的信息。
- 选择 “我” 为了 “执行方式”.
- 选择 “任何人” 为了 “谁有权访问该应用程序:”.
- 单击“部署”。
- 在脚本编辑器的右上角,单击“部署”->“测试部署”。
- 复制Web应用程序URL。它类似于
https://script.google.com/macros/s/###/exec此URL用于MCP客户端和A2A服务器。 - 请运行该函数
getRegisteringAgentCardURL()在复制的脚本中,并将显示的URL复制到控制台上。此URL用于A2A客户端。
需要注意的是,当您修改Web应用程序的Google Apps脚本时,必须将部署修改为新版本。 这可确保修改后的脚本反映在Web应用程序中。请小心这件事。此外,您可以在我的报告中找到更多详细信息”为新IDE重新部署Web应用程序而不更改Web应用程序的URL".
4.更新复制的脚本
复制文件时,请打开它。通过脚本编辑器打开。请进行以下修改。
- 将API密钥设置为
apiKey. - 将Web应用程序URL设置为
https://script.google.com/macros/s/###/exec到URLagentCard。此时,请添加一个查询参数accessKey=sample因此,URL变为https://script.google.com/macros/s/###/exec?accessKey=sample
5.测试
MCP客户端
使用Claude Desktop作为MCP客户端。 参考 在这种情况下 claude_desktop_config.json 配置如下。请更换 https://script.google.com/macros/s/###/exec 使用您的Web应用程序URL。
{
"mcpServers": {
"gas_web_apps": {
"command": "npx",
"args": [
"mcp-remote",
"https://script.google.com/macros/s/###/exec?accessKey=sample"
]
}
}
}请关闭并重新打开Claude Desktop。结果可以在以下演示中看到。

您可以看到,Claude Desktop的MCP客户端可以使用集成了MCP服务器和由Google Apps Script构建的A2A服务器的服务器。
A2A客户端
作为A2A客户端, @a2a-js/sdk 使用。 参考 在这种情况下,为了使用 @a2a-js/sdk,需要修改 @a2a-js/sdk。请修改功能 _fetchAndCacheAgentCard 属于的 node_modules/@a2a-js/sdk/build/src/client/client.js 如下所述。
使用路径请求Google Apps脚本Web应用程序 /.well-known/agent.json,需要访问令牌 参考此访问令牌用作查询参数。然而,大多数当前的A2A客户端规范都不支持这一点。因此,有必要进行以下修改。
此外,请求Web应用程序需要重定向 参考不幸的是,Python的公共A2A客户端不支持重定向。相比之下,Node.js默认支持重定向。由于这些原因, @a2a-js/sdk 被选为本报告的样本。
自
const agentCardUrl = `${this.agentBaseUrl}/.well-known/agent.json`;向
const agentCardUrl = ((agentBaseUrl) => {
/**
* ### Description
* This method is used for parsing the URL including the query parameters.
* Ref: https://tanaikech.github.io/2018/07/12/adding-query-parameters-to-url-using-google-apps-script/
*
* @param {String} url The URL including the query parameters.
* @return {Object} JSON object including the base url and the query parameters.
*/
function parseQueryParameters(url) {
if (url === null || typeof url != "string") {
throw new Error(
"Please give URL (String) including the query parameters."
);
}
const s = url.split("?");
if (s.length == 1) {
return { url: s[0], queryParameters: null };
}
const [baseUrl, query] = s;
if (query) {
const queryParameters = query.split("&").reduce(function (o, e) {
const temp = e.split("=");
const key = temp[0].trim();
let value = temp[1].trim();
value = isNaN(value) ? value : Number(value);
if (o[key]) {
o[key].push(value);
} else {
o[key] = [value];
}
return o;
}, {});
return { url: baseUrl, queryParameters };
}
return null;
}
/**
* ### Description
* This method is used for adding the query parameters to the URL.
* Ref: https://tanaikech.github.io/2018/07/12/adding-query-parameters-to-url-using-google-apps-script/
*
* @param {String} url The base URL for adding the query parameters.
* @param {Object} obj JSON object including query parameters.
* @return {String} URL including the query parameters.
*/
function addQueryParameters(url, obj) {
if (url === null || obj === null || typeof url != "string") {
throw new Error(
"Please give URL (String) and query parameter (JSON object)."
);
}
const o = Object.entries(obj);
return (
(url == "" ? "" : `${url}${o.length > 0 ? "?" : ""}`) +
o
.flatMap(([k, v]) =>
Array.isArray(v)
? v.map((e) => `${k}=${encodeURIComponent(e)}`)
: `${k}=${encodeURIComponent(v)}`
)
.join("&")
);
}
const urlObj = parseQueryParameters(agentBaseUrl);
return addQueryParameters(
`${urlObj.url}/.well-known/agent.json`,
urlObj.queryParameters
);
})(this.agentBaseUrl);A2A客户端的示例脚本如下。请更换 https://script.google.com/macros/s/###/dev?access_token=###&accessKey=sample 通过函数检索您的URL getRegisteringAgentCardURL() 在复制的脚本中。
import {
A2AClient,
Message,
MessageSendParams,
SendMessageResponse,
SendMessageSuccessResponse,
} from "@a2a-js/sdk";
import { v4 as uuidv4 } from "uuid";
// Please set your A2A server URL.
const agentBaseUrl = "https://script.google.com/macros/s/###/dev?access_token=###&accessKey=sample";
// Sample prompts for testing the above A2A server.
const prompts = [
"How much is 10 yen in USD?",
"What is the weather forecast for Tokyo at noon today?",
];
async function run(prompts: Array) {
const client = new A2AClient(agentBaseUrl);
for (let prompt of prompts) {
const messageId = uuidv4();
const sendParams: MessageSendParams = {
message: {
messageId: messageId,
role: "user",
parts: [{ kind: "text", text: prompt }],
kind: "message",
},
configuration: {
blocking: true,
acceptedOutputModes: ["text/plain"],
},
};
const sendResponse: SendMessageResponse = await client.sendMessage(
sendParams
);
const result = (sendResponse as SendMessageSuccessResponse).result;
const messageResult = result as Message;
messageResult.parts.forEach((e) => {
if (e.kind == "text") {
console.log(`Prompt: ${prompt}`);
console.log(`Response: ${e.text}`);
}
});
}
}
run(prompts);运行此脚本时,可以获得以下结果。

您可以看到由创建的A2A客户端 @a2a-js/sdk 可以使用集成了MCP服务器和由Google Apps Script构建的A2A服务器的服务器。
重要
- 如果发生错误,请重新部署Web应用程序以反映最新脚本。 需要注意的是,当您修改Web应用程序的Google Apps脚本时,必须将部署修改为新版本。 这可确保修改后的脚本反映在Web应用程序中。请小心这件事。此外,您可以在我的报告中找到更多详细信息”为新IDE重新部署Web应用程序而不更改Web应用程序的URL".
总结
- 开发了一个新的统一的Google Apps脚本,将模型上下文协议(MCP)和Agent2Agent(A2A)网络部署为单个服务器。
- 这种整合的方法解决了传统部署的低效问题,传统部署需要MCP和A2A服务器的单独项目。
- 统一服务器允许MCP和A2A客户端访问一个公共服务器,这简化了操作,促进了公共功能的共享,从而降低了开发成本。
- 该服务器利用使用Google Apps Script构建的Web Apps来处理来自MCP和A2A客户端的HTTP GET和HTTP POST请求。
- 使用Claude Desktop作为MCP客户端的演示
@a2a-js/sdkA2A客户端成功地证明了集成的Google Apps脚本服务器在两种协议下都能正常运行。
______________________________________________________________________
许可证
作者
更新历史记录
- v1.0.0(2025年6月19日)
1. 首次发布。
