{
  "openapi": "3.1.0",
  "info": {
    "title": "tomasz.fr content API",
    "version": "1.0.0",
    "summary": "Read-only machine-readable content published by Tomasz Franckiewicz's personal profile site.",
    "description": "This is a personal profile site, not a SaaS product - so this spec describes the actual surface that exists: a small set of open, read-only GET endpoints that let agents and developers fetch the profile, its structured data and its agent-discovery manifests without scraping rendered HTML. There is no authentication, no write operations, and no rate limiting beyond standard hosting limits.",
    "contact": { "name": "Tomasz Franckiewicz", "email": "hello@tomasz.fr", "url": "https://tomasz.fr/contact.html" },
    "license": { "name": "CC-BY-4.0", "url": "https://creativecommons.org/licenses/by/4.0/" }
  },
  "servers": [{ "url": "https://tomasz.fr", "description": "Production" }],
  "security": [],
  "tags": [
    { "name": "profile", "description": "The human-readable and machine-readable profile itself." },
    { "name": "agent-discovery", "description": "Manifests that tell agents what this site is and how to read it." },
    { "name": "meta", "description": "This API's own description." }
  ],
  "paths": {
    "/": {
      "get": {
        "operationId": "getHomepage",
        "summary": "Get the rendered profile page",
        "description": "Returns the homepage as HTML, with a JSON-LD Person/Organization graph embedded in the head and a full no-JS fallback in a <noscript> block. Send an `Accept: text/markdown` request header to receive the markdown representation (equivalent to GET /index.md) instead.",
        "tags": ["profile"],
        "parameters": [
          { "name": "Accept", "in": "header", "required": false, "description": "Send `text/markdown` to receive the markdown representation of this page instead of HTML.", "schema": { "type": "string", "enum": ["text/html", "text/markdown"], "default": "text/html" } }
        ],
        "responses": {
          "200": {
            "description": "Profile page.",
            "content": {
              "text/html": { "schema": { "type": "string" } },
              "text/markdown": { "schema": { "type": "string" } }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/index.md": {
      "get": {
        "operationId": "getProfileMarkdown",
        "summary": "Get the full profile in markdown",
        "description": "Complete markdown representation of the homepage: headline, approach, full track record with employer/role/dates, toolbox and contact section. This is the preferred source for agents that want structure without parsing HTML.",
        "tags": ["profile"],
        "responses": {
          "200": { "description": "Markdown profile.", "content": { "text/markdown": { "schema": { "type": "string" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getProfileSummary",
        "summary": "Get the canonical plain-text profile summary",
        "description": "Smallest, canonical plain-text summary of the profile per the llms.txt convention: role, location, experience, toolbox, and notes for agents including where every other machine-readable resource lives. Prefer this over scraping the rendered page.",
        "tags": ["profile"],
        "responses": {
          "200": { "description": "Plain-text summary.", "content": { "text/plain": { "schema": { "type": "string" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "operationId": "getSitemap",
        "summary": "Get the sitemap",
        "description": "Standard XML sitemap (sitemaps.org schema) listing every publicly indexable URL on the site.",
        "tags": ["meta"],
        "responses": {
          "200": { "description": "Sitemap.", "content": { "application/xml": { "schema": { "type": "string" } } } }
        }
      }
    },
    "/robots.txt": {
      "get": {
        "operationId": "getRobotsPolicy",
        "summary": "Get the crawling and content-signal policy",
        "description": "robots.txt plus Content-Signals (contentsignals.org) declaring this site open to search indexing, AI input and AI training, and listing named AI crawlers explicitly allowed.",
        "tags": ["meta"],
        "responses": {
          "200": { "description": "Robots policy.", "content": { "text/plain": { "schema": { "type": "string" } } } }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiSpec",
        "summary": "Get this OpenAPI specification",
        "description": "Returns this document. Also available as YAML at /openapi.yaml.",
        "tags": ["meta"],
        "responses": {
          "200": { "description": "OpenAPI 3.1 document.", "content": { "application/json": { "schema": { "type": "object" } } } }
        }
      }
    },
    "/.well-known/agent.json": {
      "get": {
        "operationId": "getAgentManifest",
        "summary": "Get the agent manifest",
        "description": "Machine-readable manifest describing this site for AI agents: capabilities, available resources, content-negotiation rules, crawling policy and content signals.",
        "tags": ["agent-discovery"],
        "responses": {
          "200": { "description": "Agent manifest.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentManifest" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/.well-known/ai-catalog.json": {
      "get": {
        "operationId": "getCapabilityCatalog",
        "summary": "Get the ARD capability catalog",
        "description": "Catalog of this host's machine-readable entries (profile summary, markdown, JSON-LD, agent manifest, agent skill), each with representative natural-language queries it answers.",
        "tags": ["agent-discovery"],
        "responses": {
          "200": { "description": "Capability catalog.", "content": { "application/json": { "schema": { "type": "object" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/.well-known/api-catalog": {
      "get": {
        "operationId": "getApiCatalog",
        "summary": "Get the RFC 9727 API catalog",
        "description": "RFC 9727 linkset describing this API's own discovery documents (service-desc, service-doc, describedby).",
        "tags": ["agent-discovery"],
        "responses": {
          "200": { "description": "API catalog linkset.", "content": { "application/linkset+json": { "schema": { "type": "object" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/.well-known/mcp.json": {
      "get": {
        "operationId": "getMcpManifest",
        "summary": "Get the MCP / WebMCP capability manifest",
        "description": "Declares that no server-side MCP (Streamable HTTP) server is operated, and lists the read-only WebMCP tools the homepage registers client-side via navigator.modelContext.provideContext().",
        "tags": ["agent-discovery"],
        "responses": {
          "200": { "description": "MCP manifest.", "content": { "application/json": { "schema": { "type": "object" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/.well-known/agent-skills/index.json": {
      "get": {
        "operationId": "getAgentSkillsIndex",
        "summary": "Get the Agent Skills index",
        "description": "Index of Agent Skills (agentskills.io convention) published by this site, currently a single skill describing how to read this profile and the etiquette for contact.",
        "tags": ["agent-discovery"],
        "responses": {
          "200": { "description": "Agent skills index.", "content": { "application/json": { "schema": { "type": "object" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AgentManifest": {
        "type": "object",
        "description": "Shape of /.well-known/agent.json.",
        "properties": {
          "schema_version": { "type": "string" },
          "name_for_human": { "type": "string" },
          "name_for_model": { "type": "string" },
          "description_for_human": { "type": "string" },
          "description_for_model": { "type": "string" },
          "contact_email": { "type": "string", "format": "email" },
          "resources": { "type": "object", "additionalProperties": { "type": "string", "format": "uri" } },
          "crawling": { "type": "object" },
          "content_negotiation": { "type": "object" },
          "content_signals": { "type": "object" },
          "capabilities": { "type": "object" }
        }
      },
      "Error": {
        "type": "object",
        "description": "Structured JSON error shape used across this API.",
        "required": ["error", "message"],
        "properties": {
          "error": { "type": "string", "description": "Machine-readable, stable error code.", "examples": ["not_found"] },
          "message": { "type": "string", "description": "Human-readable explanation." },
          "resolution_hint": { "type": "string", "description": "What an agent should try next." },
          "resources": { "type": "object", "additionalProperties": { "type": "string", "format": "uri" }, "description": "Related machine-readable resources to recover with." }
        }
      }
    },
    "responses": {
      "NotFound": {
        "description": "No resource exists at this path. See /404.json for a standalone example of this shape.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": {
              "error": "not_found",
              "message": "No resource exists at this path.",
              "resolution_hint": "See /sitemap.xml, /llms.txt or /developers.html.",
              "resources": { "sitemap": "https://tomasz.fr/sitemap.xml", "llms_txt": "https://tomasz.fr/llms.txt" }
            }
          }
        }
      }
    }
  }
}
