orkestrr-mcp
An MCP server that lets an AI agent (e.g. Claude Code) create, reuse, and manage the Orkestrr project-management hierarchy — Bundles, Goals, and Tasks — through the existing Orkestrr REST API.
It is a standalone process that talks to Orkestrr over HTTP, so once registered at user scope it works from any project/repo you open, against local or production Orkestrr.
What it exposes
Hierarchy tools (read + write):
| Area | Tools |
|---|---|
| Projects | list_projects, get_project, list_project_members |
| Bundles | list_bundles, create_bundle, update_bundle (incl. status & archive) |
| Goals | list_goals, create_goal, update_goal (incl. status) |
| Tasks | list_tasks, create_task, update_task (incl. status & assignment) |
Task details:
| Area | Tools |
|---|---|
| Status | set_task_status |
| Estimation | list_estimation_values, set_task_estimation |
| Labels | list_labels, create_label, add_task_labels, remove_task_labels |
Status changes propagate up the hierarchy automatically (Task → Goal → Bundle → Project),
handled by the Orkestrr backend. add_task_labels reads the task's current labels and sends
the union (the API replaces the label set on update), so existing labels are preserved.
Backend quirks worked around (candidates for a future backend fix)
POST /labels/does not return the new label'sid—create_labelresolves it by re-querying labels by name.- A task's
estimation_labelis null in list/update payloads (only the nestedestimationobject on the detail payload carries the label) —set_task_estimationre-fetches the detail so it can confirm the value.
Authentication
You sign in once, interactively, in the browser with your EVOHEIM SSO (Authentik):
okr login # opens the browser (OAuth device flow); approve the code
okr status # shows who you're logged in as + token validity
okr logout # clears the stored session
okr login uses the OAuth 2.0 Device Authorization Flow against the public
orkestrr-cli Authentik provider. The issued JWT carries your real identity, so tasks and
status changes stay attributed to you. Tokens are stored in
~/.config/orkestrr-mcp/tokens.json (mode 0600) and auto-refresh — the MCP server
never needs an interactive prompt. No secrets go into the MCP registration.
The browser is sent to whichever approval URL the identity provider names in its device-code response, so the flow follows the server rather than a URL built here.
If a tool ever fails with "Not logged in" or "Session expired", just run okr login again.
Upgrading from 0.3.0 may ask for one such re-login: the CLI now talks to
auth.orkestrr.com instead of auth.evoheim.com.
Configuration
| Variable | Example | Notes |
|---|---|---|
ORKESTRR_BASE_URL |
(none — required) | API root. https://api.orkestrr.com in production, http://localhost:9000 for local. /api is appended when absent. |
ORKESTRR_MCP_HOME |
~/.config/orkestrr-mcp |
Optional. Override the directory where the session is stored. |
ORKESTRR_AUTH_URL |
https://auth.orkestrr.com |
Optional. The Authentik that issues and approves the CLI's tokens. |
Install
From PyPI (recommended — no repo checkout needed):
uv tool install orkestrr-mcp # or: pipx install orkestrr-mcp
# installs the `okr` command on your PATH; upgrade with `uv tool upgrade orkestrr-mcp`
From source (for development on the server itself):
git clone git@github.com:cafadev/orkestrr.git
uv tool install --editable ./orkestrr/orkestrr-mcp
Register with Claude Code (user scope = available in every project)
No credentials in the registration — the server command is okr mcp, and it uses your
okr login session.
# Local Orkestrr
claude mcp add --scope user orkestrr-local \
--env ORKESTRR_BASE_URL=http://localhost:9000 \
-- okr mcp
# Production Orkestrr
claude mcp add --scope user orkestrr \
--env ORKESTRR_BASE_URL=https://api.orkestrr.com \
-- okr mcp
ORKESTRR_BASE_URL is the API root; /api is appended when the URL does not
already end in it, so the production host resolves to https://api.orkestrr.com/api.
Then run okr login once (it works for both environments — same Authentik). Restart Claude
Code and run /mcp to confirm the tools are listed.
Develop
uv sync # install deps + this package (editable)
uv run pytest # run the test suite
Publishing to PyPI (maintainers)
Publishing is automated by GitHub Actions
(.github/workflows/orkestrr-mcp-publish.yml)
using PyPI Trusted Publishing (OIDC) — no API token is stored anywhere.
One-time setup on PyPI (do this before the first release): on https://pypi.org/manage/account/publishing/ add a pending trusted publisher:
| Field | Value |
|---|---|
| PyPI Project Name | orkestrr-mcp |
| Owner | cafadev |
| Repository name | orkestrr |
| Workflow name | orkestrr-mcp-publish.yml |
| Environment | (leave blank) |
Each release:
- Bump
versioninpyproject.toml(PyPI never lets you re-upload the same version) and merge it. - Create a GitHub Release whose tag starts with
orkestrr-mcp-v(e.g.orkestrr-mcp-v0.1.0). The tag prefix is what triggers the workflow (and keeps it monorepo-safe).
The workflow builds the sdist + wheel and publishes them. Teammates then uv tool install orkestrr-mcp.
Manual fallback (if Actions is unavailable) — needs an API token from Account settings → API tokens:
rm -rf dist && uv build
uvx twine check dist/*
UV_PUBLISH_TOKEN=pypi-XXXX uv publish
Out of scope (for now)
Acceptance criteria, action items, comments, blockers, and estimation-scale configuration (creating/editing the scale itself — only assigning existing values is supported). A dedicated API-key / OAuth2 machine-to-machine auth layer is also deferred — token auth covers current needs.
Metadata
Release files for orkestrr-mcp 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| orkestrr_mcp-0.4.1.tar.gz | 82.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| orkestrr_mcp-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 104.0 kB
Release files / orkestrr_mcp-0.4.1.tar.gz
| Download URL | orkestrr_mcp-0.4.1.tar.gz |
|---|---|
| Size | 82.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4a4bce95a6a87be148cd32c3ba44f7543041e16b08c9e968760ff86658aeab89
|
|
BLAKE2b-256 checksum How to use checksums |
778e47960d49ff37031cc8aa68f7a261d6f78c7e68f448508e6830654ecc84a6
|
| 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 4, 2026.
Transparency logRelease files / orkestrr_mcp-0.4.1-py3-none-any.whl
| Download URL | orkestrr_mcp-0.4.1-py3-none-any.whl |
|---|---|
| Size | 21.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e1b2f502fc97b85ae8627b7111a226b14d07ad05e3194361826b49da8a9066d3
|
|
BLAKE2b-256 checksum How to use checksums |
bf0c636d5474784a54c6dc07185c3f1466799b53e3d639046a24ef77fd14c152
|
| 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 4, 2026.
Transparency log