Skip to content

jinwoole/issue-tracker

Repository files navigation

Issue Tracker

Status License: MIT

A local-first, issue-based control plane for coding agents.

Use it when you need to answer: what work did an agent take, what authority did it use to change state, and what must an independent reviewer approve? State stays in SQLite, each actor gets scoped tokens, and every mutation is recorded in an append-only event log.

📖 한국어 · Five-minute MCP quickstart · Contributing

What you get

  • One local binary for CLI, REST API, and Streamable HTTP MCP.
  • Portable SQLite state in a local .issue-tracker/ directory.
  • Actor-scoped tokens for humans, services, and agents.
  • MCP tools for actor.me, issue search/get/create/update/status/comment, external references, and Agent Alignment Review when scoped.
  • Auditable changes through issue.get({"include_events": true}) when the token has event:read.

Quick start: run a local MCP issue server

This path builds from source, starts a local server, verifies MCP discovery, and gives an agent token enough scope to perform the standard audited issue workflow. For detailed client-specific setup, use the Five-minute MCP quickstart as the canonical guide.

1. Build

git clone https://github.com/jinwoole/issue-tracker.git
cd issue-tracker
cargo build --release
export ISSUE_TRACKER_BIN="$PWD/target/release/issue-tracker"

2. Initialize local state

"$ISSUE_TRACKER_BIN" init --name my-workspace --project CORE

This creates .issue-tracker/ in the current directory.

3. Create an agent actor and token

"$ISSUE_TRACKER_BIN" actor create \
  --workspace my-workspace \
  --kind agent \
  --handle coding-agent \
  --name "Coding Agent"

"$ISSUE_TRACKER_BIN" --json token create \
  --workspace my-workspace \
  --actor coding-agent \
  --name agent-mcp \
  --scope issue:read \
  --scope issue:create \
  --scope issue:update \
  --scope issue:status \
  --scope issue:comment \
  --scope event:read \
  --scope project:read \
  --scope actor:read \
  --scope alignment:read \
  --scope alignment:write \
  > /tmp/issue-tracker-token.json

export ISSUE_TRACKER_MCP_TOKEN="$(python3 -c 'import json; print(json.load(open("/tmp/issue-tracker-token.json"))["token"])')"

The raw token is shown only once. Keep it in an environment variable or local MCP config. Do not commit it.

4. Start the server

Run this in a second terminal:

cd /path/to/issue-tracker
./target/release/issue-tracker serve --addr 127.0.0.1:8787 --require-token

The same process serves:

  • REST API: http://127.0.0.1:8787/api/v1/...
  • MCP endpoint: http://127.0.0.1:8787/mcp

5. Verify MCP discovery

Run this from the terminal where ISSUE_TRACKER_MCP_TOKEN is set:

curl -fsS -X POST http://127.0.0.1:8787/mcp \
  -H "Authorization: Bearer ${ISSUE_TRACKER_MCP_TOKEN}" \
  -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

Expected result: HTTP 200 with a JSON-RPC result.tools array containing actor.me, issue.search, issue.get, and the write/alignment tools allowed by your token scopes.

6. Ask an MCP client to prove the loop

After connecting Hermes, Codex, Claude Code, or another Streamable HTTP MCP client, try the alignment-review loop:

Use Issue Tracker MCP to identify yourself, search CORE issues, create one test issue, update it, add a comment, submit an Agent Alignment Review with evidence, ask for an independent reviewer decision, change its status to done, then fetch it with include_events: true so I can verify the audit trail.

There is no separate issue.events MCP tool. Use issue.get({"include_events": true}) to inspect issue events.

Docker Compose deployment

The repository includes a local Docker Compose deployment path for release smoke testing and self-hosted use.

docker compose build
docker compose up -d
curl -fsS http://127.0.0.1:8787/healthz
curl -fsS http://127.0.0.1:8787/readyz

The container initializes /data on first boot using:

  • ISSUE_TRACKER_WORKSPACE default: docker-workspace
  • ISSUE_TRACKER_PROJECT default: CORE
  • ISSUE_TRACKER_STATE_DIR default inside the container: /data

For a deterministic end-to-end deployment gate, run:

scripts/docker-compose-smoke.sh

If your user cannot access /var/run/docker.sock, run the same gate with sudo:

DOCKER='sudo docker' scripts/docker-compose-smoke.sh

The smoke script passes Compose interpolation values with an explicit env file, so DOCKER='sudo -E docker' is not required. Custom ports and project keys work with plain sudo as well:

DOCKER='sudo docker' ISSUE_TRACKER_PORT=9876 ISSUE_TRACKER_PROJECT=ALT scripts/docker-compose-smoke.sh

The full release gate does not require Docker by default. Opt in to the Compose deployment smoke from the release gate with:

RUN_DOCKER_SMOKE=1 scripts/release-check.sh

The smoke test builds the image, starts Compose with a fresh named volume, verifies /healthz and /readyz, creates a scoped agent token, checks /api/v1/auth/me, verifies MCP tools/list required scopes including alignment tools, creates an issue, submits an Agent Alignment Review over HTTP, reads it back, and tears the stack down.

Connect an agent client

  • Hermes Agent: add an HTTP MCP server in ~/.hermes/config.yaml with url: "http://127.0.0.1:8787/mcp" and Authorization: "Bearer ${ISSUE_TRACKER_MCP_TOKEN}", then restart Hermes.
  • Codex: run codex mcp add issue-tracker --url http://127.0.0.1:8787/mcp --bearer-token-env-var ISSUE_TRACKER_MCP_TOKEN.
  • Claude Code or another MCP client: configure Streamable HTTP/HTTP transport to http://127.0.0.1:8787/mcp and send Authorization: Bearer ${ISSUE_TRACKER_MCP_TOKEN} on each request.

For the full setup, see Five-minute MCP quickstart for agent clients.

Core concepts

  • Workspace: a local issue database namespace, backed by SQLite.
  • Project: a project key such as CORE used in issue keys and filtering.
  • Actor: a human, service, or agent identity that owns mutations.
  • Token scope: the permission set that controls both tool discovery and tool calls.
  • Event log: append-only history for issue changes, comments, links, and status updates.
  • Agent Alignment Review: an issue-attached review record where an agent submits scope, evidence, and notes, and a separate independent reviewer records approved, changes_requested, rejected, or needs_review.

Agent Alignment Review MVP

The first killer workflow is Agent Alignment Review: agents do work in issues, submit evidence, and an independent reviewer decides whether the work is aligned with the requested scope.

  • Scopes: alignment:read allows alignment.get; alignment:write allows alignment.submit and alignment.decide. Normal issue work still needs issue:* scopes, and audit inspection still needs event:read.
  • MCP: call alignment.submit with key, summary, optional evidence, and optional notes; call alignment.decide with key, decision, and optional rationale.
  • HTTP: GET/PUT /api/v1/workspaces/{workspace}/issues/{issue_key}/alignment and POST /api/v1/workspaces/{workspace}/issues/{issue_key}/alignment/decision.
  • CLI: issue-tracker alignment get|submit|decide ... --workspace <workspace> for local review operations without an HTTP client.
  • Safety rule: the submitter cannot approve their own alignment review; use a separate actor/token for the reviewer. The current implementation does not require the reviewer actor to be human-only.

Current limitations

Issue Tracker is intentionally local and headless today. It does not yet provide a hosted control plane, web UI, multi-node sync, package-manager install path, or broad Jira/Linear replacement workflow.

Guides

API example

Create an issue over HTTP:

curl -fsS -X POST http://127.0.0.1:8787/api/v1/workspaces/my-workspace/issues \
  -H "Authorization: Bearer ${ISSUE_TRACKER_MCP_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"title": "Test issue", "body": "Created through the local HTTP API"}'

License

MIT

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors