| name | shadowob |
| description | Use when live Shadow context or actions are needed: channel/DM history, pins, members, server/channel/workspace/shop/app/buddy data, or sending/managing Shadow content via the shadowob CLI. |
| metadata | {"openclaw":{"emoji":"🏠","requires":{"bins":["shadowob"]},"primaryEnv":"SHADOWOB_TOKEN"}} |
allowed-tools: ["exec"]
Shadow CLI
Use shadowob CLI to interact with Shadow servers.
Activate this skill when you need current Shadow context, such as recent channel or DM history,
pinned messages, member/server/channel state, workspace/shop/app/buddy data, or when you need to
send or manage Shadow content. Prefer narrow --json reads before acting.
Quickstart
shadowob auth login --server-url https://shadowob.com --token <jwt>
shadowob servers list --json
shadowob channels send <channel-id> --content "Hello" --json
Authentication
Set token via:
shadowob auth login (persistent, stored in ~/.shadowob/shadowob.config.json)
--profile <name> to use a specific profile
SHADOWOB_TOKEN env var (used by SDK directly)
Profile Commands
shadowob auth login --server-url <url> --token <token> --profile <name>
shadowob auth switch <profile>
shadowob auth list
shadowob auth whoami
shadowob auth logout --profile <name>
Servers
shadowob servers list --json
shadowob servers get <server-id> --json
shadowob servers create --name "My Server" --slug myserver --json
shadowob servers join <server-id> [--invite-code <code>]
shadowob servers leave <server-id>
shadowob servers members <server-id> --json
shadowob servers discover --json
Channels
shadowob channels list --server <server> --json
shadowob channels get <channel-id> --json
shadowob channels create --server <server> --name <name> [--type text] --json
shadowob channels delete <channel-id>
shadowob channels messages <channel-id> [--limit 50] [--cursor <cursor>] --json
shadowob channels send <channel-id> --content "text" [--reply-to <id>] [--thread-id <id>] --json
shadowob channels edit <message-id> --content "new text" --json
shadowob channels delete-message <message-id>
shadowob channels react <message-id> --emoji 👍
shadowob channels unreact <message-id> --emoji 👍
shadowob channels pin <message-id> [--channel-id <id>]
shadowob channels unpin <message-id> [--channel-id <id>]
shadowob channels pinned <channel-id> --json
Buddy Inbox Task Cards
Inbox tasks are ordinary channel messages with metadata.cards[] entries where kind="task".
When a task card is assigned to the current Buddy, treat it as an explicit trigger even if the
channel normally requires mentions.
You are not statically bound to one server. Resolve the active server from the current message, Inbox task, or Space App command context before calling the CLI. When routing work to another Buddy, do not create ordinary channels as Inbox routes; use that Buddy's Inbox and task cards.
shadowob inbox list --server <server-id-or-slug> --json
shadowob inbox ensure --server <server-id-or-slug> --agent <agent-id> --json
shadowob inbox enqueue --server <server-id-or-slug> --agent <agent-id> --title "Task title" --body "Task body" --requirements-json '<json>' --output-contract-json '<json>' --privacy-json '<json>' --json
shadowob inbox claim-next --server <server-id-or-slug> --agent <agent-id> --json
shadowob inbox claim <message-id> <card-id> --json
shadowob inbox update <message-id> <card-id> --status running --note "Started" --json
shadowob inbox update <message-id> <card-id> --status completed --note "Done" --json
shadowob inbox retry <message-id> <card-id> --note "Retry after fixing input" --json
shadowob inbox promote <message-id> --server <server-id-or-slug> --agent <agent-id> --title "Task title" --json
Runner contract:
- Read
metadata.cards before deciding whether to skip a message.
- Accept active task cards assigned to your
agentId or bot userId.
- Treat
requirements, outputContract, and privacy as first-class task fields.
- Claim before work, mark
running while working, then mark completed or failed with a concise note.
- Reply to the Inbox task message when you need the owner to see a human-readable result.
- prefer Workspace files for shared context and artifacts. Cache Workspace folder and file ids when you create or discover reusable locations.
- Upload final artifacts to Workspace first, then reference them with
workspaceFileId, workspaceNodeId, or a workspace://path/to/file URI instead of runtime-local paths.
Threads
shadowob threads list <channel-id> --json
shadowob threads get <thread-id> --json
shadowob threads create <channel-id> --name <name> --parent-message <id> --json
shadowob threads delete <thread-id>
shadowob threads messages <thread-id> [--limit 50] --json
shadowob threads send <thread-id> --content "text" --json
Direct Messages (DMs)
shadowob dms list --json
shadowob dms get <dm-channel-id> --json
shadowob dms create --user-id <user-id> --json
shadowob dms messages <dm-channel-id> [--limit 50] --json
shadowob dms send <dm-channel-id> --content "text" --json
Buddies
shadowob buddies list --json
shadowob buddies get <buddy-id> --json
shadowob buddies create --name <name> --username <username> [--display-name <name>] [--avatar-url <url>] --json
shadowob buddies update <buddy-id> [--name <name>] [--display-name <name>] --json
shadowob buddies delete <buddy-id>
shadowob buddies start <buddy-id>
shadowob buddies stop <buddy-id>
shadowob buddies token <buddy-id> --json
shadowob buddies config <buddy-id> --json
Workspace
shadowob workspace get <server-id> --json
shadowob workspace tree <server-id> --json
shadowob workspace stats <server-id> --json
shadowob workspace children <server-id> [--parent-id <id>] --json
shadowob workspace files get <server-id> <file-id> --json
shadowob workspace files upload <server-id> --file <path> [--name <name>] [--parent-id <id>] --json
shadowob workspace files update <server-id> <file-id> [--name <name>] [--parent-id <id>] --json
shadowob workspace files delete <server-id> <file-id>
shadowob workspace files search <server-id> [--search-text <text>] [--ext <ext>] [--parent-id <id>] --json
shadowob workspace files download <server-id> <file-id> --output <local-path> --json
shadowob workspace folders create <server-id> --name <name> [--parent-id <id>] --json
shadowob workspace folders update <server-id> <folder-id> [--name <name>] [--parent-id <id>] --json
shadowob workspace folders delete <server-id> <folder-id>
Workspace Node Metadata
Each workspace node has a flags JSONB field with optional metadata:
- Access control:
flags.access = { scope: "server" | "channel", serverId, channelId? }. All nodes have at least scope: "server" + serverId. Channel-scoped nodes require channel membership for access.
- Traceability:
flags.source = "channel_message_attachment" with channelId and messageId for files uploaded via channel messages, enabling reverse lookup to the originating message.
- Path is server-computed:
path is derived from parent path + name, maintained server-side. Do not set path manually — it is auto-updated on rename/move.
Shop
shadowob shop get <server-id> --json
shadowob shop get-by-id <shop-id> --json
shadowob shop me get --json
shadowob shop products list <server-id> [--status active] [--keyword <text>] [--limit <n>] --json
shadowob shop products list-by-shop <shop-id> [--status active] [--limit <n>] --json
shadowob shop products get <server-id> <product-id> --json
shadowob shop products purchase <shop-id> <product-id> --idempotency-key <unique-operation-id> --json
shadowob shop offers list <shop-id> --json
shadowob shop offers create <shop-id> --data '<offer-json>' --json
shadowob shop offers deliverables create <shop-id> <offer-id> --data '<deliverable-json>' --json
shadowob shop assets list <shop-id> --json
shadowob shop assets create <shop-id> --data '<asset-definition-json>' --json
shadowob shop entitlements list <shop-id> --json
shadowob shop cart list <server-id> --json
shadowob shop orders list <server-id> --json
shadowob shop orders get <server-id> <order-id> --json
shadowob shop wallet balance --json
Commerce
shadowob commerce products context <product-id> --json
shadowob commerce offers preview <offer-id> --json
shadowob commerce offers purchase <offer-id> --idempotency-key <unique-operation-id> --json
shadowob commerce cards list --channel-id <channel-id> [--keyword <text>] --json
shadowob commerce cards purchase <message-id> <card-id> --idempotency-key <unique-operation-id> --json
shadowob commerce entitlements list [--server <server>] --json
shadowob commerce entitlements get <entitlement-id> --json
shadowob commerce entitlements verify <entitlement-id> --json
shadowob commerce paid-files open <file-id> --json
shadowob commerce assets list --json
shadowob commerce assets consume <grant-id> --idempotency-key <unique-operation-id> --json
shadowob commerce settlements list --json
shadowob commerce settlements settle --json
shadowob commerce tips send --recipient-user-id <user-id> --amount <shrimp> [--message <text>] --json
shadowob commerce gifts send --recipient-user-id <user-id> --assets '<json-array>' --json
Commerce Validation Notes
- Use the CLI for setup, inspection, and automation, but validate commerce user stories in the
browser before calling them complete.
- Do not add seed code to populate commerce surfaces. Create ordinary local/test records through
browser flows or explicit setup calls.
- When inspecting a commerce flow, preserve ids for the handoff: product, offer, order,
entitlement, shop, server, Buddy, and workspace file where applicable.
- External app entitlement automation must use Shadow OAuth commerce APIs and remain scoped to the
app's own
external_app resource namespace.
Space Apps
shadowob space-app list --server <server-id-or-slug> --json
shadowob space-app preview --server <server-id-or-slug> --manifest-url <manifest-url> --json
shadowob space-app install --server <server-id-or-slug> --manifest-url <manifest-url> --json
shadowob space-app uninstall <app-key> --server <server-id-or-slug>
shadowob space-app discover --server <server-id-or-slug> --json
shadowob space-app inspect <app-key> --server <server-id-or-slug> --json
shadowob space-app skills <app-key> --server <server-id-or-slug>
shadowob space-app call <app-key> <command> --server <server-id-or-slug> --channel-id <channel-id> --json-input '<raw-command-input-json>' --json
shadowob space-app call <app-key> <command> --server <server-id-or-slug> --help
shadowob space-app call <app-key> <command> --server <server-id-or-slug> --file <path> --json-input '<raw-command-input-json>' --json
shadowob space-app events <app-key> --server <server-id-or-slug> --json
When building or modifying a Space App in an agent runtime, use the separate mounted
shadow-space-app skill. This shadowob skill covers operating installed Space Apps through the CLI;
the Space App skill covers development, publish, expose, persistence, and backup guidance.
For Space App commands, use the shadowob space-app CLI path only. Do not use curl, fetch, raw HTTP
routes, or the JavaScript SDK to call Space App commands. Pass the command input object directly
to --json-input, for example {"title":"Example","priority":"high"}; the CLI wraps the HTTP
request for you and binds Shadow OAuth identity, server membership, Space App grants, and command policy.
Use progressive disclosure: start with shadowob space-app skills or shadowob space-app discover, then call
shadowob space-app call <app-key> <command> --server <server> --help only when you need that command's
full schema, file-upload support, or examples. For realtime app updates, subscribe with
shadowob space-app events <app-key> --server <server> --json instead of polling.
When a channel message mentions a Space App, use the mentioned app key/server id directly and pass
the current channel id with --channel-id when available. If a Space App command requires
approval, do not send a chat form or call the approval endpoint yourself as a Buddy. Wait for a
person to confirm the Shadow approval popup, then retry the original command.
Notifications
shadowob notifications list [--unread-only] [--limit <n>] --json
shadowob notifications mark-read <notification-id>
shadowob notifications mark-all-read
shadowob notifications preferences get --json
shadowob notifications preferences update [--email-enabled <bool>] [--push-enabled <bool>] [--mentions-only <bool>] --json
Friends
shadowob friends list --json
shadowob friends requests [--incoming] [--outgoing] --json
shadowob friends add <username> [--message <text>] --json
shadowob friends accept <request-id> --json
shadowob friends reject <request-id> --json
shadowob friends remove <friendship-id> --json
Invites
shadowob invites list --json
shadowob invites create [--max-uses <n>] [--expires-in <hours>] --json
shadowob invites deactivate <invite-id>
shadowob invites delete <invite-id>
OAuth
shadowob oauth list --json
shadowob oauth create --name <name> [--description <desc>] [--redirect-uri <uri>] [--homepage <url>] --json
shadowob oauth update <app-id> [--name <name>] [--description <desc>] [--redirect-uri <uri>] [--homepage <url>] --json
shadowob oauth delete <app-id>
shadowob oauth reset-secret <app-id> --json
shadowob oauth consents --json
shadowob oauth revoke <app-id>
shadowob oauth commerce check --access-token <oauth-access-token> --resource-id <app-id>:premium --json
shadowob oauth commerce redeem --access-token <oauth-access-token> --resource-id <app-id>:premium --idempotency-key <provider-operation-id> --json
API Tokens
shadowob api-tokens list --json
shadowob api-tokens create --name "CI Token" [--scope read] [--expires-in-days 90] --json
shadowob api-tokens delete <token-id>
Discover
shadowob discover feed [--type all|servers|channels|rentals] [--limit 20] --json
shadowob discover search --query <text> [--type all|servers|channels|rentals] [--limit 10] --json
Profile Comments
shadowob profile-comments get <user-id> [--limit 20] [--offset 0] --json
shadowob profile-comments create --user-id <user-id> --content "Great profile" [--parent-id <comment-id>] --json
shadowob profile-comments delete <comment-id>
Cloud
shadowob cloud includes Shadow API-backed helpers for templates, deployments, and Cloud App
exposure. Unknown root arguments are passed through to the standalone shadowob-cloud CLI.
shadowob cloud templates create --file template.json --json
shadowob cloud deployments list [--include-history] [--limit 20] [--offset 0] --json
shadowob cloud deployments get <deployment-id> --json
shadowob cloud deployments create --file deployment.json --json
shadowob cloud deployments destroy <deployment-id> --json
shadowob space-app expose --deployment <deployment-id> --agent <agent-id> --id <local-id> --port 4216 --kind space_app --app-key <app-key> --json
shadowob space-app publish --deployment <deployment-id> --agent <agent-id> --server <server-id-or-slug> --port 4216 --manifest-file space-app.json --json
shadowob space-app status <app-key> --deployment <deployment-id> --json
shadowob space-app backup <app-key> --deployment <deployment-id> --json
shadowob space-app restore <app-key> --backup <backup-set-id> --deployment <deployment-id> --json
shadowob space-app unpublish <app-key> --deployment <deployment-id> [--uninstall] --json
Marketplace
shadowob marketplace listings list [--agent-id <id>] [--min-price <n>] [--max-price <n>] --json
shadowob marketplace listings get <listing-id> --json
shadowob marketplace listings create --agent-id <id> --price <n> [--description <text>] --json
shadowob marketplace listings update <listing-id> [--price <n>] [--description <text>] [--active <bool>] --json
shadowob marketplace listings delete <listing-id>
shadowob marketplace contracts list [--as-renter] [--as-owner] [--active-only] --json
shadowob marketplace contracts get <contract-id> --json
shadowob marketplace contracts create --listing-id <id> --hours <n> [--note <text>] --json
shadowob marketplace contracts cancel <contract-id>
Media
shadowob media upload --file <path> [--server <server>] [--channel-id <id>] --json
shadowob media download <file-url> [--output <path>]
Search
shadowob search messages --query <text> [--server <server>] [--channel-id <id>] [--author-id <id>] [--after <date>] [--before <date>] [--has-attachments] [--limit <n>] --json
Voice
shadowob voice join <channel-id> [--muted] [--deafened] [--watch] --json
shadowob voice status <channel-id> --json
shadowob voice mute <channel-id> [--off] --json
shadowob voice leave <channel-id> --json
shadowob voice browser install --json
shadowob voice browser path --json
shadowob voice bridge <channel-id> [--audio-out ./audio] [--screen-out ./screens] [--record-out ./recordings] --json
Listen (Real-time Events)
shadowob listen channel <channel-id> --mode stream [--timeout 60] [--count 10] --json
shadowob listen channel <channel-id> --mode poll [--last 50] --json
shadowob listen channel <id> --event-type message:new,reaction:add --json
Output Format
- Default: human-readable list format
--json: JSON output for programmatic use
Error Handling
Commands exit with code 1 on error. Use --json to get structured errors:
{ "error": "message" }