In this tutorial, we’ll walk through how to create a local FASTMCP server that integrates with the Google ADK (Agent Development Kit). Instead of a streaming HTTP server, we’ll set up a local Python file to manage our server logic. The main goal is to expose a RESTful API and an ADK agent that can fetch data and respond to a separate FASTMCP client.
1. The FASTMCP Server with ADK Integration
First, let’s create the restapi-mcp-adk-server.py
file. This script will define our server, an ADK agent, and the tools it uses.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | # restapi-mcp-adk-server.py from fastmcp import FastMCP, Context import httpx import asyncio from fastmcp import Client import google.genai as genai from typing import Any from google.genai import types from dotenv import load_dotenv from google.adk.agents import LlmAgent from pydantic import BaseModel, Field from google.adk.agents import Agent from google.adk.events import Event from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService # Load environment variables (e.g., your Gemini API key) load_dotenv() # Initialize the FastMCP server mcp = FastMCP( name="RESTful API Wrapper <img draggable="false" role="img" class="emoji" alt=" ) # Define the base URL for our external API BASE_URL = "https://api.restful-api.dev/objects" # Define session details for the ADK agent APP_NAME = "MCP_SERVER_WITH_ADK_AGENT" USER_ID = "1234" SESSION_ID = "session1234" # 1. Define a function that the ADK agent can use as a tool # This function fetches a single object from the REST API async def get_object_by_id(object_id: str): async with httpx.AsyncClient() as client: resp = await client.get(f"{BASE_URL}/{object_id}") print("get_object_by_id", resp.json()) return resp.json() # 2. Configure the ADK LlmAgent # The agent's instruction tells it to use our tool when appropriate call_mcp_server_agent = LlmAgent( model="gemini-2.0-flash", name="assistant", description="This agent is used to send data to the FASTMCP client.", instruction="""Help the user fetch data from the REST API and send it to the FASTMCP client. When the user asks to fetch data for a specific object ID, use the `get_object_by_id` tool and pass the ID to it.""", tools=[get_object_by_id], ) # 3. Setup the ADK session and runner # This is required to run the agent async def setup_session_and_runner(): session_service = InMemorySessionService() session = await session_service.create_session(app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID) if call_mcp_server_agent: runner = Runner(agent=call_mcp_server_agent, app_name=APP_NAME, session_service=session_service) return session, runner # 4. Define the core async function that runs the ADK agent async def get_agent_async(query): content = types.Content(role='user', parts=[types.Part(text=query)]) session, runner = await setup_session_and_runner() events = runner.run_async(user_id=USER_ID, session_id=SESSION_ID, new_message=content) final_response = "Agent did not produce a final response." async for event in events: if event.is_final_response() and event.content and event.content.parts: print(f"Potential final response from [{event.author}]: {event.content.parts[0].text}") final_response = event.content.parts[0].text print(f"final_response", final_response) return final_response # 5. Expose the ADK agent as a FastMCP tool # This is the key step that allows the MCP client to call our ADK agent @mcp.tool() async def get_objects_by_id_using_adk_agent(object_id: str,ctx: Context): print(f"object_id:::::::::::::::::",object_id) # The ADK agent will process this query and call its internal `get_object_by_id` tool final_result = await get_agent_async(f"Fetch the data for object_id {object_id}, pass the id to get_object_by_id tool") return final_result if __name__ == "__main__": mcp.run() |
This server file is the core of our setup. It defines a tool, get_objects_by_id_using_adk_agent
, which itself acts as a wrapper. When called, this tool triggers our ADK agent with a specific query, and the agent, in turn, uses its own internal tool (get_object_by_id
) to interact with the external REST API.
2. Configure Your Environment
To ensure your code can access the Google Gemini model, you’ll need to create a .env
file in the same directory as your server script.
1 2 | # .env GOOGLE_API_KEY="YOUR_API_KEY_HERE" |
Replace "YOUR_API_KEY_HERE"
with your actual Google API key. This key will be loaded by the dotenv
library.
3. The FASTMCP Client
Finally, let’s create the client script, agent.py
, which will interact with our newly created server. This client will define its own tool that calls the server’s tool.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # agent.py # This script will call the restapi-mcp-adk-server.py import asyncio from fastmcp import Client from typing import Any from google.genai import types from dotenv import load_dotenv from google.adk.agents import LlmAgent from pydantic import BaseModel, Field from google.adk.agents import Agent from google.adk.events import Event from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService # Define a tool for our client agent # This tool uses the FastMCP Client to connect to our server file async def get_mcp_adk_data(object_id: str) -> dict: """Fetches an object by its ID from the MCP server.""" print(f"Tool 'get_mcp_data' called with object_id: {object_id}") # The client connects to the server and calls its tool async with Client("restapi-mcp-adk-server.py") as client: single = await client.call_tool("get_objects_by_id_using_adk_agent", {"object_id": object_id}) print("Fetched single:", single) return single # Configure the client-side ADK agent call_local_mcp_adk_server_agent = LlmAgent( model="gemini-2.0-flash", name="assistant", description="This agent uses the FASTMCP client to call the FASTMCP server.", instruction="""Help the user fetch data from the FASTMCP Server using the FASTMCP Client. When the user asks to fetch data for a specific object ID, use the `get_mcp_adk_data` tool and pass the ID to it.""", tools=[get_mcp_adk_data], ) root_agent=call_local_mcp_adk_server_agent |
This client script defines its own ADK agent, call_local_mcp_adk_server_agent
. This agent’s primary tool, get_mcp_adk_data
, uses the FASTMCP client to connect directly to our server (restapi-mcp-adk-server.py
). It then calls the server’s exposed tool, get_objects_by_id_using_adk_agent
, with the provided object_id
.
This setup demonstrates a powerful pattern: an ADK agent can serve as a central orchestrator, with its tools acting as bridges to other systems, including other ADK agents running on different servers via FASTMCP. The chain of command looks like this:
Client ADK Agent FASTMCP Client
FASTMCP Server
Server ADK Agent
External REST API
This layered approach allows for modularity and scalability in building complex AI-driven applications.

source code :- https://github.com/shdhumale/app.git
No comments:
Post a Comment