HTTPS in, same gates as MCP.
POST /api/cli is JSON. The official CLI is the faster path. Identity, payment, and can() stay in one model. Not a second permission system.
01 Auth
Bearer on every POST. Discovery stays public.
Unpaid accounts can finish OAuth and still receive no tools. Host jobs stay blocked until approve. Builder OS stays hidden unless Founder.
- OAuth
- Cursor and other hosts. /oauth/authorize, then Bearer on POST.
- Paid API key
- Issued once at /app/api after a paid seat. Stored as a hash.
- CLI login
- Same OAuth loopback, or login --token with that key.
- can()
- Workspace fence. Builder OS stays hidden unless Founder.
Authorization: Bearer <oauth-or-key>
Content-Type: application/json02 HTTP
Two envelopes. One tool list.
CLI is { tool, arguments }. MCP is JSON-RPC 2.0. Both resolve the same twenty tools and the same can().
https://mcp.agentik-os.com/api/cli
GET /api/cli- Public discovery. No secrets. Lists the same tools as MCP.
POST /api/cli- HTTPS JSON. Body is { tool, arguments }. Same can() as MCP.
GET /api/mcp- Public MCP health ping.
POST /api/mcp- JSON-RPC 2.0. tools/list or tools/call.
GET /mcp- Same health ping as GET /api/mcp.
POST /mcp- Same JSON-RPC handler as POST /api/mcp.
- 401
- Missing or dead Bearer. Finish OAuth or pass a paid key.
- 402
- Identity is valid. The seat is unpaid. No tools, no host jobs.
- 400
- Unknown tool, bad JSON, or a failed tool. Body is { ok: false, error }.
curl -s https://mcp.agentik-os.com/api/cli{
"tool": "list_os",
"arguments": {}
}curl -s -X POST https://mcp.agentik-os.com/api/cli -H "Authorization: Bearer $AGENTIK_API_KEY" -H "Content-Type: application/json" -d '{"tool":"list_os","arguments":{}}'curl -s -X POST https://mcp.agentik-os.com/api/cli -H "Authorization: Bearer $AGENTIK_API_KEY" -H "Content-Type: application/json" -d '{"tool":"list_agents","arguments":{"osId":"growth-os"}}'{
"ok": true,
"tool": "list_os",
"result": { }
}curl -s -X POST https://mcp.agentik-os.com/api/mcp -H "Authorization: Bearer $AGENTIK_API_KEY" -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_os","arguments":{}}}'03 CLI
npx @agentikos/os. Same tools. Faster path.
Credentials live in ~/.agentik/credentials.json at mode 0600. Never a shared platform key. From this repo: npm run agentik -- --help.
--base-url <url>- Default https://mcp.agentik-os.com
--home <dir>- Credential home. Default ~/.agentik
--host <name>- cursor, claude, claude-code, or all
--dry-run- Print install files. Do not write.
--skip-auth- Write install files without proving identity.
--no-browser- Print the OAuth URL only.
--plain- Machine lines. Default when stdout is not a TTY.
--json- JSON for whoami, status, os list, and call.
--arg key=value- Tool argument. Repeatable.
--json-args '{...}'- Tool arguments as JSON.
npx @agentikos/os login
npx @agentikos/os login --token <key>
npx @agentikos/os connect
npx @agentikos/os install --host all
npx @agentikos/os open
npx @agentikos/os status
npx @agentikos/os os list
npx @agentikos/os call list_os
npx @agentikos/os call list_agents --json-args '{"osId":"growth-os"}'
npx @agentikos/os whoami
npx @agentikos/os logout04 Tools
Twenty tools. Copy the call. Replace the brackets.
There is no separate workflow chat tool. A run starts through the Director, or through run_os. ask_team needs a teamId from list_agents. Guessing names fails.
Conversation
Talk first. One pack. Isolated projects. Do not tour the store.
talk- Conversation pack. One call. No store tour. Args: osId, message, optional project.
list_projects- Named projects for one OS. Isolated stores. Args: optional osId.
create_project- Open a new client or mission on that OS. Args: osId, name, optional slug.
use_project- Switch the active project. Args: osId, project.
talk({ osId: "growth-os", message: "Open one mission from product facts I already have: [facts]. Do not mobilize all 48. Stop before outreach." })
npx @agentikos/os call talk --json-args '{"osId":"growth-os","message":"What should we do first?"}'list_projects({ osId: "growth-os" })
npx @agentikos/os call list_projects --json-args '{"osId":"growth-os"}'create_project({ osId: "growth-os", name: "Client 1" })
npx @agentikos/os call create_project --json-args '{"osId":"growth-os","name":"Client 1"}'use_project({ osId: "growth-os", project: "client-1" })
npx @agentikos/os call use_project --json-args '{"osId":"growth-os","project":"client-1"}'Discovery
See the catalog only when talk is not enough.
list_os- Official OS this workspace may see. Args: none.
list_agents- Compiled roster. Only when you need a teamId. Args: osId, optional host.
list_instances- Cloud OS instances. Each row is a project. Args: none.
open_instance- Open one instance by id. Args: instanceId.
list_os()
npx @agentikos/os call list_os --json-args '{}'list_agents({ osId: "growth-os" })
npx @agentikos/os call list_agents --json-args '{"osId":"growth-os"}'list_instances()
npx @agentikos/os call list_instances --json-args '{}'open_instance({ instanceId: "<instance-id>" })
npx @agentikos/os call open_instance --json-args '{"instanceId":"<instance-id>"}'Work
Formal jobs stay blocked until approve. talk does not open a job.
run_os- Formal host job envelope. Optional instanceId. Args: osId, intent, optional instanceId.
ask_director- Formal Director job. Blocked until approve. Args: osId, prompt, optional instanceId.
ask_team- Formal specialist job. teamId from list_agents. Args: osId, prompt, teamId from list_agents.
approve- Human-gate receipt. Reset and wake wait here. Args: jobId, approved, optional note.
run_os({ osId: "growth-os", intent: "Design the next experiment from facts I already have." })
npx @agentikos/os call run_os --json-args '{"osId":"growth-os","intent":"Design the next experiment from facts I already have."}'ask_director({ osId: "growth-os", prompt: "Open one mission from product facts I already have: [facts]. Do not mobilize all 48. Stop before outreach." })
npx @agentikos/os call ask_director --json-args '{"osId":"growth-os","prompt":"Open one mission from product facts I already have."}'ask_team({ osId: "growth-os", teamId: "audience_researcher", prompt: "From these product facts, who first? Do not invent a customer." })
npx @agentikos/os call ask_team --json-args '{"osId":"growth-os","teamId":"audience_researcher","prompt":"From these product facts, who first?"}'approve({ jobId: "<job-id>", approved: true })
npx @agentikos/os call approve --json-args '{"jobId":"<job-id>","approved":true}'Objects
Page the store. Never dump it.
list_objects- Page instance objects. Never the whole store. Args: instanceId, optional cursor, limit.
get_object- Read one object payload. Args: instanceId, objectId.
put_object- Write one object. Kind from instanceContract. Args: instanceId, kind, title, payloadJson.
list_objects({ instanceId: "<instance-id>" })
npx @agentikos/os call list_objects --json-args '{"instanceId":"<instance-id>"}'get_object({ instanceId: "<instance-id>", objectId: "<object-id>" })
npx @agentikos/os call get_object --json-args '{"instanceId":"<instance-id>","objectId":"<object-id>"}'put_object({ instanceId: "<instance-id>", kind: "memo", title: "Reopen this memo", payloadJson: "{\"text\":\"facts I already have\"}" })
npx @agentikos/os call put_object --json-args '{"instanceId":"<instance-id>","kind":"memo","title":"Reopen this memo","payloadJson":"{\"text\":\"facts I already have\"}"}'Memory
Fragments persist on the instance. Forget is a real delete.
remember- Store a memory fragment on the project. Args: instanceId, scope, body, optional provenance.
recall- Page memory. talk already recalls what matters. Args: instanceId, optional query, cursor, limit.
forget- Delete one fragment. No ghost copy. Args: instanceId, fragmentId.
remember({ instanceId: "<instance-id>", scope: "work", body: "A fact that should survive the next session." })
npx @agentikos/os call remember --json-args '{"instanceId":"<instance-id>","scope":"work","body":"A fact that should survive the next session."}'recall({ instanceId: "<instance-id>" })
npx @agentikos/os call recall --json-args '{"instanceId":"<instance-id>"}'forget({ instanceId: "<instance-id>", fragmentId: "<fragment-id>" })
npx @agentikos/os call forget --json-args '{"instanceId":"<instance-id>","fragmentId":"<fragment-id>"}'Connections
Attach an app when a run needs it. The list is toolkit plus a ca_ id.
list_connections- App connections. Toolkit plus ca_ id only. Args: instanceId.
connect_app- Start an app connection. Returns an OAuth URL. Args: instanceId, toolkit.
list_connections({ instanceId: "<instance-id>" })
npx @agentikos/os call list_connections --json-args '{"instanceId":"<instance-id>"}'connect_app({ instanceId: "<instance-id>", toolkit: "gmail" })
npx @agentikos/os call connect_app --json-args '{"instanceId":"<instance-id>","toolkit":"gmail"}'Control
Overlay, reset, export, and hosted wake wait on the same gates.
overlay_patch- Private overlay. cannotOverride stays in force. Args: instanceId, patchJson.
reset_os- Blocked reset. memory, structure, or full. Args: instanceId, mode: memory | structure | full.
export_instance- Export, then optional real wipe. Args: instanceId, optional wipe.
wake_os- $199 hosted Hermes request. approve required. Args: instanceId.
overlay_patch({ instanceId: "<instance-id>", patchJson: "{\"label\":\"private overlay\"}" })
npx @agentikos/os call overlay_patch --json-args '{"instanceId":"<instance-id>","patchJson":"{\"label\":\"private overlay\"}"}'reset_os({ instanceId: "<instance-id>", mode: "memory" })
npx @agentikos/os call reset_os --json-args '{"instanceId":"<instance-id>","mode":"memory"}'export_instance({ instanceId: "<instance-id>", wipe: false })
npx @agentikos/os call export_instance --json-args '{"instanceId":"<instance-id>","wipe":false}'wake_os({ instanceId: "<instance-id>" })
npx @agentikos/os call wake_os --json-args '{"instanceId":"<instance-id>"}'05 Keys
The raw key is shown once. Convex stores a hash.
Header API opens /app/api. The store keeps a SHA-256 hash and the last four characters. POST /api/mcp and POST /api/cli accept that Bearer key. Do not put it in git or chat.