Metadata-Version: 2.4
Name: yuuno-mcp
Version: 0.1.4
Summary: MCP server for yuuno.tech adflow — build and run AI media canvases from Claude/Cursor.
Author: yuuno.tech
License: Proprietary
Project-URL: Homepage, https://app.yuuno.tech
Project-URL: Documentation, https://app.yuuno.tech/settings/organization/api
Keywords: mcp,model-context-protocol,yuuno,adflow,ai-video,llm-tools
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: fastmcp~=3.4
Requires-Dist: httpx
Provides-Extra: http
Requires-Dist: uvicorn[standard]; extra == "http"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: respx; extra == "dev"
Requires-Dist: uvicorn[standard]; extra == "dev"

# yuuno-mcp

MCP server for [yuuno.tech](https://app.yuuno.tech) **adflow** — drive the
node-based AI media canvas from an MCP client (Claude Code, Claude Desktop,
Cursor, …). You become an agent on the board: create sessions, wire up
image/video/audio/text generation nodes, run flows, and read results — the
same canvas the in-app chat edits, so your changes appear live in the browser.

## Get an API key

Mint a workspace key at
**app.yuuno.tech → Settings → Organization → API**
(`https://app.yuuno.tech/settings/organization/api`). It's a 40-character hex
string scoped to your workspace. Rotating it (Reset) invalidates the previous
key for every connected client in that workspace.

## Connect

### Claude Code

Local (stdio, recommended — works everywhere):

```bash
claude mcp add yuuno -e YUUNO_API_KEY=<your-40-hex-key> -- uvx yuuno-mcp
```

Hosted (Streamable HTTP — no local install):

```bash
claude mcp add --transport http yuuno https://mcp.yuuno.tech/mcp \
  --header "Authorization: Bearer <your-40-hex-key>"
```

### Claude Desktop

Add to `claude_desktop_config.json` (stdio; Desktop connectors don't pass
custom headers, so use stdio):

```json
{
  "mcpServers": {
    "yuuno": {
      "command": "uvx",
      "args": ["yuuno-mcp"],
      "env": { "YUUNO_API_KEY": "<your-40-hex-key>" }
    }
  }
}
```

### Cursor

Add to `~/.cursor/mcp.json` (or a project `.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "yuuno": {
      "url": "https://mcp.yuuno.tech/mcp",
      "headers": { "Authorization": "Bearer ${env:YUUNO_API_KEY}" }
    }
  }
}
```

Cursor also supports stdio (`"command": "uvx", "args": ["yuuno-mcp"]`).

> **Client support note:** remote (hosted HTTP + `Authorization` header) works
> today in Claude Code and Cursor. Claude Desktop and claude.ai custom
> connectors don't pass static headers — use stdio (`uvx`) for Desktop; OAuth
> for claude.ai is a later release.

## First moves for the agent

Call **`get_cheatsheet`** once at the start of a session — it explains the 18
node types, the DAG op rules, the run lifecycle, and model selection. Then a
typical build is: `list_models` → `create_session` → `apply_ops_batch` (build
the graph) → `auto_layout` → `estimate_credits` → `run_flow` → `wait_for_run`.
`list_examples` returns ready-to-apply op recipes.

## Tools (37)

- **Sessions** — `whoami`, `create_session`, `list_sessions`, `get_dag`,
  `copy_session`, `delete_session`
- **DAG ops** — `add_node`, `add_node_with_inputs`, `update_node`,
  `remove_node`, `add_edge`, `update_edge`, `remove_edge`, `apply_ops_batch`,
  `set_uploaded_assets`
- **Structure** — `add_group`, `move_to_group`, `ungroup`, `replace_edge`,
  `insert_node_on_edge`, `bypass_node`, `list_node_io`, `auto_layout`
- **Runs** — `run_flow`, `get_run_status`, `list_runs`, `wait_for_run`,
  `estimate_credits`
- **Generate / catalog** — `execute_utility_node`, `wait_for_task`,
  `generate_text`, `generate_asset`, `list_models`, `get_model_schema`,
  `upload_asset`
- **Docs** — `get_cheatsheet`, `list_examples` (also exposed as MCP resources
  `yuuno://cheatsheet` and `yuuno://examples/<name>`)

## Configuration

| var | default | purpose |
|---|---|---|
| `YUUNO_API_KEY` | — | workspace API key (40 hex), stdio mode |
| `YUUNO_BACKEND_URL` | `https://api.yuuno.tech` | Django backend base URL |
| `YUUNO_APP_URL` | `https://app.yuuno.tech` | SPA base URL (canvas links) |
| `YUUNO_WORKSPACE_ID` | — | optional workspace uuid (`X-API-ID`), stdio only |
| `YUUNO_JWT` | — | dev fallback: SimpleJWT access token |
| `MCP_HTTP_HOST` / `MCP_HTTP_PORT` | `127.0.0.1` / `8765` | `--transport http` bind |

In hosted HTTP mode the key is never held server-side — each request carries
its own `Authorization: Bearer <key>`, verified against the backend, and the
server proxies that exact key to Django (no cross-tenant state).

## Development

```bash
cd mcp
python3.12 -m venv .venv
.venv/bin/pip install -e '.[dev]'
.venv/bin/python -m pytest tests -q
```

The contract-parity test (`tests/test_parity.py`) imports
`adflow.dag_protocol.constants` from the monorepo root and asserts the mirrored
constants match; it auto-skips outside the monorepo. Deploy artifacts (systemd
units, nginx config, operator runbook) are under [`deploy/`](deploy/).
