# Agent Skill Discovery via Well-Known URI

> **Status:** Active  
> **Version:** 2026-06-13  
> **Author:** Colin Knapp  

## Abstract

This specification defines a simple way for a public API to tell agents how to use it.

If a site has an internet-facing API, it should publish a short Markdown file at `/.well-known/skills.md`. That file should explain the API base path, auth rules, safe actions, and links to more detail. A site may also publish `/.well-known/mcp.json` when a client needs JSON endpoint data.

This is the pattern used by this site. It is written so other sites can copy it.

## Status of This Memo

This is an active specification. The goal is clear agent guidance.

The main contract is `/.well-known/skills.md`. The JSON file is optional. Use JSON when a client needs a machine-readable list of tools, servers, auth hints, or API roots.

This project recommends `github.com/Leopere/autoskill-md` for building the Markdown file. Other tools may produce the same file. Pull requests for more language templates and generators are welcome.

## Table of Contents

1. [Introduction](#1-introduction)
2. [Well-Known Resources](#2-well-known-resources)
3. [Skills Document](#3-skills-document)
4. [JSON Discovery Document](#4-json-discovery-document)
5. [Processing Model](#5-processing-model)
6. [Cross-Origin Rules](#6-cross-origin-rules)
7. [Security Rules](#7-security-rules)
8. [IANA Notes](#8-iana-notes)
9. [References](#9-references)
10. [Appendix A: Complete Example](#appendix-a-complete-example)
11. [Appendix B: JSON Schema](#appendix-b-json-schema)

---

## 1. Introduction

### 1.1 Goal

Many sites expose an API. Agents need a clear way to learn how to use it.

Today, that guidance is often buried in docs. It may be in a README, an OpenAPI file, a private page, or a code comment. Agents then guess too much.

This specification puts a small agent guide at a fixed URL:

```text
/.well-known/skills.md
```

The guide should be plain Markdown. It should be easy to read. It should tell an agent what the API is for and how to act safely.

### 1.2 Terms

The words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" use the meanings from BCP 14.

- **Origin**: The scheme, host, and port of a URL, such as `https://api.example.com`.
- **Public API**: Any internet-facing HTTP API or service that a client can call.
- **Skills document**: The Markdown file at `/.well-known/skills.md`.
- **Discovery document**: The optional JSON file at `/.well-known/mcp.json`.
- **Client**: Software that reads these files. This may be an agent, IDE, browser extension, or script.
- **Tool**: A service or API action a client can call.
- **MCP server**: A service that implements the Model Context Protocol.

### 1.3 Basic Rule

If an origin exposes a public API, it SHOULD serve `/.well-known/skills.md`.

If an origin has no public API and no agent actions, it MAY return `404 Not Found`.

If a site also wants JSON discovery, it MAY serve `/.well-known/mcp.json`.

### 1.4 Autoskill Generation

The skills document may be written by hand. It may also be generated.

This project recommends `github.com/Leopere/autoskill-md` for generating Markdown skills files. The generator should read source code, route files, OpenAPI files, or other API metadata. It should then write a clear `skills.md` file for agents.

The output matters more than the tool. A valid generator should produce plain Markdown that follows this specification. PRs for more language support are welcome.

### 1.5 API Location

The well-known path is always at the origin root.

- If the API is under `/api/v1`, serve `/.well-known/skills.md` at the same origin. In the file, state that the API base is `/api/v1`.
- If the API is on `https://api.example.com`, serve `https://api.example.com/.well-known/skills.md`.
- If the main site is `https://www.example.com`, it may link to the API origin. The API origin should still publish its own skills file.
- If the product is a CLI or private repo, keep `SKILLS.md` next to the code. A checked-in `.well-known/skills.md` may also help local tools.

---

## 2. Well-Known Resources

### 2.1 Paths

The skills document SHOULD be served at:

```text
/.well-known/skills.md
```

The JSON discovery document MAY be served at:

```text
/.well-known/mcp.json
```

For `https://example.com`, the full URLs are:

```text
https://example.com/.well-known/skills.md
https://example.com/.well-known/mcp.json
```

### 2.2 HTTP Methods

- Clients MUST use `GET` to read either file.
- Clients MAY use `HEAD` to check if a file exists.
- Servers SHOULD support both `GET` and `HEAD`.
- Servers MUST NOT require auth to read these files.

### 2.3 Content Type

- `skills.md` SHOULD use `text/markdown; charset=utf-8`.
- `skills.md` MAY use `text/plain; charset=utf-8`.
- `mcp.json` MUST use `application/json` or `application/json; charset=utf-8`.

### 2.4 Caching

Servers SHOULD send cache headers.

Good defaults are:

- `ETag` or `Last-Modified`
- `Cache-Control` with a short `max-age`, such as 300 to 3600 seconds

Static files may use a longer cache time.

---

## 3. Skills Document

### 3.1 Purpose

The skills document tells agents how to work with a site or API.

It should be short. It should use plain words. It should avoid marketing copy.

### 3.2 Required Content

A skills document for a public API SHOULD include:

- The API name and purpose
- The API base URL or base path
- Auth rules
- Safe read actions
- Risky write actions
- Rate limits or abuse rules, if known
- Links to OpenAPI, MCP, docs, or support
- A clear note that secrets must not be placed in the file

### 3.3 Example

```md
# Skills

This API lets agents read repair ticket status.

## API

- Base URL: `https://tracker.example.com/api/v1`
- Public reads: ticket status by ticket id
- Writes: admin only

## Auth

- Public status reads do not need auth.
- Customer actions need a bearer token.
- Do not put tokens in prompts, logs, or this file.

## Safety

- Ask before changing a ticket.
- Do not guess a customer id.
- Stop after three failed auth attempts.

## More Info

- JSON discovery: `/.well-known/mcp.json`
- Docs: `https://tracker.example.com/docs`
```

---

## 4. JSON Discovery Document

### 4.1 Purpose

The JSON file is optional. Use it when clients need structured endpoint data.

Do not duplicate long instructions in JSON. Put plain guidance in `skills.md`.

### 4.2 Root Object

If present, `/.well-known/mcp.json` MUST be a JSON object with an `mcp` object.

```json
{
  "mcp": {
    "spec_version": "2026-06-13",
    "status": "stable",
    "servers": [],
    "tools": []
  }
}
```

### 4.3 The `mcp` Object

The `mcp` object MUST include:

| Field | Type | Meaning |
|-------|------|---------|
| `spec_version` | string | Date version for this discovery specification |
| `status` | string | `stable` or `experimental` |

The `mcp` object MAY include:

| Field | Type | Meaning |
|-------|------|---------|
| `spec_url` | string | Link to this spec |
| `skills_url` | string | Link to `/.well-known/skills.md` |
| `notes` | string | Short human note |
| `contact` | string | Maintainer email or URL |
| `servers` | array | MCP servers |
| `tools` | array | API tools or services |

Clients MUST ignore unknown fields.

### 4.4 `servers[]`

Use `servers[]` for real MCP servers.

Each entry SHOULD include:

- `name`: short id
- `url`: absolute URL
- `description`: short text
- `transport`: transport name, if needed
- `auth`: auth hint
- `capabilities`: short list of actions

### 4.5 `tools[]`

Use `tools[]` for APIs or services that are not full MCP servers.

Each entry SHOULD include:

- `name`: short id
- `url`: absolute URL
- `description`: short text
- `auth`: auth hint
- `capabilities`: short list of actions
- `methods`: HTTP methods, if useful
- `content_types`: content types, if useful

---

## 5. Processing Model

### 5.1 Client Flow

Clients SHOULD use this order:

1. Fetch `/.well-known/skills.md`.
2. Read the safety rules and API base path.
3. Fetch `/.well-known/mcp.json` only if structured data is needed.
4. Check auth, origin, and user consent before any call.
5. Prefer read-only actions unless the user asks for a write.

### 5.2 Client Rules

A client:

- SHOULD read `skills.md` first.
- MUST use HTTPS in production.
- MUST NOT require `mcp.json` if `skills.md` gives enough guidance.
- MUST ignore unknown JSON fields.
- SHOULD validate URLs before use.
- SHOULD ask before cross-origin calls with side effects.

### 5.3 Server Rules

A server:

- SHOULD serve `skills.md` when it has a public API.
- MAY serve `mcp.json` for structured discovery.
- MUST NOT require auth to read either file.
- MUST NOT place secrets in either file.
- SHOULD use HTTPS in production.
- SHOULD use cache headers.

### 5.4 Error Handling

| Case | Client Behavior |
|------|-----------------|
| Missing `skills.md` | Continue only if other trusted docs exist |
| Missing `mcp.json` | Continue with `skills.md` |
| Invalid JSON | Ignore JSON and warn the user or logs |
| Unknown `spec_version` | Read what is safe and warn if needed |
| Network timeout | Retry with backoff or stop |

---

## 6. Cross-Origin Rules

Each host is its own origin.

Clients SHOULD prefer same-origin APIs.

If a file points to another origin:

- The client SHOULD show that origin to the user.
- The client SHOULD ask before write actions.
- The client MAY keep an allowlist or blocklist.
- The server SHOULD keep external links short and clear.

---

## 7. Security Rules

### 7.1 No Secrets

These files MUST NOT contain:

- API keys
- Tokens
- Passwords
- Private keys
- Session ids
- Customer secrets

Auth fields may explain how auth works. They must not include real credentials.

### 7.2 HTTPS

Production servers SHOULD use HTTPS.

Clients SHOULD reject plain HTTP in production. Localhost is allowed for development.

### 7.3 Safe Actions

The skills document SHOULD state which actions are safe.

Read-only actions are usually safer. Write actions, deletes, purchases, emails, and admin tasks usually need user approval.

### 7.4 CORS

Only enable CORS if browser clients need it.

For public discovery, this is common:

```http
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, OPTIONS
Access-Control-Allow-Headers: Accept, Content-Type
```

Do not use broad CORS to expose private data.

---

## 8. IANA Notes

This specification does not request IANA action.

If this pattern later becomes a formal standard, `skills.md` and `mcp.json` may need well-known URI registration.

---

## 9. References

### 9.1 Normative References

- **RFC 2119**: Key words for requirement levels
- **RFC 8174**: Uppercase and lowercase requirement words
- **RFC 8259**: JSON
- **RFC 8615**: Well-Known URIs

### 9.2 Informative References

- **Model Context Protocol**: https://modelcontextprotocol.io/
- **MCP Specification**: https://spec.modelcontextprotocol.io/
- **Recommended generator**: https://github.com/Leopere/autoskill-md

---

## Appendix A: Complete Example

### `/.well-known/skills.md`

```md
# Skills

This API lets agents read repair ticket status.

## API

- Base URL: `https://tracker.example.com/api/v1`
- Public reads: ticket status by ticket id
- Writes: admin only

## Auth

- Public status reads do not need auth.
- Customer actions need a bearer token.
- Do not put tokens in prompts, logs, or this file.

## Safety

- Ask before changing a ticket.
- Do not guess a customer id.
- Stop after three failed auth attempts.

## More Info

- JSON discovery: `/.well-known/mcp.json`
- Docs: `https://tracker.example.com/docs`
```

### `/.well-known/mcp.json`

```json
{
  "mcp": {
    "spec_version": "2026-06-13",
    "spec_url": "https://colinknapp.com/specs/skill-discovery.html",
    "skills_url": "https://tracker.example.com/.well-known/skills.md",
    "status": "stable",
    "notes": "Example JSON discovery file. This file must not contain secrets.",
    "contact": "https://tracker.example.com/support",
    "servers": [],
    "tools": [
      {
        "name": "repair-tracker",
        "description": "Repair ticket status API",
        "url": "https://tracker.example.com/api/v1",
        "capabilities": ["ticket-status"],
        "methods": ["GET"],
        "content_types": ["application/json"],
        "auth": {
          "type": "bearer"
        }
      }
    ]
  }
}
```

---

## Appendix B: JSON Schema

JSON Schema 2020-12 for `/.well-known/mcp.json`:

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://colinknapp.com/specs/mcp-discovery.schema.json",
  "title": "Agent Skill JSON Discovery Document",
  "type": "object",
  "required": ["mcp"],
  "properties": {
    "mcp": {
      "type": "object",
      "required": ["spec_version", "status"],
      "properties": {
        "spec_version": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        "spec_url": {
          "type": "string",
          "format": "uri"
        },
        "skills_url": {
          "type": "string",
          "format": "uri"
        },
        "status": {
          "type": "string",
          "enum": ["stable", "experimental"]
        },
        "notes": {
          "type": "string"
        },
        "contact": {
          "type": "string"
        },
        "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"
        },
        "description": {
          "type": "string"
        },
        "url": {
          "type": "string",
          "format": "uri"
        },
        "transport": {
          "type": "string"
        },
        "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"
        },
        "auth": {
          "$ref": "#/$defs/auth"
        },
        "capabilities": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "methods": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "content_types": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "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"
        }
      }
    }
  }
}
```

---

## Revision History

| Version | Date | Changes |
|---------|------|---------|
| 2026-06-13 | 2026-06-13 | Refocus on `/.well-known/skills.md` for public APIs; add autoskill generator guidance; make `/.well-known/mcp.json` optional; simplify wording |
| 2026-04-12 | 2026-04-12 | Document SKILLS.md-first agent guidance; cover `/.well-known/skills.md`; add deployment notes |
| 2026-01-24 | 2026-01-24 | Initial specification |
