# io.github.ivanlai/primer-mcp (pypi · primer-mcp)

A Jira-lite MCP server that guides planning-first workflows for AI-assisted development.

- Trust score: 67/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-19

## Components

- pypi · `primer-mcp`: 67/100 (this document), [markdown](https://verifymcp.io/servers/ivanlai-primer-mcp/primer-mcp.md), [page](https://verifymcp.io/servers/ivanlai-primer-mcp/primer-mcp)

## Channel facts

- Registry: `pypi`
- Package: `primer-mcp`
- Version: `0.1.4`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-19.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised native-build step with no shell scripting around it.
  - 2 of 33 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 32/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - License check failed: the license (MIT License) isn't a recognized OSI-approved license.
  - Actively maintained (last published 0 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 82/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 1811 tokens (~106/item across 17 items; 17 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 17/100
  - Stability observed for 5 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### Claude

```bash
claude mcp add ivanlai-primer-mcp -- uvx primer-mcp
```

### Codex

```bash
codex mcp add ivanlai-primer-mcp -- uvx primer-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ivanlai-primer-mcp": {
      "type": "local",
      "command": [
        "uvx",
        "primer-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add ivanlai-primer-mcp --command uvx --arg primer-mcp
```

### Hermes

```yaml
mcp_servers:
  ivanlai-primer-mcp:
    command: "uvx"
    args: ["primer-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "ivanlai-primer-mcp": {
      "command": "uvx",
      "args": [
        "primer-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-18 (score 67, +2)

- [functional improvement] Stability: unverified → 0.13
- [functional] Package version: 0.1.3 → 0.1.4

### 2026-08-15 (score 65, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-08-14 (score 50)

First indexed and scored.

## MCP tools (17)

### `init_project` (~95 tokens)

Initialise this project for primer-mcp: creates the primer/ ticket
store and adds the workflow section to CLAUDE.md (and AGENTS.md if
it exists). Non-destructive and idempotent. Call this once per
project, before any other tool.
Optionally pass jira_project_key if tickets may later be exported to Jira.

Input parameters:

- `jira_project_key`
- `project_name` (string, required)

Output parameters:

- `result` (string)

### `plan_epic` (~109 tokens)

Create an Epic — the top-level container for a body of work. Start
here: state why the work matters, its goals, and how you'll know
it's done. Consider recording decisions (record_adr) before creating
stories — it captures reasoning that gets lost once implementation
starts.

Input parameters:

- `constraints`
- `goals` (array, required)
- `non_goals`
- `success_criteria`
- `title` (string, required)
- `why` (string, required)

Output parameters:

- `result` (string)

### `record_adr` (~102 tokens)

Record an Architecture Decision Record under an epic: the context
forcing a choice, the decision, alternatives rejected (with reasons),
and consequences accepted. Recording decisions before creating stories
is recommended — it captures reasoning that gets lost once
implementation starts.

Input parameters:

- `alternatives` (array, required)
- `consequences` (string, required)
- `context` (string, required)
- `decision` (string, required)
- `epic_id` (string, required)
- `title` (string, required)

Output parameters:

- `result` (string)

### `create_story` (~182 tokens)

Create a Story under an epic — a deliverable with acceptance criteria.
The epic must exist — if one hasn't been created yet, call plan_epic
first. The user will have described their goals; use that to create
the epic, asking for clarification if needed. If no ADR has been
recorded, the response will suggest capturing decisions first, but
the story is still created.

Pass adr_ids to link the story to the architectural decisions that
govern it. Each ADR must exist and belong to the same epic.

After creating stories, present the plan to the user and wait for
their agreement before creating tasks or starting work.

Input parameters:

- `acceptance_criteria`
- `adr_ids`
- `definition_of_done`
- `epic_id` (string, required)
- `title` (string, required)
- `what` (string, required)

Output parameters:

- `result` (string)

### `create_task` (~142 tokens)

Create a Task under a story — a concrete unit of implementation work
with a testable outcome. The parent story must already exist.

After breaking a story into tasks, present the task list to the
user before starting work — don't create tasks and immediately
begin implementing.

For small bug fixes (1–2 tasks), prefer adding a task under the
standing bug-fix story rather than creating a new story. Suggest
a dedicated story only when the fix spans 3+ tasks.

Input parameters:

- `story_id` (string, required)
- `testable_outcome` (string, required)
- `title` (string, required)
- `what_to_do` (string, required)

Output parameters:

- `result` (string)

### `create_spike` (~84 tokens)

Create a Spike under a story — a timeboxed investigation to answer a
specific question before committing to an implementation approach. The
parent story must already exist. When done, call complete_spike with
your findings.

Input parameters:

- `question` (string, required)
- `story_id` (string, required)
- `timebox` (string, required)
- `title` (string, required)

Output parameters:

- `result` (string)

### `start_task` (~58 tokens)

Transition a task to in-progress — call this when you begin working
on a task. Works from any status; you'll get a note if the transition
is unusual. After finishing, call complete_task.

Input parameters:

- `task_id` (string, required)

Output parameters:

- `result` (string)

### `complete_task` (~106 tokens)

Mark a task as completed with notes on what was done. The notes
parameter is a terse one-liner for the frontmatter field; write a
fuller summary (approach, key changes, decisions) into the
\## Completion Notes body section of the ticket separately.
Ideally call start_task first, but this works from any status.
After this, call verify_task with evidence to finalise.

Input parameters:

- `notes` (string, required)
- `task_id` (string, required)

Output parameters:

- `result` (string)

### `verify_task` (~92 tokens)

Verify a task with evidence that the work holds (e.g. "218 passed,
mypy clean"). Pass the short commit hash in the commit parameter
so it is labelled consistently. Ideally call complete_task first
to capture notes, but this works from any status. Sets the task
to verified.

Input parameters:

- `commit` (string)
- `evidence` (string, required)
- `task_id` (string, required)

Output parameters:

- `result` (string)

### `complete_spike` (~52 tokens)

Close a spike by recording its findings — the answer to the
question it was investigating and any recommendations. Works
from any status.

Input parameters:

- `findings` (string, required)
- `spike_id` (string, required)

Output parameters:

- `result` (string)

### `list_actionable` (~204 tokens)

List what can be acted on right now, with epic context.

Returns the epic's goals, story coverage, and a table of actionable
items. Always show the full table to the user first, then add your
recommendation below it. The table is the primary output — the user
needs to see all options to make their own call.

After showing the table, recommend what to do next:

1\. Check whether the stories cover the epic's goals. If goals are
   uncovered, recommend more planning (create_story) before
   execution.
2\. Urgent items (unverified or in-progress tasks) should usually
   be finished before starting new work.
3\. For the remaining items, read the tickets that look relevant
   (get_ticket) and recommend based on impact — what unblocks the
   most work, what aligns with current momentum, why now.
4\. If several items are genuinely equal, say so and explain why.

Output parameters:

- `result` (string)

### `get_ticket` (~56 tokens)

Read one ticket by ID, with its full body. Also reports which
tickets it blocks — that direction is not stored on the ticket itself,
so this is the only way to see it.

Input parameters:

- `ticket_id` (string, required)

Output parameters:

- `result` (string)

### `list_tickets` (~77 tokens)

List tickets one per line, newest work last. Filter by type (epic,
adr, story, task, spike), status, or parent_id (show only children of
that ticket). Use this to find an ID before calling another tool.

Input parameters:

- `parent_id`
- `status`
- `ticket_type`

Output parameters:

- `result` (string)

### `update_ticket` (~133 tokens)

Amend a ticket after creation; anything left out is left alone.
status sets todo, in-progress or blocked — for finished states,
prefer complete_task, verify_task or complete_spike as they also
record notes. blocked_by replaces the dependency list and is
refused if a referenced ticket does not exist or the edge would
create a cycle. To say "A blocks B", set blocked_by on B.
body_sections replaces whole markdown sections by heading.

Input parameters:

- `blocked_by`
- `body_sections`
- `external_ref`
- `status`
- `ticket_id` (string, required)

Output parameters:

- `result` (string)

### `delete_ticket` (~70 tokens)

Delete a ticket. Non-todo tickets are deleted with a warning.
Children are reported but not deleted — call delete_ticket on
each to cascade. After all deletions, call sweep_blocked_by to
clean up dangling references. Recoverable from git history.

Input parameters:

- `ticket_id` (string, required)

Output parameters:

- `result` (string)

### `sweep_blocked_by` (~38 tokens)

Remove blocked_by references that point to tickets that no
longer exist. Call once after finishing a batch of delete_ticket
calls.

Output parameters:

- `result` (string)

### `export_graph` (~85 tokens)

Generate a self-contained HTML file visualising the project as an
interactive graph. Opens in any browser with no external requests.
Nodes are coloured by type and status; edges show both hierarchy
(epic -> story -> task) and dependencies (blocked_by). Click a node
to see its details. On-demand — call when you want a snapshot.

Input parameters:

- `output_path`

Output parameters:

- `result` (string)

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/ivanlai-primer-mcp/primer-mcp#diagnostics

## Score history

- 2026-08-19: 67
- 2026-08-18: 67
- 2026-08-17: 65
- 2026-08-16: 65
- 2026-08-15: 65
- 2026-08-14: 50

## Links

- PyPI project: https://pypi.org/project/primer-mcp/
- Socket report: https://socket.dev/pypi/package/primer-mcp
- Repository: https://github.com/ivanlai/primer-mcp
- Changelog RSS feed: https://verifymcp.io/servers/ivanlai-primer-mcp/primer-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/ivanlai-primer-mcp/primer-mcp.json
- HTML version of this page: https://verifymcp.io/servers/ivanlai-primer-mcp/primer-mcp
