{
  "openapi": "3.1.0",
  "info": {
    "title": "RightBlogger Public API",
    "version": "1.0.0",
    "summary": "Public, machine-readable surface of rightblogger.com: the MCP server plus agent-facing content endpoints.",
    "description": "RightBlogger is an AI blog automation tool that helps you research, write, publish, promote, and maintain your blog.\n\nProgrammatic access to a user's RightBlogger account (Search Console data, keyword research, CMS posts, content library) is provided through the Model Context Protocol server at `/api/mcp` (OAuth 2.1, no API keys). Human-readable docs: https://rightblogger.com/developers and https://rightblogger.com/mcp. Agent authorization is described in https://rightblogger.com/auth.md.\n\nAll other `/api/*` routes power the interactive app, are session-authenticated, and are not a public integration surface. Requests to nonexistent `/api/*` paths return a structured JSON error (see the `ApiError` schema).",
    "contact": {
      "name": "RightBlogger Support",
      "email": "contact@rightblogger.com",
      "url": "https://rightblogger.com/help"
    },
    "termsOfService": "https://rightblogger.com/terms",
    "license": {
      "name": "Proprietary",
      "url": "https://rightblogger.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://rightblogger.com"
    }
  ],
  "tags": [
    {
      "name": "MCP",
      "description": "Model Context Protocol server (Streamable HTTP transport). The primary programmatic interface to a RightBlogger account."
    },
    {
      "name": "Discovery",
      "description": "Machine-readable discovery and index documents for AI agents and crawlers."
    },
    {
      "name": "Content",
      "description": "Markdown and feed alternates of site content."
    }
  ],
  "paths": {
    "/api/mcp": {
      "post": {
        "tags": [
          "MCP"
        ],
        "operationId": "mcpPost",
        "summary": "Send an MCP JSON-RPC message",
        "description": "Model Context Protocol endpoint (Streamable HTTP transport, JSON-RPC 2.0). Connect an MCP client (Claude, ChatGPT, Cursor) to `https://rightblogger.com/api/mcp` to query Google Search Console performance, research keywords, read CMS posts and content library items, and manage automations, calendars and the Site Agent for the authorized user's projects. Writes follow the project role and confirm before anything publishes. Authorization is OAuth 2.1 with PKCE; discovery starts at `/.well-known/oauth-protected-resource` and the agent flow is documented in `/auth.md`. Unauthenticated requests receive `401` with a `WWW-Authenticate` header pointing at the resource metadata.",
        "externalDocs": {
          "description": "RightBlogger MCP connector docs",
          "url": "https://rightblogger.com/mcp"
        },
        "security": [
          {
            "oauth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonRpcMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC response, as JSON or an SSE stream depending on the negotiated transport.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcMessage"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "get": {
        "tags": [
          "MCP"
        ],
        "operationId": "mcpStream",
        "summary": "Open the MCP server event stream",
        "description": "Server-to-client stream of the MCP Streamable HTTP transport.",
        "security": [
          {
            "oauth": []
          }
        ],
        "responses": {
          "200": {
            "description": "SSE stream.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "delete": {
        "tags": [
          "MCP"
        ],
        "operationId": "mcpEndSession",
        "summary": "Terminate an MCP session",
        "security": [
          {
            "oauth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Session terminated."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "description": "Ends the current MCP session (Streamable HTTP transport session teardown)."
      }
    },
    "/.well-known/oauth-protected-resource": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getProtectedResourceMetadata",
        "summary": "OAuth 2.0 Protected Resource Metadata (RFC 9728)",
        "description": "Names the authorization server for the MCP endpoint. Fetch this first, then the authorization server's own RFC 8414 metadata, then run an authorization code + PKCE flow.",
        "responses": {
          "200": {
            "description": "Protected resource metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtectedResourceMetadata"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/auth.md": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getAuthManifest",
        "summary": "Agent authorization manifest (auth.md protocol)",
        "description": "Markdown manifest telling AI agents how to register an OAuth client (RFC 7591 dynamic registration) and obtain user-scoped access tokens for the MCP server.",
        "responses": {
          "200": {
            "description": "Markdown manifest.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/llms.txt": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getLlmsTxt",
        "summary": "llms.txt product index",
        "description": "Machine-readable index of RightBlogger for LLMs: what the product does, who it is for, pricing, integrations, the Site Agent, the MCP connector, and links to every key page and tool.",
        "responses": {
          "200": {
            "description": "llms.txt markdown.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/openapi.json": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getOpenApiSpec",
        "summary": "This OpenAPI document",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 spec.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [],
        "description": "The OpenAPI 3.1 document you are reading: the machine-readable index of every public RightBlogger endpoint."
      }
    },
    "/sitemap.xml": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getSitemap",
        "summary": "XML sitemap",
        "responses": {
          "200": {
            "description": "Sitemap of all indexable pages.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [],
        "description": "XML sitemap of every indexable page, including all tool pages, blog posts, glossary entries, and help articles."
      }
    },
    "/feed.xml": {
      "get": {
        "tags": [
          "Content"
        ],
        "operationId": "getFeed",
        "summary": "Blog RSS feed",
        "responses": {
          "200": {
            "description": "RSS 2.0 feed of the RightBlogger blog.",
            "content": {
              "application/rss+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [],
        "description": "RSS 2.0 feed of the RightBlogger blog with full post metadata."
      }
    },
    "/pricing.md": {
      "get": {
        "tags": [
          "Content"
        ],
        "operationId": "getPricingMarkdown",
        "summary": "Pricing in markdown",
        "description": "Current plans, prices, and plan limits as markdown for AI agents.",
        "responses": {
          "200": {
            "description": "Pricing markdown.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/blog/{slug}.md": {
      "get": {
        "tags": [
          "Content"
        ],
        "operationId": "getBlogPostMarkdown",
        "summary": "Blog post as markdown",
        "description": "Markdown alternate of any blog post. Append `.md` to a post URL from the sitemap or feed.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          }
        ],
        "responses": {
          "200": {
            "description": "Post markdown.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": []
      }
    },
    "/glossary/{slug}.md": {
      "get": {
        "tags": [
          "Content"
        ],
        "operationId": "getGlossaryMarkdown",
        "summary": "Glossary entry as markdown",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          }
        ],
        "responses": {
          "200": {
            "description": "Entry markdown.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [],
        "description": "Markdown alternate of any glossary entry. Append .md to a glossary URL from the sitemap."
      }
    },
    "/help/{slug}.md": {
      "get": {
        "tags": [
          "Content"
        ],
        "operationId": "getHelpArticleMarkdown",
        "summary": "Help article as markdown",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          }
        ],
        "responses": {
          "200": {
            "description": "Article markdown.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [],
        "description": "Markdown alternate of any help center article. Append .md to a help URL from the sitemap."
      }
    }
  },
  "components": {
    "parameters": {
      "Slug": {
        "name": "slug",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "URL slug of the content item."
      }
    },
    "responses": {
      "NotFound": {
        "description": "No content exists at this path.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid access token. The `WWW-Authenticate` header points at `/.well-known/oauth-protected-resource`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        }
      }
    },
    "schemas": {
      "ApiError": {
        "type": "object",
        "description": "Structured error returned by API routes, including requests to nonexistent /api/* paths.",
        "required": [
          "error",
          "code",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Short human-readable error name."
          },
          "code": {
            "type": "string",
            "description": "Stable machine-readable error code, e.g. NOT_FOUND or AUTH_REQUIRED."
          },
          "message": {
            "type": "string",
            "description": "What went wrong."
          },
          "hint": {
            "type": "string",
            "description": "How to resolve it or where to look next."
          },
          "openapi": {
            "type": "string",
            "format": "uri",
            "description": "URL of this OpenAPI document."
          },
          "docs": {
            "type": "string",
            "format": "uri",
            "description": "URL of the developer docs."
          }
        }
      },
      "JsonRpcMessage": {
        "type": "object",
        "description": "A JSON-RPC 2.0 message per the Model Context Protocol specification (https://modelcontextprotocol.io).",
        "required": [
          "jsonrpc"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ]
          },
          "method": {
            "type": "string"
          },
          "params": {
            "type": "object"
          },
          "result": {},
          "error": {
            "type": "object"
          }
        }
      },
      "ProtectedResourceMetadata": {
        "type": "object",
        "description": "RFC 9728 OAuth 2.0 Protected Resource Metadata.",
        "properties": {
          "resource": {
            "type": "string",
            "format": "uri"
          },
          "authorization_servers": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "bearer_methods_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "scopes_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "oauth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "OAuth 2.1 access token",
        "description": "OAuth 2.1 authorization code + PKCE, bound to a RightBlogger user account. Discover the authorization server via `/.well-known/oauth-protected-resource` (RFC 9728); dynamic client registration (RFC 7591) is supported. Step-by-step agent flow: https://rightblogger.com/auth.md. No API keys and no anonymous access."
      }
    }
  }
}
