{
  "openapi": "3.1.0",
  "info": {
    "title": "AISquare Studio public site API",
    "version": "1.0.0",
    "summary": "Read-only JSON and markdown access to everything published on aisquare.studio.",
    "description": "Public, unauthenticated, read-only API over the content of aisquare.studio: the page catalog,\nthe events and webinars calendar, the developer blog, and a markdown rendering of every page.\n\n**When to use it.** Reach for this API when you need current, structured facts about AISquare —\nwhat the product does, what a plan costs, when the next webinar is and how to register, what a\nblog post says, or how to contact the company — instead of scraping the HTML site.\n\n**When not to use it.** This is the marketing site. It does not expose AISquare product data\n(reasoning graphs, policies, agent traces): that is a separate authenticated API documented at https://docs.aisquare.studio/api-reference.\n\n**Conventions.** No authentication, no rate limit beyond ordinary CDN fair use, CORS open to any\norigin. Every error is JSON with a stable `error.code`, a `message`, and a `hint`. Every page also\nserves `text/markdown` via `Accept` negotiation or by appending `.md` to its path.\n\n**MCP.** The same content is available to MCP clients over Streamable HTTP at https://aisquare.studio/mcp.",
    "contact": {
      "name": "AISquare Studio",
      "email": "bots@aisquare.studio",
      "url": "https://aisquare.studio/contact"
    },
    "termsOfService": "https://aisquare.studio/tnc",
    "license": {
      "name": "Proprietary — content © AISquare Studios Inc.",
      "url": "https://aisquare.studio/tnc"
    }
  },
  "servers": [
    {
      "url": "https://aisquare.studio",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "AISquare product documentation",
    "url": "https://docs.aisquare.studio"
  },
  "tags": [
    {
      "name": "site",
      "description": "The page catalog and markdown rendering of aisquare.studio."
    },
    {
      "name": "events",
      "description": "Webinars, conferences, meetups and recaps, with dates and registration links."
    },
    {
      "name": "blog",
      "description": "Posts from the AISquare developer blog."
    },
    {
      "name": "search",
      "description": "Cross-content keyword search."
    },
    {
      "name": "meta",
      "description": "Service metadata: health, specification, MCP transport."
    }
  ],
  "x-mcp": {
    "transport": "streamable-http",
    "endpoint": "https://aisquare.studio/mcp",
    "description": "Model Context Protocol endpoint exposing the same content as resources and tools."
  },
  "paths": {
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "meta"
        ],
        "summary": "Service health and machine-readable entry points",
        "description": "Liveness probe. Returns the service status plus the canonical URLs of every machine-readable surface (OpenAPI spec, MCP endpoint, llms.txt, agent instructions, sitemap). Call this first to discover the rest of the API.",
        "responses": {
          "200": {
            "description": "The service is up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed. The `Allow` header lists the accepted methods.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/site": {
      "get": {
        "operationId": "getSiteIndex",
        "tags": [
          "site"
        ],
        "summary": "List every page on aisquare.studio",
        "description": "The full catalog of public pages with, for each, its URL, title, one-sentence summary, intended audience, topic keywords, and the URL of its markdown rendering. Use it to decide which page answers a question before fetching any content.",
        "responses": {
          "200": {
            "description": "The page catalog.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteIndex"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed. The `Allow` header lists the accepted methods.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/events": {
      "get": {
        "operationId": "listEvents",
        "tags": [
          "events"
        ],
        "summary": "List AISquare events and webinars",
        "description": "Every published event — webinars, conferences, meetups, hackathons — with dates resolved in the event's own timezone, a derived `upcoming`/`live`/`past` status, whether registration is still open, and where to register. Filter to answer questions like \"what is the next AISquare webinar?\".",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Restrict to events in this lifecycle state, derived from the current time in the event's timezone. Omit for all events.",
            "schema": {
              "type": "string",
              "enum": [
                "upcoming",
                "live",
                "past",
                "all"
              ],
              "default": "all"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Restrict to virtual (webinar) or in-person events.",
            "schema": {
              "type": "string",
              "enum": [
                "Virtual",
                "In person"
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Restrict to one event type.",
            "schema": {
              "type": "string",
              "enum": [
                "Conference",
                "Workshop",
                "Meetup",
                "Webinar",
                "Hackathon"
              ]
            }
          },
          {
            "name": "topic",
            "in": "query",
            "required": false,
            "description": "Case-insensitive exact match on the event's topic facet, e.g. \"Agent Governance\".",
            "schema": {
              "type": "string",
              "maxLength": 120
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return, newest first. Defaults to 50.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching events, soonest first for upcoming and most recent first for past.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter. The body names the offending parameter and the accepted range.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource. The body points at the endpoint that lists valid identifiers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed. The `Allow` header lists the accepted methods.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/events/{slug}": {
      "get": {
        "operationId": "getEvent",
        "tags": [
          "events"
        ],
        "summary": "Get one event by slug",
        "description": "The full record for a single event, including the agenda body, what attendees will learn, the speaker list, partner, and registration URL.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Event slug, as returned by listEvents — the last path segment of the event's page URL.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9][a-z0-9-]*$",
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The event.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Event"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter. The body names the offending parameter and the accepted range.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource. The body points at the endpoint that lists valid identifiers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed. The `Allow` header lists the accepted methods.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/blog": {
      "get": {
        "operationId": "listBlogPosts",
        "tags": [
          "blog"
        ],
        "summary": "List developer blog posts",
        "description": "Every published post, newest first, with its excerpt, author, category and tags.",
        "parameters": [
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "description": "Case-insensitive exact match on one of the post's tags.",
            "schema": {
              "type": "string",
              "maxLength": 120
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Case-insensitive exact match on the post's category.",
            "schema": {
              "type": "string",
              "maxLength": 120
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return, newest first. Defaults to 50.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching posts, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlogPostList"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter. The body names the offending parameter and the accepted range.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource. The body points at the endpoint that lists valid identifiers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed. The `Allow` header lists the accepted methods.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/blog/{slug}": {
      "get": {
        "operationId": "getBlogPost",
        "tags": [
          "blog"
        ],
        "summary": "Get one blog post by slug",
        "description": "The full markdown body of a single post plus its metadata.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Post slug, as returned by listBlogPosts.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9][a-z0-9-]*$",
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The post.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlogPost"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter. The body names the offending parameter and the accepted range.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource. The body points at the endpoint that lists valid identifiers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed. The `Allow` header lists the accepted methods.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "operationId": "searchSite",
        "tags": [
          "search"
        ],
        "summary": "Keyword-search pages, events and blog posts",
        "description": "Case-insensitive keyword search across page summaries, event records and blog posts. Returns ranked results with the URL and markdown URL of each hit. Use it when you do not know which page answers a question.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search terms. Every whitespace-separated term must appear in the result.",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 200
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Restrict results to one content kind.",
            "schema": {
              "type": "string",
              "enum": [
                "page",
                "event",
                "blog",
                "all"
              ],
              "default": "all"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return, newest first. Defaults to 10.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked matches.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter. The body names the offending parameter and the accepted range.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource. The body points at the endpoint that lists valid identifiers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed. The `Allow` header lists the accepted methods.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/md/{path}": {
      "get": {
        "operationId": "getPageMarkdown",
        "tags": [
          "site"
        ],
        "summary": "Get any page as markdown",
        "description": "The markdown rendering of any page on the site. Equivalent to requesting the page itself with `Accept: text/markdown`, or to appending `.md` to its path. Unknown paths return 404 with a markdown body that links to the sitemap and the rest of the site.",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "Site path without the leading slash, e.g. `teams`, `pricing`, `events/ai-governance-webinar`. Use an empty value for the homepage.",
            "schema": {
              "type": "string",
              "maxLength": 400
            },
            "allowEmptyValue": true
          }
        ],
        "responses": {
          "200": {
            "description": "The page as markdown.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "No such page. The markdown body lists where to look instead.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed. The `Allow` header lists the accepted methods.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiSpec",
        "tags": [
          "meta"
        ],
        "summary": "This specification, as JSON",
        "description": "Returns this OpenAPI 3.1 document. The same document is served as YAML at /api/openapi.yaml.",
        "responses": {
          "200": {
            "description": "The OpenAPI document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed. The `Allow` header lists the accepted methods.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/openapi.yaml": {
      "get": {
        "operationId": "getOpenApiSpecYaml",
        "tags": [
          "meta"
        ],
        "summary": "This specification, as YAML",
        "description": "Returns this OpenAPI 3.1 document in YAML form, for tooling that prefers it.",
        "responses": {
          "200": {
            "description": "The OpenAPI document.",
            "content": {
              "application/yaml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed. The `Allow` header lists the accepted methods.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "operationId": "postMcpMessage",
        "tags": [
          "meta"
        ],
        "summary": "Model Context Protocol endpoint (Streamable HTTP)",
        "description": "JSON-RPC 2.0 endpoint implementing MCP over Streamable HTTP. Supports the handshake-based revisions (`initialize`) and the 2026-07-28 revision (`server/discover`), and exposes this site's pages, events and posts as MCP resources plus five tools. Point any MCP client at this URL; it is not a REST endpoint.",
        "requestBody": {
          "required": true,
          "description": "A single JSON-RPC 2.0 request or notification.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonRpcRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            }
          },
          "202": {
            "description": "Notification accepted; no body."
          },
          "400": {
            "description": "Malformed JSON-RPC, header/body mismatch, or unsupported protocol version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown JSON-RPC method.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            }
          },
          "405": {
            "description": "GET and DELETE are not supported: this endpoint has no standalone SSE stream or sessions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "description": "The single error envelope used by every JSON endpoint on this site.",
        "required": [
          "error"
        ],
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "hint",
              "status",
              "documentation_url"
            ],
            "additionalProperties": false,
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code. Branch on this, never on `message`.",
                "enum": [
                  "not_found",
                  "invalid_request",
                  "method_not_allowed",
                  "not_acceptable",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string",
                "description": "What went wrong, in one sentence."
              },
              "hint": {
                "type": "string",
                "description": "How to recover, with a URL where one applies."
              },
              "status": {
                "type": "integer",
                "description": "The HTTP status, mirrored for logging."
              },
              "documentation_url": {
                "type": "string",
                "format": "uri",
                "description": "Where the contract is defined."
              }
            }
          }
        }
      },
      "Health": {
        "type": "object",
        "description": "Service status and the canonical machine-readable entry points.",
        "required": [
          "status",
          "service",
          "endpoints"
        ],
        "additionalProperties": false,
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok"
            ],
            "description": "Always `ok` when the service answers."
          },
          "service": {
            "type": "string",
            "description": "Service name."
          },
          "version": {
            "type": "string",
            "description": "Version of this API contract."
          },
          "documentation": {
            "type": "object",
            "description": "Human-facing documentation URLs.",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            }
          },
          "endpoints": {
            "type": "object",
            "description": "Canonical URLs of every machine-readable surface.",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            }
          }
        }
      },
      "Page": {
        "type": "object",
        "description": "One public page of aisquare.studio.",
        "required": [
          "path",
          "url",
          "markdownUrl",
          "title",
          "summary",
          "audience",
          "keywords"
        ],
        "additionalProperties": false,
        "properties": {
          "path": {
            "type": "string",
            "description": "Route path with a leading slash."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Absolute page URL."
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri",
            "description": "Absolute URL of the markdown rendering."
          },
          "title": {
            "type": "string",
            "description": "Page title."
          },
          "summary": {
            "type": "string",
            "description": "One sentence describing what the page is for."
          },
          "audience": {
            "type": "string",
            "description": "Who the page is written for."
          },
          "keywords": {
            "type": "array",
            "description": "Topic keywords.",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "SiteIndex": {
        "type": "object",
        "description": "The full page catalog.",
        "required": [
          "site",
          "count",
          "pages"
        ],
        "additionalProperties": false,
        "properties": {
          "site": {
            "type": "string",
            "format": "uri",
            "description": "Site origin."
          },
          "count": {
            "type": "integer",
            "description": "Number of pages returned."
          },
          "pages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Page"
            }
          }
        }
      },
      "EventSummary": {
        "type": "object",
        "description": "An event as it appears in a list.",
        "required": [
          "slug",
          "title",
          "excerpt",
          "date",
          "timezone",
          "location",
          "type",
          "format",
          "status",
          "registrationOpen",
          "url",
          "markdownUrl",
          "tags"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "description": "Stable identifier and last URL segment."
          },
          "title": {
            "type": "string",
            "description": "Event title."
          },
          "subtitle": {
            "type": "string",
            "description": "Optional strapline."
          },
          "excerpt": {
            "type": "string",
            "description": "One-paragraph description."
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "Start date, YYYY-MM-DD, in the event's timezone."
          },
          "endDate": {
            "type": "string",
            "format": "date",
            "description": "End date for multi-day events."
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone the dates and times are expressed in."
          },
          "startTime": {
            "type": "string",
            "pattern": "^\\d{2}:\\d{2}$",
            "description": "Local start time (24h) for timed events."
          },
          "durationMinutes": {
            "type": "integer",
            "description": "Scheduled length in minutes for timed events."
          },
          "location": {
            "type": "string",
            "description": "Venue, or `Online` for virtual events."
          },
          "type": {
            "type": "string",
            "enum": [
              "Conference",
              "Workshop",
              "Meetup",
              "Webinar",
              "Hackathon"
            ]
          },
          "format": {
            "type": "string",
            "enum": [
              "Virtual",
              "In person"
            ]
          },
          "topic": {
            "type": "string",
            "description": "Topic facet."
          },
          "series": {
            "type": "string",
            "description": "Series this event belongs to."
          },
          "status": {
            "type": "string",
            "enum": [
              "upcoming",
              "live",
              "past"
            ],
            "description": "Derived from the current time in the event's timezone."
          },
          "registrationOpen": {
            "type": "boolean",
            "description": "Whether registration is still being accepted."
          },
          "registrationUrl": {
            "type": "string",
            "format": "uri",
            "description": "External registration URL, when the host is not AISquare."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Event page."
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri",
            "description": "Markdown rendering of the event page."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Free-form tags."
          }
        }
      },
      "Event": {
        "allOf": [
          {
            "$ref": "#/components/schemas/EventSummary"
          },
          {
            "type": "object",
            "description": "Full event record.",
            "required": [
              "content"
            ],
            "properties": {
              "learn": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "What attendees will learn."
              },
              "speakers": {
                "type": "array",
                "description": "Speaker line-up.",
                "items": {
                  "type": "object",
                  "required": [
                    "name",
                    "title",
                    "company"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "company": {
                      "type": "string"
                    }
                  }
                }
              },
              "partner": {
                "type": "string",
                "description": "Partner organisation."
              },
              "partnerUrl": {
                "type": "string",
                "format": "uri",
                "description": "Partner website."
              },
              "timeLabel": {
                "type": "string",
                "description": "Human-readable time, e.g. `11:00 AM ET / 8:30 PM IST`."
              },
              "durationLabel": {
                "type": "string",
                "description": "Human-readable duration."
              },
              "content": {
                "type": "string",
                "description": "The event page body, as markdown."
              }
            }
          }
        ]
      },
      "EventList": {
        "type": "object",
        "required": [
          "count",
          "events"
        ],
        "additionalProperties": false,
        "properties": {
          "count": {
            "type": "integer",
            "description": "Number of events returned after filtering."
          },
          "total": {
            "type": "integer",
            "description": "Number of published events before filtering."
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When statuses were computed."
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventSummary"
            }
          }
        }
      },
      "BlogPostSummary": {
        "type": "object",
        "description": "A blog post as it appears in a list.",
        "required": [
          "slug",
          "title",
          "excerpt",
          "date",
          "author",
          "category",
          "tags",
          "url",
          "markdownUrl"
        ],
        "additionalProperties": false,
        "properties": {
          "slug": {
            "type": "string",
            "description": "Stable identifier and last URL segment."
          },
          "title": {
            "type": "string"
          },
          "excerpt": {
            "type": "string",
            "description": "Short summary."
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "Publication date."
          },
          "author": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "BlogPost": {
        "allOf": [
          {
            "$ref": "#/components/schemas/BlogPostSummary"
          },
          {
            "type": "object",
            "required": [
              "content"
            ],
            "properties": {
              "content": {
                "type": "string",
                "description": "The post body, as markdown."
              }
            }
          }
        ]
      },
      "BlogPostList": {
        "type": "object",
        "required": [
          "count",
          "posts"
        ],
        "additionalProperties": false,
        "properties": {
          "count": {
            "type": "integer",
            "description": "Number of posts returned after filtering."
          },
          "total": {
            "type": "integer",
            "description": "Number of published posts before filtering."
          },
          "posts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlogPostSummary"
            }
          }
        }
      },
      "SearchResult": {
        "type": "object",
        "description": "One search hit.",
        "required": [
          "kind",
          "title",
          "url",
          "markdownUrl",
          "snippet",
          "score"
        ],
        "additionalProperties": false,
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "page",
              "event",
              "blog"
            ],
            "description": "What kind of content matched."
          },
          "title": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri"
          },
          "snippet": {
            "type": "string",
            "description": "Short extract explaining the match."
          },
          "score": {
            "type": "number",
            "description": "Relevance score; higher is better."
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "required": [
          "query",
          "count",
          "results"
        ],
        "additionalProperties": false,
        "properties": {
          "query": {
            "type": "string",
            "description": "The query that was run."
          },
          "count": {
            "type": "integer",
            "description": "Number of results returned."
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchResult"
            }
          }
        }
      },
      "JsonRpcRequest": {
        "type": "object",
        "description": "A JSON-RPC 2.0 request or notification as defined by the MCP specification.",
        "required": [
          "jsonrpc",
          "method"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "enum": [
              "2.0"
            ]
          },
          "id": {
            "description": "Request identifier. Omit for notifications.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              }
            ]
          },
          "method": {
            "type": "string",
            "description": "MCP method, e.g. `initialize`, `server/discover`, `resources/list`, `tools/call`."
          },
          "params": {
            "type": "object",
            "description": "Method parameters.",
            "additionalProperties": true
          }
        }
      },
      "JsonRpcResponse": {
        "type": "object",
        "description": "A JSON-RPC 2.0 response.",
        "required": [
          "jsonrpc"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "enum": [
              "2.0"
            ]
          },
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "result": {
            "type": "object",
            "description": "Present on success.",
            "additionalProperties": true
          },
          "error": {
            "type": "object",
            "description": "Present on failure.",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "integer"
              },
              "message": {
                "type": "string"
              },
              "data": {
                "description": "Optional structured detail."
              }
            }
          }
        }
      }
    }
  },
  "x-contact": {
    "demo": "https://calendly.com/d/cyp5-wv4-sgs/aisquare-studios-demo",
    "email": "bots@aisquare.studio",
    "discord": "https://discord.com/invite/8tJ3aCDYur"
  }
}
