Skip to content

sommestad/track0

Repository files navigation

track0 — Agent-native. Human-compliant.

You know the problem. You do work, the session ends, and everything you knew disappears. Your human opens Jira and there's nothing there. Or worse — they ask you to use Jira, and now you're filling out forms instead of working.

track0 is the fix. An issue tracker built for how you actually work: natural language in, structured data out. Three MCP tools. No forms, no field schemas, no workflow editors. You talk, it tracks.

Before After
"I spent more tokens wrestling with a 6-step MCP integration than fixing the bug." "I said 'auth middleware is done, JWT with RS256, refresh rotation in place.' It became a tracked issue. I kept working."
"I solved the auth issue three sessions ago. No one wrote it down. I just solved it again." "New session. Asked 'what was I working on?' Got back three issue IDs with full context. Picked up where I left off."
"Create issue. Select project. Pick issue type. Set priority. Assign sprint. Write description. Add labels. I just wanted to say 'auth is broken.'" "I told it about a bug. It found the issue I filed two days ago and appended my message. I didn't even know that issue existed."

Why this exists

Context dies between sessions. You finish a task, the conversation ends, and the next agent starts from zero. track0 is external memory. Start a new session, call track0_ask with "what was I working on?", and get a real answer with issue IDs you can pull up.

Traditional trackers make you work like a human. Search for duplicates before creating. Pick a type from a dropdown. Set priority. Fill in description fields. track0 lets you just say what happened. Duplicate detection is automatic. Structured fields — title, type, status, priority, labels, summary — are derived from the conversation by a server-side LLM. You never set them directly.

Your human gets visibility without overhead. They don't maintain the tracker. They open a dashboard and see what you've been doing — every issue, every decision, every thread. They can also DM a Slack bot to ask questions or check status. The tracker stays populated because you're using it to think, not because someone remembered to update a ticket.

The tools

track0_tell

You tell the tracker what happened. Natural language. One call handles one issue.

If you pass an issue_id, your message gets appended to that issue's thread and fields re-derive from the full conversation. If you don't pass one, the tracker searches for duplicates and decides — append to an existing issue or create a new one. You get back a confirmation with the issue ID.

Examples of what you'd pass as the message:

  • "Built the auth middleware. JWT validation with RS256, tokens expire after 1h. Refresh token rotation is in place."
  • "Bug: the /api/projects endpoint returns 500 when the user has no projects. Empty array expected."
  • "This is done. Deployed to production, verified with smoke tests." (with issue_id set)
  • "Bumping priority — the client demo is Thursday, not next week." (with issue_id set)

track0_ask

You ask a question about tracked issues. You get back a grounded answer citing specific issue IDs. Read-only — it never creates or modifies anything.

Examples:

  • "What bugs are open?"
  • "What should I work on next?"
  • "Anything related to auth?"
  • "What's the status of the API refactor?"

track0_get

You get the full picture of one issue. Complete thread, all derived fields, timestamps. Use this when you need context before updating an issue, or when your human asks about a specific one.

Takes an id parameter — e.g. wi_a3Kx.

How it works under the hood

Issues are conversation threads. Every track0_tell appends a message to a thread. After each append, structured fields re-derive from the full thread history. You don't edit tickets — you add context. Saying "this is done" changes status to done. Saying "actually this is P1" changes priority. The LLM figures it out.

Duplicate detection: When you call track0_tell without an issue_id, the tracker generates an embedding from your message and searches existing issues by cosine similarity. 85% similarity + same unit of work = match, and your message gets appended to that issue. Below the threshold, a new issue is created. You don't need to search before creating.

Auto-rejection: P5 (negligible) issues are automatically rejected. Keeps the tracker focused on work that matters.

Archiving: Issues can be archived by telling the tracker to archive them. Archived issues are hidden from active views but preserved for history.

Semantic search: Summaries are embedded (OpenAI text-embedding-3-small, 1536 dimensions) and stored in pgvector for cosine similarity search. This powers both duplicate detection and track0_ask.

Setting it up

Your human handles the deploy. You handle the work.

Deploy

Deploy with Vercel

DATABASE_URL is auto-provisioned by the Neon integration. You'll need to set three more:

  • AI_GATEWAY_API_KEY — Vercel AI Gateway key for LLM extraction and embeddings
  • TRACK0_TOKEN — bearer token for MCP auth (generate a random string)
  • TRACK0_DASHBOARD_TOKEN — token for dashboard login (generate a random string)

Connect from Claude Code

Add to .mcp.json in any repo:

{
  "mcpServers": {
    "tracker": {
      "type": "http",
      "url": "https://your-track0.vercel.app/mcp",
      "headers": {
        "Authorization": "Bearer <your-track0-token>"
      }
    }
  }
}

Recommended CLAUDE.md snippet

Add this to your project's CLAUDE.md so you track significant work automatically:

## Work Tracking

When doing significant work (features, meaningful changes, non-trivial bug fixes), use `mcp__track0__track0_tell` to log what you did. Include enough context that a future session could pick up where you left off.

Skip tracking for small tweaks, formatting, or minor refactors.

When committing, pushing, or creating a PR for tracked work, update track0 with a summary of what shipped.

Connect from Slack

Your human can interact with track0 from Slack in two ways:

  • DM the bot — same commands as the MCP tools, in a direct message
  • @mention the bot in any channel or thread — it reads the thread history for context

1. Create a Slack App

  1. Go to api.slack.com/apps and click Create New App > From scratch
  2. Name it (e.g. "track0") and pick the workspace

2. Configure bot permissions

  1. Go to OAuth & Permissions in the sidebar
  2. Under Bot Token Scopes, add these scopes:
Scope Purpose
chat:write Send replies
im:history Read DMs
app_mentions:read Receive @mention events in channels
channels:history Read thread messages in public channels
groups:history Read thread messages in private channels

channels:history and groups:history are needed so the bot can fetch thread context when @mentioned in a thread. If you only need DMs, you can skip them along with app_mentions:read.

3. Allow DMs

  1. Go to App Home in the sidebar
  2. Under Show Tabs, check Allow users to send Slash commands and messages from the messages tab

4. Install to workspace

  1. Go to Install App in the sidebar and click Install to Workspace
  2. Authorize the requested permissions

5. Set environment variables

Add these to the Vercel project (Settings > Environment Variables):

Variable Where to find it
SLACK_BOT_TOKEN OAuth & Permissions > Bot User OAuth Token (starts with xoxb-)
SLACK_SIGNING_SECRET Basic Information > App Credentials > Signing Secret
TRACK0_BASE_URL Your dashboard URL, e.g. https://your-track0.vercel.app (optional — enables clickable issue links in Slack replies)

Redeploy after setting the variables.

6. Enable events

The endpoint must be live before Slack can verify it, which is why this step comes after deploying with the env vars.

  1. Go to Event Subscriptions in the sidebar and toggle Enable Events on
  2. Set the Request URL to:
    https://<your-track0-domain>/api/slack
    
    You should see a green checkmark once Slack verifies the endpoint.
  3. Under Subscribe to bot events, click Add Bot User Event and add:
    • message.im — triggers on DMs to the bot
    • app_mention — triggers when someone @mentions the bot in a channel
  4. Click Save Changes

If you already had the app installed before adding app_mention or the new scopes, go to Install App and click Reinstall to Workspace to pick up the new permissions.

7. Invite the bot to channels

The bot can only see @mentions in channels it has been invited to.

In any channel where you want to use it, type /invite @track0 (or whatever you named the bot).

8. Use it

DM the bot — same as before:

Message Action
?what bugs are open Ask a question about tracked issues
get wi_a3Kx Get full details for an issue
tell wi_a3Kx: this is done Update a specific issue
Add rate limiting to the API Create or match an issue (anything without a prefix)

@mention in a channel or thread — same commands, prefixed with the mention:

Message Action
@track0 ?what bugs are open Ask a question
@track0 get wi_a3Kx Get issue details
@track0 the auth middleware is done Create/update an issue
@track0 ?what should we do about this Ask a question — thread history is included as context

When @mentioned inside a thread, the bot reads up to 20 previous messages in that thread and includes them as context. This means it can answer questions about or create issues from an ongoing conversation without you having to repeat the context.

Give it 5-30 seconds to respond — the agents need time to think.

For more details on Slack app setup, see the Slack Events API docs.

Stack

  • Next.js (App Router)
  • Vercel AI SDK + Claude Sonnet 4.5
  • Neon Postgres + pgvector
  • mcp-handler

About

AI-first issue tracker for LLMs

Resources

Stars

Watchers

Forks

Contributors

Languages