{
  "openapi": "3.1.0",
  "info": {
    "title": "Sebastian Esser – Content API",
    "version": "1.0.0",
    "summary": "Lesezugriff auf die Inhalte von sebastian-esser.de in maschinenlesbarer Form.",
    "description": "Öffentliche, unauthentifizierte Read-only-API. Jede HTML-Seite ist per `Accept: text/markdown` oder über die `.md`-URL auch als Markdown abrufbar. Zusätzlich gibt es einen MCP-Server und einen A2A-Endpunkt, die beide dieselben vier Werkzeuge anbieten.",
    "contact": {
      "name": "Sebastian Esser",
      "email": "hallo@sebastian-esser.de",
      "url": "https://sebastian-esser.de/kontakt"
    },
    "license": {
      "name": "Inhalte © Sebastian Esser",
      "url": "https://sebastian-esser.de/impressum"
    }
  },
  "servers": [
    {
      "url": "https://sebastian-esser.de",
      "description": "Produktion"
    }
  ],
  "paths": {
    "/{slug}": {
      "get": {
        "operationId": "getPage",
        "summary": "Eine Seite abrufen – als HTML oder als Markdown",
        "description": "Mit `Accept: text/markdown` kommt die Markdown-Fassung zurück, sonst HTML.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "angebot",
                "hallo",
                "impressum",
                "index",
                "kontakt",
                "kurs",
                "martin",
                "material",
                "medialab-newsletter-workshop",
                "medium",
                "newsletter-strategie",
                "pressefrderung",
                "radio",
                "remarkable",
                "share",
                "werben-im-newsletter",
                "workshop"
              ]
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "text/markdown"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Die Seite.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Immer `Accept`."
              },
              "x-markdown-tokens": {
                "schema": {
                  "type": "integer"
                },
                "description": "Token-Schätzung der Markdown-Fassung."
              }
            },
            "content": {
              "text/html": {},
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Seite gibt es nicht."
          }
        }
      }
    },
    "/{slug}.md": {
      "get": {
        "operationId": "getPageMarkdown",
        "summary": "Markdown-Fassung einer Seite, ohne Content Negotiation",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "angebot",
                "hallo",
                "impressum",
                "index",
                "kontakt",
                "kurs",
                "martin",
                "material",
                "medialab-newsletter-workshop",
                "medium",
                "newsletter-strategie",
                "pressefrderung",
                "radio",
                "remarkable",
                "share",
                "werben-im-newsletter",
                "workshop"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Markdown.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "summary": "Kompakte Seitenübersicht nach llmstxt.org",
        "responses": {
          "200": {
            "description": "Übersicht.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/agent-index.json": {
      "get": {
        "operationId": "getAgentIndex",
        "summary": "Volltext-Index aller Seiten in einem Dokument",
        "responses": {
          "200": {
            "description": "Index.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "operationId": "mcp",
        "summary": "MCP-Server (Streamable HTTP, JSON-RPC 2.0)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC-Antwort.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/a2a": {
      "post": {
        "operationId": "a2a",
        "summary": "A2A-Endpunkt (JSON-RPC 2.0)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC-Antwort.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "health",
        "summary": "Statusendpunkt",
        "responses": {
          "200": {
            "description": "Status.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  }
}
