# MCP Tools Reference (Backoffice)

> **Update (13.5.2026)**: Tento doc popisuje **backoffice MCP**
> (`apps/web`) — modules: skills, crm, happenings, team, checkin,
> integrations, users, support.
>
> Per-user **Context Store byl odstraněn** (`list_files`, `read_file`,
> `write_file`, `delete_file`, `search_files` tooly už neexistují).
> User-facing kontextový MCP žije v akademii (`apps/akademie`) —
> JSON-RPC 2.0 dispatcher s 11 context tools + 7 Studio tools.
> Pro vlastní Claude / Cursor s vlastním kontextem použij
> `akademie.davidkirs.cz/api/mcp` (viz `apps/akademie/src/docs/mcp.md`).
>
> Backoffice MCP zůstává pro **interní agent workflows** — skills
> knihovna, CRM operations, support drafting, admin operations.

Backoffice MCP exponuje jeden endpoint rozdělený do modulů. Každý modul
obsahuje sadu tools v jednom doménu (context-store, team a hosti na
akcích, skills knihovna).

## Connection

**Streamable HTTP** transport:

```
URL: https://ja2.davidkirs.cz/api/mcp
Auth: Bearer token (from Settings → API Tokens)
```

> Legacy URL `ja-2-academy-platform.replit.app` stále funguje, ale
> doporučujeme produkční doménu.

### Claude Code Configuration

```json
{
  "mcpServers": {
    "ja2-context": {
      "url": "https://ja-2-academy-platform.replit.app/api/mcp",
      "token": "cs_your-token-here"
    }
  }
}
```

### Cursor / OpenClaw

Same configuration — just add the MCP server with URL and token.

---

## Kdo má k čemu přístup

MCP rozlišuje **dvě úrovně tools**:

- **`public`** (default) — **kdokoliv s platným tokenem**. Používá se pro osobní per-user moduly (context-store). Komunitní členové, kteří si budují vlastní context, sem patří.
- **`admin`** — jen uživatelé s `allowed_emails.role='admin'`. Platform-control tools (správa akcí, týmu, CRM, …). **Community tokeny tyto tools vůbec neuvidí** v `tools/list` — prevence info leaku i zmatku.

Každý tool má volitelný `requiredRole`. Dispatch kontroluje dvakrát (registry + handler `requireMcpAdmin()`), takže i kdyby někdo obešel `tools/list`, na `tools/call` dostane 403.

## Moduly

| Namespace | Role | Scope | Co obsahuje |
|---|---|---|---|
| `skills` | **public** | Global (sdílená knihovna) | **Vstupní bod** — `bootstrap`, `skill_list`, `skill_get`. Kdokoliv s tokenem vidí veřejné skills. |
| `crm` | **admin** | Global | Zákazníci + entitlements + attributions + events timeline |
| `happenings` | **admin** | Global | Akce CRUD + features + products (FAPI/Affilbox/Stripe mapping) |
| `team` | **admin** | Per-happening | Role katalog + interní lidé (tým a hosti) |
| `checkin` | **admin** | Per-happening | Odbavení / undo / lookup voucheru + dev test seed |
| `integrations` | **admin** | Global | FAPI & Affilbox sync + affiliate partners (read) |
| `users` | **admin** | Global | `allowed_emails` whitelist + `module_access` grants |
| `support` | **admin** | Global | Inbox konverzace + reply (Gmail) + status workflow |
| ~~`context-store`~~ | — | — | **Odstraněno 13.5.2026** — žije v akademii jako Studio (workspace) |
| 🔮 `community` | public | Chat/posty | Komunita, discussions (plánováno) |

---

## Skills tools (public — entry point pro AI agenta)

Sdílená knihovna AI skills (Markdown instrukce) spravovaná adminem v `/admin/skills`. Každý uživatel s validním tokenem vidí všechny aktivní skills v jeho `tier` (v1 vždy `public`).

**Použití:** uživatel si jednorázově vloží **bootstrap prompt** (`docs/platform/agent-bootstrap-prompt.md`) jako system prompt do Claude Cowork / Desktop. Claude pak při každém dotazu nejdřív zavolá `bootstrap`, najde si skill podle `when_to_use` a pak `skill_get(slug)` pro full body.

### bootstrap

Vstupní call. Žádné parametry. Vrací JSON s:
- `identity` — `{user_id, email, name, role, tier}`
- `context_store` — `{file_count, paths[], note}`
- `skills` — `{count, manifest: [{slug, name, description, when_to_use, tools_needed, tier}], note}`
- `mcp_tools` — `{available: [tool_name], note}` — filtrováno podle role (admin vidí víc)
- `next_steps` — instrukce co dělat dál

### skill_list

Manifest skills (slug + name + description + when_to_use + tools_needed). Lightweight — pro matching uživatelského úkolu.

**Parametry:** žádné (filter podle uživatelova tier proběhne automaticky).

### skill_get

Plný Markdown body skillu — instrukce co dělat.

**Parametry:** `{ slug: string }` (snake-case identifier z manifestu).

**Response:** `{slug, name, description, when_to_use, tools_needed, tier, body}`.

---

## Context-store tools — REMOVED (13.5.2026)

Per-user file CRUD tools (`list_files`, `read_file`, `write_file`,
`delete_file`, `search_files`) byly z backoffice MCP odstraněny.

User-facing kontext žije v akademii — Studio (workspace) + 3-tier sloty.
Akademie MCP server má rozšířenější tools s indexovým workflow:

| Backoffice (zrušeno) | Akademie ekvivalent |
|---|---|
| `list_files` | `ja2_workspace_list` (lightweight) nebo `ja2_workspace_index` (s headings, tagy) |
| `read_file` | `ja2_workspace_read` |
| `write_file` | `ja2_workspace_write` |
| `delete_file` | (zrušeno — destruktivní ops user dělá v UI) |
| `search_files` | `ja2_workspace_search` (fuzzy) nebo `ja2_workspace_grep` (precision regex) |

Pro detail viz `apps/akademie/src/docs/mcp.md` a
`apps/akademie/src/docs/studio.md`.

---

## Error Handling

| HTTP Status | Meaning |
|-------------|---------|
| 401 | Missing or invalid Bearer token |
| 401 | Token has been revoked |
| Tool error | File not found (for read_file) |

---

## Rate Limits

Currently no hard rate limits. Please be reasonable — this is a personal tool, not a bulk data API.

---

## Team & hosti tools (admin only)

Tools pro správu **interních lidí** (speakeři, moderátoři, tým, crew, hosté, VIP partneři) napříč všemi akcemi. Admin-only scope — ověřeno přes `allowed_emails.role='admin'` na emailu uživatele z Bearer tokenu.

Všechny mutace se **auditují** do `events` tabulky (`type='team_mgmt'`, `source='mcp'`, metadata s detaily).

### team_list_happenings

Seznam akcí.

**Parametry:**
| Name | Type | Required | Description |
|---|---|---|---|
| `active_only` | boolean | No | Default `true` — jen akce s `active=true` |

**Response:** JSON array — `[{id, slug, name, days, starts_at, ends_at, features, roles_count}]`.

### team_list_roles

Role katalog + dostupné features pro akci.

**Parametry:** `{ happening_slug: string }`

**Response:** `{ happening: {...}, available_features: [...], team_roles: {...} }`

### team_upsert_role

Vytvoří/upraví roli v katalogu. Neplatné flag klíče (ne v `happening.features`) se tichoce zahodí.

**Parametry:**
| Name | Type | Required |
|---|---|---|
| `happening_slug` | string | ✓ |
| `role_key` | string | ✓ |
| `label` | string | ✓ |
| `attendee_type` | enum (standard/vip/vip_2plus1/partner_vip/speaker/team/guest/crew) | ✓ |
| `default_flags` | object (feature_key → true) | ✓ |
| `order` | number | - |

### team_delete_role

Smaže roli z katalogu.

**Parametry:** `{ happening_slug, role_key }`

### team_list_members

Seznam interních lidí (`imported_by='internal'`) v akci.

**Parametry:** `{ happening_slug }`

### team_add_member

Upsert člověka do akce s rolí. Idempotentní — stejný email + akce = registrace se aktualizuje.

**Parametry:**
| Name | Type | Required |
|---|---|---|
| `happening_slug` | string | ✓ |
| `role_key` | string | ✓ |
| `email` | string | ✓ |
| `first_name` / `last_name` / `phone` | string | - |
| `flags` | object | - (default z role) |
| `notes` | string | - |

**Response:** `{ ok, customer_id, registration_id }`

### team_update_member

Změna role / flagů / kontaktu. Identifikuje přes `registration_id`.

### team_remove_member

Odebere registraci z akce. CRM profil zůstává.

### team_search_customers

Search v `customers` + `allowed_emails` (pro dohledání interního účtu, který ještě nemá CRM kartu).

**Parametry:** `{ query, happening_slug? }`

**Response:** Až 10 hits, každý má `source: 'customer' | 'app'` + `already_registered` flag.

---

## CRM tools (admin only)

Práce s CRM customer profily, entitlements, attributions a events timeline.

| Tool | Účel |
|---|---|
| `crm_list_customers` | List customerů (globální / filtrem happening_slug / search) |
| `crm_get_customer` | Detail customera (profil + registrace + entitlements + attributions) |
| `crm_add_customer` | Upsert customera. Volitelně registrace na happening + attribution |
| `crm_update_customer` | Update profile (jméno, telefon, tagy, notes, attendee_type, newsletter) |
| `crm_delete_customer` | Smaže customer a kaskádně registrace/entitlements/attributions/events |
| `crm_get_timeline` | Events pro customera (newest first) |
| `crm_add_event` | Zápis custom eventu (agent poznámky, follow-ups) |
| `entitlement_list` | Entitlements pro customera |
| `entitlement_grant` | Vydat manuální entitlement (comp ticket, extra benefit) |
| `entitlement_revoke` | Smazat entitlement |
| `attribution_list` | Attribution záznamy pro customera |
| `attribution_add` | Přidat manuální attribution (source + affiliate_code + campaign) |

## Happenings tools (admin only)

CRUD akcí + features catalog + product mapping (FAPI/Affilbox/Stripe).

| Tool | Účel |
|---|---|
| `happening_get` | Full happening row (včetně features + team_roles) |
| `happening_create` | Vytvořit akci (slug + name + data + location) |
| `happening_update` | Upravit basic info akce |
| `happening_set_features` | Nahradit features JSONB (katalog benefitů) |
| `happening_delete` | Smazat akci |
| `product_list` | FAPI/Affilbox/Stripe mapping pro akci |
| `product_upsert` | Vytvořit/upravit product mapping |
| `product_delete` | Smazat product mapping |

## Check-in tools (admin only)

Odbavení + dev test seed.

| Tool | Účel |
|---|---|
| `checkin_list_attendees` | List účastníků (filter all/arrived/pending) |
| `checkin_lookup_voucher` | Voucher → registration_id + customer_id + arrived status |
| `checkin_mark_arrived` | Označit jako přítomen (idempotentní) |
| `checkin_undo` | Zrušit odbavení |
| `checkin_stats` | Agregované statistiky akce |
| `dev_seed_test_checkin` | Vytvořit N test účastníků s TEST-* vouchery |
| `dev_cleanup_test_seed` | Smazat všechny dev-seed customery z akce |

## Integrations tools (admin only)

Trigger sync + read affiliate partners.

| Tool | Účel |
|---|---|
| `fapi_sync_now` | Trigger FAPI sync (recent_days, max_pages) |
| `fapi_get_state` | Stav FAPI integrace (last_synced_at, last_result) |
| `affilbox_sync_now` | Trigger Affilbox sync |
| `affilbox_get_state` | Stav Affilbox integrace |
| `affiliate_list_partners` | List affiliate partnerů (aktivní / search) |
| `affiliate_get_partner` | Detail partnera + attributions (customers, které přivedl) |

## Support tools (admin only)

Sjednocená podpora — Gmail-backed inbox + web tickety. Agent může číst konverzace, odpovídat (přes Gmail API se zachováním threadu), měnit status, hledat customery.

| Tool | Účel |
|---|---|
| `support_list_conversations` | List konverzací (filter status open/closed/pending/resolved/all + search v subject/customer + limit) |
| `support_get_conversation` | Detail konverzace + customer summary + messages thread. Default plain text; `include_body_html=true` přidá sanitized HTML |
| `support_reply` | Odpověď zákazníkovi přes Gmail API se zachováním threadId + In-Reply-To. Plain text body (max 10k chars), volitelné CC. Brand signature se přidá automaticky. Audit do `events`. |
| `support_set_status` | Změň status (open/closed/pending/resolved) |
| `support_search_customers` | Najdi customery podle email/name fragmentu (ILIKE), pomáhá agentovi spárovat thread s CRM |

## Users tools (admin only)

Platform whitelist + module access grants.

| Tool | Účel |
|---|---|
| `user_list_allowed` | List emailů v `allowed_emails` (whitelist + role) |
| `user_add_allowed` | Přidat (upsert) email do whitelistu s rolí |
| `user_remove_allowed` | Odebrat email z whitelistu |
| `user_list_module_access` | List module grants pro uživatele |
| `user_grant_module_access` | Grant modulu (např. `checkin:ja2-zive-brno-2026`) |
| `user_revoke_module_access` | Odebrat grant |

---

## Architektura — jak přidat nový modul

MCP endpoint je postaven na **registry patternu** (`lib/mcp/registry.ts`). Každý modul = jeden soubor s tools handlers + `McpModule` export. Registruje se v `lib/mcp/index.ts`, route handler se nemění.

### Kroky pro nový modul (např. `akademie`)

1. **Vytvoř `lib/mcp/akademie-tools.ts`** — handlery (`akademieListCourses`, ...) + export `akademieMcpModule: McpModule`.
2. **Přidej do `lib/mcp/index.ts`**:
   ```ts
   import { akademieMcpModule } from "./akademie-tools";
   registerMcpModule(akademieMcpModule);
   ```
3. **Dokumentuj v `docs/mcp.md`** — sekce per modul.

Registry detekuje kolize názvů tools při startu (throw při registraci) a exponuje `getMcpToolSchemas()` + `dispatchMcpTool()` — handler v `/app/api/mcp/route.ts` nic nezmění.

### Auth scope konvence

- **Per-user tools** (`context-store`, budoucí `community`): `requiredRole` vynechat nebo nastavit `"public"`. Scope = `user_id` z Bearer tokenu. Každý user vidí jen svoje. **Komunitní tokeny sem mají přístup.**
- **Admin tools** (`team`, budoucí `crm`): `requiredRole: "admin"` + `await requireMcpAdmin(userId)` na začátku handleru. **Community tokeny je v `tools/list` neuvidí.**
- **Role-specific tools** (budoucí lektor/support): rozšířit `McpToolRole` typ v `registry.ts` + helper `requireMcpRole(userId, ["admin", "support"])` v `auth.ts`.

### Defense in depth

Tool s `requiredRole: "admin"` je chráněn na **třech místech**:
1. `tools/list` — registry filtruje podle `userRole` → non-admin tokens tool vůbec neuvidí.
2. `tools/call` dispatch — `dispatchMcpTool()` throws "Forbidden" pokud role nesedí.
3. Handler — `requireMcpAdmin(userId)` na začátku throwne, i kdyby #1 + #2 zkotvili.

### Audit

Mutating tools volají `auditMcp(admin, {email, action, happening_slug, customer_id, summary})` (nebo analog pro svůj modul) zapisující do `events` tabulky. Admin UI na `/admin/customers/[id]` zobrazí timeline automaticky.

### Soubory

- `lib/mcp/registry.ts` — typy + registrační API.
- `lib/mcp/index.ts` — bootstrap (všechny moduly registered here).
- `lib/mcp/auth.ts` — `validateToken`, `getMcpUserIdentity`, `requireMcpAdmin`.
- `lib/mcp/skills-tools.ts` — skills module (bootstrap + skill_list + skill_get).
- `lib/mcp/tools.ts` — context-store module.
- `lib/mcp/team-tools.ts` — team module.
- `app/api/mcp/route.ts` — JSON-RPC endpoint (neměnit při přidávání modulů).
