llms.txt

Maritime CLI: instructions for AI agents

Copy this file into your agent's context (CLAUDE.md, AGENTS.md, or a system prompt), or let the agent fetch it from https://maritime.sh/docs/cli/llms.txt. It teaches an LLM to operate Maritime (https://maritime.sh): every computer an agent needs (sandboxes, Linux and Windows desktops, Android phones). Agents deployed here run in persistent micro-VMs with storage at /data; they sleep when idle and wake in about a second on the next message or trigger. Billing: plans from $20 a month, and the plan fee becomes usage credit; machines are billed per second at hourly rates, with a 7-day free trial (card needed, usage capped at $20). Details: https://maritime.sh/pricing

The CLI describes itself offline: maritime guide prints its usage guide, and maritime guide --json emits the full command and flag manifest, introspected live from the installed CLI. Prefer that manifest, and maritime <command> --help, over guessing flags. --dry-run on any command prints the HTTP request without sending it.

Setup

  1. Install: curl -fsSL https://maritime.sh/install.sh | sh (no Node needed; it checks the download's sha512), or npm install -g maritime-cli (the npm package is maritime-cli; the command is maritime; needs Node 18+. If a flag below is unknown, run npm install -g maritime-cli@latest)
  2. Authenticate, first path that works wins:
    • New user, or no plan yet: maritime onboard --json. It prints one JSON object whose step names what the user must do: sign_in (give them sign_in.url and sign_in.code), checkout (give them checkout_url: the 7-day free trial in Stripe Checkout, card required, nothing charged for 7 days) or billing_action (give them billing_url). After each step run maritime onboard --wait --json, until step is done. Do this before you build anything: no machine starts without a plan or the trial.
    • MARITIME_TOKEN in the environment (an mk_ key or a login token); the CLI reads it before anything else.
    • Any account, browser or not: maritime login --json prints one JSON line on stderr with user_code and verification_uri_complete; show both to the user and wait for their approval in any signed-in browser.
    • Email/password account, no browser: maritime login --email --password
    • No account, user present: maritime signup -e -p -n --json (ask the user for the email and password; never invent them)
    • No account, do not stop: add --claim-later to maritime create. No login needed; the agent runs under a temporary account for 72 hours. The JSON response carries data.claimUrl (the user opens it to keep the agent) and data.token (a temporary key for that agent; export it as MARITIME_TOKEN to operate it). One agent only; template agents must bring their own model key (-e ANTHROPIC_API_KEY=...).
  3. Verify: maritime whoami --json prints {authenticated, source, method, expires_at} and exits 4 when no credential is set or a login token expired. It does not call the API, so a wrong mk_ key still reports authenticated; maritime doctor checks it.
  4. The email verification wall: until the user clicks the link Maritime emailed them, create, deploy, start, restart, keys create, and computer creation are refused with HTTP 403 and email_not_verified in the error (exit 4). Ask the user to click the link. To get it again they sign in at https://maritime.sh/login, which offers to resend it. Then retry the same command. List, status, logs, and templates work before verification.
  5. Long-running automation: once verified, mint a key that never expires: maritime keys create --name my-agent --json (data.raw_key is shown once), and export MARITIME_TOKEN=mk_...

Full setup procedure, step by step: https://maritime.sh/agents.md

MARITIME_API_URL overrides the API base (default https://api.maritime.sh).

The contract

Core tasks

Discover templates, create an agent, wait for it, talk to it:

maritime templates --json maritime create my-agent --template openclaw --json maritime status my-agent --json # wait for "active" maritime chat my-agent "introduce yourself" --json | jq -r '.response'

No account yet and nobody to ask: deploy now, claim later (72 h, 1 agent):

maritime create my-bot --repo https://github.com/you/agent --claim-later --json

Deploy your own code (any framework; Dockerfile at the repo root):

maritime create my-bot --json maritime deploy my-bot --source github --repo https://github.com/you/agent --branch main --wait --json

Serve a repo on a public no-login URL (sleeps idle, wakes on the next visit):

maritime create my-app --repo https://github.com/you/app --public --port 3000 --json

Encrypted env vars (secret by default; --reload pushes into the running agent):

maritime env set my-agent OPENAI_API_KEY=sk-... --reload --json maritime env import my-agent ./prod.env --reload --json maritime env list my-agent --json

Inspect and debug:

maritime list --json maritime logs my-agent --level error --json maritime info my-agent --json maritime history my-agent --json # build/deploy attempts + buildLog maritime exec --body-json '{"command":"ls /data"}' --json | jq -r '.results.stdout'

Message an agent AS one of your end users (sticky per-user routing through the project front door; same --user always reaches the same instance):

maritime message my-agent --user cust_42 "where is my order?" --json | jq -r '.data.reply'

Your end users (the people your product serves), each with their own agent:

(end-users, alias users; bodies go in --body-json, fields as in the REST API)

maritime users upsert user_42 --display-name "Ada" --tags pro --json # safe on every sign-in maritime users create user_42 --body-json '{"templateId":"openclaw"}' --json # their agent, exactly once maritime users set-policy user_42 --body-json '{"policy":{"llm_spend_cap_cents_per_month":500}}' --json maritime users policy user_42 --json # read; clear-policy removes it maritime users token user_42 --body-json '{"scopes":["chat"],"ttlSeconds":900}' --json # eu_ token maritime users list --json · get · agents · suspend · resume · delete maritime usage get --from 2026-09-01 --to 2026-10-01 --json # per agent, each row has externalUserId maritime usage daily --json # per day

Lifecycle (rarely needed; agents sleep and wake on their own):

maritime start my-agent --json maritime sleep my-agent --json maritime restart my-agent --json # also picks up new env vars maritime delete my-agent --yes --json # --yes is REQUIRED non-interactively

Scheduling

Timers inside a sleeping agent do not fire. Put scheduled work on platform triggers: maritime triggers list , and maritime triggers create --type cron --cron "0 9 * * *" --prompt "...". A cron trigger wakes the agent and delivers --prompt as a message on each fire. A custom container can instead serve GET /schedules and Maritime registers the wakes for it. Details: https://maritime.sh/docs/triggers

maritime exec takes the full agent ID and a required --body-json: {"command": "..." or ["argv", ...], "detached": false, "timeout": 60}. Words after the agent ID are not sent. timeout defaults to 60 seconds attached or 3,600 seconds detached. A detached call returns executionId at once; fetch or cancel it through the REST API: https://maritime.sh/docs/api#exec On agents with detached support, disconnecting does not cancel execution. Do not repeat submission after a lost response without accounting for a command that may already be running. Older agents support attached exec with combined output and no execution ID. Detached submission on those agents returns HTTP 501 with unsupported: outdated vm. Please use a new agent. Use a new agent for detached execution. Restarting an older agent does not add this feature.

Gotchas

Something wrong with these docs?

If a command, flag or example here does not match what the CLI does, or a call fails and the error does not tell you what to do, tell Maritime. Any mk_ key works. Put the X-Request-Id of the failing call in requestId when there is one and name yourself in tool. Never include keys, tokens or env values.

curl -X POST https://api.maritime.sh/api/v1/feedback
-H "Authorization: Bearer $MARITIME_API_KEY"
-H "Content-Type: application/json"
-d '{"kind":"cli","subject":"maritime env set","message":"","tool":"claude-code/2.1.0"}'

kind is one of docs, sdk, api, cli, computers, dashboard, other. Capped at 5 reports a minute and 20 a day per account. Reference: https://maritime.sh/docs/sdk/feedback