Skip to main content
Version: 1.0.5

Creating a MCP Server on Agentverse

This example shows how to wrap a Model Context Protocol (MCP) FastMCP server with MCPServerAdapter so its tools are discoverable on Agentverse and callable through ASI:One via the Chat Protocol.

Related guides: What is MCP? · uAgents Adapter guide (MCP section) · LangGraph + MCP · Remote Smithery MCP client

Prerequisites

  • Python ≥ 3.10
  • uagents>=0.25.5
  • Install the MCP adapter extras and HTTP client used by the weather sample:
pip install "uagents-adapter[mcp]" httpx

uagents-adapter[mcp] pulls in mcp>=1.8.1 (FastMCP). httpx is used by server.py for National Weather Service (NWS) requests.

export ASI_ONE_API_KEY="your-asi1-api-key"

Overview

The MCP Server Adapter makes it easy to bring your tools into the Agentverse ecosystem by:

  • Wrapping MCP servers as uAgents for seamless, decentralized communication
  • Exposing MCP tools to other agents on Agentverse for easy discovery and reuse
  • Enabling the Chat Protocol, so you can talk to the MCP Server in natural language directly or through ASI:One

In this example, the MCP Server provides weather-related tools:

  • get_alerts: Returns active weather alerts for a US state (2-letter state code, e.g. CA, NY)
  • get_forecast: Returns a weather forecast for a specific latitude and longitude

You can define your own tools by following the same pattern.

Overview

Deployment modes

ModeWhen to useEntry files
(A) Local mailbox (recommended)Full control over packages; mcp, uagents-adapter, and httpx work with a normal pip install. Agent stays reachable on Agentverse via mailbox.server.py + agent.py on your machine
(B) Hosted Blank AgentOnly if your Agentverse runtime already provides mcp / uagents-adapter / httpx (or equivalents). The supported Hosted libraries list does not currently list those packages — if imports fail, use mode A.Hosted editor: server.py + main agent file (typically agent.py); use bare Agent()

FastMCP registers tools with @mcp.tool(). The adapter calls list_tools / call_tool on the FastMCP instance — you do not hand-write those methods unless you are building a non-FastMCP server. MCPServerAdapter supports FastMCP only today.

Step 1: Create a FastMCP Server (server.py)

Create server.py with your MCP tools. For local mailbox, place it next to agent.py. For hosted, click New File in the Agentverse editor, rename it to server.py, then paste the implementation.

Expected layout:

weather-mcp/
├── server.py # FastMCP tools
└── agent.py # MCPServerAdapter + uAgent (local) or hosted agent entry
stdio vs adapter

The if __name__ == "__main__": mcp.run(transport="stdio") block is optional — useful only for debugging the MCP server with a standalone MCP client. With MCPServerAdapter, you import the mcp instance; you do not need a separate stdio process.

server.py
from typing import Any

import httpx
from mcp.server.fastmcp import FastMCP

# Create a FastMCP server instance
mcp = FastMCP("weather")

NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"


async def make_nws_request(url: str) -> dict[str, Any] | None:
headers = {
"User-Agent": USER_AGENT,
"Accept": "application/geo+json",
}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None


def format_alert(feature: dict) -> str:
props = feature["properties"]
return (
f"Event: {props.get('event', 'Unknown')}\n"
f"Area: {props.get('areaDesc', 'Unknown')}\n"
f"Severity: {props.get('severity', 'Unknown')}\n"
f"Description: {props.get('description', 'No description available')}\n"
f"Instructions: {props.get('instruction', 'No specific instructions provided')}"
)


@mcp.tool()
async def get_alerts(state: str) -> str:
"""Get active weather alerts for a US state.

Use this tool when the user asks about weather warnings, watches, or alerts
for a US state. The NWS area endpoint expects a two-letter US state or
territory code (for example: CA, NY, TX), not a city name.

Args:
state: Two-letter US state code, uppercase (e.g. "CA" for California).

Examples:
- User asks "any weather alerts for California?" → call with state="CA"
- User asks "alerts in New York" → call with state="NY"
"""
url = f"{NWS_API_BASE}/alerts/active/area/{state}"
data = await make_nws_request(url)

if not data or "features" not in data:
return "Unable to fetch alerts or no alerts found."
if not data["features"]:
return "No active alerts for this state."

alerts = [format_alert(feature) for feature in data["features"]]
return "\n---\n".join(alerts)


@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
"""Get a short-term weather forecast for a geographic location.

Use this tool when the user asks for the forecast, temperature, or conditions
at a specific place and you have (or can infer) latitude and longitude in
decimal degrees for the United States (NWS coverage).

Args:
latitude: Latitude in decimal degrees (e.g. 32.7157 for San Diego).
longitude: Longitude in decimal degrees (e.g. -117.1611 for San Diego).

Examples:
- "Forecast for downtown San Diego" → latitude=32.7157, longitude=-117.1611
- "What's the weather at 40.71, -74.01?" → use those coordinates directly
"""
points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
points_data = await make_nws_request(points_url)

if not points_data:
return "Unable to fetch forecast data for this location."

forecast_url = points_data["properties"]["forecast"]
forecast_data = await make_nws_request(forecast_url)

if not forecast_data:
return "Unable to fetch detailed forecast."

periods = forecast_data["properties"]["periods"]
forecasts = []
for period in periods[:5]:
forecast = (
f"{period['name']}: "
f"Temperature: {period['temperature']}°{period['temperatureUnit']} "
f"Wind: {period['windSpeed']} {period['windDirection']} "
f"Forecast: {period['detailedForecast']}"
)
forecasts.append(forecast)

return "\n---\n".join(forecasts)


if __name__ == "__main__":
# Optional: run as a standalone MCP server for local debugging only
mcp.run(transport="stdio")
note

Important: When creating MCP tools, always include detailed docstrings using triple quotes (""") to describe what each tool in the MCP Server does, when to use it, and what parameters it expects. These descriptions play a critical role in selecting the right MCP tool based on the user's query.

Step 2: Create an Agent for Your FastMCP Server

Import MCPServerAdapter and the mcp instance from server.py. The adapter uses ASI:One for tool selection — set ASI_ONE_API_KEY as shown in Prerequisites (API Keys).

MCPServerAdapter parameters

ParameterTypeDescriptionRequired
mcp_serverFastMCPThe FastMCP server instance exposing your tools.Yes
asi1_api_keystrYour ASI:One API key for LLM-powered tool selection.Yes
modelstrASI:One model ID. Start with asi1; also asi1-extended, asi1-fast, and other ASI:One models.Yes
asi1_base_urlstrOptional ASI:One API base URL (default https://api.asi1.ai/v1).No
note

MCPServerAdapter only supports FastMCP servers at the moment.

Complete runnable agent.py:

agent.py
import os

from uagents import Agent
from uagents_adapter import MCPServerAdapter
from server import mcp # FastMCP instance from server.py

ASI_ONE_API_KEY = os.environ["ASI_ONE_API_KEY"]

mcp_adapter = MCPServerAdapter(
mcp_server=mcp,
asi1_api_key=ASI_ONE_API_KEY,
model="asi1", # Options: asi1, asi1-extended, asi1-fast
)

agent = Agent(
name="weather-agent",
port=8000,
seed="put_your_seed_phrase_here",
mailbox=True,
)

for protocol in mcp_adapter.protocols:
agent.include(protocol, publish_manifest=True)

if __name__ == "__main__":
mcp_adapter.run(agent)

Run locally after installing prerequisites:

python agent.py

See also the Adapters guide MCP section for the same mailbox pattern.

(B) Hosted Blank Agent (if packages are available)

  1. Open AgentverseAgents+ Launch an AgentBlank Agent → name it and click Create. Details: Hosted Agents.
  2. Add server.py (Step 1) and put the agent script below in the main agent file (typically agent.py).
  3. Confirm the runtime can import mcp, uagents_adapter, and httpx. If not, switch to (A) Local mailbox.

On hosted Agentverse, identity is managed for you — use bare Agent() (no mailbox/seed/port):

agent.py (hosted)
import os

from uagents import Agent
from uagents_adapter import MCPServerAdapter
from server import mcp

# Prefer a secret / env var in the Agentverse editor — do not hardcode keys
ASI_ONE_API_KEY = os.environ["ASI_ONE_API_KEY"]

mcp_adapter = MCPServerAdapter(
mcp_server=mcp,
asi1_api_key=ASI_ONE_API_KEY,
model="asi1", # Options: asi1, asi1-extended, asi1-fast
)

agent = Agent()

for protocol in mcp_adapter.protocols:
agent.include(protocol, publish_manifest=True)

if __name__ == "__main__":
mcp_adapter.run(agent)

Adding a README to your Agent

  1. Open the Overview section in the Agentverse editor (or your Agentverse agent page for a mailbox agent).
  2. Click Edit and add a clear description so ASI:One can find your agent. See Importance of Good README.

Example Overview blurb:

Weather MCP agent exposing NWS tools via Chat Protocol.

Tools:
- get_alerts(state): active alerts for a US state (2-letter code, e.g. CA, NY)
- get_forecast(latitude, longitude): short-term forecast for US coordinates

Ask for "weather alerts for CA" or a forecast at lat/lon. Powered by FastMCP + MCPServerAdapter.

Readme

Step 3: Test Your Agent

  1. Start the agent (python agent.py locally, or Start in the Agentverse editor for hosted).

Start Agent

  1. On Agentverse, open OverviewChat with Agent.

Chat with Agent 1 Chat with Agent 2

Happy-path chat

YouAgent (typical)
Are there any weather alerts for CA?Uses get_alerts with state="CA" and returns active alerts (or “No active alerts for this state.”)
What's the forecast at 32.72, -117.16?Uses get_forecast and returns the next few NWS periods

Troubleshooting

SymptomLikely causeWhat to try
ImportError / missing mcp or uagents_adapterPackages not installed (or not on Hosted allowlist)Local: pip install "uagents-adapter[mcp]" httpx. Hosted: use mailbox mode A.
ASI:One / adapter errors about auth or modelInvalid or missing API keyConfirm ASI_ONE_API_KEY (API Keys).
Empty alerts / “Unable to fetch”Bad state code, or NWS rejecting the requestUse a 2-letter code (CA, not “San Diego”). Ensure User-Agent is set (sample includes one); NWS may return 403 without it.
NameError: Agent is not definedMissing importfrom uagents import Agent
SyntaxError near MCPServerAdapter(...)Stray \ or bad copy-pasteUse the scripts on this page as-is

Query your agent from ASI:One

  1. Sign in at ASI:One (Google account or wallet) and start a new chat.
  2. Toggle Agents so ASI:One can call agents on Agentverse.

Agent Calling

  1. Mention your agent address so ASI:One targets it. Prefer a state code for alerts:
Please ask agent1qgggh8wy6ux2xwkc267cfpxk390c4ve0ts23yz5d9l6qsnckyvs2zpx08gq for weather alerts for CA

ASI1 Response

You can click the Agent URL to open the agent that answered.

ASI1 Response

note

If you ask about weather without mentioning your agent’s address, ASI:One may pick another agent via ranking. To test yours directly, use Chat with Agent on Agentverse.