Poster MCP
<p align="center"><img src="https://raw.githubusercontent.com/aistudy11/poster-mcp/codex/public-release/assets/logo.png" alt="Poster.sh logo" width="128" height="128"></p>
# Poster MCP — AI Poster Generator
[Poster.sh](https://poster.sh) is an **[AI Poster Generator](https://poster.sh)** that turns a text brief into a poster. This MCP server lets your AI assistant get an exact quote, create a poster after your approval, and retrieve your own result.
Use it for café openings, event announcements, product launches or promotional posters. Describe the message and visual direction in your assistant; Poster returns the actual preview URL and structured poster document when the task is ready.
**Four tools · Local stdio · Your own Poster API Key · MIT adapter**
[Website](https://poster.sh) · [API Keys](https://poster.sh/api-keys) · [Releases](https://github.com/aistudy11/poster-mcp/releases) · [Report an issue](https://github.com/aistudy11/poster-mcp/issues)
## Quick start
Requires **Node.js 20.10+ with npm/npx** and an MCP client that can launch local **stdio** servers. This is not a remote HTTP connector: do not enter `poster.sh` as an MCP endpoint. Your assistant runs this adapter locally and it calls the existing Poster HTTPS API.
1. Sign in to [Poster.sh API Keys](https://poster.sh/api-keys) and use your own existing key. Generation uses that account's balance.
2. Paste the configuration below into your client's **private local MCP settings**, replacing only the key placeholder. Clients using `mcpServers` JSON, including Claude Desktop and Cursor, can use this format.
3. Restart or reconnect your client's MCP server. Check that the four tools below appear, then ask for a quote. Quoting does not generate a poster or spend credits.
```json
{
"mcpServers": {
"poster": {
"command": "npx",
"args": [
"--yes",
"--package=https://github.com/aistudy11/poster-mcp/releases/download/v0.1.2/poster-sh-mcp-0.1.2.tgz",
"poster-mcp"
],
"env": {
"POSTER_API_KEY": "YOUR_POSTER_API_KEY"
}
}
}
}
```
This installs the versioned official GitHub release automatically; no private product checkout, global package install or absolute script path is needed. The first start downloads dependencies, so allow it to finish. `npx` needs network access during installation.
**Enable generation deliberately:** the configuration above allows quotes and reads but blocks new creation. To allow creation, add `POSTER_MAX_CREDITS_PER_POSTER` to `env` with your chosen integer limit as a string (for example `"10"` means a ceiling of 10 credits per new poster, **not** a price quote). If the actual quote exceeds your limit, creation is refused. It is a per-poster ceiling, not a daily or account budget. Your assistant must still show the exact prompt, selection and cost and ask for approval before creating. Do not auto-approve `create_poster` or `advance_poster`.
**Try this first:** “Quote a vertical 2:3 poster for a café opening, with the headline 'Grand Opening', warm terracotta colors and a simple modern layout. Show me the exact credits before generating.” A quote returns a request and its current cost. Only approve creation once you have checked them; a pending task is not a completed poster.
## Install from source (optional)
The standalone source is published at [aistudy11/poster-mcp](https://github.com/aistudy11/poster-mcp). For contributors or a fixed local checkout:
```sh
git clone https://github.com/aistudy11/poster-mcp.git
cd poster-mcp
pnpm install --frozen-lockfile
```
For a source checkout, validate it with:
```sh
pnpm check
pnpm test
```
Alternatively, configure that source checkout directly. Replace the path and key with your own values in the client's **private local settings**, never in a public repository or directory submission:
```json
{
"mcpServers": {
"poster": {
"command": "node",
"args": ["/absolute/path/to/poster-mcp/cli.mjs"],
"env": {
"POSTER_API_KEY": "your-existing-poster-api-key"
}
}
}
}
```
Use an existing key from your own [Poster API Keys](https://poster.sh/api-keys) page. The key is sent only to the configured Poster origin as `X-API-Key`. No website cookies or shared operator account are needed for ordinary use. This directory is independent of the Next.js installation and its dependencies.
Both default configurations permit quoting and reading while new creation is disabled. To enable creation, explicitly configure `POSTER_MAX_CREDITS_PER_POSTER` to the maximum credits you approve **for each new poster**. This is a per-request limit, not a daily or account spending budget. Each creation still requires the user's explicit approval of the actual quoted prompt, selection and credits in the MCP client. Do not configure automatic approval of `create_poster` or `advance_poster`.
Advancing an existing job is a separate mutating operation, available only with `confirmed: true`. It can perform recovery attempts within the original job's budget and settle that job's frozen price. The new-creation cap does not change or limit an already accepted job's price. Only advance a job whose original operation and cost were approved; if that approval is unavailable, read it with `get_poster` and ask the user before continuing. No new creation cap or quote authorizes an old job's settlement.
| Variable | Behavior |
|---|---|
| `POSTER_API_KEY` | Required for business calls; without a key, only MCP discovery is available. Use your existing personal Poster key. Never pass it as tool input or a URL parameter. |
| `POSTER_API_URL` | Optional HTTPS origin; defaults to `https://poster.sh`. HTTP is allowed only for local development on loopback. |
| `POSTER_MAX_CREDITS_PER_POSTER` | Optional nonnegative integer. Omitted disables creation; quotes and existing results remain available. Zero permits only a genuinely zero-credit quote. |
| `POSTER_REQUEST_TIMEOUT_MS` | Optional positive integer, default 15000. A timeout does not prove a submission failed. |
## Tools and workflow
| Tool | Existing API | Effect |
|---|---|---|
| `quote_poster` | `GET /api/poster/structured/capability` | Free authenticated quote. Returns the actual model, selection, credits and an exact request with a UUID. |
| `create_poster` | `POST /api/poster/structured` | Potentially paid. Requires `confirmed: true`, the exact quoted request and an operator-configured credit limit. |
| `get_poster` | `GET /api/poster/structured/{id}` | Read-only owned task/result. |
| `advance_poster` | `POST /api/poster/structured/{id}` | Requires `confirmed: true` to continue the approved existing job, including original-budget recovery, persistence and frozen-price settlement. |
Example conversation:
1. “Quote a 2:3 poster for our café opening.” The client calls `quote_poster` with the brief and optional selection. Omitted model/quality/ratio values are resolved by Poster, not guessed locally.
2. Show the returned prompt, model, ratio and credits. Ask the user to approve the actual operation and cost.
3. After explicit approval and with the configured limit, call `create_poster` with the returned `request` unchanged and `confirmed: true`.
4. If the result is `planning` or `generating`, use `advance_poster` with its existing ID and `confirmed: true` only under the original job/cost approval. These states are pending; do not report an image as completed. Use `get_poster` when only reading status.
5. When the API returns `ready`, return its real `previewUrl`, document and other result fields. `get_poster` can reopen the same owned result. Private results stay subject to the existing API's ownership check; do not submit them to a public directory.
This initial adapter exposes the supported text-to-poster flow. It does not add editing, uploading, batch generation or translation tools. The existing website and QRCodeBrain capabilities remain available through their existing paths.
## Common setup questions
- **No Poster tools?** Check that Node/npm are installed and available to your desktop app, that the release URL is copied in full, and that the client supports local stdio. Restart the MCP connection and inspect its server log. If the desktop app cannot find `npx`, use its absolute executable path from your Node installation.
- **Can I use it in browser-only ChatGPT?** This release requires a client that can launch a local stdio process. It does not publish a remote MCP URL or OAuth connector.
- **Is it free?** The adapter is MIT licensed. Quotes and reads do not spend generation credits; poster creation uses your Poster account's actual quoted credits. Continuing an approved existing job can perform recovery and settle its original price.
- **What comes back?** A task ID and state; once `ready`, the actual `previewUrl`, structured `document` and other API result fields. The initial adapter has no editing, upload, translation or batch tools. The website's editor is a separate existing product capability.
- **Where does my key go?** It stays in your private client settings and is sent only to the configured Poster origin. Never paste a real key into a directory, issue, example prompt or shared configuration.
## Errors and retries
- `API_KEY_REQUIRED`: tool discovery is available, but no Poster API request is sent until you configure your own key.
- `CREDIT_LIMIT_REQUIRED`: no creation cap configured; no submission was sent.
- `CREDIT_LIMIT_EXCEEDED`: the approved quote exceeds the configured cap; no submission was sent.
- `POSTER_HTTP_400/409`: the existing API refused the request; quote the intended selection again when the price or input needs correcting. Do not retry indefinitely.
- `POSTER_HTTP_401/403`: the key or permission is not accepted.
- `POSTER_HTTP_402`: the key owner's Poster balance is insufficient. This adapter does not create a new billing system.
- `POSTER_HTTP_404`: unavailable or non-owned result; do not infer another user's data exists.
- `POSTER_HTTP_429/503`: respect the service's refusal and retry deliberately; no automatic paid resubmission is performed.
- `REQUEST_OUTCOME_UNKNOWN`: the response was lost or timed out. Preserve the original UUID **and exact complete request**. Read/advance a known task ID, or explicitly retry that same request. Never invent a replacement UUID to recover an uncertain purchase.
- `INVALID_POSTER_RESPONSE`: malformed or incomplete output, including a false `ready` with no actual result; never presented as success.
The API remains authoritative for quote changes and idempotent retries. Credential-bearing redirects are refused. Arbitrary upstream error text is not returned to the AI client. Stdout carries only MCP protocol messages; startup diagnostics use sanitized structured stderr.
## Validation and distribution status
`pnpm test` uses the official MCP SDK client over a real child-process stdio transport and a controlled local HTTP API fixture. It proves adapter wiring, body preservation, confirmation/cap boundaries, error propagation and credential-safe redirects. The fixture is not a production generation or billing receipt. Production checks and release results belong to the project's current development checklist; do not claim they passed merely because local tests passed.
Create a reviewable installation archive with:
```sh
pnpm pack --pack-destination /absolute/path/to/output
```
The independently written adapter is distributed through the public GitHub repository under the included MIT license. `private: true` prevents accidental **npm** publication; it does not prevent cloning or installing this public repository. No npm registry package or remotely hosted MCP endpoint is claimed.
Only this adapter directory is distributed. The parent product repository, licensed template source, `.env` files, API keys and private acceptance records are excluded. The product repository maintains the canonical adapter; the standalone repository is its distribution snapshot, not a separately developed business implementation. A directory submission, publication and a publicly visible backlink are separate states.
## Protocol references
- [Official TypeScript SDK server guide](https://ts.sdk.modelcontextprotocol.io/server)
- SDK dependency pinned to `@modelcontextprotocol/sdk@1.32.1`, using its real `McpServer`, `registerTool`, `StdioServerTransport` and `StdioClientTransport` APIs.
- JSON Schema in MCP tool inputs is validated by the SDK. This package does not modify website Schema.org JSON-LD.
TDQS
Scored across 4 tools
Each tool occupies a distinct phase of the poster lifecycle: quote is read-only pricing, create is the paid submission, get is read-only status, and advance mutates an existing owned job. The descriptions explicitly clarify boundaries, especially quote vs. create and get vs. advance.
All four tools follow the same snake_case verb_noun pattern with a consistent noun: quote_poster, create_poster, get_poster, advance_poster. The verbs are distinct and predictable.
Four tools are well-scoped for a focused quote-create-read-advance workflow. There is no obvious bloat, and each tool has a clear role in the pipeline.
The core lifecycle is covered: quote a request, create after approval, read status, and advance an existing job. Minor gaps remain around listing owned posters, cancellation, or refund/delete paths, which agents may need in edge cases.