{
  "openapi": "3.1.0",
  "info": {
    "title": "Ailurn public HTTP catalog",
    "summary": "Machine-readable website, MCP, and OAuth discovery for the Ailurn learning workspace. Not a course-generation API.",
    "description": "Ailurn is a web product: humans sign up, describe a learning goal, and get a structured course. This OpenAPI document lists unauthenticated discovery URLs (llms.txt, MCP, OAuth metadata). Ailurn does not offer a public API. Authenticated /api/course and /api/auth routes are for the Ailurn session cookie only.",
    "version": "1.0.0",
    "contact": {
      "name": "Ailurn",
      "url": "https://www.ailurn.com",
      "email": "support@ailurn.com"
    }
  },
  "servers": [
    {
      "url": "https://www.ailurn.com",
      "description": "Ailurn production"
    }
  ],
  "tags": [
    {
      "name": "Discovery",
      "description": "Agent indexes and instructions"
    },
    {
      "name": "Content",
      "description": "Markdown content negotiation"
    },
    {
      "name": "OAuth",
      "description": "OAuth 2.0 authorization server"
    },
    {
      "name": "MCP",
      "description": "Ailurn MCP Streamable HTTP server"
    }
  ],
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "code",
          "message",
          "hint"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "hint": {
            "type": "string"
          },
          "cause": {
            "type": "string"
          }
        }
      }
    },
    "responses": {
      "Problem": {
        "description": "Structured JSON error (RFC 7807 problem+json)",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          },
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/llms.txt": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "Ailurn llms.txt",
        "description": "llmstxt.org index: when to use Ailurn, and links to Markdown resources.",
        "operationId": "getLlmsTxt",
        "responses": {
          "200": {
            "description": "Markdown index",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms-full.txt": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "Expanded Ailurn agent context",
        "operationId": "getLlmsFullTxt",
        "responses": {
          "200": {
            "description": "Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/agent-instructions.md": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "Ailurn agent instructions (when to use)",
        "operationId": "getAgentInstructions",
        "responses": {
          "200": {
            "description": "Markdown instructions",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "Public sitemap",
        "operationId": "getSitemap",
        "responses": {
          "200": {
            "description": "XML sitemap",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/{path}": {
      "get": {
        "tags": [
          "Content"
        ],
        "summary": "Public page (HTML or Markdown)",
        "description": "Send `Accept: text/markdown` to receive Markdown. Unsupported types with no overlap return 406. Missing paths return 404 with a Markdown recovery body when Markdown is requested.",
        "operationId": "getPublicPage",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Public path without a leading slash. Empty for home."
          },
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "examples": [
                "text/html",
                "text/markdown"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page representation",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string",
                  "example": "Accept, Accept-Encoding"
                }
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Unknown path — recovery links in the body",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "406": {
            "description": "No acceptable representation"
          }
        }
      }
    },
    "/api": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "Public resource index (JSON)",
        "operationId": "getApiIndex",
        "responses": {
          "200": {
            "description": "JSON catalog",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "This OpenAPI document",
        "operationId": "getOpenApi",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 JSON",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/oauth-authorization-server": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "summary": "OAuth 2.0 authorization server metadata (RFC 8414)",
        "operationId": "getOauthAuthorizationServer",
        "responses": {
          "200": {
            "description": "Authorization server metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/openid-configuration": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "summary": "OpenID Connect Discovery",
        "operationId": "getOpenIdConfiguration",
        "responses": {
          "200": {
            "description": "OIDC discovery document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/oauth-protected-resource": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "summary": "OAuth 2.0 protected resource metadata (RFC 9728)",
        "operationId": "getOauthProtectedResource",
        "responses": {
          "200": {
            "description": "Protected resource metadata for the Ailurn MCP server",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/oauth/register": {
      "post": {
        "tags": [
          "OAuth"
        ],
        "summary": "Dynamic client registration (RFC 7591)",
        "operationId": "registerOauthClient",
        "responses": {
          "201": {
            "description": "Registered public client"
          },
          "400": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/oauth/authorize": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "summary": "Authorization endpoint (authorization code + PKCE)",
        "operationId": "oauthAuthorize",
        "responses": {
          "302": {
            "description": "Redirect to login or client redirect_uri"
          },
          "400": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/oauth/token": {
      "post": {
        "tags": [
          "OAuth"
        ],
        "summary": "Token endpoint",
        "operationId": "oauthToken",
        "responses": {
          "200": {
            "description": "Access token response"
          },
          "400": {
            "description": "OAuth error JSON"
          }
        }
      }
    },
    "/.well-known/mcp.json": {
      "get": {
        "tags": [
          "MCP"
        ],
        "summary": "Ailurn MCP server card (SEP-2127)",
        "operationId": "getMcpServerCard",
        "responses": {
          "200": {
            "description": "MCP server card",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "tags": [
          "MCP"
        ],
        "summary": "Ailurn MCP Streamable HTTP endpoint",
        "description": "JSON-RPC 2.0 over Streamable HTTP. Methods: initialize, tools/list, tools/call, ping.",
        "operationId": "mcpStreamableHttp",
        "responses": {
          "200": {
            "description": "JSON-RPC response"
          },
          "202": {
            "description": "Notification acknowledged"
          },
          "400": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/api/{path}": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "Unknown API path",
        "description": "Unmatched /api/* paths return RFC 7807 JSON errors, not HTML.",
        "operationId": "unknownApiPath",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "404": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    }
  }
}