{
  "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, and read CMS posts and content library items for the authorized user's projects. Read-only. 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."
      }
    }
  }
}
