Yarr MCP
Rust MCP and CLI server for Sonarr, Radarr, Prowlarr, Plex, Jellyfin, and download clients.
Open source Open in the app JSON README (API)
About
Rust MCP and CLI server for Sonarr, Radarr, Prowlarr, Plex, Jellyfin, and download clients.
Details
- Kind
- MCP servers
- Topic
- Developer tools
- Publisher
- ai.dinglebear
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 1.1.1
- Stars
- 10
- Forks
- 2
- Open pull requests
- 3
- Last push
- 2026-08-25T15:13:18Z
- Repository state
- ativo
- Language
- Rust
- License
- AGPL-3.0
- Added
- 2026-08-29 03:00:10
- Updated
- 2026-08-29 03:00:10
- Origin id
ai.dinglebear/yarr-mcp
README
# yarr
Self-hosted media fleet operations across Sonarr, Radarr, Plex, and related apps over MCP and CLI.
If you run Claude Code, Codex, or Gemini CLI against a self-hosted media stack,
`yarr` gives an agent one consistent way to query and control all of it instead
of eleven different ad hoc integrations. It is an upstream-client MCP server:
it does not replace those applications or mirror every REST endpoint as a web
UI. Its job is to provide one consistent tool surface for agents and one
equivalent CLI surface for operators.
**Not for:** a general-purpose REST gateway to arbitrary services, or a
scheduler/automation engine in its own right. `yarr` only talks to the service
kinds it knows about, and only does what you or your agent ask it to do.
## Contents
- [Naming](#naming)
- [Capabilities And Boundaries](#capabilities-and-boundaries)
- [Install](#install)
- [Unraid Plugin](#unraid-plugin)
- [Quickstart](#quickstart)
- [Client Configuration](#client-configuration)
- [Runtime Surfaces](#runtime-surfaces)
- [MCP Tool Reference](#mcp-tool-reference)
- [CLI Reference](#cli-reference)
- [Configuration](#configuration)
- [Authentication](#authentication)
- [Safety And Trust Model](#safety-and-trust-model)
- [Architecture](#architecture)
- [Distribution Contract](#distribution-contract)
- [Development](#development)
- [Verification](#verification)
- [Deployment](#deployment)
- [Troubleshooting](#troubleshooting)
- [Related Servers](#related-servers)
- [Documentation](#documentation)
- [License](#license)
## Naming
This repository is published at `github.com/dinglebear-ai/yarr`.
The Rust package and installed binary are both `yarr`. The npm launcher package
is `yarr-mcp` because the shorter `yarr` name is occupied on npm; installing the
launcher still gives you a `yarr` command. The MCP registry name is
`ai.dinglebear/yarr`, and Docker images use `ghcr.io/dinglebear-ai/yarr`.
Production Compose deployments select that image by immutable manifest digest.
Plugin naming is intentionally split:
- `yarr` is the full MCP server plugin. It launches the repository-coupled
`@dinglebear/yarr` npm package over stdio and includes every per-service fallback
skill; it does not commit a platform-specific binary.
- `sonarr`, `radarr`, `prowlarr`, `overseerr`, `sabnzbd`, `qbittorrent`, `plex`,
`jellyfin`, `tautulli`, `tracearr`, and `bazarr` are skills-only plugins with
no MCP server and no bundled binary.
## Capabilities And Boundaries
`yarr` wraps a configured media automation fleet through one action-dispatched
service layer. The same implementation backs MCP and CLI calls, so behavior
does not drift between "agent used the tool" and "operator ran the command."
Primary capabilities:
- Fleet status checks across the configured services.
- Credentialed upstream API passthrough for known service kinds.
- Table-driven OpenAPI operation metadata for Sonarr, Radarr, Prowlarr,
Overseerr, Jellyfin, and Plex. The executor preserves the declared parameter,
request-media, and successful-response transport contract; unsupported rows
are excluded and listed in the generated
[capability matrix](https://github.com/dinglebear-ai/yarr/blob/main/docs/TOOLS_ACTIONS_ENDPOINTS.md#generated-operations-spec-backed-services).
- Curated commands for SABnzbd, qBittorrent, Tautulli, Bazarr, and Tracearr,
whose upstreams do not ship usable machine-readable specs.
- Code Mode over MCP for multi-step media automation scripts.
- Snippet storage and execution for repeatable Code Mode workflows.
- Skills-only direct-HTTP plugin fallbacks for each individual service.
Boundaries:
- `yarr` does not store or schedule media jobs on its own.
- It does not expose a local REST action API or embedded web UI.
- It does not accept arbitrary unknown service kinds.
- MCP callers never provide credentials, tokens, keys, or secrets as action
arguments. Credentials come from environment variables, config files, or
strict per-service plugin config JSON.
## Install
The native release installer is the safest default because it verifies the
release archive and SHA-256 before installing `yarr` into `~/.local/bin`:
```bash
curl -fsSL https://raw.githubusercontent.com/dinglebear-ai/yarr/main/install.sh | bash
yarr --version
```
The npm launcher is a coupled distribution, not an alias for whatever version
happens to be tagged `latest`. Verify the exact release version exists on npm
before using it:
```bash
YARR_VERSION=2.1.0
npm view "@dinglebear/yarr@${YARR_VERSION}" version
npx -y "@dinglebear/yarr@${YARR_VERSION}" mcp
# Or, after the same availability check:
npm i -g "@dinglebear/yarr@${YARR_VERSION}"
```
Never use an unpinned `npx @dinglebear/yarr` or `@latest` in an MCP manifest: npm may
still point at an older launcher after a partial release. At the time of this
documentation refresh, GitHub release `v2.1.0` is public but
`@dinglebear/yarr@2.1.0` is not yet available on npm; recovery is tracked in
[issue #80](https://github.com/dinglebear-ai/yarr/issues/80). Use the native
installer, a verified release archive, a source build, or the independent
Unraid package until the exact npm version resolves.
## Unraid Plugin
The coordinated Unraid distribution lives under
[`unraid-plugin/`](https://github.com/dinglebear-ai/yarr/tree/main/unraid-plugin). It combines the classic `.plg`
installer and privileged service lifecycle, an external NestJS GraphQL
extension, and Vue settings/dashboard custom elements.
Install the plugin URL from Unraid's **Plugins > Install Plugin** page:
```text
https://raw.githubusercontent.com/dinglebear-ai/yarr/main/unraid-plugin/yarr.plg
```
Fresh installs bind Yarr to loopback. LAN or custom-address binding is rejected
until authentication is configured; Tailscale Serve is the supported
tailnet-only option. Service credentials stay in server-side boot
configuration and are never returned to the browser. See the
[Unraid operator and release guide](https://github.com/dinglebear-ai/yarr/blob/main/unraid-plugin/README.md) for persistence,
discovery, updates, rollback, uninstall retention, troubleshooting, and
release gates.
## Quickstart
The first-screen 30-second path is:
```bash
export YARR_SERVICES=sonarr
export YARR_SONARR_URL=http://127.0.0.1:8989
export YARR_SONARR_API_KEY=...
yarr sonarr status
yarr mcp
```
Then point an MCP client at the stdio command:
```json
{
"mcpServers": {
"yarr": {
"command": "yarr",
"args": ["mcp"],
"env": {
"YARR_SERVICES": "sonarr",
"YARR_SONARR_URL": "http://127.0.0.1:8989",
"YARR_SONARR_API_KEY": "${YARR_SONARR_API_KEY}"
}
}
}
}
```
For Claude Code plugin installs, use the marketplace commands inside a Claude
Code chat session, not in a shell:
```text
/plugin marketplace add dinglebear-ai/yarr
/plugin install yarr@yarr
```
The full plugin starts the exact launcher pinned in its manifest. Confirm that
version exists before installing or debugging the plugin:
```bash
npm view @dinglebear/yarr@2.1.0 version
```
Until issue #80 is resolved, the full plugin cannot start from npm. The
service-specific skills-only plugins do not depend on that launcher and remain
available for direct upstream workflows.
Install one skills-only plugin when you want direct service scripts without the
MCP server:
```text
/plugin install sonarr@yarr
/plugin install plex@yarr
```
## Client Configuration
### stdio
stdio is the preferred local MCP transport. It starts `yarr mcp` on demand and
does not require binding a local HTTP port.
```json
{
"mcpServers": {
"yarr": {
"command": "yarr",
"args": ["mcp"],
"env": {
"RUST_LOG": "info,yarr=debug"
}
}
}
}
```
### Streamable HTTP
Run a persistent server when several clients or machines should share one MCP
endpoint:
```bash
YARR_MCP_TOKEN=change-me yarr serve
```
```json
{
"mcpServers": {
"yarr": {
"url": "http://127.0.0.1:40070/mcp",
"headers": {
"Authorization": "Bearer ${YARR_MCP_TOKEN}"
}
}
}
}
```
HTTP MCP initialization smoke call:
```bash
curl --fail http://127.0.0.1:40070/mcp \
-H "Authorization: Bearer $YARR_MCP_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl-smoke","version":"1"}}}'
```
Use an MCP client such as mcporter for session-aware `tools/list` and Code Mode
calls; a raw one-shot `tools/call` is not a complete MCP session.
## Runtime Surfaces
| Surface | Status | Purpose |
|---|---:|---|
| MCP | Required | One default `yarr` Code Mode tool over the whole fleet |
| CLI | Required | Scriptable parity surface for debugging and automation |
| REST | Not shipped | Upstream-client servers do not expose a local REST action API |
| Web | Core: not shipped | The core server has no embedded UI; the classic Unraid distribution ships a separate settings/dashboard web surface |
Set `YARR_MCP_TOOL_MODE=flat` to advertise one action-dispatched MCP tool per
configured service instead of the single Code Mode tool. That mode is useful
behind a gateway such as Labby that already provides its own discovery and
sandbox layer. `codemode` is the default and the right choice for standalone
MCP clients.
## MCP Tool Reference
By default, MCP exposes one tool named `yarr`.
| Field | Type | Required | Notes |
|---|---|---:|---|
| `code` | string | yes | JavaScript async arrow function executed in the in-process Code Mode sandbox |
Inside Code Mode, scripts can use:
- Per-service callables such as `sonarr.get_series()`,
`radarr.post_movie({ body })`, `prowlarr.get_indexer()`, and
`plex.get_sessions()`.
- Curated commands such as `qbittorrent.download_queue()` and
`tautulli.stats_activity()`.
- Raw passthrough helpers at `api.<service>.get/post/put/delete(path, body)`.
- `callTool(action, params)` for the underlying action-dispatch escape hatch.
- `codemode.search(query)` and `codemode.describe(path)` for discovery.
- `codemode.run(name, input)`, `codemode.snippets()`, and `writeArtifact(...)`
for reusable scripts and artifacts.
Generated callables come from metadata tables. They preserve method/path,
required path arguments, known query names, JSON-body presence, and a bounded
single-file multipart escape hatch. They do not enforce every required query,
header/cookie parameter, style/explode rule, form schema, media type, or
response schema. See `docs/API.md` before relying on a generated operation for
a non-JSON or serialization-sensitive endpoint.
Example:
```js
async () => {
const queue = await radarr.get_queue();
await radarr.post_command({
body: { name: "MoviesSearch", movieIds: [456] }
});
return { queued: queue.records?.length };
}
```
### Generic Actions
These actions work for every configured service kind:
| Action | Scope | CLI | Description |
|---|---|---|---|
| `service_status` | `yarr:read` | `yarr <service> status` | Fetch an upstream service status endpoint |
| `api_get` | `yarr:write` | `yarr <service> get --path <path>` | Proxy a credentialed GET request |
| `api_post` | `yarr:write` | `yarr <service> post --path <path> --body <json>` | Proxy a POST request |
| `api_put` | `yarr:write` | `yarr <service> put --path <path> --body <json>` | Proxy a PUT request |
| `api_delete` | `yarr:write` | `yarr <service> delete --path <path>` | Proxy a DELETE request |
| `help` | public | `yarr help` | Return action reference |
### Code Mode Actions
| Action | Scope | Surface | Description |
|---|---|---|---|
| `codemode` | `yarr:write` | `yarr` tool / `yarr codemode --code <JS>` | Run a JS arrow function over the fleet |
| `op` | `yarr:write` | `<service>.<operation>()` / `yarr <service> op <name>` | Dispatch a generated OpenAPI operation |
| `snippet_list` | `yarr:read` | `yarr snippet list` / `codemode.snippets()` | List saved snippets |
| `snippet_save` | `yarr:write` | `yarr snippet save` | Save a reusable snippet |
| `snippet_run` | `yarr:write` | `yarr snippet run` / `codemode.run(name, input)` | Run a saved snippet |
| `snippet_delete` | `yarr:write` | `yarr snippet delete` | Delete a saved snippet |
There is no `confirm` argument. CLI destructive commands dispatch immediately.
MCP direct and nested Code Mode destructive calls require elicitation and fail
closed if the peer cannot elicit or approval is not granted.
## CLI Reference
The CLI is service-grouped:
```bash
yarr help
yarr radarr status
yarr sonarr get --path /api/v3/system/status
yarr radarr post --path /api/v3/command --body '{"name":"RefreshMovie"}'
yarr sonarr put --path /api/v3/series/editor --body '{"seriesIds":[1],"qualityProfileId":4}'
yarr radarr delete --path /api/v3/movie/12
# Generated operations for spec-backed services.
yarr sonarr op get_series
yarr radarr op post_command --args '{"body":{"name":"MoviesSearch","movieIds":[456]}}'
# Curated commands for doc-only services.
yarr qbittorrent queue
yarr tautulli activity
# Code Mode and snippets.
yarr codemode --code 'async () => sonarr.get_system_status()'
yarr snippet list
```
There is no `--service` flag. Infra commands such as `help`, `codemode`, and
`snippet` are service-less.
## Configuration
Copy `.env.example` or use `config.example.toml` as a starting point. Common
environment variables:
```bash
YARR_MCP_HOST=127.0.0.1
YARR_MCP_PORT=40070
YARR_MCP_TOKEN=change-me
YARR_SERVICES=sonarr,radarr,prowlarr,tautulli,overseerr,bazarr,tracearr,sabnzbd,qbittorrent,plex,jellyfin
YARR_SONARR_URL=http://sonarr:8989
YARR_SONARR_API_KEY=...
YARR_RADARR_URL=http://radarr:7878
YARR_RADARR_API_KEY=...
YARR_QBITTORRENT_URL=http://qbittorrent:8080
YARR_QBITTORRENT_USERNAME=...
YARR_QBITTORRENT_PASSWORD=...
YARR_PLEX_URL=http://plex:32400
YARR_PLEX_TOKEN=...
```
Supported service kinds are `sonarr`, `radarr`, `prowlarr`, `tautulli`,
`overseerr`, `bazarr`, `tracearr`, `sabnzbd`, `qbittorrent`, `plex`, and
`jellyfin`.
`*_API_KEY` covers most Arr-style services. qBittorrent uses username/password
login. Plex and Jellyfin token headers are handled separately.
`YARR_MCP_TOOL_MODE=codemode` is the default. Use
`YARR_MCP_TOOL_MODE=flat` only when a gateway should see separate per-service
tools.
## Authentication
`YARR_MCP_TOKEN` authenticates `/mcp` on any HTTP bind, including loopback.
It receives the scopes in `YARR_MCP_STATIC_TOKEN_SCOPES`, which defaults to
read-only `yarr:read`. A read-only bearer deployment must use
`YARR_MCP_TOOL_MODE=flat`; using the default Code Mode surface requires an
explicit `yarr:write` scope. On `127.0.0.1` or `localhost` with no explicit
bearer/OAuth configuration, auth is bypassed for local development.
Auth states:
| State | Condition | Behavior |
|---|---|---|
| `LoopbackDev` | loopback bind with no explicit auth, or explicit loopback no-auth | no auth, no scopes |
| `TrustedGatewayUnscoped` | `YARR_NOAUTH=true` behind a trusted gateway | no local auth or scopes |
| `Mounted` bearer | any HTTP bind with `YARR_MCP_TOKEN` | bearer auth with configured static-token scopes |
| `Mounted` OAuth | `YARR_MCP_AUTH_MODE=oauth` on any HTTP bind | OAuth/JWT auth plus optional bearer |
Unauthenticated health endpoints are `/health`, `/ready`, `/status`, and
`/metrics`. `/status` redacts secrets; `/metrics` exposes HTTP and bounded
domain metrics and should be network-restricted when needed.
## Safety And Trust Model
Secrets stay server-side. MCP clients provide action parameters, never upstream
tokens. Query-string secrets such as `apikey=`, `token=`, and `X-Plex-Token`
are rejected by path validation.
`help` is public at the action layer, but mounted HTTP transports still require
bearer or OAuth transport auth. `service_status` requires `yarr:read`.
Credentialed passthrough, generated operations, curated write operations, and
Code Mode require `yarr:write`; write satisfies read.
Generated DELETE operations, `api_delete`, `download_remove`,
`stats_delete_image_cache`, and `trace_terminate_stream` are destructive. CLI
commands dispatch them immediately. MCP callers get an interactive elicitation
prompt at the actual dispatch point, including inside Code Mode, with no call
argument or nested `callTool` path that can skip it.
Responses are capped by the shared token-limit layer before they are returned to
MCP clients.
## Architecture
```text
MCP shim (src/mcp/tools.rs) CLI shim (src/cli.rs)
JSON args -> dispatch argv -> dispatch
\ /
execute_service_action (src/actions/dispatch.rs)
shared validation + curated-command dispatch
|
YarrService (src/app.rs + src/app/*.rs)
validation, service lookup, response shaping
|
YarrClient (src/yarr.rs)
network calls and auth headers
```
`src/mcp.rs` and `src/cli.rs` are thin facades re-exporting their own
submodules. `execute_service_action` makes CLI-to-MCP parity structural rather
than something kept in sync by hand.
The service layer owns:
- supported service catalog and config lookup
- safe path validation
- credential redaction
- qBittorrent login flow
- response normalization
## Distribution Contract
The source of truth for release identity is the version shared by `Cargo.toml`,
`Cargo.lock`, `xtask/Cargo.toml`, `.release-please-manifest.json`,
`packages/yarr-mcp/package.json`, and `server.json`.
Generated code and docs must be regenerated from the committed source inputs,
not patched by hand:
- Generated OpenAPI operations live under `src/openapi/generated/` and come
from vendored specs in `specs/`.
- Curated actions live in the handwritten action registries and docs.
- Plugin manifests stay versionless; marketplaces derive plugin version from
the git commit SHA.
- The npm package version and the GitHub Release tag must match.
- `server.json` must name the exact `yarr-mcp` npm version and stdio launch
contract under the `ai.dinglebear/yarr` registry identity.
- The Docker image path is `ghcr.io/dinglebear-ai/yarr`; production deployment uses a
promoted immutable `@sha256:` digest.
## Development
```bash
cargo run -- help
cargo fmt --check
cargo test
cargo clippy -- -D warnings
cargo build --release
```
When changing generated operations:
```bash
cargo xtask gen-openapi
cargo xtask tool-docs
cargo test --test parity
```
When changing plugin packaging:
```bash
cargo test --test plugin_contract
cargo test --test template_invariants
```
## Verification
Use the README guide checker before landing documentation changes:
```bash
python3 /home/jmagar/workspace/soma/scripts/check-readme-guide.py README.md
```
Use the package and Rust checks for distribution-sensitive work:
```bash
npm --prefix packages/yarr-mcp run check
cargo fmt --check
cargo check
cargo test
git diff --check
```
For live install verification, validate the native installer and only exercise
the npm path after the exact coupled version resolves:
```bash
curl -fsSL https://raw.githubusercontent.com/dinglebear-ai/yarr/main/install.sh | bash
yarr --version
YARR_VERSION=2.1.0
npm view "@dinglebear/yarr@${YARR_VERSION}" version
npx -y "@dinglebear/yarr@${YARR_VERSION}" mcp
```
Documentation changes also require the repository-local link and anchor guard:
```bash
python3 scripts/check-doc-links.py
```
## Deployment
Run as a persistent HTTP MCP server:
```bash
YARR_MCP_HOST=0.0.0.0 \
YARR_MCP_PORT=40070 \
YARR_MCP_TOKEN=change-me \
YARR_MCP_STATIC_TOKEN_SCOPES=yarr:read \
YARR_MCP_TOOL_MODE=flat \
yarr serve
```
Docker Compose deployments are covered by `docker-compose.yml`,
`docker-compose.prod.yml`, `docs/DOCKER.md`, and `docs/DEPLOYMENT.md`.
Production deployments should put `yarr` behind a trusted reverse proxy or MCP
gateway when exposed outside loopback.
## Troubleshooting
- `401` or `403` from HTTP MCP: confirm `YARR_MCP_TOKEN`, OAuth mode, and
gateway headers.
- `unknown service`: confirm the service is listed in `YARR_SERVICES` and has a
matching `YARR_<SERVICE>_URL`.
- upstream `401`: confirm the service-specific API key or token in the server
environment, not in tool arguments.
- `query-string secret rejected`: remove tokens from `--path` and put them in
config.
- plugin skill cannot reach a service: its per-service config JSON under
`~/.config/lab-<service>/config.json` is missing or stale. It is written by the
plugin's `SessionStart` / `ConfigChange` hook, so start a new session (or change
a plugin setting) to refresh it. To rebuild it by hand, export the settings
yourself — the scripts read `CLAUDE_PLUGIN_OPTION_*`, which only the hook sets:
```bash
CLAUDE_PLUGIN_OPTION_SONARR_URL=https://sonarr.example.com \
CLAUDE_PLUGIN_OPTION_SONARR_API_KEY=… \
bash plugins/sonarr/scripts/setup.sh
```
Skill scripts run through the Bash tool, which receives **no**
`CLAUDE_PLUGIN_OPTION_*` variables — only hook processes do. That is why these
plugins need the hook: it is the one channel that can carry a `sensitive: true`
value to a skill, since sensitive values are never substituted into skill prose
and these plugins have no MCP server to receive an `${user_config.*}` env block.
- Code Mode cannot find a callable: use `codemode.search(...)` and
`codemode.describe(...)`; generated names follow upstream OpenAPI operation
IDs after normalization.
- `npm` or the full plugin reports `E404`/`ETARGET`: check the exact pinned
launcher with `npm view @dinglebear/yarr@2.1.0 version`. Do not fall back to unpinned
`latest`; use the native binary while issue #80 is open.
## Related Servers
- [soma](https://github.com/dinglebear-ai/soma) - RMCP runtime for provider-backed MCP servers.
- [unifi-rmcp](https://github.com/dinglebear-ai/runifi) - UniFi controller REST API bridge.
- [tailscale-rmcp](https://github.com/dinglebear-ai/rtailscale) - Tailscale API bridge for devices, users, and tailnet operations.
- [unraid-rmcp](https://github.com/dinglebear-ai/runraid) - Unraid GraphQL bridge for NAS and server management.
- [apprise-rmcp](https://github.com/dinglebear-ai/rapprise) - Apprise notification fan-out bridge for many delivery backends.
- [gotify-rmcp](https://github.com/dinglebear-ai/rgotify) - Gotify push notification bridge for sends, messages, apps, and clients.
- [arcane-rmcp](https://github.com/dinglebear-ai/rarcane) - Arcane Docker management bridge for containers and related resources.
- [ytdl-rmcp](https://github.com/dinglebear-ai/rytdl) - Media download and metadata workflow server.
- [synapse-rmcp](https://github.com/dinglebear-ai/synapse) - Local Synapse workflow server for scout and flux actions.
- [cortex](https://github.com/dinglebear-ai/cortex) - Syslog and homelab log aggregation MCP server.
- [axon](https://github.com/dinglebear-ai/axon) - RAG, crawl, scrape, extract, and semantic search project.
- [labby](https://github.com/dinglebear-ai/labby) - Homelab control plane and MCP gateway project.
- [lumen](https://github.com/jmagar/lumen) - Local semantic code search MCP server.
## Documentation
The source of truth docs split is:
- `docs/README.md` is the audience-oriented documentation index.
- `docs/DOCS.md` defines authority, generated-doc rules, freshness checks, and
where new documentation belongs.
- `docs/API.md` covers action contracts and Code Mode call shape.
- `docs/CONFIG.md`, `docs/ENV.md`, and `docs/AUTH.md` cover configuration,
environment variables, auth states, and tool modes.
- `docs/QUICKSTART.md` covers native, source, exact-version npm, and Unraid
first-run paths.
- `docs/MCP_SCHEMA.md` and `docs/TOOLS_ACTIONS_ENDPOINTS.md` are checked
schema/action references.
- `docs/DEPLOYMENT.md`, `docs/DOCKER.md`, and `docs/SYSTEMD.md` cover production
runtime choices.
- `docs/CI.md`, `docs/SCRIPTS.md`, and `docs/runbooks/` cover validation,
releases, incidents, and rollback.
- `docs/PATTERNS.md` holds conventions shared across the RMCP server family.
- `docs/PLUGINS.md`, `plugins/README.md`, and `plugins/yarr/README.md` cover
marketplace packaging and launcher availability.
- `unraid-plugin/README.md` is the operator, API, recovery, verification, and
release guide for the classic Unraid distribution.
- `CLAUDE.md` holds repo-local agent memory and the "How to add an action"
checklist.
## License
Original Dinglebear-authored portions of this project are licensed under [AGPL-3.0-only](LICENSE). Separate commercial licensing is available for organizations that need terms outside the AGPL. Third-party material remains under its original license. See [LICENSING.md](https://github.com/dinglebear-ai/yarr/blob/main/LICENSING.md).