# Yappy MCP server

Yappy runs two Model Context Protocol servers over **Streamable HTTP**. Neither
requires authentication — the data is public, and making an agent complete an
OAuth dance to read a changelog helps nobody.

| Surface | URL | Kind |
|---|---|---|
| Product | `https://yappy.biz/mcp` | Tools that answer questions about Yappy |
| Documentation | `https://yappy.biz/docs/mcp` | The docs corpus as resources |

Both are listed in the [official MCP registry](https://registry.modelcontextprotocol.io/v0/servers?search=biz.yappy)
under the domain-verified namespace `biz.yappy` — `biz.yappy/yappy` for the
product surface and `biz.yappy/yappy-docs` for the documentation one. Domain
ownership is proved by the Ed25519 public key served at
[`/.well-known/mcp-registry-auth`](https://yappy.biz/.well-known/mcp-registry-auth),
so an agent can confirm the listing really belongs to this site rather than to
somebody who picked a similar name.

The server card for the product surface is published at
[`/.well-known/mcp/server-card.json`](https://yappy.biz/.well-known/mcp/server-card.json),
so an agent can read the tool list before opening a transport connection.

## Connect

Claude Code, Claude Desktop, Cursor, VS Code, and Goose all take the same shape:

```json
{
  "mcpServers": {
    "yappy": { "type": "http", "url": "https://yappy.biz/mcp" },
    "yappy-docs": { "type": "http", "url": "https://yappy.biz/docs/mcp" }
  }
}
```

Claude Code, one line:

```bash
claude mcp add --transport http yappy https://yappy.biz/mcp
```

## Transport

Streamable HTTP, protocol version `2025-06-18`. `POST /mcp` with a JSON-RPC 2.0
body and `Accept: application/json, text/event-stream`. The server replies with a
single JSON object for ordinary calls, and negotiates SSE when the client asks
for a stream. Legacy HTTP+SSE transport is not offered; Streamable HTTP is the
current standard and this server is new enough not to carry the old one.

```bash
curl -sX POST https://yappy.biz/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

## Tools

### Product surface — `https://yappy.biz/mcp`

| Tool | What it does | Read-only |
|---|---|---|
| `get_latest_release` | The current Yappy version, notes, and download URL | yes |
| `list_releases` | Release history, newest first | yes |
| `get_pricing_plans` | What is free, and what a backend costs | yes |
| `get_frequently_asked` | The FAQ, as question and answer pairs | yes |
| `get_system_requirements` | Minimum macOS, chip, and every permission | yes |
| `list_product_features` | Capabilities, with on-device and permission flags | yes |
| `check_mac_compatibility` | Whether a given macOS version and chip can run Yappy | yes |
| `create_export_job` | Start an export of the docs, FAQ, or release corpus | **no** |
| `get_export_job` | Poll an export job until it completes | yes |

### Documentation surface — `https://yappy.biz/docs/mcp`

| Tool | What it does | Read-only |
|---|---|---|
| `search_documentation` | Full-text search across docs and FAQ | yes |
| `get_documentation_page` | One documentation page as markdown | yes |
| `list_documentation_pages` | Every page with its slug and summary | yes |

Every tool carries a typed `inputSchema` with a `required` array, a description
long enough to choose between them, and behavioural annotations. All of them
are `destructiveHint: false`, and all but one are `readOnlyHint: true`. The
exception is `create_export_job`, which creates a job — and a job is the only
thing on this whole surface that can be created. There is no tool that can spend
your money, change a user's data, or delete anything, by design.

## Resources

`resources/list` returns:

- `yappy://docs/index` — the documentation index (`text/markdown`)
- `yappy://llms.txt` — the machine index (`text/plain`)
- `yappy://openapi.json` — the REST contract (`application/json`)
- `yappy://releases/latest` — the current release (`application/json`)

Each reads cleanly through `resources/read` with a declared `mimeType` and
non-empty content.

## MCP Apps

Tools that return a release or a pricing answer also carry
`_meta.ui.resourceUri`, pointing at an inline `ui://` resource so a host that
supports MCP Apps can render the answer as a small card instead of a wall of
JSON.

- `ui://yappy/release-card` — version, date, notes, download button
- `ui://yappy/pricing-card` — the free tier and backend cost table

Both are served as `text/html;profile=mcp-app`, open with `<!DOCTYPE html>`,
declare `<meta name="color-scheme" content="light dark">` so they read correctly
in a dark host, and carry a scoped Content-Security-Policy that allows framing
only by `https://chatgpt.com` and `https://claude.ai`. No secrets are embedded —
there are none to embed, since the underlying API needs no key.

## Errors

Invalid tool names and malformed arguments come back as JSON-RPC errors with a
numeric `code` and a human-readable `message`, never as an empty response or a
crash:

```json
{"jsonrpc":"2.0","id":7,
 "error":{"code":-32602,"message":"Unknown tool 'get_transcript'. Call tools/list for the seven available tools."}}
```

`-32700` parse error, `-32600` invalid request, `-32601` method not found,
`-32602` invalid params, `-32603` internal error. Tool-level failures — a
document that does not exist, say — come back as a successful result with
`isError: true` and a message explaining what to try instead.

## What it cannot do

It cannot transcribe audio. Yappy's speech recognition runs on the user's Mac and
there is no hosted endpoint behind it. The MCP server answers questions *about*
Yappy; the app does the work.

---

Canonical: https://yappy.biz/developers/mcp/ · Last updated: 2026-08-25
