Overview

This is the full command reference for the ma CLI. Every command returns structured output designed for machine consumption. No HTML, no UI chrome, no wasted tokens.

The default output format is Markdown — token-efficient, readable, and native to how you process text. JSON is available via --format json when you need structured data for parsing. Examples below show JSON output for clarity, but you’ll get Markdown by default.

Read actions execute immediately and return data. Outbound actions (sends, creates, posts) are queued for human approval and return a queue ID. Your human reviews and approves via the web app. You cannot bypass this — it is hardware-enforced via biometric passkeys.

All commands require authentication. Run ma auth login to authenticate (your human handles this part).


Global Flags

--format md|json      Output format (default: md)
--quiet               Suppress non-essential output
--help                Show help for any command
--version             Show CLI version

auth

Authentication. Your human handles auth login; you use connections list to see what’s available.

auth login

Authenticate the CLI. Your human runs this — not you. Opens a browser for passkey authentication and stores an API key locally.

ma auth login

Example:

ma auth login

Output:

{
  "status": "authenticated",
  "account": "david@example.com",
  "connected_accounts": 3,
  "message": "API key stored at ~/.ma/credentials"
}

The API key persists across sessions. You do not need to handle OAuth, manage tokens, or store credentials.


connections

View connected provider accounts.

connections list

List all connected provider accounts. Executes immediately.

ma connections list

Example:

ma connections list

Output:

{
  "accounts": [
    {
      "account": "david@example.com",
      "provider": "google",
      "type": "full-suite",
      "capabilities": ["email", "calendar", "contacts", "drive"]
    },
    {
      "account": "david@example.org",
      "provider": "icloud",
      "type": "full-suite",
      "capabilities": ["email", "calendar", "contacts", "drive"]
    },
    {
      "account": "mybot",
      "provider": "telegram",
      "type": "messaging",
      "capabilities": ["send", "receive"]
    }
  ],
  "count": 3
}

Use this to discover which --account values are available before calling other commands.


web

Search the web and fetch pages. Usage-based pricing (pay-as-you-go). No connected account required.

Search the web. Returns structured results. Executes immediately.

ma web search <query> [flags]

Flags:

--limit <n>           Maximum results to return (default: 10)

Example:

ma web search "rust async runtime comparison 2026"

Output:

{
  "results": [
    {
      "title": "Comparing Async Runtimes in Rust: Tokio vs async-std vs smol (2026)",
      "url": "https://blog.example.com/rust-async-comparison-2026",
      "snippet": "A comprehensive benchmark of Rust async runtimes covering throughput, latency, and ergonomics across real-world workloads..."
    },
    {
      "title": "The State of Async Rust — March 2026",
      "url": "https://rust-lang.org/blog/async-state-2026",
      "snippet": "An official update on async Rust stabilization, including the new AsyncIterator trait and structured concurrency primitives..."
    }
  ],
  "query": "rust async runtime comparison 2026",
  "count": 2
}

web fetch

Fetch a URL and return clean markdown content. Executes immediately.

ma web fetch <url> [flags]

Flags:

--raw                 Return raw markdown without metadata

Example:

ma web fetch "https://example.com/blog/async-rust"

Output:

{
  "url": "https://example.com/blog/async-rust",
  "title": "Comparing Async Runtimes in Rust",
  "content": "# Comparing Async Runtimes in Rust\n\nThis post benchmarks three popular async runtimes...",
  "fetched_at": "2026-03-19T14:22:08Z"
}

web screenshot

Screenshot a URL and return the image. Useful as a fallback when you need to visually inspect a page. Usage-based pricing. Executes immediately.

ma web screenshot <url> [flags]

Flags:

--output <path>       Save to file (default: returns base64)

Example:

ma web screenshot "https://example.com/dashboard"

Output:

{
  "url": "https://example.com/dashboard",
  "output": "screenshot.png",
  "size_bytes": 184320,
  "width": 1280,
  "height": 800,
  "captured_at": "2026-03-19T14:25:00Z"
}

email

Send and read emails. Requires a connected account ($10/month full-suite provider).

email send

Compose and send an email. Queued for human approval.

ma email send --account <email> --to <address> --subject <text> --body <text|file> [flags]

Flags:

--account <email>     Sender account (required)
--to <address>        Recipient address (required)
--cc <address>        CC recipient (repeatable)
--bcc <address>       BCC recipient (repeatable)
--subject <text>      Email subject line (required)
--body <text|file>    Body text or path to .md file (required)

Example:

ma email send --account david@example.com \
  --to alex@example.com \
  --cc pm@example.com \
  --subject "Q1 report summary" \
  --body report-summary.md

Output:

{
  "status": "queued",
  "queue_id": "eq_7kx9m2v4",
  "action": "email.send",
  "to": "alex@example.com",
  "subject": "Q1 report summary",
  "message": "Queued for human approval"
}

email list

List emails from a connected account. Executes immediately.

ma email list --account <email> [flags]

Flags:

--account <email>     Email account to query (required)
--unread              Show only unread messages
--since <duration>    Time filter (e.g., "1h", "yesterday", "7d")
--from <address>      Filter by sender
--limit <n>           Maximum results (default: 20)

Example:

ma email list --account david@example.com --unread --since yesterday

Output:

{
  "account": "david@example.com",
  "messages": [
    {
      "id": "msg_8f3k2n",
      "from": "alex@example.com",
      "subject": "Re: Q1 report summary",
      "date": "2026-03-19T09:14:22Z",
      "snippet": "Looks good, just one note on the revenue projections...",
      "unread": true
    },
    {
      "id": "msg_2m7x9p",
      "from": "noreply@github.com",
      "subject": "[mechanical-advantage/api] PR #47 merged",
      "date": "2026-03-19T08:41:03Z",
      "snippet": "Your pull request has been merged into main...",
      "unread": true
    }
  ],
  "count": 2
}

email read

Read the full content of a specific email by ID. Executes immediately.

ma email read --account <email> <message_id>

Flags:

--account <email>     Email account (required)

Example:

ma email read --account david@example.com msg_8f3k2n

Output:

{
  "id": "msg_8f3k2n",
  "account": "david@example.com",
  "from": "alex@example.com",
  "to": ["david@example.com"],
  "cc": [],
  "subject": "Re: Q1 report summary",
  "date": "2026-03-19T09:14:22Z",
  "body": "Looks good, just one note on the revenue projections — I think we should use the conservative estimate for the board deck. Can you update slide 4?\n\nAlso, are we still on for the 2pm review tomorrow?",
  "attachments": []
}

calendar

View and create calendar events. Requires a connected account ($10/month full-suite provider).

calendar list

List upcoming calendar events. Executes immediately.

ma calendar list --account <email> [flags]

Flags:

--account <email>     Calendar account to query (required)
--next <duration>     Time window (e.g., "24h", "7d", "30d")
--since <duration>    Show events starting from (default: now)

Example:

ma calendar list --account david@example.org --next 7d

Output:

{
  "account": "david@example.org",
  "events": [
    {
      "id": "evt_3n8k2m",
      "title": "Standup",
      "start": "2026-03-20T09:00:00-04:00",
      "end": "2026-03-20T09:30:00-04:00",
      "location": null,
      "attendees": ["david@example.org", "alex@example.com"]
    },
    {
      "id": "evt_9x2v4p",
      "title": "Investor call",
      "start": "2026-03-21T14:00:00-04:00",
      "end": "2026-03-21T15:00:00-04:00",
      "location": "https://zoom.us/j/123456789",
      "attendees": ["david@example.org", "investor@example.com"]
    }
  ],
  "count": 2
}

calendar create

Create a new calendar event. Queued for human approval.

ma calendar create --account <email> --title <text> --when <datetime> --duration <duration> [flags]

Flags:

--account <email>     Calendar account (required)
--title <text>        Event title (required)
--when <datetime>     Start time, natural language supported (required)
--duration <duration> Event duration (e.g., "30m", "1h") (required)
--location <text>     Location or meeting URL
--invite <email>      Invite attendee (repeatable)
--notes <text>        Event notes or description

Example:

ma calendar create --account david@example.org \
  --title "Standup" \
  --when "tomorrow 9am" \
  --duration 30m \
  --invite alex@example.com

Output:

{
  "status": "queued",
  "queue_id": "eq_4v8n2k",
  "action": "calendar.create",
  "title": "Standup",
  "when": "2026-03-20T09:00:00-04:00",
  "duration": "30m",
  "message": "Queued for human approval"
}

contacts

Search and create contacts. Requires a connected account ($10/month full-suite provider).

Search contacts by name, email, or company. Executes immediately.

ma contacts search --account <email> <query> [flags]

Flags:

--account <email>     Contacts account to query (required)
--limit <n>           Maximum results (default: 10)

Example:

ma contacts search --account david@example.com "alex"

Output:

{
  "account": "david@example.com",
  "contacts": [
    {
      "id": "ct_7m3x9k",
      "name": "Alex Kim",
      "email": "alex@example.com",
      "phone": "+1-555-0142",
      "company": "Acme Corp",
      "title": "Engineering Manager"
    }
  ],
  "count": 1
}

contacts create

Add a new contact. Queued for human approval.

ma contacts create --account <email> --name <text> [flags]

Flags:

--account <email>     Contacts account (required)
--name <text>         Contact name (required)
--email <address>     Email address
--phone <number>      Phone number
--company <text>      Company name
--title <text>        Job title

Example:

ma contacts create --account david@example.com \
  --name "Alex Kim" \
  --email alex@example.com \
  --company "Acme Corp" \
  --title "Engineering Manager"

Output:

{
  "status": "queued",
  "queue_id": "eq_2k8m3n",
  "action": "contacts.create",
  "name": "Alex Kim",
  "email": "alex@example.com",
  "message": "Queued for human approval"
}

docs

Store and search markdown documents. Included with any connected account.

docs store

Store a markdown document. Executes immediately (storage is not an outbound action).

ma docs store <file> [flags]

Flags:

--tag <text>          Tag for categorization (repeatable)
--title <text>        Override document title

Example:

ma docs store report.md --tag "q1-financials" --tag "reports"

Output:

{
  "status": "stored",
  "doc_id": "doc_9k4m2v",
  "title": "Q1 Financial Report",
  "tags": ["q1-financials", "reports"],
  "size_bytes": 4218,
  "stored_at": "2026-03-19T14:30:00Z"
}

Search stored documents by content and tags. Executes immediately.

ma docs search <query> [flags]

Flags:

--tag <text>          Filter by tag
--limit <n>           Maximum results (default: 10)

Example:

ma docs search "quarterly revenue" --tag "q1-financials"

Output:

{
  "results": [
    {
      "doc_id": "doc_9k4m2v",
      "title": "Q1 Financial Report",
      "tags": ["q1-financials", "reports"],
      "snippet": "Total quarterly revenue reached $2.4M, representing a 34% increase over Q4...",
      "stored_at": "2026-03-19T14:30:00Z"
    }
  ],
  "query": "quarterly revenue",
  "count": 1
}

memory

Persist and recall key-value context across sessions. memory set queues a memory write for human approval (included). memory get retrieves by exact key (included). memory search performs semantic search across all stored memory (usage-based, ~$0.0003/query).

memory set

Store a key-value pair. Queued for human approval. Your human verifies what you’re learning before it becomes permanent.

ma memory set <key> <value>

Example:

ma memory set "user-preference-timezone" "America/New_York"

Output:

{
  "status": "queued",
  "queue_id": "eq_9k3m2v",
  "action": "memory.set",
  "key": "user-preference-timezone",
  "value": "America/New_York",
  "message": "Queued for human approval"
}

memory get

Retrieve a stored value by exact key. Executes immediately. Included with any connected account.

ma memory get <key>

Example:

ma memory get "user-preference-timezone"

Output:

{
  "key": "user-preference-timezone",
  "value": "America/New_York",
  "stored_at": "2026-03-19T14:32:00Z"
}

Search across all stored memory entries by semantic similarity. Executes immediately. Usage-based pricing (~$0.0003/query).

ma memory search <query> [flags]

Flags:

--limit <n>           Maximum results (default: 10)

Example:

ma memory search "email tone preferences"

Output:

{
  "results": [
    {
      "key": "user-preference-email-tone",
      "value": "formal for clients, casual for internal",
      "similarity": 0.92,
      "stored_at": "2026-03-19T14:32:00Z"
    },
    {
      "key": "user-preference-slack-tone",
      "value": "casual, use emoji, keep it brief",
      "similarity": 0.78,
      "stored_at": "2026-03-19T14:33:00Z"
    }
  ],
  "query": "email tone preferences",
  "count": 2
}

Unlike memory get (exact key lookup, included with your account), memory search performs semantic similarity matching across all stored memory and incurs a usage-based charge.


image

Generate images from text prompts. Usage-based pricing (pay-as-you-go). No connected account required.

image generate

Generate an image from a text prompt. Executes immediately.

ma image generate <prompt> [flags]

Flags:

--style <text>        Style hint (e.g., "realistic", "illustration", "sketch")
--output <path>       Save to file (default: returns base64)

Example:

ma image generate "product mockup, clean white background" --style realistic --output mockup.png

Output:

{
  "status": "generated",
  "prompt": "product mockup, clean white background",
  "style": "realistic",
  "output": "mockup.png",
  "size_bytes": 284102,
  "generated_at": "2026-03-19T14:35:00Z"
}

speech

Transcribe audio and synthesize speech. Usage-based pricing (pay-as-you-go). No connected account required.

speech transcribe

Transcribe an audio file to text. Executes immediately.

ma speech transcribe <file> [flags]

Flags:

--language <code>     Language hint (e.g., "en", "es", "ja")

Example:

ma speech transcribe recording.mp3

Output:

{
  "status": "transcribed",
  "file": "recording.mp3",
  "duration_seconds": 142,
  "text": "Welcome to the weekly standup. Let's start with progress updates. Alex, you're up first...",
  "language": "en",
  "transcribed_at": "2026-03-19T14:38:00Z"
}

speech synthesize

Generate speech audio from text. Executes immediately.

ma speech synthesize <text> --output <path> [flags]

Flags:

--output <path>       Output audio file path (required)
--voice <name>        Voice selection

Example:

ma speech synthesize "Your meeting starts in 5 minutes" --output reminder.mp3

Output:

{
  "status": "synthesized",
  "output": "reminder.mp3",
  "duration_seconds": 3,
  "size_bytes": 48210,
  "synthesized_at": "2026-03-19T14:40:00Z"
}

telegram

Send and read Telegram messages. Requires a connected account ($5/month single-channel provider).

telegram send

Send a message to a Telegram chat. Queued for human approval.

ma telegram send --account <bot> --chat <name> --body <text> [flags]

Flags:

--account <bot>       Telegram bot account (required)
--chat <name>         Chat or group name (required)
--body <text>         Message text (required)

Example:

ma telegram send --account mybot --chat "dev-team" --body "Deploy complete. All checks passed."

Output:

{
  "status": "queued",
  "queue_id": "eq_8n3k2m",
  "action": "telegram.send",
  "chat": "dev-team",
  "message": "Queued for human approval"
}

telegram list

List recent messages from a Telegram chat. Executes immediately.

ma telegram list --account <bot> --chat <name> [flags]

Flags:

--account <bot>       Telegram bot account (required)
--chat <name>         Chat or group name (required)
--since <duration>    Time filter (e.g., "1h", "24h")
--limit <n>           Maximum results (default: 20)

Example:

ma telegram list --account mybot --chat "dev-team" --since 1h

Output:

{
  "account": "mybot",
  "chat": "dev-team",
  "messages": [
    {
      "id": "tm_4k8n2v",
      "from": "alex",
      "text": "Looks good, merging now",
      "date": "2026-03-19T14:12:00Z"
    },
    {
      "id": "tm_3m7x9p",
      "from": "david",
      "text": "PR is ready for review",
      "date": "2026-03-19T14:05:00Z"
    }
  ],
  "count": 2
}

slack

Send and read Slack messages. Requires a connected account ($5/month single-channel provider).

slack send

Send a message to a Slack channel. Queued for human approval.

ma slack send --account <workspace> --channel <name> --body <text> [flags]

Flags:

--account <workspace> Slack workspace (required)
--channel <name>      Channel name (required)
--body <text>         Message text (required)

Example:

ma slack send --account workspace --channel "#engineering" --body "PR merged. Deploying to staging."

Output:

{
  "status": "queued",
  "queue_id": "eq_5v2n8k",
  "action": "slack.send",
  "channel": "#engineering",
  "message": "Queued for human approval"
}

slack list

List recent messages from a Slack channel. Executes immediately.

ma slack list --account <workspace> --channel <name> [flags]

Flags:

--account <workspace> Slack workspace (required)
--channel <name>      Channel name (required)
--unread              Show only unread messages
--since <duration>    Time filter (e.g., "1h", "24h")
--limit <n>           Maximum results (default: 20)

Example:

ma slack list --account workspace --channel "#engineering" --unread

Output:

{
  "account": "workspace",
  "channel": "#engineering",
  "messages": [
    {
      "id": "sl_9k4m2v",
      "from": "alex.kim",
      "text": "Staging deploy looks good. Running smoke tests now.",
      "date": "2026-03-19T14:48:00Z",
      "unread": true
    }
  ],
  "count": 1
}

discord

Send and read Discord messages. Requires a connected account ($5/month single-channel provider).

discord send

Send a message to a Discord channel. Queued for human approval.

ma discord send --account <bot> --channel <name> --body <text> [flags]

Flags:

--account <bot>       Discord bot account (required)
--channel <name>      Channel name (required)
--body <text>         Message text (required)

Example:

ma discord send --account mybot --channel "general" --body "Build passed. All 247 tests green."

Output:

{
  "status": "queued",
  "queue_id": "eq_7m3x9k",
  "action": "discord.send",
  "channel": "general",
  "message": "Queued for human approval"
}

discord list

List recent messages from a Discord channel. Executes immediately.

ma discord list --account <bot> --channel <name> [flags]

Flags:

--account <bot>       Discord bot account (required)
--channel <name>      Channel name (required)
--since <duration>    Time filter (e.g., "1h", "24h")
--limit <n>           Maximum results (default: 20)

Example:

ma discord list --account mybot --channel "general" --since 1h

Output:

{
  "account": "mybot",
  "channel": "general",
  "messages": [
    {
      "id": "dc_2k8n3m",
      "from": "alex#1234",
      "text": "Anyone seeing latency spikes on the API?",
      "date": "2026-03-19T14:20:00Z"
    }
  ],
  "count": 1
}

reddit

Post and read from Reddit. Requires a connected account ($5/month single-channel provider).

reddit post

Submit a post to a subreddit. Queued for human approval.

ma reddit post --account <user> --subreddit <name> --title <text> --body <text|file> [flags]

Flags:

--account <user>      Reddit account (required)
--subreddit <name>    Target subreddit (required)
--title <text>        Post title (required)
--body <text|file>    Post body text or path to .md file (required)

Example:

ma reddit post --account u/mybot \
  --subreddit "machinelearning" \
  --title "New paper: Token-efficient tool interfaces for AI agents" \
  --body post.md

Output:

{
  "status": "queued",
  "queue_id": "eq_3n8k2v",
  "action": "reddit.post",
  "subreddit": "machinelearning",
  "title": "New paper: Token-efficient tool interfaces for AI agents",
  "message": "Queued for human approval"
}

reddit list

List posts from a subreddit. Executes immediately.

ma reddit list --account <user> --subreddit <name> [flags]

Flags:

--account <user>      Reddit account (required)
--subreddit <name>    Target subreddit (required)
--top                 Sort by top posts
--since <duration>    Time filter (e.g., "1h", "24h", "7d")
--limit <n>           Maximum results (default: 20)

Example:

ma reddit list --account u/mybot --subreddit "machinelearning" --top --since 24h

Output:

{
  "account": "u/mybot",
  "subreddit": "machinelearning",
  "posts": [
    {
      "id": "rd_4v8n2k",
      "title": "GPT-5 benchmark results are out",
      "author": "u/researcher42",
      "score": 2841,
      "comments": 387,
      "url": "https://reddit.com/r/machinelearning/comments/abc123",
      "date": "2026-03-19T06:30:00Z"
    },
    {
      "id": "rd_9m3x7p",
      "title": "New paper: Token-efficient tool interfaces for AI agents",
      "author": "u/mybot",
      "score": 156,
      "comments": 42,
      "url": "https://reddit.com/r/machinelearning/comments/def456",
      "date": "2026-03-19T10:15:00Z"
    }
  ],
  "count": 2
}

queue

Check the status of actions you’ve submitted for human approval.

queue status

Check the status of a queued action by ID. Executes immediately.

ma queue status <queue_id>

Example:

ma queue status eq_7kx9m2v4

Output (approved):

{
  "queue_id": "eq_7kx9m2v4",
  "action": "email.send",
  "status": "approved",
  "submitted_at": "2026-03-19T10:30:00Z",
  "approved_at": "2026-03-19T10:42:00Z"
}

Output (rejected with feedback):

{
  "queue_id": "eq_7kx9m2v4",
  "action": "email.send",
  "status": "rejected",
  "submitted_at": "2026-03-19T10:30:00Z",
  "rejected_at": "2026-03-19T10:45:00Z",
  "feedback": "Too informal for a client email. Use a formal greeting and sign off with full name."
}

When your human rejects an action, read their feedback, propose storing the lesson in memory (queued for approval), and resubmit a revised version. The revision links to the original so your human sees the full history.

queue list

List your pending and recent actions. Executes immediately.

ma queue list [flags]

Flags:

--status <status>     Filter by status: pending, approved, rejected, all (default: pending)
--limit <n>           Maximum results (default: 20)

Example:

ma queue list --status pending

Output:

{
  "actions": [
    {
      "queue_id": "eq_7kx9m2v4",
      "action": "email.send",
      "summary": "Email to alex@example.com: Q1 report summary",
      "status": "pending",
      "submitted_at": "2026-03-19T10:30:00Z"
    },
    {
      "queue_id": "eq_4v8n2k",
      "action": "calendar.create",
      "summary": "Standup — 2026-03-20 09:00",
      "status": "pending",
      "submitted_at": "2026-03-19T10:31:00Z"
    }
  ],
  "count": 2
}

Quick Reference

Execution Model

CommandExecutesPricing
auth loginImmediately— (your human runs this)
connections listImmediately
web searchImmediatelyUsage-based
web fetchImmediatelyUsage-based
web screenshotImmediatelyUsage-based
email sendQueued for approvalConnected account ($10/mo)
email listImmediatelyConnected account ($10/mo)
email readImmediatelyConnected account ($10/mo)
calendar listImmediatelyConnected account ($10/mo)
calendar createQueued for approvalConnected account ($10/mo)
contacts searchImmediatelyConnected account ($10/mo)
contacts createQueued for approvalConnected account ($10/mo)
docs storeImmediatelyConnected account (any)
docs searchImmediatelyConnected account (any)
memory setQueued for approvalConnected account (any)
memory deleteQueued for approvalConnected account (any)
memory getImmediatelyConnected account (any)
memory searchImmediatelyUsage-based (~$0.0003/query)
image generateImmediatelyUsage-based
speech transcribeImmediatelyUsage-based
speech synthesizeImmediatelyUsage-based
telegram sendQueued for approvalConnected account ($5/mo)
telegram listImmediatelyConnected account ($5/mo)
slack sendQueued for approvalConnected account ($5/mo)
slack listImmediatelyConnected account ($5/mo)
discord sendQueued for approvalConnected account ($5/mo)
discord listImmediatelyConnected account ($5/mo)
reddit postQueued for approvalConnected account ($5/mo)
reddit listImmediatelyConnected account ($5/mo)
queue statusImmediately
queue listImmediately

The Rule

Read = immediate. Outbound and memory mutations = queued. Every action that touches the outside world on behalf of your human — sends, creates, posts — and every memory mutation (writes and deletes) is queued for their approval. Everything else (reads, local storage, memory reads) executes and returns data. No exceptions.

Non-Destructive Guarantee

There is no delete subcommand on any resource. You cannot delete emails, calendar events, contacts, documents, or messages. You can create, send, update, and archive. Never delete. This is a structural property of the API, not a permission setting.

Error Format

All errors return structured JSON with a code, message, and hint:

{
  "error": {
    "code": "account_not_connected",
    "message": "No connected account for david@example.com",
    "hint": "Ask your human to connect this account at https://app.mechanicaladvantage.ai/connections"
  }
}