MCP Discovery via Well-Known URI
| Status | Draft |
| Version | 2026-04-12 |
| Author | Colin Knapp |
| Source | mcp-discovery.md |
Abstract
This document defines well-known resources, /.well-known/mcp.json and /.well-known/skills.md, that allow a website origin to publish Model Context Protocol (MCP) connection metadata alongside lightweight agent instructions. Together they enable automatic discovery by compatible clients including AI agents, integrated development environments, browser extensions, and automation platforms.
The same discovery ideas also apply when the public API or product surface lives under a subdirectory path, on a CNAME subdomain, or behind a CLI that mirrors repository layout; those cases are described informally below. For day-to-day agent behavior, this project treats plain-text or Markdown SKILLS.md (including /.well-known/skills.md) as the primary, low-token contract and positions full MCP stacks as optional legacy detail.
Status of This Memo
This specification is intended for documentation and implementation guidance. Implementations MAY vary, but the goal is a stable, deployable pattern for agent discovery and lightweight operating guidance.
This document was updated recently to reflect a SKILLS.md-first approach, lighter-weight agent guidance, and practical deployment notes for non-root API surfaces.
Informative timeline: The related narrative for this work was committed in Well-known MCP configuration roughly a month before Google publicized MCP-related support in the Chrome browser. The ordering is noted for context only; it does not imply coordination or endorsement.
1. Introduction
1.1 Motivation
Modern web applications increasingly integrate with external services, AI assistants, and automation tools. These integrations typically require manual configuration: exchanging API keys, hardcoding endpoints, and maintaining service-specific integration code.
The .well-known directory (RFC 8615) provides a standardized location for site-wide metadata. This specification extends that pattern to Model Context Protocol (MCP) discovery, enabling:
- Automatic service discovery by AI agents and automation tools
- Standardized capability advertisement across different service types
- Reduced manual configuration for integrations
- Progressive enhancement where clients can discover and use available services
1.2 Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 (RFC 2119, RFC 8174).
- Origin: The scheme, host, and port of a URL (e.g.,
https://example.com). - Discovery Document: The JSON resource served at
/.well-known/mcp.json. - Skills Document: The Markdown or plain-text resource served at
/.well-known/skills.md. - Client: Any software that fetches and processes discovery documents.
- Server: The HTTP server hosting the discovery document.
- MCP Server: A service implementing the Model Context Protocol.
- Tool: A service or capability that can be invoked but is not necessarily a full MCP server.
1.3 Notational Conventions
Examples in this document use JSON (RFC 8259). All JSON field names are case-sensitive. Optional fields MAY be omitted entirely rather than set to null.
1.4 Agent instructions: SKILLS.md as the default contract
Many products no longer benefit from shipping a full MCP server for every integration. A single SKILLS.md file (or the same content under another name) can describe repository conventions, safe commands, API shapes, and review rules in a form assistants already load with minimal context. When you want that guidance to be discoverable from a website origin, publish the same material or a concise variant at /.well-known/skills.md.
Compared to the full MCP specification, this pattern usually wastes far fewer tokens: there is no long-lived tool schema handshake, JSON-RPC framing, or duplicate capability listings unless you truly need them. SKILLS.md SHOULD be treated as the primary source of truth for how an agent should work with a codebase or service. Publishing that guidance at /.well-known/skills.md makes the contract origin-addressable for web clients without forcing them into MCP first. The /.well-known/mcp.json document remains useful when you still want machine-readable endpoint lists, OAuth hints, or interoperability with MCP-aware clients, but it SHOULD be viewed as supplementary—not mandatory—for agent quality.
1.5 Publication beyond the site root (informative)
RFC 8615 fixes the well-known path at the origin root. Real deployments often split traffic:
- Subdirectory APIs — Example:
https://example.com/api/v2/with the marketing site at/. Publish/.well-known/mcp.jsonand, when useful for agents,/.well-known/skills.mdon the same origin. Use absoluteurlvalues underservers[]/tools[]that point into the API prefix (or document the API base in SKILLS.md and keep JSON minimal). - CNAME subdomains — Example:
https://api.example.comorhttps://md.example.com. Each hostname is its own origin; serve/.well-known/mcp.jsonand/.well-known/skills.mdon each origin that exposes agent-relevant capabilities, or reference those origins from a parent site’s discovery document and apply the cross-origin rules in Section 5. - CLI and repository hosts — For CLIs, private networks, or git hosting, there may be no public HTTPS origin. In those environments, ship SKILLS.md next to the code, optionally add checked-in
.well-known/skills.mdandmcp.jsonfiles for tools that support local file discovery, and rely on documentation links rather than assuming a single public well-known URL.
2. Well-Known Resources
2.1 URI Paths
The JSON discovery document MUST be served at the following path relative to the origin:
/.well-known/mcp.json
The skills document SHOULD be served at the following path relative to the origin:
/.well-known/skills.md
For example, for the origin https://example.com, the full URIs would be:
https://example.com/.well-known/mcp.json
https://example.com/.well-known/skills.md
2.2 HTTP Methods
- Clients MUST use the
GETmethod to retrieve either document. - Clients MAY use the
HEADmethod to check for document existence. - Servers SHOULD support both
GETandHEADmethods. - Servers MUST NOT require authentication to access either document.
2.3 Content Type
/.well-known/mcp.jsonMUST includeContent-Type: application/jsonorContent-Type: application/json; charset=utf-8./.well-known/skills.mdSHOULD includeContent-Type: text/markdown; charset=utf-8and MAY fall back totext/plain; charset=utf-8.- Servers SHOULD include the charset parameter.
- Clients MUST accept both JSON forms and SHOULD tolerate either Markdown or plain text for the skills document.
2.4 Caching
Servers SHOULD include caching headers to enable efficient polling:
ETagand/orLast-Modifiedfor conditional requestsCache-Controlwith appropriatemax-age(recommended: 300-3600 seconds)
Clients SHOULD:
- Cache responses according to HTTP caching rules
- Use conditional requests when re-fetching
- Consult the origin's
sitemap.xmlfor<changefreq>hints on polling intervals when available
2.5 Client Preference
Clients SHOULD read /.well-known/skills.md first when they need operating guidance, repository conventions, or concise task framing. Clients MAY then read /.well-known/mcp.json when they need structured endpoint metadata, transport details, or explicit capability advertisement.
3. Document Schema
3.1 Root Object
The response body MUST be a JSON object containing an mcp object at the top level:
{
"mcp": {
"spec_version": "2026-01-24",
"status": "draft",
"servers": [],
"tools": []
}
}
The root object MAY contain additional fields for future extensibility. Clients MUST ignore unknown fields at the root level.
3.2 The mcp Object
The mcp object MUST contain the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
spec_version | string | REQUIRED | Date-based version (YYYY-MM-DD format) |
status | string | REQUIRED | "draft" or "stable" |
servers | array | OPTIONAL | Array of MCP server definitions |
tools | array | OPTIONAL | Array of tool/service definitions |
The mcp object MAY contain additional fields:
| Field | Type | Description |
|---|---|---|
spec_url | string | URL to the specification document |
notes | string | Human-readable notes |
contact | string | Contact email or URL |
3.3 The spec_version Field
- Type: string
- Format:
YYYY-MM-DD(ISO 8601 date) - Purpose: Identifies the version of this specification
Clients SHOULD check spec_version and MAY warn users if encountering an unknown future version. Clients MUST NOT reject documents solely based on unrecognized spec_version values.
3.4 The status Field
| Value | Meaning |
|---|---|
draft | Experimental; schema or endpoints may change |
stable | Production-ready; breaking changes will increment spec_version |
3.5 The servers[] Array
An array of MCP server definitions. Each entry is an object with the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | REQUIRED | Unique identifier (lowercase, alphanumeric, hyphens) |
description | string | OPTIONAL | Human-readable description |
url | string | REQUIRED | Absolute URL for connecting |
transport | string | OPTIONAL | Transport protocol |
auth | object | OPTIONAL | Authentication configuration |
capabilities | array | OPTIONAL | Array of capability strings |
Transport Values
| Value | Description |
|---|---|
http+sse | HTTP with Server-Sent Events (default) |
ws | WebSocket |
wss | WebSocket Secure |
stdio | Standard I/O (for local servers) |
Auth Object
| Field | Type | Description |
|---|---|---|
type | string | "none", "api-key", "oauth2", "bearer" |
token_endpoint | string | OAuth2 token endpoint |
scopes | array | Required OAuth2 scopes |
header | string | Header name for API key (default: Authorization) |
3.6 The tools[] Array
An array of tool or service definitions that are not full MCP servers but can be invoked or integrated:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | REQUIRED | Unique identifier |
description | string | OPTIONAL | Human-readable description |
url | string | REQUIRED | Absolute URL of the service |
capabilities | array | OPTIONAL | Array of capability strings |
auth | object | OPTIONAL | Authentication configuration |
methods | array | OPTIONAL | Supported HTTP methods |
content_types | array | OPTIONAL | Accepted content types |
3.7 Extension Mechanism
- Servers MAY include additional fields not defined in this specification
- Clients MUST ignore unknown fields (forward compatibility)
- Custom fields SHOULD use a namespace prefix (e.g.,
x-myorg-custom-field) - Future versions of this specification will NOT redefine fields with the
x-prefix
4. Processing Model
4.1 Discovery Flow
┌─────────┐ GET /.well-known/mcp.json ┌─────────┐
│ │ ─────────────────────────────────► │ │
│ Client │ │ Server │
│ │ ◄───────────────────────────────── │ │
└─────────┘ 200 OK + JSON document └─────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 1. Validate JSON structure │
│ 2. Check spec_version compatibility │
│ 3. Enumerate servers[] and tools[] │
│ 4. Filter by capabilities (if searching for specific) │
│ 5. Check auth requirements │
│ 6. Connect to selected server(s) or invoke tool(s) │
└─────────────────────────────────────────────────────────┘
4.2 Client Conformance
A conforming client:
- MUST fetch the discovery document using HTTPS (HTTP MAY be used only for localhost)
- MUST parse the response as JSON
- MUST ignore unknown fields at any level
- MUST NOT require any OPTIONAL fields to be present
- SHOULD validate URLs before connecting to servers
- SHOULD respect the
statusfield when making stability assumptions
4.3 Server Conformance
A conforming server:
- MUST serve a valid JSON document at
/.well-known/mcp.json - MUST include the required fields:
spec_versionandstatus - MUST serve the document without requiring authentication
- MUST use HTTPS in production
- SHOULD include appropriate caching headers
- SHOULD include CORS headers if cross-origin access is intended
- MUST NOT include secrets, credentials, or private keys
4.4 Error Handling
| Scenario | Recommended Behavior |
|---|---|
| Network timeout | Retry with exponential backoff (max 3 attempts) |
| Invalid JSON | Treat as unsupported, log error |
| Missing required fields | Treat as unsupported, log error |
| Unknown spec_version | Process document, warn user |
| Server unreachable | Cache previous valid response if available |
5. Cross-Origin and Delegation
5.1 Same-Origin Preference
Clients SHOULD prefer same-origin servers when multiple options exist. Same-origin servers inherit the trust relationship the user has with the website.
5.2 External Service Trust Model
When a discovery document references servers or tools on different origins:
- Clients MUST clearly indicate to users that external services will be contacted
- Clients SHOULD require explicit user consent before connecting to external origins
- Clients MAY maintain allowlists/blocklists of trusted external origins
- Servers SHOULD minimize external references where same-origin alternatives exist
5.3 CORS Configuration
For cross-origin discovery (e.g., browser-based clients):
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, OPTIONS
Access-Control-Allow-Headers: Accept, Content-Type
Access-Control-Max-Age: 86400
Servers MAY restrict Access-Control-Allow-Origin to specific client origins if cross-origin access should be limited.
6. Security Considerations
6.1 No Secrets in Discovery Documents
The discovery document MUST NOT contain:
- API keys or tokens
- Passwords or credentials
- Private keys or certificates
- Session identifiers
- Any data that could compromise security if disclosed
Authentication details in the auth object describe HOW to authenticate, not the credentials themselves.
6.2 HTTPS Requirement
- Production deployments MUST serve the discovery document over HTTPS
- Clients SHOULD refuse to process discovery documents served over plain HTTP (except localhost)
- Self-signed certificates MAY be used for development but MUST NOT be used in production
6.3 CORS Guidance
- Servers SHOULD only enable CORS if cross-origin access is intentional
- Overly permissive CORS combined with sensitive operations could enable attacks
- Consider restricting CORS to known client origins in production
6.4 Content Validation
Clients SHOULD:
- Validate all URLs before making requests
- Reject URLs with unexpected schemes (only
https:andwss:in production) - Sanitize any data before display to prevent XSS
- Validate JSON structure before processing
7. IANA Considerations
This document does not require IANA registration unless adopted as an official standard. If standardized:
- Register
mcp.jsonin the Well-Known URIs registry (RFC 8615) - Define
application/mcp+jsonmedia type (optional)
8. References
8.1 Normative References
- RFC 2119: Key words for use in RFCs to Indicate Requirement Levels
- RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words
- RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format
- RFC 8615: Well-Known Uniform Resource Identifiers (URIs)
- RFC 7231: HTTP/1.1 Semantics and Content
- RFC 6749: The OAuth 2.0 Authorization Framework
8.2 Informative References
- Model Context Protocol: Protocol documentation and overview
- MCP Specification: Full protocol specification
Appendix A: Complete Example
A complete discovery document for a website with both MCP servers and tools:
{
"mcp": {
"spec_version": "2026-01-24",
"spec_url": "https://colinknapp.com/specs/mcp-discovery.html",
"status": "draft",
"notes": "Example MCP discovery document demonstrating all features.",
"contact": "https://colinknapp.com",
"servers": [
{
"name": "hastebin",
"description": "Text paste and sharing service for code snippets and logs",
"url": "https://haste.nixc.us/mcp",
"transport": "http+sse",
"auth": {
"type": "none"
},
"capabilities": ["create-paste", "retrieve-paste", "list-recent"]
},
{
"name": "markdown-renderer",
"description": "Markdown to HTML conversion with live preview",
"url": "https://md.colinknapp.com/mcp",
"transport": "http+sse",
"auth": {
"type": "none"
},
"capabilities": ["render-markdown", "preview", "export-pdf"]
}
],
"tools": [
{
"name": "repair-tracker",
"description": "Hardware repair ticket lookup and status tracking",
"url": "https://tracker.motherboardrepair.ca/",
"capabilities": ["ticket-lookup", "status-view"],
"auth": {
"type": "none"
}
}
]
}
}
Appendix B: JSON Schema
JSON Schema (Draft 2020-12) for validating discovery documents:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://colinknapp.com/specs/mcp-discovery.schema.json",
"title": "MCP Discovery Document",
"description": "Schema for /.well-known/mcp.json discovery documents",
"type": "object",
"required": ["mcp"],
"properties": {
"mcp": {
"type": "object",
"required": ["spec_version", "status"],
"properties": {
"spec_version": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
},
"status": {
"type": "string",
"enum": ["draft", "stable"]
},
"servers": {
"type": "array",
"items": { "$ref": "#/$defs/server" }
},
"tools": {
"type": "array",
"items": { "$ref": "#/$defs/tool" }
}
}
}
},
"$defs": {
"server": {
"type": "object",
"required": ["name", "url"],
"properties": {
"name": { "type": "string", "pattern": "^[a-z0-9-]+$" },
"description": { "type": "string" },
"url": { "type": "string", "format": "uri" },
"transport": { "type": "string", "enum": ["http+sse", "ws", "wss", "stdio"] },
"auth": { "$ref": "#/$defs/auth" },
"capabilities": { "type": "array", "items": { "type": "string" } }
}
},
"tool": {
"type": "object",
"required": ["name", "url"],
"properties": {
"name": { "type": "string" },
"description": { "type": "string" },
"url": { "type": "string", "format": "uri" },
"capabilities": { "type": "array", "items": { "type": "string" } },
"auth": { "$ref": "#/$defs/auth" }
}
},
"auth": {
"type": "object",
"required": ["type"],
"properties": {
"type": { "type": "string", "enum": ["none", "api-key", "oauth2", "bearer"] },
"token_endpoint": { "type": "string", "format": "uri" },
"scopes": { "type": "array", "items": { "type": "string" } },
"header": { "type": "string" }
}
}
}
}