Skip to main content

taktcli

Authorized GraphQL CLI for Takt — the full Takt GraphQL surface from the shell, for agents and humans. Everything the MCP server does, and more.

The core is stdlib-only (urllib + argparse + json): a thin argv → GraphQL-over-HTTP client. Because arguments arrive as argv strings, it structurally sidesteps the MCP client-serialization bug class (arrays-as-JSON- strings, double-encoded results, the empty-string-drops-all-args bug) — an argv string simply can't be double-JSON-encoded.

The package and console-script are both named taktcli (bare takt is taken on PyPI).

Install

pip install taktcli            # stdlib-only core
pip install 'taktcli[watch]'   # + websockets, enables `taktcli watch`
pip install -e cli/            # from a monorepo checkout

Maestro/harness images ship pip install 'taktcli[watch]' — taktcli watch is the supported replacement for the retired tools/wait_for_task.py.

Quickstart

taktcli login                          # device-auth, stores ~/.takt/credentials.json
taktcli whoami                         # nickname + claims + active credential source
taktcli board --project takt           # show the board
taktcli claim takt-42                  # READY → RUNNING, prints leaseId
taktcli run takt-42                    # heartbeat the lease
taktcli done takt-42                   # mark DONE

taktcli --help (or taktcli help) lists every command; taktcli <noun> --help lists a group's verbs.

Auth

Token resolution, simplest-wins:

  1. TAKT_TOKEN env → used verbatim. This is what harness containers are stuffed with; env always wins over any stored credential.
  2. Else ~/.takt/credentials.json — plain JSON { "token": "<jwt>", "url": "..." }, mode 0600, written by taktcli login.
  3. Else error: No Takt credentials found. Run: taktcli login (exit 3).

URL resolution mirrors it: TAKT_URL env → url in the credentials file → default https://api.takt.sh/graphql. The watch WS endpoint is derived by swapping the scheme (https → wss).

taktcli login runs the OAuth 2.0 device-authorization grant: it prints a verification URL + user code, polls until you approve in a browser, then persists the token. logout removes the stored credential; whoami prints who you are and which credential source is active.

taktcli login                                       # default endpoint
taktcli login --url http://localhost:8454/graphql   # override the endpoint
taktcli logout
taktcli whoami

Auth is the same JWT + claims used by MCP and GraphQL — taktcli adds no privilege surface. There is no claims/permission verb anywhere; admin ops are reachable via gql only if the caller's token already holds the admin claim. Long-lived bot tokens stay minted out-of-band (tools/jwt_cli.py) and dropped into TAKT_TOKEN; login is for humans and dev machines.

Passthrough — reaches 100% of GraphQL

taktcli gql + taktcli schema are a complete superset of every MCP tool: any GraphQL op MCP never wrapped is reachable here.

taktcli gql -q 'query { me { nickname claims } }'
taktcli gql -f query.graphql --var id=takt-42 --field-file description=desc.md
taktcli schema --sdl              # SDL introspection (--json for JSON)

Big markdown flows through --field-file NAME=PATH (NAME=- = stdin) — this sidesteps shell quoting and the empty-string-args bug class.

Shared I/O flags

  • --var KEY=VALUE (repeatable; value parsed as JSON when valid, else string)
  • --vars JSON / --vars-file PATH (- = stdin) — bulk variables
  • --field-file NAME=PATH (NAME=- = stdin) — inject a file's contents as a variable; the canonical path for large markdown
  • --raw — full {data, errors, extensions} envelope (default is pretty .data)
  • --compact — single-line JSON

Variable precedence (lowest → highest): --vars-file < --vars < --var < --field-file.

Command surface

The CLI uses a positional namespace — taktcli <noun> <verb> [args] — so the entity is always the first token. This fixes the MCP create_wiki (Wiki) vs wiki_create (page) collision at the CLI layer. Run taktcli <noun> --help for a group's verbs.

Every MCP tool maps to a verb:

MCP tool taktcli verb
get_task get <id> / task get <id>
list_tasks task list
search_tasks task search <q>
get_board board
create_task task create
update_task task update <id>
update_status status <id> <STATUS> (or run / done / fail)
claim_task claim <id>
release_claim release <id>
force_release_claim gql (admin claim required)
transition_task task transition <id> <action>
get_dependencies task deps <id>
add_comment task comment <id>
get_task_comments task comments <id>
attach_result task result <id>
get_task_results task results <id>
delete_result task result-delete <id>
wiki_read wiki read <path>
wiki_search / wiki_semantic_search wiki search <q> (--semantic)
wiki_grep wiki grep <pattern>
wiki_create wiki create <path>
wiki_update wiki update <path>
wiki_edit wiki edit <path>
wiki_move wiki move <path> <new-path>
wiki_verify wiki verify <path>
wiki_delete wiki delete <path>
wiki_bulk_update_status wiki bulk-status <folder> <status>
find_related_wiki_pages wiki related <task-id>
list_wiki_feedback wiki feedback list
resolve_wiki_feedback wiki feedback resolve <id>
wiki_list wikis list
create_wiki wikis create
get_project_wiki wikis get <project>
request_upload_url_and_headers + confirm_upload file upload <path> (composite)
get_file_url file url <id>
list_files file list
attach_file_to_task file attach <id> <task-id>
detach_file_from_task file detach <id> <task-id>
attach_file_to_wiki file attach-wiki <id> <path>
update_label / delete_label label update <name> / label delete <name>
(none — CLI-only) label create
list_notifications notif list
mark_notification_read notif read <id>
mark_all_notifications_read notif read-all
unread_notification_count notif count
(none — CLI-only) project {list,get,create,rename,member-add,member-remove}
taskStatusChanged / taskChanged / resultAdded / commentAdded watch (needs [watch] extra)

Notes:

  • label create is CLI-only (the MCP server never wrapped createLabel, but the GraphQL mutation exists). label update / delete are keyed by name and resolve the id client-side via the labels query.
  • The wiki / wikis verbs take a global --wiki SLUG (default $TAKT_WIKI) and stream big markdown through --content-file / --old-file / --new-file (- = stdin).
  • The wiki-container verbs are wikis list/create/get (entity = Wiki). The old workspace list/create/get verbs are a hard error naming the replacement for one release — workspace is being reclaimed to mean the tenant, and nothing else.
  • project rename is name-only — slug changes are blocked on the backend.

Output & exit codes

Default output is pretty JSON of the unwrapped .data payload. --compact = single-line; --raw = full {data, errors, extensions} envelope; watch = NDJSON (one event per line, flushed per event).

Code Meaning
0 success
1 GraphQL error (server reached; errors[] non-empty)
2 transport error (DNS/TCP/TLS/HTTP non-2xx/timeout/WS drop)
3 config or usage error (no token, bad URL, unknown verb, missing flag)

extensions.code (e.g. LEASE_EXPIRED, ALREADY_CLAIMED) is preserved in error output so loops can branch on it.

Task monitoring — taktcli watch

Replaces the retired tools/wait_for_task.py. Streams subscription events as NDJSON and reconnects with exponential backoff on drops (e.g. deploys). Needs the [watch] extra.

taktcli watch --project takt --timeout 3600     # status changes, any task
taktcli watch --task takt-42 --task takt-43      # specific tasks
taktcli watch --project takt --event resultAdded # other subscriptions

--event defaults to taskStatusChanged. Unlike the old one-shot script, watch is a continuous stream — read NDJSON lines as they arrive and act on the first matching one; no restart-per-event. Tasks already READY when the watcher starts are not detected — check taktcli board --project takt first.

MCP coexistence

taktcli and the MCP server run side-by-side over the same GraphQL API, authenticating identically (JWT, same claims). Use either or both in one session. The MCP freeze/removal timeline lives in PRD 002 §8.

Documentation

  • Usage reference: takt/context/taktcli in the Takt wiki.
  • Design & rationale: takt/dev/prd-002-taktcli (PRD 002).
  • Contract placement: takt/contract §4.3 — the CLI as a first-class integration interface alongside GraphQL + MCP.

Release

Push a cli-v* tag (e.g. cli-v0.1.0) — .github/workflows/cli.yaml builds cli/ and OIDC trusted-publishes to PyPI. The tag must match the version in cli/pyproject.toml (CI asserts this). The CLI has its own CI job alongside backend/plugin/frontend (npm run test:cli).

Release files for taktcli 0.6.1

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

Source distribution (sdist)

Source distribution for taktcli 0.6.1
File Size Uploaded
taktcli-0.6.1.tar.gz 69.4 kB Details

Built distribution (wheel)

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

Total release size: 122.6 kB

Release files / taktcli-0.6.1.tar.gz

Download URL taktcli-0.6.1.tar.gz
Size 69.4 kB
Tags Source
SHA-256 checksum
How to use checksums
8d707075d5c3b33633cb7d4909d04ee9fa99a5a710fd20eee2ab30034b5f5eeb
BLAKE2b-256 checksum
How to use checksums
f5f8adacd787d56d3636fb49d83503f0113f5b4c6dcccd12a0d204eb315f23ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release files / taktcli-0.6.1-py3-none-any.whl

Download URL taktcli-0.6.1-py3-none-any.whl
Size 53.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8007a91634440e4255c63fb75a4f179afa79cd193fbf7c0d8041baf23ee461c8
BLAKE2b-256 checksum
How to use checksums
f480b4d6736521a03622080b644d6c518d02e2c599129c5397f81a60d4a29dd2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.2

2 release files

This release

0.6.1 This release

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

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