Unified MCP & A2A Server
Um servidor Google Apps Script que unifica o Model Context Protocol (MCP) e o Agent2Agent (A2A) para usuários do Google Workspace.
Documentação
Consolidando Protocolos de IA Generativa: Uma Solução de Servidor Único para MCP e A2A

Resumo
Um novo Google Apps Script unificado agora implanta redes Model Context Protocol (MCP) e Agent2Agent (A2A) como um único servidor, simplificando a integração de modelos de IA para usuários do Google Workspace.
Introdução
O rápido crescimento da IA generativa levou a uma integração cada vez maior entre modelos de IA, exemplificada por protocolos como o Model Context Protocol (MCP) e o Protocolo Agent2Agent (A2A). Recentemente, lancei o MCPApp e o A2AApp, que estabelecem as redes MCP e A2A usando Google Apps Script. Ref e Ref Essa abordagem oferece vantagens significativas para usuários do Google Workspace e das APIs do Google, pois permite autorização e integração contínuas desses recursos diretamente nos aplicativos.
Tradicionalmente, implantar servidores MCP e A2A separados exigia configurar e desenvolver dois projetos distintos. Este relatório aborda essa ineficiência apresentando um script unificado capaz de criar tanto os servidores MCP quanto A2A como um único servidor integrado. Essa consolidação permite que clientes MCP e A2A acessem um servidor comum, simplificando as operações. Além disso, facilita o compartilhamento de funções comuns entre os servidores MCP e A2A, reduzindo significativamente os custos de desenvolvimento e aumentando a eficiência geral.
Fluxo
O fluxograma disso é o seguinte.
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
Repositório
Uso
1. Obter chave de API
Para usar os scripts deste relatório, use sua chave de API. Ref Essa chave de API é usada para acessar a API Gemini.
2. Copiar script de demonstração
Você pode copiar o script de demonstração usando o seguinte Google Apps Script. Copie e cole o script a seguir no editor de scripts do Google Apps Script e execute a função myFunction. Com isso, o projeto de script de demonstração do Google Apps Script é copiado para a pasta raiz do seu Google Drive.
function myFunction() {
const fileId = "1N1eg3vEgi_eVAiPB1SrPG9NIfEEQ5qohZED9haQQ7VbOKnMfLkPkYkUe";
const file = DriveApp.getFileById(fileId);
file.makeCopy(file.getName());
}
Claro, você também pode copiar e colar diretamente o script do repositório. GitHub
3. Implantar Web Apps
Para permitir o acesso tanto dos clientes MCP quanto A2A, o projeto usa Web Apps criados com Google Apps Script como servidor. Ambos os clientes podem acessar esse servidor usando solicitações HTTP GET e HTTP POST. Assim, os Web Apps podem servir como um servidor unificado, integrando as funcionalidades MCP e A2A.
Informações detalhadas podem ser encontradas na documentação oficial.
Siga estas etapas para implantar o Web App no editor de scripts.
- No editor de scripts, no canto superior direito, clique em "Implantar" -> "Nova implantação".
- Clique em "Selecionar tipo" -> "Web App".
- Insira as informações sobre o Web App nos campos sob "Configuração da implantação".
- Selecione "Eu" para "Executar como".
- Selecione "Qualquer pessoa" para "Quem tem acesso ao app:".
- Clique em "Implantar".
- No editor de scripts, no canto superior direito, clique em "Implantar" -> "Testar implantações".
- Copie o URL do Web App. Ele será semelhante a
https://script.google.com/macros/s/###/exec. Esse URL é usado para o cliente MCP e o servidor A2A. - Execute a função
getRegisteringAgentCardURL()no script copiado e copie o URL exibido no console. Esse URL é usado para o cliente A2A.
É importante observar que, ao modificar o Google Apps Script para o Web App, você deve modificar a implantação como uma nova versão. Isso garante que o script modificado seja refletido no Web App. Tenha cuidado com isso. Além disso, você pode encontrar mais detalhes sobre isso no meu relatório "Redeploying Web Apps without Changing URL of Web Apps for new IDE".
4. Atualizar script copiado
Ao copiar o arquivo, abra-o. O editor de scripts será aberto. Faça as seguintes modificações.
- Defina sua chave de API para
apiKey. - Defina o URL dos Web Apps como
https://script.google.com/macros/s/###/execpara o URL deagentCard. At that time, please add a query parameter ofaccessKey=sample. So, the URL becomeshttps://script.google.com/macros/s/###/exec?accessKey=sample
5. Testes
Cliente MCP
Como cliente MCP, o Claude Desktop é usado. Ref Nesse caso, o claude_desktop_config.json é configurado da seguinte forma. Substitua https://script.google.com/macros/s/###/exec pelo URL do seu Web App.
{
"mcpServers": {
"gas_web_apps": {
"command": "npx",
"args": [
"mcp-remote",
"https://script.google.com/macros/s/###/exec?accessKey=sample"
]
}
}
}
Feche e abra o Claude Desktop novamente. O resultado pode ser visto na demonstração a seguir.

Você pode ver que o cliente MCP do Claude Desktop pode usar o servidor que integra o servidor MCP e o servidor A2A criados pelo Google Apps Script.
Cliente A2A
Como cliente A2A, o @a2a-js/sdk é usado. Ref Nesse caso, para testar o script usando @a2a-js/sdk, é necessário modificar @a2a-js/sdk. Modifique a função _fetchAndCacheAgentCard de node_modules/@a2a-js/sdk/build/src/client/client.js da seguinte forma.
Para solicitar Web Apps do Google Apps Script com o caminho /.well-known/agent.json, é necessário um token de acesso Ref. Esse token de acesso é usado como um parâmetro de consulta. No entanto, a maioria das especificações atuais de clientes A2A não suporta isso. Portanto, a seguinte modificação é necessária.
Além disso, solicitar Web Apps requer um redirecionamento Ref. Infelizmente, o cliente A2A público para Python não suporta redirecionamentos. Em contraste, o Node.js suporta redirecionamentos por padrão. Por esses motivos, @a2a-js/sdk foi escolhido como exemplo para este relatório.
De
const agentCardUrl = `${this.agentBaseUrl}/.well-known/agent.json`;
Para
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);
O script de exemplo do cliente A2A é o seguinte. Substitua https://script.google.com/macros/s/###/dev?access_token=###&accessKey=sample pelo seu URL obtido pela função getRegisteringAgentCardURL() no script copiado.
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<string>) {
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);
Quando este script é executado, o seguinte resultado pode ser obtido.

Você pode ver que o cliente A2A criado por @a2a-js/sdk pode usar o servidor que integra o servidor MCP e o servidor A2A criados pelo Google Apps Script.
IMPORTANTE
- Se ocorrer um erro, reimplante os Web Apps para refletir o script mais recente. É importante observar que, ao modificar o Google Apps Script para o Web App, você deve modificar a implantação como uma nova versão. Isso garante que o script modificado seja refletido no Web App. Tenha cuidado com isso. Além disso, você pode encontrar mais detalhes sobre isso no meu relatório "Redeploying Web Apps without Changing URL of Web Apps for new IDE".
Resumo
- Um novo Google Apps Script unificado foi desenvolvido para implantar redes Model Context Protocol (MCP) e Agent2Agent (A2A) como um único servidor.
- Essa abordagem consolidada abordou a ineficiência das implantações tradicionais, que exigiam projetos separados para servidores MCP e A2A.
- O servidor unificado permitiu que clientes MCP e A2A acessassem um servidor comum, o que simplificou as operações e facilitou o compartilhamento de funções comuns, reduzindo assim os custos de desenvolvimento.
- O servidor utilizou Web Apps criados com Google Apps Script para lidar com solicitações HTTP GET e HTTP POST de clientes MCP e A2A.
- Demonstrações usando Claude Desktop como cliente MCP e
@a2a-js/sdkcomo cliente A2A mostraram com sucesso que o servidor integrado do Google Apps Script funcionou corretamente para ambos os protocolos.
Licença
Autor
Histórico de Atualizações
-
v1.0.0 (19 de junho de 2025)
- Lançamento inicial.