Building Your Own MCP Server for AI
Give AI Access to an API
Wrap a real REST API as MCP tools so the assistant never invents URLs or auth headers.
The model should not concatenate https://api.github.com/ and hope. You wrap the endpoints you trust, with timeouts and a User-Agent, and you return a thin result.
Pick an API you can call without a secret first
Use a public JSON endpoint so this lesson is not blocked on keys. https://httpbin.org/get echoes the request. GitHub’s public user API works without a token for a single profile. We will use httpbin so you are not fighting rate limits.
python -m pip install httpxOne tool, one HTTP call
import httpx
from mcp.server.mcpserver import MCPServer
mcp = MCPServer("http-demo")
@mcp.tool()
def inspect_get(url: str = "https://httpbin.org/get") -> dict:
'''GET a URL and return status plus JSON or a text preview. Default is httpbin.'''
headers = {"User-Agent": "geek-university-mcp-course/1.0"}
with httpx.Client(timeout=10.0, headers=headers, follow_redirects=True) as client:
response = client.get(url)
payload: dict = {"status": response.status_code, "url": str(response.url)}
try:
payload["json"] = response.json()
except ValueError:
payload["text"] = response.text[:500]
return payload
if __name__ == "__main__":
mcp.run()What “wrap” means
- The tool name is a verb the model understands (
inspect_get), notget_endpoint. - You own retries, timeouts, and which fields come back. Drop headers and cookies the model does not need.
- Auth, when you add it, lives in the environment — see Authentication and Secrets.
Check it
Invoke the tool with the default URL. You should see status 200 and a JSON body that includes a url field. Then lock the URL to a constant and remove the argument — that is the shape of a useful wrapper. Next: validation and error shapes.