Minimalist project management API with MCP server for task, story, and project management
Strong naming conventions (verb_noun pattern across all 10 tools). Descriptions are detailed and contextual, averaging ~150 chars, well above the 34-char baseline minimum. All tools have explicit input schemas with typed parameters and descriptions. However, output schemas are not documented in the visible code, responses are inferred from implementation. Error handling via @tool_errors decorator is present but opaque; recovery guidance is minimal. No tool annotations (readOnlyHint/destructiveHint) despite clear risk stratification (7 READ_ONLY, 3 WRITE). Parameter constraints (e.g., priority enum, date format) are documented in descriptions but not enforced in JSON Schema.
Add a comment to a project, story, or task. target is 'project:<uuid>', 'story:<uuid>', or 'task:<uuid>' - the same item-reference format used by the CLI. A malformed target returns an error string instead of attempting a request.
Create a new task in a project or story. If story_id is given, the task is created within that story; otherwise it is created at the project level. title is required; all other fields are optional. assignee_id must be a member user_id from get_project. priority is one of low|medium|high. due_date is YYYY-MM-DD.
Call this before creating or updating anything in a project. Statuses are per-project - the slugs returned here are the only values update_task will accept. Member user_ids here are the only valid assignee_ids.
Get a task by id. Includes its comments unless include_comments=False.
List projects accessible to the current user. By default returns only active (non-archived) projects. Set include_archived=True to see only archived projects instead of active ones - the two sets are not combined.
Output schemas not documented. LLMs cannot plan downstream tool calls or extract required fields (e.g., task_id from create_task, project_id from list_projects). Responses are inferred from implementation only.
No tool annotations (readOnlyHint/destructiveHint/idempotentHint) despite clear risk stratification. 7 tools are READ_ONLY; 3 are WRITE. LLMs cannot distinguish safe from destructive operations without explicit hints.
Parameter constraints (priority enum, date format YYYY-MM-DD, status slug validation) documented in descriptions but not enforced in JSON Schema. LLMs cannot parse enum constraints from text; they need formal schema definitions.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 60 | 2026-07-28+ | v2 |
List stories in a project.
List tasks in a project, or within a single story if story_id is given. Filter by status slug, assignee_id, or a free-text query q. unassigned=True returns only tasks with no assignee (works with or without story_id).
Full-text search across projects, stories, and tasks visible to the current user.
Partially update a task. Only the arguments you pass are changed (PATCH semantics) - leave everything else as None. status must be one of the status slugs returned by get_project for this task's project - it is not a fixed enum, each project defines its own workflow; a 422 response means the slug is unknown to that project. priority is one of low|medium|high. assignee_id must be a member user_id from get_project. due_date is YYYY-MM-DD. effort is an integer estimate. sprint_id must belong to the same project. At least one field must be given; calling with none of them makes no HTTP request and returns an error string instead.
Return the current identity: user id, name, email, role, and (if authenticated via API key) the key's label and scopes. Call this first if you're unsure what you're allowed to do.
Error handling via @tool_errors decorator is opaque. Recovery guidance is minimal. 'Invalid status' errors mention project-specific slugs but do not suggest calling get_project() first to discover valid values.
list_stories and search have minimal descriptions (70-75 chars). 'List stories in a project' lacks context on when to call it vs. list_tasks. 'Full-text search' does not explain scope or result ordering.