/blu:integrate [path to the app or API; default: the current repository]
Integrate a team's app or API with the Blu platform using @blu/sdk (and @blu/next-adapter for Next.js apps, horizonmedia-blu-sdk for Python APIs: FastAPI, Flask, Django). Covers the module manifest (blu.module.json), the front end (inline, via Module Federation), the API (verifying Blu tokens, route policies, CORS), optional tools for the Blu Concierge (MCP), and verifying the result with blu check. Use when asked to add Blu support, make an app a Blu module, "publish to Blu", use @blu/sdk or @blu/next-adapter, or fix blu check failures.
This is the skill's own text, which Claude reads when the skill runs. $ARGUMENTS stands for what you type after the command.
Integrate with Blu
Blu is HorizonMedia's platform shell. Team apps appear inside it as modules, and the Blu Concierge (an AI assistant) can call a module's API through tools. Your job is to make this repository a working Blu module, while it keeps working on its own exactly as before, and to prove it with blu check.
Target: $ARGUMENTS (if empty, the current repository).
Ground rules
These keep the integration secure. Don't trade them away to make something work.
- Additive and reversible. Keep the app's existing sign-in, routes and behaviour. Blu support is extra code paths, mostly in new files.
- The client comes from the verified token, never the request. On the server, scope data with the client in the verified Blu caller (
req.principal.clientId), not a query parameter or body. - The team decides permissions. Blu says who the user is, their client and their Blu role (
viewer,analyst,owner). The team's ownroleMapturns that role into this API's permissions. Ask the user what each role should be allowed if it isn't obvious from the existing code. - Import only public entry points:
@blu/sdk,@blu/sdk/server,@blu/sdk/dev,@blu/next-adapter/vite,/client,/server; in Python,blu_sdkand its documented modules. Never@blu/sdk/shell,blu_sdk._*, or files inside the packages. - Tokens only go to the module's own API. Use
useApiClient(),moduleFetch()or the adapter's helpers. Never build URLs from the environment name, and never send the token anywhere else. - No secrets in front-end code or in the repo. The Blu packages are public on npm, so installing them needs no token.
Step 0: understand the repo, then choose a path
Read the repo first: package.json files, framework config, how the front end talks to the API, how users sign in, and how data is scoped to clients or tenants.
Decide what's being integrated: a front end, an API, or both (they may be in different repos; do the one here). Ask the user if you can't tell. Front ends mount inline, in Blu's page through Module Federation (Next.js apps through the adapter).
Then follow the matching reference. Read it fully before editing:
| Front end | Reference |
|---|---|
| React SPA (Vite), inline | reference/frontend-inline.md |
| Next.js (App Router) app | reference/nextjs.md, which uses @blu/next-adapter; it covers its API routes too |
| API | Reference |
|---|---|
| Express, or Web-standard handlers (Hono, workers, Next.js route handlers) | reference/server.md |
| Python: FastAPI, Flask or Django (horizonmedia-blu-sdk) | reference/server-python.md |
Every integration also needs reference/manifest.md and reference/install.md. Common mistakes, and their blu check messages, are in reference/gotchas.md.
The packages' own READMEs are the API reference: node_modules/@blu/sdk/README.md and node_modules/@blu/next-adapter/README.md once installed; for Python, the README on pypi.org/project/horizonmedia-blu-sdk. Their types carry doc comments too.
Steps
Track these as a checklist and do them in order:
- Install the packages under their
@blu/*names, from npm (install.md). - Manifest: create or update
blu.module.jsonat the module's root (manifest.md). Ask the user for anything you can't infer: module id, display name, owning team, environment URLs. - Front end per its reference. It must still run standalone.
- API per server.md: verify Blu callers, add the team's
roleMap, add route policies and CORS for the Blu shell's origins. - Concierge tools (optional; ask the user): wrap existing read endpoints as MCP tools, declared in the manifest, returning links to declared routes.
- Verify:
- Run
npx blu check(orpnpm exec blu check) in the module's folder. Fix every ✘ and re-run until it prints "All checks passed". Treat ⚠ as advice. Explain any you leave. - Run the project's own build, type check and tests, and fix what you broke.
- If you can, run the app standalone to confirm it still works as before.
- Run
- Report:
- the files you changed and added, with one line each on why;
- the roleMap and other decisions you made, and the questions still open;
- anything a Blu admin must do (register the manifest per environment, enable the module for clients, add the redirect addresses).
What "done" looks like
blu checkpasses.- Builds: the project's build and tests pass.
- Standalone: the app still runs on its own, unchanged for its users.
- Front end: it reads the user, client and theme from
@blu/sdkhooks, and calls its API withuseApiClient()(ormoduleFetchin Next.js). - API: it accepts Blu callers for its own module id only, scopes data by
principal.clientId, and enforces the team'sroleMapper route.