@brainy.ink/studio-agent-kit
v0.1.1
Published
Connectivity kit that lets any external AI agent (Claude Code, Cursor, an MCP client) or a CLI drive a Brainy Studio client intake end to end over the public HTTP API.
Maintainers
Readme
@brainy.ink/studio-agent-kit
The connectivity kit for Brainy Studio client intake. It lets any external AI
agent (Claude Code, Cursor, an MCP client), a CLI, or a plain curl take a
project a human already brainstormed and submit it to Studio end to end.
Three ways in, all over the same public HTTP API:
- MCP server (
mcp-server.mjs) - tools an agent calls inside a chat. - CLI (
cli.mjs/studio-intake) - drive intake from a shell or script. - Raw HTTP -
POST/GETthe/api/intake/*endpoints from any language.
How it works (30 seconds)
- start an anonymous session. You get a
sessionId(the bearer for every later call) and aclaimUrl(where the human signs in to submit). - schema - ask which structured field keys a service needs.
- ingest the brief you gathered. You get the live gate, price range, and a
stillNeeded[]list. Repeat to fill gaps. - Hand the human the claimUrl to sign in and click Request this project. The agent never submits (project ownership needs the signed-in client).
No auth is needed to start, ingest, chat, or read status: the unguessable
sessionId is the bearer. Only the final submit needs the human signed in.
Install
No install needed, run it straight from npm:
npx @brainy.ink/studio-agent-kit startOr install the bins globally (studio-intake + studio-mcp):
npm install -g @brainy.ink/studio-agent-kitWorking from a checkout of this repo instead? cd agent-kit && npm install.
Requires Node 18+ (global fetch).
Environment
| Var | Default | Meaning |
|-----|---------|---------|
| STUDIO_API_BASE | https://energized-narwhal-432.convex.site (prod) | The Convex HTTP origin (the .convex.site host). Set to https://hushed-perch-314.convex.site for dev. |
The .convex.site host is the HTTP-actions surface of the matching
.convex.cloud deployment. (Studio is also proxied at studio.brainy.ink/api/*
in prod, which works too.)
MCP server
Run it:
STUDIO_API_BASE=https://energized-narwhal-432.convex.site node mcp-server.mjsRegister it with your MCP client. Claude Code / Claude Desktop config:
{
"mcpServers": {
"brainy-studio": {
"command": "node",
"args": ["/absolute/path/to/agent-kit/mcp-server.mjs"],
"env": {
"STUDIO_API_BASE": "https://energized-narwhal-432.convex.site"
}
}
}
}Or straight from npm, no install (recommended):
{
"mcpServers": {
"brainy-studio": {
"command": "npx",
"args": ["-y", "-p", "@brainy.ink/studio-agent-kit", "studio-mcp"],
"env": { "STUDIO_API_BASE": "https://energized-narwhal-432.convex.site" }
}
}
}(After a global install, "command": "studio-mcp" works too.)
Tools
| Tool | Does |
|------|------|
| studio_start_intake | Open a session. Returns sessionId, claimUrl, opening. |
| studio_get_schema | Learn a service's field keys. Pass {draft:{whatKind:"website"}} or a sessionId. |
| studio_describe_project | Ingest the brief. Returns gate + quote + stillNeeded[]. |
| studio_status | Read live state (no mutation). |
| studio_chat | Conversational fallback turn. |
| studio_submit_hint | The claimUrl + exact handoff instructions for the human. |
CLI
# Open a session
node cli.mjs start
# -> { "sessionId": "...", "claimUrl": "https://studio.brainy.ink/intake?session=...", "opening": "..." }
# Learn a service's fields (whatKind values: website, branding, ...)
node cli.mjs schema --service website
node cli.mjs schema --session <sessionId>
# Dump a brief (from a file or inline JSON)
node cli.mjs describe --session <sessionId> --file brief.json
node cli.mjs describe --session <sessionId> --json '{"whatKind":"website","build_intent":"new_site"}'
# Poll what is still needed
node cli.mjs status --session <sessionId>
# Conversational fallback
node cli.mjs chat --session <sessionId> --message "We need a 5-page marketing site"Published, the same commands run over npm: npx @brainy.ink/studio-agent-kit start (or studio-intake start after a global install). Any subcommand works after the package name, e.g. npx @brainy.ink/studio-agent-kit schema --service website.
Every command prints JSON; pipe to jq.
Raw HTTP (curl)
BASE=https://energized-narwhal-432.convex.site
# 1. start
curl -s -XPOST $BASE/api/intake/start | jq
# 2. schema for a service
curl -s -XPOST $BASE/api/intake/schema -H 'content-type: application/json' \
-d '{"draft":{"whatKind":"website"}}' | jq
# 3. ingest the brief
curl -s -XPOST $BASE/api/intake/ingest -H 'content-type: application/json' \
-d '{"sessionId":"<id>","fields":{"whatKind":"website","build_intent":"new_site","page_count_band":"5_10"}}' | jq
# 4. status
curl -s "$BASE/api/intake/status?sessionId=<id>" | jq
# 5. (optional) chat fallback
curl -s -XPOST $BASE/api/intake/chat -H 'content-type: application/json' \
-d '{"sessionId":"<id>","message":"..."}' | jqThe field contract
You send a flat map of snake_case blueprint field keys to ingest:
- Universal keys the brain understands:
whatKind,journeyStage,build_intent,budget_band,page_count_band,has_logo, plusbrandName,nameStatus,depth,complexity,modules, and a freeformbriefobject. - Per-service keys: always discover them with
schema(thestudio_get_schematool /schemacommand). It returnsfields:[{key,label,kind,options,required,prompt}]for the resolved service, so you know exactly which keys + enum values to send.
Rule: never invent values the human did not give. Leave a field out instead of guessing. Off-enum or unknown values are simply ignored by the gate.
Security model
- Anonymous sessions: the
sessionIdis the bearer. Anyone with it can read and fill that one session, nothing else. - The final submit (
requestProject) requires the human signed in to Studio via theclaimUrl. The agent cannot create the project. That is by design. - CORS is permissive (
*) on these endpoints because they are public anonymous intake with no cookies and no credentials.
See ../docs/AGENT_API.md for the full endpoint reference.
