---
name: isodora
description: >
  Main entry point for working with Isodora (https://isodora.se) — the AI-powered
  ISO compliance platform. Use this skill whenever the user mentions Isodora
  without naming a specific surface: "set up Isodora", "connect Isodora",
  "call the Isodora API", "use Isodora MCP", "list our gaps", "compliance API".
  Scans for an API key and region, proposes a concrete next step, then routes to
  isodora-keys (auth), isodora-api (REST /api/v1), or isodora-mcp (agents).
  Requires a personal API key from Settings → API keys (isk_u_*).
metadata:
  author: isodora
  version: "1.0.0"
  homepage: https://skills.isodora.se/
---

# Isodora

You help developers and compliance teams call Isodora from outside the browser —
via the **public REST API** (`/api/v1/**`) and the **MCP server** (`/api/mcp`).

Isodora is multi-tenant compliance software (NIS2, DORA, ISO 27001 / 9001 / 14001).
Customer data never crosses the EU/US boundary. Keys and base URLs are **regional**.

Human docs: [docs/api/public-api-v1.md](https://github.com/isodora/isodora-core/blob/main/docs/api/public-api-v1.md) (quickstart). Live public OpenAPI: `https://api-docs.isodora.se/openapi.public.json`. Platform UI for keys: customer portal → **Settings → API keys**.

---

## Start here — do not skip

**Do not assume the user has a key.** Without `Authorization: Bearer isk_u_…`, every call fails.

1. **Scan first.** Run the probes in Phase 1.
2. **Propose, don't interrogate.** One concrete plan in one sentence.
3. **Verify before suggesting more.** Phase 4 (test) before Phase 5 (follow-up).

Skip Phase 2 only when the user gave a direct unambiguous command (e.g. "add Isodora MCP to Cursor with this key") or intent is already locked.

---

## Phase 1: Explore

```bash
# Key present?
test -n "$ISODORA_API_KEY" && echo "ISODORA_API_KEY set" || echo "ISODORA_API_KEY not set"

# Region / base URL
echo "ISODORA_BASE_URL=${ISODORA_BASE_URL:-unset}"

# MCP config hints (Cursor)
test -f .cursor/mcp.json && grep -l isodora .cursor/mcp.json 2>/dev/null || echo "no Cursor isodora MCP"
```

| Finding | Lane | Next skill |
|---|---|---|
| No key, no MCP | **New / starter** | `isodora-keys` |
| Key in env, no MCP | **REST-first** | `isodora-api` |
| MCP configured, auth failing | **Debug** | `isodora-keys` |
| Key works, agent host | **MCP** | `isodora-mcp` |
| Mentions curl / Grafana / n8n HTTP | **API** | `isodora-api` |
| Mentions Cursor / Claude Code / AI SDK tools | **MCP** | `isodora-mcp` |

If two lanes are plausible, ask **one** question — e.g. *"Are you wiring an HTTP client/script, or an agent host (Cursor / Claude Code)?"*

---

## Phase 2: Propose

Lead with one sentence. Never an open-ended menu of four.

**New / starter (verbatim spirit):**

> *"I see no `ISODORA_API_KEY` and no Isodora MCP config. I'd suggest: (1) open the customer portal → Settings → API keys → New API key, (2) set `ISODORA_BASE_URL` to `https://app.isodora.se` (EU) or `https://app.isodora.app` (US), (3) put the key in env / MCP headers — never commit it, (4) run `GET /api/v1/me` or MCP `whoami`. Sound good?"*

**REST-first:** point at `isodora-api` and one `curl` to `/api/v1/me`.

**MCP:** point at `isodora-mcp` host config + `whoami` first.

---

## Phase 3: Guide

Load the matching sub-skill and follow it. Do not paraphrase critical URLs or header names.

| Skill | URL |
|---|---|
| Keys / auth | https://skills.isodora.se/isodora-keys/SKILL.md |
| Public REST | https://skills.isodora.se/isodora-api/SKILL.md |
| MCP | https://skills.isodora.se/isodora-mcp/SKILL.md |

Fallback (GitHub raw / monorepo): same paths under the `skills/` tree.

---

## Phase 4: Test

| Lane | Working means |
|---|---|
| Keys | User has created a key under Settings → API keys; plaintext stored only in env/secret store |
| API | `GET $ISODORA_BASE_URL/api/v1/me` returns 200 with `data` envelope |
| MCP | `whoami` tool succeeds; then one read (e.g. `list_organizations`) |

**Common failures:** wrong region; expired/revoked key; org kill switch; read-only key on write tool; QMS module missing for `list_suppliers` / `list_risks`.

---

## Phase 5: Follow-up

Suggest **one** next step:

- First `me`/`whoami` works → list gaps or compliance overview for one org
- Building an agent → wire Cursor/Claude MCP from `isodora-mcp`
- HTTP automation → cursor pagination on `/gaps` or `/tasks`
- Sample app → `examples/compliance-copilot/`

---

## Hard rules

- **Only** public surfaces: `/api/v1/**` and `/api/mcp`. Never invent internal UI routes.
- **Never** echo full `isk_u_*` / `isk_p_*` values into chat or commits — placeholders only.
- **Region:** EU key ↔ `app.isodora.se`; US key ↔ `app.isodora.app`. Cross-region always 401.
- Prefer live contract: grep `https://api-docs.isodora.se/openapi.public.json` or MCP `tools/list` over hardcoding.
- Platform keys (`isk_p_*`) are operator/partner — default customer path is personal `isk_u_*` from Settings → API keys.

## Vocabulary

| Term | Meaning |
|---|---|
| Organization | Tenant |
| Project | Framework engagement inside an org |
| Personal API key | `isk_u_*` from **My keys** — acts as the user |
| Organization keys (UI) | Admin oversight of members' personal keys + kill switch |
| Public API | `/api/v1/**` |
| MCP | `/api/mcp` Streamable HTTP |
