Skip to content

Latest commit

 

History

History
615 lines (419 loc) · 13.1 KB

File metadata and controls

615 lines (419 loc) · 13.1 KB

Miru CLI

Overview

Miru CLI is the command-line interface for Miru.

For MCP server/client setup and AI-agent integration, see Miru MCP Server and Client.

It is intended to work equally well for:

  • humans working in a terminal
  • shell scripts and automation
  • AI agents acting on behalf of a user

The CLI does not have a separate permission model. Every command runs with the same access and scoping rules as the authenticated Miru user.

Install

Hosted or public install

curl -fsSL https://raw.githubusercontent.com/saeloun/miru-web/main/tools/miru-cli/install.sh | bash

This installs miru into ~/.local/bin/miru using mise and Go 1.24.1.

Local development install

From the repo:

cd tools/miru-cli
mise exec -- env GOBIN="$HOME/.local/bin" go install ./cmd/miru

Requirements

  • mise
  • a Miru user account
  • access to a Miru instance, hosted or self-hosted

Authentication

Log in with email and password:

miru login --email user@example.com --password your-password

By default this uses:

https://app.miru.so

For local or self-hosted Miru:

miru login --base-url http://127.0.0.1:9000 --email user@example.com --password your-password
miru config set-base-url --url http://127.0.0.1:9000

Session behavior

  • The CLI stores its session in ~/.config/miru/config.json
  • The token is a dedicated CLI bearer token, not the user’s main app token
  • The session lasts 7 days
  • Every successful CLI request refreshes the expiry for another 7 days
  • miru logout revokes the server-side CLI session and removes local credentials

Config

The local config file lives at:

~/.config/miru/config.json

Current shape:

{
  "base_url": "https://app.miru.so",
  "token": "..."
}

Config commands

Show current config:

miru config show

Print current CLI token (for MCP/client setup):

miru config token
miru config token --format shell

Set a different Miru instance:

miru config set-base-url --url http://127.0.0.1:9000

Use CLI Token With MCP Clients

Miru MCP uses the same authenticated CLI token. There is no separate MCP login flow.

Export the active CLI token:

export MIRU_CLI_TOKEN="$(miru config token)"

For tools that expect shell assignment format:

miru config token --format shell

Example MCP config (Codex):

[mcp_servers.miru]
url = "https://app.miru.so/mcp"
bearer_token_env_var = "MIRU_CLI_TOKEN"

For stdio mode from this repo:

cd /path/to/miru-web
MIRU_MCP_TOKEN="$MIRU_CLI_TOKEN" bin/miru-mcp

See Miru MCP Server and Client for protocol details, Pro gating, and tool schemas.

Command Reference

Global

miru help

Shows the available command surface.

miru version

Prints the installed CLI version.

miru capabilities

Shows the current supported command set as JSON.

miru whoami

Fetches the current authenticated user and workspace.

miru logout

Revokes the CLI session and removes local credentials.

miru upgrade

Upgrades the CLI.

Behavior:

  • when run from a local Miru checkout, it upgrades from that checked-out repo
  • otherwise it upgrades from github.com/saeloun/miru-web/tools/miru-cli/cmd/miru@latest

Project Commands

miru project list

Lists projects visible to the authenticated user.

Options:

  • --search <term> filters projects by search term

Examples:

miru project list
miru project list --search solar

Use this command to find the project_id required by miru time create and miru time update.

Client Commands

miru client list

Lists clients visible to the authenticated user.

Options:

  • --query <term> optional search term

Examples:

miru client list
miru client list --query solar

Expense Commands

miru expense list

Lists expenses visible to the authenticated user.

The response also includes vendors and categories, which provide the ids needed for miru expense create.

Options:

  • --query <term> optional search term

Examples:

miru expense list
miru expense list --query travel

miru expense create

Creates an expense in the current workspace.

Options:

  • --amount <amount> required
  • --date <YYYY-MM-DD> required
  • --category-id <id> required
  • --vendor-id <id> optional
  • --description <text> optional
  • --type <business|personal> optional, defaults to business

Examples:

miru expense create --amount 42.25 --date 2026-03-09 --category-id 3 --description "Lunch with client"
miru expense create --amount 125.50 --date 2026-03-09 --category-id 3 --vendor-id 2 --type business

Time Commands

miru time list

Lists the authenticated user’s timesheet entries for a date range.

Options:

  • --from <YYYY-MM-DD>
  • --to <YYYY-MM-DD>

Example:

miru time list --from 2026-03-01 --to 2026-03-09

miru time create

Creates a timesheet entry for the authenticated user.

Options:

  • --project-id <id> required
  • --duration <minutes> required
  • --date <YYYY-MM-DD> required
  • --note <text> optional
  • --bill-status <status> optional, defaults to unbilled

Example:

miru time create \
  --project-id 2 \
  --duration 90 \
  --date 2026-03-09 \
  --note "Worked on invoice flow" \
  --bill-status unbilled

Example prompt for daily Jira-to-Miru drafting:

Pull all work I did in Jira today, summarize it hour by hour when the issue history supports that, or collapse it into one full-day summary when it does not. Use `miru project list` to find the best matching Miru project, then draft the exact `miru time create` commands I should run. Do not submit anything until I approve the draft.

If you want the agent to submit after review, use:

Pull all work I did in Jira today, summarize it hour by hour when the issue history supports that, or collapse it into one full-day summary when it does not. Match each block to the best Miru project, show me the draft first, and only after I approve it run the `miru time create` commands.

miru time update

Updates one of the authenticated user’s own timesheet entries.

Options:

  • --id <id> required
  • --project-id <id> required
  • --duration <minutes> required
  • --date <YYYY-MM-DD> required
  • --note <text> optional
  • --bill-status <status> optional, defaults to unbilled

Example:

miru time update \
  --id 631 \
  --project-id 2 \
  --duration 45 \
  --date 2026-03-09 \
  --note "Adjusted after review"

miru time delete

Deletes one of the authenticated user’s own timesheet entries.

Options:

  • --id <id> required

Example:

miru time delete --id 631

Invoice Commands

miru invoice list

Lists invoices visible to the authenticated user.

Options:

  • --query <term> search term
  • --page <page> pagination page
  • --per <count> page size
  • --status <status> invoice status filter

Examples:

miru invoice list
miru invoice list --status draft
miru invoice list --query INV0001 --page 1 --per 20

miru invoice show

Shows one invoice in detail.

Options:

  • --id <id> required

Example:

miru invoice show --id 1

miru invoice create

Creates a draft invoice with one or more line items.

Options:

  • --client-id <id> required
  • --invoice-number <number> required
  • --issue-date <YYYY-MM-DD> required
  • --due-date <YYYY-MM-DD> required
  • --line-item <name|description|YYYY-MM-DD|rate|minutes> required unless --line-items-json or --payload-file is used
  • --line-items-json <json> optional JSON array for advanced line-item payloads
  • --payload-file <path> optional full invoice JSON payload; the file may contain either { "invoice": { ... } } or the invoice object
  • --currency <code> optional
  • --reference <text> optional
  • --status <status> optional, defaults to draft
  • --discount <amount> optional
  • --tax <amount> optional
  • --tax-configuration-id <id> optional and repeatable
  • --stripe-enabled <true|false> optional

Examples:

miru invoice create \
  --client-id 2 \
  --invoice-number INV-CLI-001 \
  --issue-date 2026-05-19 \
  --due-date 2026-06-18 \
  --currency USD \
  --line-item "Implementation|API work|2026-05-19|150|120"

For generated or agent-authored invoices, a payload file is usually cleaner:

{
  "invoice": {
    "client_id": 2,
    "invoice_number": "INV-CLI-002",
    "issue_date": "2026-05-19",
    "due_date": "2026-06-18",
    "status": "draft",
    "invoice_line_items_attributes": [
      {
        "name": "Implementation",
        "description": "API work",
        "date": "2026-05-19",
        "rate": 150,
        "quantity": 120
      }
    ]
  }
}
miru invoice create --payload-file invoice.json

miru invoice send

Sends an invoice email.

Options:

  • --id <id> required
  • --recipients <email1,email2> required, comma-separated
  • --subject <text> optional
  • --message <text> optional

Example:

miru invoice send \
  --id 1 \
  --recipients client@example.com,finance@example.com \
  --subject "Your invoice from Miru" \
  --message "Please review and pay online."

Payment Commands

miru payment list

Lists payments visible to the authenticated user.

Options:

  • --query <term> optional search term

Examples:

miru payment list
miru payment list --query INV0003

miru payment show

Shows one payment.

Options:

  • --id <id> required

Example:

miru payment show --id 1

Common Workflows

Check current identity

miru whoami

Find a project id, then create time

miru project list --search solar
miru time create --project-id 2 --duration 30 --date 2026-03-09 --note "CLI entry"

Correct a time entry

miru time list --from 2026-03-09 --to 2026-03-09
miru time update --id 631 --project-id 2 --duration 45 --date 2026-03-09 --note "Adjusted entry"

Send an invoice

miru invoice create \
  --client-id 2 \
  --invoice-number INV-CLI-001 \
  --issue-date 2026-05-19 \
  --due-date 2026-06-18 \
  --line-item "Implementation|API work|2026-05-19|150|120"
miru invoice send --id 1 --recipients client@example.com

Security and Scoping

  • CLI requests use a dedicated bearer token
  • retrieve the current CLI token with miru config token when wiring MCP clients
  • the CLI session is tied to a user and workspace
  • all normal authentication and authorization remain in force
  • client list respects the authenticated user's normal client visibility
  • expense list and expense create stay restricted to roles already permitted by the app
  • project list, invoice list/show/send, and payment list/show all use the same app permissions as the web UI
  • time create is scoped through ProjectPolicy::Scope
  • time update and time delete are scoped to the authenticated user’s own entries in the current workspace
  • the CLI cannot impersonate another user when creating time

API Mapping

  • miru login -> POST /api/v1/users/login
  • miru logout -> DELETE /api/v1/cli/session
  • miru whoami -> GET /api/v1/users/_me
  • miru capabilities -> GET /api/v1/cli/capabilities
  • miru client list -> GET /api/v1/cli/clients
  • miru project list -> GET /api/v1/projects
  • miru expense list -> GET /api/v1/cli/expenses
  • miru expense create -> POST /api/v1/cli/expenses
  • miru invoice list -> GET /api/v1/invoices
  • miru invoice create -> POST /api/v1/invoices
  • miru invoice show -> GET /api/v1/invoices/:id
  • miru invoice send -> POST /api/v1/invoices/:id/send_invoice
  • miru payment list -> GET /api/v1/payments
  • miru payment show -> GET /api/v1/payments/:id
  • miru time list -> GET /api/v1/timesheet_entry
  • miru time create -> POST /api/v1/cli/timesheet_entries
  • miru time update -> PATCH /api/v1/cli/timesheet_entries/:id
  • miru time delete -> DELETE /api/v1/cli/timesheet_entries/:id

Troubleshooting

missing CLI credentials: run miru login

Log in again:

miru login --email user@example.com --password your-password

Wrong server

Point the CLI at the correct Miru instance:

miru config set-base-url --url http://127.0.0.1:9000

Need the project id for time entry commands

Use:

miru project list
miru project list --search <term>

CLI session expired

Run:

miru login --email user@example.com --password your-password

Upgrade the CLI

Run:

miru upgrade

Current Scope

Current supported CLI surface:

  • authentication + session: login, logout, whoami
  • config: config show, config token, config set-base-url
  • discovery: help, version, capabilities
  • projects: project list
  • clients: client list
  • time: time list, time create, time update, time delete
  • expenses: expense list, expense create
  • invoices: invoice list, invoice create, invoice show, invoice send
  • payments: payment list, payment show

MCP parity: