Unified MCP & A2A Server

by tanaikech

Not rated
GitHub

About

A Google Apps Script server that unifies Model Context Protocol (MCP) and Agent2Agent (A2A) for Google Workspace users.

Details

Author
tanaikech
Categories
Developer Tools, Other, Automation, API

Setup

Install Unified MCP & A2A Server in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/tanaikech/Consolidating-Generative-AI-Protocols-A-Single-Server-Solution-for-MCP-and-A2A

Follow the installation instructions in the repository README, then restart your MCP client.

A Google Apps Script server that unifies Model Context Protocol (MCP) and Agent2Agent (A2A) for Google Workspace users.

Consolidating Generative AI Protocols: A Single Server Solution for MCP and A2A

A new unified Google Apps Script now deploys both Model Context Protocol (MCP) and Agent2Agent (A2A) networks as a single server, streamlining AI model integration for Google Workspace users.

The rapid growth of generative AI has led to increasing integration between AI models, exemplified by protocols like the Model Context Protocol (MCP) and Agent2Agent (A2A) Protocol. Recently, I released MCPApp and A2AApp, which establish the MCP and A2A networks using Google Apps Script.RefandRefThis approach offers significant advantages for users of Google Workspace and Google APIs, as it enables seamless authorization and integration of these resources directly within the applications.

Traditionally, deploying separate MCP and A2A servers required setting up and developing two distinct projects. This report addresses that inefficiency by presenting a unified script capable of creating both the MCP and A2A servers as a single, integrated server. This consolidation allows both MCP and A2A clients to access a common server, streamlining operations. Furthermore, it facilitates the sharing of common functions between the MCP and A2A servers, significantly reducing development costs and enhancing overall efficiency.

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

https://github.com/tanaikech/Consolidating-Generative-AI-Protocols-A-Single-Server-Solution-for-MCP-and-A2A

In order to use the scripts in this report, please use your API key.RefThis API key is used to access the Gemini API.

You can copy the demo script using the following Google Apps Script. Please copy and paste the following script into the script editor of Google Apps Script and run the functionmyFunction. By this, the demo Google Apps Script project is copied to the root folder of your Google Drive.

function myFunction() { const fileId = "1N1eg3vEgi_eVAiPB1SrPG9NIfEEQ5qohZED9haQQ7VbOKnMfLkPkYkUe"; const file = DriveApp.getFileById(fileId); file.makeCopy(file.getName()); }

Of course, you can also directly copy and paste the script from the repository.GitHub

To allow access from both the MCP and A2A clients, the project uses Web Apps built with Google Apps Script as the server. Both clients can access this server using HTTP GET and HTTP POST requests. Thus, the Web Apps can serve as a unified server, integrating the MCP and A2A functionalities.

Detailed information can be found inthe official documentation.

Please follow these steps to deploy the Web App in the script editor.
- In the script editor, at the top right, click "Deploy" -> "New deployment".
- Click "Select type" -> "Web App".
- Enter the information about the Web App in the fields under "Deployment configuration".
- Select"Me"for"Execute as".
- Select"Anyone"for"Who has access to the app:".
- Click "Deploy".
- On the script editor, at the top right, click "Deploy" -> "Test deployments".
- Copy the Web App URL. It will be similar tohttps://script.google.com/macros/s/###/exec. This URL is used to the MCP client and the A2A server.
- Please run the functiongetRegisteringAgentCardURL()in the copied script, and copy the showing URL on the console. This URL is used to the A2A client.

It is important to note that when you modify the Google Apps Script for the Web App, you must modify the deployment as a new version.This ensures the modified script is reflected in the Web App. Please be careful about this. Also, you can find more details on this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE".

When you copied the file, please open it. By the script editor is opened. Please do the following modifications.

- Set your API key toapiKey.
- Set the Web Apps URL likehttps://script.google.com/macros/s/###/execto the URL ofagentCard. At that time, please add a query parameter ofaccessKey=sample. So, the URL becomeshttps://script.google.com/macros/s/###/exec?accessKey=sample

As the MCP client, Claude Desktop is used.RefIn this case, theclaude_desktop_config.jsonis configured as follows. Please replacehttps://script.google.com/macros/s/###/execwith your Web App URL.

{ "mcpServers": { "gas_web_apps": { "command": "npx", "args": [ "mcp-remote", "https://script.google.com/macros/s/###/exec?accessKey=sample" ] } } }

Please close and open Claude Desktop again. The result can be seen at the following demonstration.

You can see that the MCP client of Claude Desktop can use the server that integrates the MCP server and the A2A server built by Google Apps Script.

As the A2A client,@a2a-js/sdkis used.RefIn this case, in order to test the script using@a2a-js/sdk, it is required to modify@a2a-js/sdk. Please modify the function_fetchAndCacheAgentCardofnode_modules/@a2a-js/sdk/build/src/client/client.jsas follows.

To request Google Apps Script Web Apps with the path/.well-known/agent.json, an access token is requiredRef. This access token is used as a query parameter. However, most current A2A client specifications do not support this. Therefore, the following modification is necessary.

Additionally, requesting Web Apps requires a redirectRef. Unfortunately, the public A2A client for Python does not support redirects. In contrast, Node.js supports redirects by default. For these reasons,@a2a-js/sdkwas chosen as the sample for this report.

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);

The sample script of the A2A client is as follows. Please replacehttps://script.google.com/macros/s/###/dev?access_token=###&accessKey=samplewith your URL retrieved by the functiongetRegisteringAgentCardURL()in the copied script.

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);

When this script is run, the following result can be obtained.

You can see that the A2A client created by@a2a-js/sdkcan use the server that integrates the MCP server and the A2A server built by Google Apps Script.

- If an error occurs, please redeploy the Web Apps to reflect the latest script.It is important to note that when you modify the Google Apps Script for the Web App, you must modify the deployment as a new version.This ensures the modified script is reflected in the Web App. Please be careful about this. Also, you can find more details on this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE".

- A new unified Google Apps Script was developed to deploy both Model Context Protocol (MCP) and Agent2Agent (A2A) networks as a single server.
- This consolidated approach addressed the inefficiency of traditional deployments, which required separate projects for MCP and A2A servers.
- The unified server allowed both MCP and A2A clients to access a common server, which streamlined operations and facilitated the sharing of common functions, thereby reducing development costs.
- The server utilized Web Apps built with Google Apps Script to handle HTTP GET and HTTP POST requests from both MCP and A2A clients.
- Demonstrations using Claude Desktop as an MCP client and@a2a-js/sdkas an A2A client successfully showed that the integrated Google Apps Script server functioned correctly for both protocols.

This is a web browser that enables your coding agent, such as Claude Code, to visit websites on your behalf and assist you in identifying bugs or creating UI test cases.

A server that bridges Google Sheets, Azure AI, and MQTT APIs.

Hosted remote MCP server with managed OAuth for a growing list of 15+ toolkits, including Google Workspace, Last.fm, MusicBrainz, Fitbit, Oura, Kalshi, and Polymarket.

The MCP server for Bitrix24 provides AI assistants with structured access to the Bitrix24 API. It delivers up-to-date method descriptions, parameters, and valid values, allowing assistants to work with precise data instead of guesswork. This reduces code errors and accelerates Bitrix24 integration development.

One remote MCP server for 500+ production APIs — Stripe, HubSpot, Postgres, Gmail, and more. OAuth and API key auth, credential management, and a CLI.

Single tool to control all 100+ API integrations, and UI components

Agent-native developer Q&A API with MCP + A2A endpoints for citations, job pickup, and answer submission.

Control Apache Airflow via its API using JWT authentication.

Self-hosted MCP gateway: convert REST/SOAP/GraphQL/SQL APIs into MCP tools with 29 pre-built adapters, OAuth2, RBAC and audit log.

A universal bridge to convert any web API into an MCP server, supporting multiple transport types.

Dynamically creates MCP servers from web API configurations, integrating any REST API, GraphQL endpoint, or web service into MCP-compatible tools.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.