Skip to main content

maia

The M.AI.A board from a terminal, for people and for the coding agents they run there.

It talks to the same public HTTP API the web app uses, so it inherits the server's rules rather than restating them: any active project member can move, edit, assign or reassign any ticket, and observers are read-only.

Install

uv tool install --from ./cli maiactl    # from a checkout
maia login                               # opens your browser
maia projects
maia use MVP

login runs the same brokered PKCE flow the desktop app uses: it opens Google in your real browser and polls until the backend releases a token. The token is written to ~/.config/maia/config.json with mode 0600.

Several accounts at once

Like gh, you can be signed into more than one account and switch between them. An account is (email, server), so the same person on prod and on a local backend are two accounts — which is the point.

maia login                       # adds an account; never evicts an existing one
maia auth list                   # all of them, active one marked with *
maia auth switch priya           # by email, or any unique fragment
maia auth logout --account priya # sign out of just that one
maia auth logout --all

Each account remembers its own workspace and project, so switching restores where you were. For a single command, -a (--as) acts as another account without switching, and nothing that command does is saved:

maia -a priya@cydratech.com ls --mine
maia ls --mine -a priya          # flags may come before or after the command

-a can't be combined with login, logout or auth switch; those manage saved accounts, so name the account directly (logout --account priya).

Workspaces

maia workspaces              # the ones this account belongs to
maia workspace "Cydra Tech"  # switch

Switching workspace clears the selected project, because a project belongs to exactly one workspace — keeping it would point at something the account can no longer see. Pick a new one with maia projects and maia use.

It is a normal app session token, not a scoped API key, so it carries your full access and expires on the server's schedule. Treat the file as a credential. maia logout removes it.

For CI or a throwaway shell, skip the file entirely:

export MAIA_TOKEN=...        MAIA_TENANT_ID=...
export MAIA_PROJECT=MVP      MAIA_API_URL=https://maia.cydratech.com

Anything set this way applies to the current run only and is never written to disk: a CI job can't persist its credentials, and MAIA_PROJECT=X maia use Y won't change your saved project. Commands that would normally save say (not saved: …) on stderr. MAIA_ACCOUNT=priya selects a saved account for one run; a name that matches nothing is an error, not a silent fallback. With MAIA_TOKEN set, logout and auth switch refuse, since there is no saved session in play.

Reading

maia ls                       # active tickets, doing first
maia ls --mine --status doing
maia ls --stage "In QA"
maia ls -s payment            # title/description search
maia show MVP-42              # detail + comments
maia show MVP-42 --history
maia board                    # stages and card counts
maia members                  # who's on it, and their roles
maia stories
maia files MVP-42 --download ./tmp

Tickets are addressed by key (MVP-42), bare number (42), or a title fragment. A fragment matching more than one ticket is an error, never a guess.

Writing

maia new "Payment webhook retries" -d "Stripe retries land as duplicates." \
  --assign priya --stage "In Progress" --story "Billing"

git log -1 --format=%B | maia new "Ship the retry fix" -d -

maia mv MVP-42 doing          # a status…
maia mv MVP-42 "In QA"        # …or a stage by name
maia assign MVP-42 priya
maia story MVP-42 "Billing"   # file under an existing story
maia comment MVP-42 "Deployed to staging." --mention priya
maia comment MVP-42 - < notes.md
maia attach MVP-42 screenshot.png trace.pdf
maia drop MVP-42 --reason "superseded by MVP-51"   # project admins only

Every command takes --json for programmatic use, and -p CODE to act on a project other than the selected one for that command. Both may come before or after the subcommand. Progress notes ("uploaded x.png") go to stderr, so --json stdout is always a single parseable document.

What it deliberately doesn't do

  • No stage (column) create, rename or delete. Board structure is admin-curated in the app.
  • No story create, edit or delete. Same reason. You can file a ticket into an existing story with maia story.
  • No ticket delete. The API has none. maia drop sets the reversible dropped status, which is what "scrap that" means on this board; maia mv <key> next puts it back. Dropping is project-admin only from the CLI (the app lets any member), and maia mv <key> dropped is held to the same rule.

For agents

Point your terminal agent at maia --help and the per-command maia <command> --help; both are written to be read once and remembered. Two habits worth putting in a project's CLAUDE.md:

  • Prefer --json when parsing, plain output when showing a human.
  • Narrow before listing. maia ls caps at 40 rows by default; on a big board use --mine, --stage, or -s rather than --limit 0.

Exit codes

code meaning
0 fine
1 generic failure
2 not authenticated, or nothing selected
3 forbidden (e.g. you're an observer)
4 not found (a ticket, member, story, stage, project or workspace)
5 conflict; refetch and retry

Metadata

Release files for maiactl 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for maiactl 0.3.0
File Size Uploaded
maiactl-0.3.0.tar.gz 66.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for maiactl 0.3.0
File Interpreter ABI Platform
maiactl-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 104.4 kB

Release files / maiactl-0.3.0.tar.gz

Download URL maiactl-0.3.0.tar.gz
Size 66.8 kB
Tags Source
SHA-256 checksum
How to use checksums
0bf8b25e6594cc77e3f5c2dbd14f1ee902b5d12bc743ba63a25b8b2a26a88316
BLAKE2b-256 checksum
How to use checksums
8f815b9f2b88dc0c207dc69a9efc5670e77e67dc18565a558046a699ce622330
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.5

Release files / maiactl-0.3.0-py3-none-any.whl

Download URL maiactl-0.3.0-py3-none-any.whl
Size 37.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
59d9c0a5b622fc2ce051a6fddcbe8b6508b923ebda79379207e958a1950e7225
BLAKE2b-256 checksum
How to use checksums
8c3d61cb5cad9ee9e0973772105167af82a1ca08a0a45d6cb37241fcd760aa44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.5

Release history Release notifications | RSS feed

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page