HTTPS in, same gates as MCP.
POST /api/cli is JSON. The official CLI is the faster path. One access rule answers every call: from your host, the API or the CLI. 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.
- 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.
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 tools and the same access rule.
https://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://agentik-os.com/api/cli{
"tool": "list_os",
"arguments": {}
}curl -s -X POST https://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://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
The 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 return a review link and stay blocked until you approve them in the browser. talk does not open a job.
run_os- Formal host job envelope. Optional instanceId. Args: osId, intent, optional instanceId.
ask_director- Formal Director job. Browser approval required. Args: osId, prompt, optional instanceId.
ask_team- Formal specialist job. teamId from list_agents. Args: osId, prompt, teamId from list_agents.
approve- Open browser review. This tool records no approval. 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. Browser approval 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. We store 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.