Skip to main content
Glama
README.md
# BrewPage API -- Open Source Public Layer

<p>
<a href="https://www.npmjs.com/package/brewpage-mcp"><img height="18" alt="npm brewpage-mcp" src="https://img.shields.io/npm/v/brewpage-mcp?label=brewpage-mcp"></a>
<a href="https://www.npmjs.com/package/n8n-nodes-brewpage"><img height="18" alt="npm n8n-nodes-brewpage" src="https://img.shields.io/npm/v/n8n-nodes-brewpage?label=n8n-nodes-brewpage"></a>
<a href="https://pypi.org/project/langchain-brewpage/"><img height="18" alt="PyPI langchain-brewpage" src="https://img.shields.io/pypi/v/langchain-brewpage?label=langchain-brewpage"></a>
<a href="https://pypi.org/project/llama-index-tools-brewpage/"><img height="18" alt="PyPI llama-index-tools-brewpage" src="https://img.shields.io/pypi/v/llama-index-tools-brewpage?label=llama-index-tools-brewpage"></a>
<a href="https://github.com/marketplace/actions/publish-to-brewpage"><img height="18" alt="GitHub Marketplace: Publish to BrewPage" src="https://img.shields.io/badge/Marketplace-Publish%20to%20BrewPage-purple?logo=github"></a>
<a href="https://github.com/kochetkov-ma/brewpage-openapi/blob/main/openapi/openapi.yaml"><img height="18" alt="OpenAPI 3.1" src="https://img.shields.io/badge/OpenAPI-3.1-green?logo=openapiinitiative"></a>
<a href="https://github.com/kochetkov-ma/brewpage-openapi/tree/main/mcp-server"><img height="18" alt="MCP server brewpage-mcp" src="https://img.shields.io/badge/MCP-brewpage--mcp-gold"></a>
<a href="https://github.com/kochetkov-ma/brewpage-openapi/blob/main/LICENSE"><img height="18" alt="License Apache-2.0" src="https://img.shields.io/badge/License-Apache%202.0-blue"></a>
<a href="https://github.com/kochetkov-ma/brewpage-openapi/actions/workflows/docs.yml"><img height="18" alt="Deploy Docs" src="https://github.com/kochetkov-ma/brewpage-openapi/actions/workflows/docs.yml/badge.svg"></a>
<a href="https://github.com/kochetkov-ma/brewpage-openapi/actions/workflows/release.yml"><img height="18" alt="Release" src="https://github.com/kochetkov-ma/brewpage-openapi/actions/workflows/release.yml/badge.svg"></a>
<a href="https://github.com/kochetkov-ma/brewpage-openapi"><img height="18" alt="GitHub stars" src="https://img.shields.io/github/stars/kochetkov-ma/brewpage-openapi"></a>
</p>
<p>
<a href="https://glama.ai/mcp/servers/kochetkov-ma/brewpage-openapi"><img height="18" alt="kochetkov-ma/brewpage-openapi MCP server" src="https://glama.ai/mcp/servers/kochetkov-ma/brewpage-openapi/badges/score.svg"></a>
<a href="https://mcprush.com/to/brewpage-mcp?ref=badge"><picture><source media="(prefers-color-scheme: light)" srcset="https://mcprush.com/badge/brewpage-mcp/score.svg?theme=light"><img height="18" alt="Brewpage MCP on mcprush" src="https://mcprush.com/badge/brewpage-mcp/score.svg"></picture></a>
<a href="https://appside.build/mcp-servers/brewpage-openapi/"><img height="18" alt="Verified on Appside" src="https://appside.build/mcp-servers/brewpage-openapi/badge.svg"></a>
</p>

> This repository is the **open-source public layer** of [BrewPage](https://brewpage.app) --
> a proprietary HTML/KV/JSON/file hosting platform.
> The backend, frontend, and infrastructure remain closed-source.

**Docs:** https://kochetkov-ma.github.io/brewpage-openapi/ | **API Reference:** https://kochetkov-ma.github.io/brewpage-openapi/api-reference/

## What is BrewPage

[BrewPage](https://brewpage.app) is a free instant hosting service for HTML pages, Markdown documents,
multi-file sites, AI artifacts, JSON documents, key-value stores, and binary files.
No signup or API key required for creation. Use the exact returned primary HTTPS `link`; publications may use a BrewPage path or their own content host.

Key characteristics:

- **HTML and Markdown pages** -- publish raw HTML or Markdown rendered to styled HTML, up to 5 MiB, with instant short URLs.
- **Multi-file sites** -- upload a ZIP archive or individual files (up to 200 files, 5 MiB per file, 20 MiB total; current values at `GET /api/limits`) and get a fully served static site.
- **Key-value store** -- KV pairs addressed by namespace/store ID, up to 1,000 keys per store, mutable in place via the owner token.
- **JSON documents** -- store and retrieve arbitrary JSON, up to 1 MiB per document, 10,000 documents per namespace.
- **File hosting** -- upload any safe file type (images, PDFs, video, audio, archives, code), up to 5 MiB (video 20 MiB), with inline preview.
- **Visibility** -- REST omitted `?ns=` publishes privately; MCP omitted namespace generates a private namespace: unlisted and not indexed; anyone with the link can still open it. `public` lists HTML, sites and files in the gallery and sitemap, so Google, Bing and AI search can find and index them; public pages are served on the brewpage.app domain for the strongest reach (a site always gets its own subdomain). Never put secrets in a public publication. Password-protected publications, JSON and KV are never listed. `POST …/visibility {"listed":false}` hides a public publication, link unchanged.
- **Owner tokens** -- every publish response includes an `ownerToken`. Use it to update content in place (stable URL), delete it, or list your own resources. No account needed. Optional: sign in free (Google or any email) at https://account.brewpage.app to never lose your pages or tokens and to mint tokens that never expire. Not needed to publish. Creates also return a private `manageUrl` (management link) for that one publication: an assistant gives it to the user with the link; never post it publicly.
- **TTL** -- in days through the REST `ttl` query parameter on create: up to 30 days without an account, up to 90 with a free profile (send its `X-Owner-Token`); a default applies when `ttl` is omitted. Accepts whole days: `15`, `15d`, `15 days`. Updates keep the original expiry; use returned `expiresAt`.
- **Access** -- unprotected reads and creation require no account. Protected reads use `X-Password`; owner updates, deletion and scoped lists use `X-Owner-Token`. Rate limits depend on operation/visibility; handle `429` and `Retry-After`.

The API base URL is `https://brewpage.app`. `brewdata.app` is a redirect domain: every path answers 301 to `brewpage.app`.

Choosing a host? See how BrewPage compares with GitHub Pages, Netlify Drop, Tiiny Host and other tools: [brewpage.app/compare](https://brewpage.app/compare).

## Why this matters for LLMs and agents

AI agents frequently need to share structured outputs -- reports, artifacts, generated HTML, intermediate JSON state -- with users or downstream systems via a stable URL. BrewPage provides that as a zero-setup REST API: one `POST` call, one URL back. No OAuth, no S3 bucket configuration, no infrastructure. The MCP server (`brewpage-mcp`) wraps the API into thirty-two typed tools that any MCP-compatible agent (Claude, Codex, Gemini, Cursor) can call directly.

## Quick Start

Publish an HTML page and get a shareable link:

```bash
curl -X POST 'https://brewpage.app/api/html?ns=public&format=html&ttl=15' \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyAgent/1.0" \
  -d '{"content": "<h1>Hello, world!</h1>"}'
```

Response:

```json
{
  "id": "aBcDeFgHiJ",
  "namespace": "public",
  "link": "https://brewpage.app/public/aBcDeFgHiJ",
  "ownerLink": "https://brewpage.app/api/html/public/aBcDeFgHiJ",
  "ownerToken": "your-secret-token",
  "expiresAt": "2026-06-04T02:00:00Z",
  "sizeBytes": 22
}
```

Open `link` in any browser -- no further steps required.

## Use Cases for LLMs and Agents

| Scenario | API call |
|----------|----------|
| An AI agent generates a shareable HTML report and needs a stable URL to return to the user | `POST /api/html` -- returns link immediately |
| A GPT pipeline needs to persist JSON state between conversation turns without external storage | `POST /api/json?ns=myproject` then `GET /api/json/myproject/{id}` |
| A code-generation tool produces a downloadable file (PDF, archive, script) and needs to host it | `POST /api/files` -- file served with correct MIME type and inline preview |
| An agent publishes an artifact and later refines it without invalidating the shared URL | `PUT /api/html/{ns}/{id}` with `X-Owner-Token` -- content replaced, URL unchanged |
| A multi-step pipeline deploys a complete static site (HTML + CSS + JS) from a ZIP | `POST /api/sites` with `archive=@site.zip` -- all files served with relative links intact |

## API Features

| Resource | Description | Limits |
|----------|-------------|--------|
| **HTML pages** | Raw HTML or Markdown with instant short URLs | 5 MiB, TTL up to 30 days (90 with a free profile) |
| **Key-value store** | Named key-value pairs addressed by namespace/store ID | 1,000 keys/store |
| **JSON documents** | Store and retrieve arbitrary JSON with owner-scoped listing | 1 MiB, 10,000 docs/namespace |
| **Files** | Upload files with automatic MIME detection and inline preview | 5 MiB (video 20 MiB), 1,000 files/namespace |
| **Sites** | Multi-file HTML sites via ZIP or individual files | 20 MiB total, 200 files, 5 MiB/file, TTL up to 30 days (90 with a free profile) |

Creation returns a primary link and owner token. Keep the token for management and share the link exactly. Password-protected publications are never listed. TTL and supported inputs vary by operation.

## API Examples

**Publish Markdown:**

```bash
curl -X POST "https://brewpage.app/api/html?format=markdown" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyAgent/1.0" \
  -d '{"content": "# My Document\n\nHello **world**"}'
```

**Store a JSON document:**

```bash
curl -X POST https://brewpage.app/api/json \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyAgent/1.0" \
  -d '{"name": "config", "version": 1}'
```

**Upload a site (ZIP archive):**

```bash
curl -X POST "https://brewpage.app/api/sites" \
  -H "User-Agent: MyAgent/1.0" \
  -F "archive=@site.zip;type=application/zip"
```

**Update content in place (stable URL):**

```bash
curl -X PUT "https://brewpage.app/api/html/public/aBcDeFgHiJ" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyAgent/1.0" \
  -H "X-Owner-Token: your-secret-token" \
  -d '{"content": "<h1>Updated content</h1>"}'
```

**Get platform stats:**

```bash
curl https://brewpage.app/api/stats
```

## API Reference

- **Interactive docs** -- [kochetkov-ma.github.io/brewpage-openapi](https://kochetkov-ma.github.io/brewpage-openapi/)
- **API Reference (Scalar)** -- [kochetkov-ma.github.io/brewpage-openapi/api-reference](https://kochetkov-ma.github.io/brewpage-openapi/api-reference/)
- **OpenAPI spec (YAML)** -- [`openapi/openapi.yaml`](openapi/openapi.yaml)
- **OpenAPI spec (JSON)** -- [`openapi/openapi.json`](openapi/openapi.json)

The backend-generated public JSON contract owns schema authority. YAML is derived deterministically; Scalar serves an identical JSON copy. See [`openapi/openapi.provenance.json`](openapi/openapi.provenance.json) for export provenance. Correct backend generation before importing a new snapshot; do not author schemas in YAML.

Both imports run in one step and neither output is hand-edited: `node scripts/sync-openapi.mjs <backend export public.json>` writes the contract, its YAML, the Scalar copy and the provenance; `node scripts/sync-guide.mjs <brewpage-app>/frontend/src` writes the MCP Page data guide ([`mcp-server/src/guides/page-data.ts`](mcp-server/src/guides/page-data.ts)) from `llms-full.txt` and `llms.txt` and fails when the cheat-sheet block or the call-shapes line is missing; the same run writes the custom-domain status and problem tables ([`mcp-server/src/guides/custom-domain.ts`](mcp-server/src/guides/custom-domain.ts)) from the `Custom Domains` section of `llms-full.txt`.

### Endpoints

| Tag | Description |
|-----|-------------|
| **HTML** | Publish, retrieve, update, delete HTML/Markdown pages |
| **KV** | Key-value store CRUD (get, set, list, delete keys) |
| **JSON** | JSON document CRUD with owner-scoped listing |
| **Files** | File upload, download, list, delete |
| **Sites** | Multi-file site upload (ZIP or files), info, serve, delete |
| **Gallery** | Browse public content with search and pagination |
| **Stats** | Platform-wide usage statistics |
| **Short Links** | URL shortener for published content |
| **SEO** | Sitemap and robots.txt endpoints |
| **Reports** | Abuse reports for published content |
| **Namespace** | Collision-free namespace suggestions |
| **Custom Domains** | Show an HTML page or site on a domain you own: set, check DNS, list, remove |
| **Page data** | What visitors save on a page (form answers, guestbook, votes): read, write author entries, change settings, delete |

## MCP Server

The `brewpage-mcp` package provides a Model Context Protocol server with **32 tools** for AI-assisted content publishing and management. Selected tools appear below; see [`mcp-server/README.md`](mcp-server/README.md) for the complete list and documentation.

Package releases use `.github/workflows/release.yml` with package-scoped npm Trusted Publisher/OIDC for `kochetkov-ma/brewpage-openapi`, workflow `release.yml`, without an environment. CI needs no `NPM_TOKEN`, manual npm login or static-token rotation. Local `npm whoami` does not validate GitHub Actions OIDC authentication. Publication to the official MCP registry (`io.github.kochetkov-ma/brewpage-mcp`) is automatic via GitHub OIDC in the same workflow; no local `mcp-publisher` token is needed.

To retry publication from a local terminal, dispatch the current `main` workflow:

```bash
gh workflow run release.yml --repo kochetkov-ma/brewpage-openapi --ref main
```

Rerunning historical tag workflows that used token authentication is unsupported; use current `main` instead. The retry checks the matching version tag and unchanged MCP source, and skips publication when that version already exists.

| Tool | Description |
|------|-------------|
| `publish_html` | Publish HTML, Markdown, code or JSON content with optional password, TTL, filename, and top toolbar |
| `publish_file` | Upload a file from a URL |
| `publish_site` | Publish a single-page or multi-file HTML site |
| `delete_resource` | Delete any resource (HTML, site, KV, JSON, file) by owner token |
| `set_visibility` | List or unlist a public publication in the gallery and sitemap |
| `make_private` | Make a public publication private: new private link, the public link stops working |
| `set_badge` | Hide or show the BrewPage badge on a publication of your profile, up to 5 hidden |
| `set_title` | Rename an HTML page or site; the title stays on republish |
| `set_domain` | Connect a domain you own to an HTML page or site; returns the DNS records to create |
| `check_domain` | Run a DNS check once the records exist; status `pending_dns` -> `verifying` -> `active` |
| `list_domains` | Read one custom domain's status and DNS records without a check, or list the profile's custom domains |
| `remove_domain` | Remove a custom domain; the BrewPage link keeps working |
| `get_guide` | Read a short guide: Page data before writing a page that saves what visitors enter, or the custom-domain steps |
| `get_page_data` | Read what visitors saved on your page: settings and usage, or one list's entries |
| `set_page_data` | Write author entries (for example today's menu) without republishing |
| `configure_page_data` | Change who can read a list and its limits |
| `delete_page_data` | Delete entries by id or by time range |
| `get_page` | Fetch a published HTML page and its content |
| `get_stats` | Get platform-wide usage statistics |

### Remote (no install)

One remote MCP server for every client: `https://brewpage.app/mcp` (Streamable HTTP, no authentication, same 32 tools). Add it by URL in Claude (a custom connector), ChatGPT (a custom MCP server) or any Streamable HTTP client.

Claude Code: `claude mcp add --transport http brewpage --scope user https://brewpage.app/mcp` (leave out `--scope user` to add it to the current project only), or in `.mcp.json`:

```json
{
  "mcpServers": {
    "brewpage": {
      "type": "http",
      "url": "https://brewpage.app/mcp"
    }
  }
}
```

### Claude.ai and Claude Desktop

Claude calls a remote MCP server a custom connector. Add it once in Claude on the web; Claude Desktop picks it up too. Nothing to install.

1. Open **Customize** > **Connectors**.
2. Click **+ Add**, then **Add custom connector**.
3. Name it **BrewPage**, paste `https://brewpage.app/mcp` and click **Continue**.
4. Click **Continue** again, choose **No sign in** under Authentication and click **Add**.

The free plan includes one custom connector.

Local fallback (stdio, needs Node.js; the same tools): add to `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "brewpage": {
      "command": "npx",
      "args": ["-y", "brewpage-mcp@1.22.0"]
    }
  }
}
```

### Claude Code

The remote command above is the default. Local fallback (stdio, needs Node.js): add to project-root `.mcp.json`:

```json
{
  "mcpServers": {
    "brewpage": {
      "command": "npx",
      "args": ["-y", "brewpage-mcp@1.22.0"]
    }
  }
}
```

Claude Code plugin, run in Claude Code:

```
/plugin marketplace add kochetkov-ma/claude-brewcode
/plugin install brewdoc@claude-brewcode
/brewdoc:publish
```

### Gemini CLI

`gemini extensions install https://github.com/kochetkov-ma/brewpage-openapi`

## Resources

| Resource | URL |
|----------|-----|
| Live platform | https://brewpage.app |
| LLM context file | https://brewpage.app/llms.txt |
| Full LLM reference | https://brewpage.app/llms-full.txt |
| OpenAPI spec (YAML) | [`openapi/openapi.yaml`](openapi/openapi.yaml) |
| MCP server | [`mcp-server/`](mcp-server/) |
| npm package | https://www.npmjs.com/package/brewpage-mcp |
| Interactive API docs | https://kochetkov-ma.github.io/brewpage-openapi/ |
| Claude skill | https://github.com/kochetkov-ma/claude-brewcode/tree/main/skills/brewpage-publish |
| Brewcode plugin suite | https://github.com/kochetkov-ma/claude-brewcode |
| Brewcode site | https://brewcode.app |
| brewdoc CLI (document-to-Markdown conversion for agent systems) | https://pypi.org/project/brewdoc/ |
| brewdoc CLI source | https://github.com/kochetkov-ma/brewdoc |
| Wiki | https://github.com/kochetkov-ma/brewpage-openapi/wiki |
| Releases | https://github.com/kochetkov-ma/brewpage-openapi/releases |

## Related

- [brewpage.app](https://brewpage.app): the hosting service; [API guide](https://brewpage.app/api); [OpenAPI docs](https://kochetkov-ma.github.io/brewpage-openapi/)
- [brewpage-action](https://github.com/kochetkov-ma/brewpage-action): GitHub Action that publishes CI artifacts ([Marketplace](https://github.com/marketplace/actions/publish-to-brewpage))
- [brewpage-cookbook](https://github.com/kochetkov-ma/brewpage-cookbook): interactive recipes published on BrewPage
- [brewpage-obsidian](https://github.com/kochetkov-ma/brewpage-obsidian): Obsidian plugin that publishes notes ([Obsidian community](https://community.obsidian.md/plugins/brewpage-publisher))
- [brewpage-browser-extension](https://github.com/kochetkov-ma/brewpage-browser-extension): browser extension that publishes pages, selections and files
- [brewpage-codex-plugin](https://github.com/kochetkov-ma/brewpage-codex-plugin): Codex plugin with the publishing skill and remote MCP
- [brewpage-publish-plugins](https://github.com/kochetkov-ma/brewpage-publish-plugins): publishing plugins for AI coding tools and the n8n node ([npm](https://www.npmjs.com/package/n8n-nodes-brewpage))
- [langchain-brewpage](https://github.com/kochetkov-ma/langchain-brewpage): LangChain tools ([PyPI](https://pypi.org/project/langchain-brewpage/))
- [llama-index-tools-brewpage](https://github.com/kochetkov-ma/llama-index-tools-brewpage): LlamaIndex tool spec ([PyPI](https://pypi.org/project/llama-index-tools-brewpage/))

Support: [info@brewpage.app](mailto:info@brewpage.app)

BrewPage is described using [schema.org/SoftwareApplication](https://schema.org/SoftwareApplication) structured data on the platform homepage.

## What's Open Here

| Component | Description |
|-----------|-------------|
| OpenAPI 3.1 spec | Complete API contract for all public endpoints (YAML + JSON) |
| Interactive docs | Astro + Scalar documentation site (GitHub Pages) |
| MCP server | `brewpage-mcp` -- Claude Desktop/Code integration (32 tools) |
| Wiki | Code snippets, cheatsheet, tips & tricks |
| Release notes | Changelog for API and public tooling |

## What's Proprietary

| Component | Description |
|-----------|-------------|
| Backend | Spring Boot + Kotlin REST API |
| Frontend | HTML/CSS/JS + Caddy reverse proxy |
| Infrastructure | VPS deployment, CI/CD pipelines |
| E2E test suite | Playwright + Testcontainers |

## Project Structure

```
brewpage-openapi/
  openapi/
    openapi.json          # OpenAPI 3.1 spec (JSON)
    openapi.yaml          # OpenAPI 3.1 spec (YAML)
  docs/                   # Astro documentation site
    src/
      pages/              # Documentation pages
      components/         # Scalar API reference
  mcp-server/             # MCP server (brewpage-mcp)
    src/
      index.ts            # Server entry point
  .github/
    workflows/            # CI/CD (docs deploy, releases)
  README.md
  RELEASE-NOTES.md
  LICENSE
```

## License

[Apache 2.0](LICENSE) covers this repository's contract/docs layer. The independently packaged [MCP server](mcp-server/LICENSE) uses MIT. The hosted backend, frontend and infrastructure remain proprietary. SDK/CLI module specifications are proposals; they do not establish released packages.

TDQS

A3.5/5.0

Scored across 32 tools

Disambiguation3/5

Most tools map to distinct resources (json, kv, site, domain, page data), but the publish family overlaps heavily: publish_file can produce an HTML page, which collides with publish_html, and update_html vs update_json vs republish_site require careful reading of long descriptions to choose correctly. get_page vs get_json vs get_kv is separable, but the boundary between 'file' and 'page' depends on server-side extension detection that the agent cannot predict.

Naming Consistency4/5

Nearly all 32 tools follow snake_case verb_noun: publish_*, get_*, set_*, update_*, delete_*/remove_*. A few deviations (make_private uses an adjective, delete_resource and delete_page_data use different verbs than remove_domain) are minor and readable.

Tool Count2/5

32 tools is heavy for a single publishing service, and several are near-duplicates in scope (publish_html/publish_file/publish_site, update_html/update_json). The domain-management and page-data clusters are justified, but the publish surface could be consolidated into fewer parameterized tools.

Completeness4/5

Coverage is broad: create/update/delete for HTML, JSON, KV, sites, full custom-domain lifecycle, page-data read/write/configure/delete, stats, limits and gallery search. Main gaps are no way to list or enumerate your own publications and no per-key KV deletion or KV read/list of keys beyond get_kv.

Maintenance

ActivityActive
ResponsivenessLimited data