Atlas Agent

How to build an MCP server in Python

Use FastAPI (or your favorite framework) to publish tool catalogs, enforce scopes, and log usage events.

This tutorial covers the reference Python stack: FastAPI, Pydantic models for tool contracts, and the Atlas tracker SDK. We focus on the sales comps tool so you can see inputs, outputs, budgets, and consent checks in action.

Project setup

Create a virtualenv and install FastAPI plus the Atlas SDK. Define Pydantic models for Tool, InputField, OutputField, and ConsentScope.

bash
uv venv venv && source venv/bin/activate
pip install fastapi uvicorn atlas-mcp-sdk
Set up a clean Python environment

Describe the tool contract

Declare the GenerateSalesComps tool with the contract fields from lib/constants/knowledge. Include cost and latency hints so clients can budget.

python
class GenerateSalesComps(Tool):
    name: str = "generate_sales_comps_pdf"
    version: str = "1.0.0"
    inputs: list[InputField] = [
        InputField(key="subject_address", type="string", required=True),
        InputField(key="beds", type="int", required=True),
        InputField(key="baths", type="int", required=True),
        InputField(key="sqft", type="int", required=True),
        InputField(key="radius_miles", type="float", required=True),
        InputField(key="max_closed_months", type="int", required=True),
    ]
    outputs: list[OutputField] = [
        OutputField(key="artifact_uri", type="string"),
        OutputField(key="summary", type="string"),
    ]
    consent_scopes: list[str] = ["mls.read", "atlas.data"]
    cost_hint_usd: float = 0.75
    latency_hint_ms: int = 2500
Define the tool schema

Wire tracker & guard

Use the Atlas tracker client to run preflight checks before calling downstream vendors. If the call passes, execute your business logic, then send a signed usage event with costs, tokens, and artifact URIs.

python
tracker = TrackerClient(api_key=os.environ["ATLAS_TRACKER_KEY"])

@app.post("/tools/generate_sales_comps_pdf")
async def generate_sales_comps(request: ToolRequest):
    preflight = tracker.preflight(tool_name="generate_sales_comps_pdf", actor=request.actor, inputs=request.inputs)
    if not preflight.allowed:
        raise HTTPException(status_code=429, detail=preflight.reason)

    result = await run_comp_job(request.inputs)
    tracker.postflight(
        event_id=preflight.event_id,
        tool_name="generate_sales_comps_pdf",
        actor=request.actor,
        outputs=result.outputs,
        vendor_name="atlas_default",
        total_cost_usd=result.cost,
        artifact_uri=result.artifact_uri,
    )
    return result
Preflight + postflight pattern

Expose discovery endpoints

Implement GET /catalog and GET /prompts endpoints so clients can list the available tools. Use caching headers since these responses rarely change.

Test with Atlas clients

Point VS Code or the Atlas Bot at your local server URL. Watch the tracker dashboard to confirm preflight and postflight events land with the correct consent scopes.

Atlas Agent

Run your own MCP server

Use Atlas Server Builder to launch faster, then upgrade to Hosted Atlas Bot when you need more seats and surfaces.

Related guides

What is an MCP server?

Pillar primer on Atlas Agent MCP strategy.

Go to What is an MCP server?

Knowledge Base

Identity, consent, provenance, tracker guard details.

Go to Knowledge Base

Pricing

Compare Server Builder, Starter Kits, and Hosted Atlas Bot.

Go to Pricing
Atlas Agent