This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
iblai/api is a toolkit for operating the ibl.ai platform from an AI agent. It ships two things:
- Skills (
skills/) — installable vianpx skills add iblai/api. Each/iblai-api-*skill maps one agent-configuration or platform-admin operation to its exactapi.iblai.appREST endpoints (method, URL, body). They drive the platform directly — no UI. - MCP server (
mcp/) — a single hosted Model Context Protocol server,iblai-api-agent-chat, for the one runtime capability that isn't a REST call: holding a live conversation with a deployed agent (streamed responses, tool use, RAG).
This is the API-driven complement to iblai/vibe, which provides UI components for building ibl.ai apps.
Naming. Skills are iblai-api-*; scope is encoded by prefix. iblai-api-agent-* acts on one agent; iblai-api-profile* on the signed-in user. Org-wide is the default scope, so those skills are bare — iblai-api-management, iblai-api-rbac, iblai-api-crm, iblai-api-token, iblai-api-integration, iblai-api-notification, iblai-api-invite — and iblai-api-org itself is the org-settings skill. Cross-cutting skills are bare too: iblai-api-search, iblai-api-analytics, iblai-api-course-create, iblai-api-login. (These iblai-api-* names overlap some of vibe's; that's accepted.)
Skills describe APIs, not UIs. Each skill documents endpoints (method, URL, body) and when to use them. Do not reference user interfaces (menus, tabs, buttons, pages, "Edit Agent → …") in skill prose — the UI was only a means to discover endpoints; the value is the API.
Skills vs MCP server — REST vs runtime chat. Skills do everything reachable over REST (configure agents, datasets, memory, users, roles, notifications, discovery/search, recommendations, user profile + analytics, reporting). The MCP server is only for live agent chat — and even wiring it up is a skill (/iblai-api-agent-chat writes the .mcp.json / claude mcp add config from the .env token + a chosen agent's unique_id), so the whole offering installs via npx skills add iblai/api. Rule: if a skill covers it, there is no server for it. That's why only iblai-api-agent-chat remains — the former analytics, agent-create, search, and user servers were removed once skills covered analytics (/iblai-api-analytics), agent creation (/iblai-api-agent-create), discovery + recommendations (/iblai-api-search), and user profile + analytics (/iblai-api-profile).
Three words used to be mixed for a customer's workspace. The convention for this repo:
- Platform — the ibl.ai system as a whole (
api.iblai.app,login.iblai.app). One platform serves every customer. Never use "platform" to mean a single customer's workspace. (It is fine in product terms like "Platform API Token" and in prose like "the platform API".) - Organization (org) — one customer's isolated workspace (its own users, agents, branding, data). This is the primary noun in all prose and docs. It matches what customers see on
login.iblai.app/me("Organizations") and the API path/orgs/{org}/. - org key — the organization's identifier, e.g.
enterprise. On the API wire it also appears asorg,platform_key, andplatform_org— keep those verbatim in endpoint references; they all mean the org key. - tenant — architectural adjective only ("multi-tenant", "tenant isolation"). Do not use it as the workspace noun. The only literal
tenantallowed is a verbatim wire name the API actually uses (e.g. thetenantquery param on some search endpoints) — and the MCP scope enum isuser|mentor|platform, not…|tenant. Note the@iblaiSDK / vibe / os usetenantin env vars (NEXT_PUBLIC_TENANT); this repo deliberately usesorginstead.
Env vars follow the noun: active workspace is IBLAI_ORG + IBLAI_API_KEY; saved per-workspace keys are IBLAI_ORG_<NAME>_KEY.
skills/ # downloadable skills (npx skills add iblai/api)
iblai-api-login/ # connect an organization — run first
iblai-api-agent-*/ # one-agent skills (settings, llm, prompts, datasets, memory, evals, …)
iblai-api-profile*/ # signed-in user's profile + per-user metadata
iblai-<other>/ # org-wide ops (management, rbac, crm, tokens, …) + search, analytics, course-create
mcp/ # hosted Python MCP server — runtime chat only
iblai-api-agent-chat/
.env # active organization + per-org Api-Tokens (gitignored)
-
Each skill is a
SKILL.mdwith YAML frontmatter (name,description) following the format ofskills/iblai-api-agent-setting/SKILL.mdandskills/iblai-api-login/SKILL.md. A skill MAY additionally bundle areferences/directory and anassets/directory for sample files, each linked fromSKILL.mdvia a## Reference materialsection.references/holds anything that would bloat the scannable primary: exhaustive lookup tables (field schemas, action catalogs) and the developer docs' fuller explanatory material — concepts, architecture/data-flow, configuration and integration guides, and troubleshooting (this is where non-endpoint doc content that doesn't belong in the endpoint-focusedSKILL.mdis preserved, including UI/integration walkthroughs).SKILL.mditself stays the scannable, endpoint-focused primary and still obeys the "APIs not UIs" rule;references/is doc-sourced supplementary material. Seeskills/iblai-api-external-service-proxy/,skills/iblai-api-crm/, andskills/iblai-api-agent-memory/for the pattern. -
Canonical section structure (every endpoint-documenting skill MUST follow this):
## Auth & conventions— base URL, header, path vars, prefix, "run/iblai-api-loginfirst" line, and the destructive-confirm note.- (optional) one short explanatory section (e.g.
## Concepts,## Pagination) when the API needs framing before the endpoints. ## Reads— every read endpoint (GET/HEAD).## Writes— every write endpoint (POST/PUT/PATCH/DELETE); mark each destructive/outward-facing call "Confirm with the user first."## Example— one realisticcurl.## Notes— gotchas.
- Multi-resource skills (catalog, crm, rbac, billing, …) keep their resource grouping as
###sub-headings inside## Readsand## Writes(a resource with both appears under each). Do not group endpoints by resource at the top level — Reads/Writes is always the top-level split. - A read-only skill may omit
## Writes; a write-only skill may omit## Reads. - Exceptions: non-REST skills do not use Reads/Writes —
iblai-api-loginandiblai-api-agent-chat(setup flows), andiblai-api-infrastructureandiblai-api-ecosystem(deployment / open-source-ecosystem guides sourced from the developer docs, content held inreferences/). These are guides, not endpoint references.
-
Auth model (every skill): base URL
https://api.iblai.app, headerAuthorization: Api-Token $IBLAI_API_KEY. Path vars{org}=$IBLAI_ORG(a.k.a.platform_key),{username}=$IBLAI_USERNAME,{mentor}= the agent's unique id. -
Gateway prefixes —
/dmand/edx.api.iblai.appis a gateway that sits in front of the backend services and strips a prefix before routing:https://api.iblai.app/dm/...→ the Data Manager service (theiblai/iblai-dm-prorepo).https://api.iblai.app/edx/...→ the Open edX service (a different system).
The prefix is added at the gateway, so it does not appear in any backend
urls.py— the source repos register bare/api/...routes. A skill must prepend the right prefix (e.g. a DM route/api/catalog/courses/is documented and called ashttps://api.iblai.app/dm/api/catalog/courses/). When in doubt, an endpoint is a/dmendpoint. -
Source of truth = the repo URLconf, not the docs. Skills for DM features are derived from
iblai-dm-pro. The appUSAGE.mdfiles are a starting point but contain errors, gaps, and (critically) endpoints that only apply to edX — those do not belong here. Rule: only document an endpoint if it is registered in that repo'surls.py(i.e. reachable atapi.iblai.app/dm/...). If a path is not in this repo's URL configuration, drop it — it would not resolve via/dm. Always verify each endpoint's method, path, and request fields against the actualurls.py/ views / serializers before shipping a skill. -
Connecting an organization:
/iblai-api-loginopenshttps://login.iblai.app/me, lets the user pick one of their organizations, and writesIBLAI_ORG,IBLAI_USERNAME, andIBLAI_API_KEYto.env. Always ask the user which org to target — accounts can belong to many (40+ is normal).- Logged out:
/meredirects to/login. Detect this (URL is/login, no "My Account" content), hand the user thehttps://login.iblai.app/meURL, and wait for them to sign in — never enter their credentials. - After login the platform redirects somewhere else (the destination varies and may change), NOT back to
/me. Don't depend on where it lands — always re-navigate explicitly tohttps://login.iblai.app/mebefore reading params. /meis server-rendered — there is no JSON API; read org keys + username from the rendered page content. Each org block is the display name followed by its key (e.g.Enterprise → enterprise,ibl.ai → iblai, or a UUID).- There is no working logout route (
/logout,/api/auth/logoutboth 4xx); the session is an httpOnly cookie. To force a logged-out state for testing, clear the browser's cookies forlogin.iblai.app.
- Logged out:
-
Mark every DELETE / destructive / outward-facing call (delete, send, invite) "confirm with the user first."
# Install dependencies
cd mcp/iblai-<service>
uv sync
# Run the server
uv run iblai-<service>
# Run tests
uv run pytestEach server contains:
- server.py: tool definitions via
@server.tool()decorators - auth.py:
AuthManagersupporting api_key, bearer, basic, custom_header, oauth2_client_credentials via env vars - client.py:
APIClientfor async httpx requests
Conventions: server names iblai-<service>, package names iblai_<service>; stdio transport locally, streamable-http for hosted. The hosted servers expect Authorization: Api-Token <key>; the org is derived from the token.
Use the iblai-mcp-creator tool to generate new MCP servers from HAR files.