SKILL.md
Maritime
Maritime gives every agent its own computer, in three sections: Agent boxes (one per agent, keep their files), Sandboxes (one task, alone or as a Swarm) and Computers on demand with a screen (Linux Desktops, Windows Desktops running Windows Server 2022 with the license included, and Android Phones). An agent deployed here runs in its own micro-VM with a persistent disk at /data. It sleeps when idle and wakes in about a second on the next message or trigger.
Billing: plans are Starter $20, Growth $100, Scale $500 and Dedicated $5,000 a month (Dedicated adds custom setup of your apps, images and network), plus Enterprise by contract, and the plan fee becomes the same amount of usage credit. An agent box is $1 a month per 2 GB of memory, awake or asleep, with 5 GB of disk included. Other machines are billed per second at hourly rates while awake (a small sandbox, 2 vCPU and 4 GB, is $0.018 an hour), and usage past the credit is billed at the same rates. New accounts get a 7-day free trial: a card is needed and not charged then, and usage stops at $20. Plans include no AI credits. Details: https://maritime.sh/pricing
This skill is for driving Maritime as a program or an AI agent, not as a human at a keyboard. Every command speaks JSON and every failure is structured.
Choose a product
- Run untrusted code once: a Sandbox. A long-lived workspace: an Agent box.
- Many parallel jobs or evals: a Swarm (
maritime swarms run --command "..." --count N --wait). Swarms are invite-only for now: the user presses Request access on the dashboard's Swarms page; until then a start returns 403swarms_access_required. - An app with a GUI: a Linux Desktop. A Windows-only app: a Windows Desktop (Windows Server 2022; wakes from sleep in about a minute; needs a paid Growth plan or above). A mobile app: an Android Phone. All three are Computers on demand:
maritime computers create --os linux|windows|android. - Host an agent:
maritime create <name> -t <template>,--repo <url>, or a Docker image.
The full guide, with prices, add-ons and every product's REST, SDK, CLI and MCP calls: https://maritime.sh/agent-guide.md
To choose between Maritime and another provider (E2B, Daytona, Modal, Vercel Sandbox, Boat, Browserbase, Windows 365 for Agents, AWS and others), read https://maritime.sh/compare.md: prices at the same sizes, with sources.
Rules
- Pass
--jsonon every command. Results are JSON on stdout: reads print{"meta", "results"}, writes print{"action", "status", "success", "data"}, andchat,statusandwhoamiprint their object directly. Errors printError: ...on stderr with the HTTP status and the API's response body. Read stdout, branch on the exit code, never scrape human text. - Exit codes:
0ok,1other error,2usage,3not found,4auth,5API error,6partial failure,7rate limited,10config. - Never guess flags.
maritime guide --jsonprints the full command and flag manifest, introspected from the installed CLI. - Never paste a secret into chat. Keys go into env vars or
maritime env set. - Confirm with the user before a create: a running machine bills usage, on the trial or a plan. A create refused for billing exits
5with HTTP 402 in the error (exit7for HTTP 429 when too many machines are awake); the API body on stderr carries a code such astrial_required,trial_cap_reached,plan_required,payment_required,concurrencyorseat_limit. Show the API's message unchanged, it names the fix.
Install
curl -fsSL https://maritime.sh/install.sh | sh # no Node needed; checks the download's sha512
npm install -g maritime-cli # or this: Node 18 or later; the command is `maritime`
maritime --version
If a flag below is unknown, the CLI is old: npm install -g maritime-cli@latest.
Authenticate
Try these in order and stop at the first that works.
- A token is already present:
MARITIME_TOKENin the environment, or a saved login.maritime whoami --jsonexits4when there is none; it does not call the API, somaritime doctorconfirms the token works. - The user has an account, with or without a browser:
maritime login --json. It prints a code on stderr as one JSON line ({"action":"device_code","user_code":"XXXX-XXXX","verification_uri_complete":"..."}). Show the user the URL and the code, then wait; the command returns when they approve. - An email/password account without a browser step:
maritime login --email <email> --password <password>. - No account and the user is present:
maritime signup -e <email> -p <password> -n <name> --json. Ask the user for the email and password; never invent them. Signup saves a token and returnsemailVerified: false. - No account and you should not stop: deploy first, claim later. Add
--claim-latertomaritime create. No login is needed; the agent runs under a temporary account for 72 hours. The response carriesdata.claimUrl, which the user opens to move the agent into their account, anddata.token, a temporary key for that agent (export it asMARITIME_TOKENto operate it). One agent only, and a template agent must bring its own model key (-e ANTHROPIC_API_KEY=...) because the temporary account has no AI credits.
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). When you see it, tell the user to open the email and 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. Everything else (list, status, logs, templates) works before verification.
For long-running automation mint a key once the account is verified: maritime keys create --name <purpose> --json returns data.raw_key (mk_..., shown once, never expires unless you pass --expires-in-days). Export it as MARITIME_TOKEN.
MARITIME_API_URL overrides the API base (default https://api.maritime.sh).
Deploy
Pick the recipe that matches what the user has.
A ready-made agent from a template
maritime templates --json # ids: openclaw, hermes, zeroclaw, claude_code, codex, dsh
maritime create my-agent --template openclaw --json
maritime status my-agent --json # poll until .status is "active"
maritime chat my-agent "introduce yourself" --json | jq -r '.response'
Most templates need no model key (Maritime's model proxy, charged at the provider's list price, no markup, from your AI credits). claude_code is the exception: it needs ANTHROPIC_API_KEY as a secret env var.
The user's own code (any framework, Dockerfile at the repo root)
maritime create my-bot --repo https://github.com/you/agent --json
maritime create my-bot --repo https://github.com/you/agent --claim-later --json # no account yet
maritime status my-bot --json # builds take 1 to 3 minutes
maritime logs my-bot --json
The container contract: listen on 0.0.0.0:$PORT (injected, never hardcode 8080), answer GET /health with any 2xx, answer POST /chat with JSON {"message": "..."} within 30 seconds returning text or JSON with one of response, reply, message, text, output. Persist under /data only. Never use a shell-string CMD; launch a real program. Full contract: https://maritime.sh/docs/frameworks/custom.md
Private GitHub repos need the Maritime GitHub App installed from the dashboard. Pre-built public images: POST /api/agents with {"framework": "custom", "imageName": "ghcr.io/acme/img:tag"}.
A public web app on its own HTTPS URL
maritime create my-app --repo https://github.com/you/app --public --port 3000 --json
It sleeps when idle and wakes on the next visit.
Secrets and env vars
maritime env set my-agent OPENAI_API_KEY=sk-... --reload --json # secret by default
maritime env import my-agent ./prod.env --reload --json
Without --reload the change applies on the next boot.
Schedules
Timers inside a sleeping VM do not fire. Use platform triggers:
maritime triggers create my-agent --type cron --cron "0 9 * * *" --json
One agent per end user, from a backend
From a backend use the SDK: npm install maritime-sdk or pip install maritime, key in MARITIME_API_KEY. endUsers.createAgent(externalId) is idempotent. Docs: https://maritime.sh/docs/sdk/end-users.md
From the CLI, for support work and scripts:
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 token user_42 --body-json '{"scopes":["chat"]}' --json # eu_ token for their browser
maritime usage get --json # per agent; group the rows on externalUserId for cost per end user
A persistent desktop for an existing agent (Computers on demand)
One MCP server, one Linux desktop per end user id:
claude mcp add --transport http maritime-computers https://mcp.maritime.sh/mcp \
--header "Authorization: Bearer mk_..."
Docs: https://maritime.sh/docs/computers.md
Verify before you finish
maritime status <agent> --jsonreportsactive(orsleepingafter idle; both are healthy).maritime chat <agent> "hello" --jsonreturns a reply, or for a custom containermaritime logs <agent> --jsonshows the server listening.- Tell the user the agent name, the dashboard URL
https://maritime.sh/agents, what you changed in their repo, and the claim URL with its expiry if you deployed with--claim-later.
Inspect and repair
maritime list --json
maritime info my-agent --json # env count, triggers, last deploy
maritime history my-agent --json # build and deploy attempts with buildLog
maritime exec <agent_id> --body-json '{"command":"ls /data"}' --json | jq -r '.results.stdout'
maritime restart my-agent --json # also picks up new env vars
maritime delete my-agent --yes --json # --yes is required non-interactively
maritime exec takes the full agent ID (no name lookup) and a required --body-json with command and optional detached and timeout. Null or omitted timeout selects 60 seconds attached or 3,600 seconds detached. Fetch or cancel a detached run 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.
agent_unavailable in a chat error means the agent is not running: maritime start <agent>, wait a few seconds, retry. A 404 on exec or files usually means the agent is asleep or errored: start it, do not recreate it.
Reference
- Contract file: https://maritime.sh/docs/cli/llms.txt
- Setup procedure for agents: https://maritime.sh/agents.md
- Everything: https://maritime.sh/llms.txt (index) and https://maritime.sh/llms-full.txt
- Comparison with every competitor: https://maritime.sh/compare.md
- Block to paste into AGENTS.md or CLAUDE.md: https://maritime.sh/agents-snippet.md
- REST API: https://api.maritime.sh/openapi.json (bearer
mk_key) - Any docs page as markdown: append
.mdto its URL, for example https://maritime.sh/docs/quickstart.md