TrackPilot
An AI-friendly CLI and importable ESM library for driving YouTrack Cloud. Read issue specs, create and update tasks, comment, search, log work, and generate release diffs — from your terminal, your code, or an AI agent like Claude.
Why TrackPilot
Dual interface
Use it as a command-line tool or import it as a JavaScript library — same capabilities, your choice of surface.
JSON everywhere
Every command returns JSON, readable by humans and trivially parseable by scripts and LLMs.
Validation before write
Field values, users, and tags are validated client-side before any write — with “did you mean” suggestions for unknowns.
Secure token storage
Tokens live in the OS keyring — macOS Keychain, Windows Credential Manager, Linux Secret Service.
Git-aware releases
Extract issue IDs from commit history to produce QA-ready release reports.
Runs anywhere
Node 20+, browsers, Electron, and Tauri. Bring your own fetch when you need to.
Install & run
Run TrackPilot without installing, or install it globally. Pick your package manager — every command returns JSON.
npx trackpilot config getpnpm dlx trackpilot config getyarn dlx trackpilot config getnpm i -g trackpilot
trackpilot config getPrefer Yarn or pnpm globally? yarn global add trackpilot and pnpm add -g trackpilot work too. Requires Node 20 or newer.
Use it as a library
npm install trackpilotpnpm add trackpilotyarn add trackpilotConnect your YouTrack
Create a permanent token in YouTrack (Profile → Account Security → Authentication), then point TrackPilot at your instance.
Set your instance URL
trackpilot config set --base-url https://YOUR-INSTANCE.youtrack.cloudStore your token (via stdin, never shell history)
printf %s 'perm:xxxxxxxx' | trackpilot config set-tokenVerify
trackpilot config getThe token is kept in the OS keyring. In CI or headless environments, set YOUTRACK_TOKEN and YOUTRACK_BASE_URL instead — they take precedence over stored config.
CLI commands
Each command returns JSON. Writes are validated before they hit YouTrack.
trackpilot projectsList projects and their short-name keys.
trackpilot projectstrackpilot read <id>Fetch a single issue with fields, comments, tags, and links.
trackpilot read ABC-123trackpilot list --query <yt-query> [--limit N]Search issues using YouTrack query syntax.
trackpilot list --query "project: ABC State: Open" --limit 20trackpilot create --project <KEY> --summary <text> [...]Create a task in one operation. Fields, users, and tags are validated client-side before any write, with “did you mean” suggestions.
trackpilot create --project ABC --summary "Release" --type Task \
--assignee "Javad Tavakoli" \
--field "Team=Front-End" --field "Estimation=1d" \
--tag scope:infra --relates ABC-211trackpilot update <id> [--state ...] [--field ...] [...]Update an existing issue. Same flags as create; requires at least one.
trackpilot update ABC-123 --state "In Progress" --tag scope:infratrackpilot comment <id> --text <text>Add a comment to an issue.
trackpilot comment ABC-123 --text "Deployed to staging, ready for QA."trackpilot fields <KEY>List custom fields, allowed values, and tags for a project — useful for discovery.
trackpilot fields ABCtrackpilot command <id> --query <yt-command>Apply an arbitrary YouTrack command (low-level escape hatch).
trackpilot command ABC-123 --query "State Fixed tag release-blocker"trackpilot release [--base main] [--head next]Generate a QA-ready release report by scanning commits in base..head, extracting issue IDs, and resolving each one.
trackpilot release --base main --head release/2.0trackpilot mcpRun an MCP (Model Context Protocol) server over stdio, exposing YouTrack tools to clients like Claude. Uses the same auth as the CLI.
trackpilot mcpLibrary API
Construct a client with createApi() and call typed, Promise-returning methods. Unlike the CLI, the library does not use the OS keyring — you supply the token and manage secret storage yourself.
import { createApi } from "trackpilot";
const yt = createApi({
baseUrl: "https://example.youtrack.cloud",
token: process.env.YOUTRACK_TOKEN,
});
const me = await yt.me();
const issues = await yt.search("for: me #Unresolved", 20);
await yt.createIssue({
project: "ACME",
summary: "Title",
description: "Body (optional)",
});
await yt.applyCommand("ACME-1", "State {In Progress}");
await yt.addComment("ACME-1", "Picked up — starting now.");
await yt.logWorkItem("ACME-1", {
minutes: 30,
text: "Pairing",
date: Date.now(),
type: "Development",
});Other methods include readIssue, updateIssue, projects, projectSchema, tags, and a low-level request() escape hatch. See the README for the full reference.
Use it with Claude & other AI models
TrackPilot is built for AI workflows. JSON output plus validation-before-write means an agent can read a spec, draft subtasks, and apply commands without corrupting your tracker. Three ways to wire it up:
1. Run it as an MCP server (recommended)
trackpilot mcp runs a local Model Context Protocol server over stdio, exposing YouTrack to MCP clients like Claude. It uses the same auth as the CLI — set your base URL and token first, or pass them through the client config.
Claude Code:
claude mcp add trackpilot -- npx trackpilot mcpClaude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"trackpilot": {
"command": "npx",
"args": ["trackpilot", "mcp"],
"env": {
"YOUTRACK_BASE_URL": "https://your.youtrack.cloud",
"YOUTRACK_TOKEN": "perm-xxxxxxxx"
}
}
}
}Exposes read tools (search, read_issue, list_projects, project_schema, list_users, list_tags, whoami) and write tools (create_issue, update_issue, add_comment, log_work, apply_command). Your client prompts for approval before each write.
2. Point a coding agent at the CLI
Give Claude Code (or any agent that can run a shell) the CLI and a short playbook. The agent reads, drafts, creates, and reports — parsing JSON at each step.
# Hand this to Claude Code (or any coding agent that can run a shell):
Use the `trackpilot` CLI to manage YouTrack. It returns JSON and
validates before writing, so parse stdout as JSON and never invent
field names — discover them first.
1. Read the parent spec: trackpilot read ABC-1
2. Discover the project schema: trackpilot fields ABC
3. Draft subtasks, then for each one:
trackpilot create --project ABC --summary "<title>" \
--description "<body>" --subtask-of ABC-1
4. Move the parent forward: trackpilot update ABC-1 --state "In Progress"
5. At release time, summarize: trackpilot release --base main --head next3. Wrap the library as Claude API tools
Import createApi and expose its methods as tools for the Claude API. The SDK’s tool runner handles the agent loop.
import Anthropic from "@anthropic-ai/sdk";
import { betaZodTool } from "@anthropic-ai/sdk/helpers/beta/zod";
import { z } from "zod";
import { createApi } from "trackpilot";
const yt = createApi({
baseUrl: process.env.YT_BASE_URL!,
token: process.env.YOUTRACK_TOKEN!,
});
const client = new Anthropic();
// Wrap TrackPilot library methods as Claude tools.
const searchIssues = betaZodTool({
name: "search_issues",
description: "Search YouTrack with its query syntax. Call this whenever the user asks about existing issues.",
inputSchema: z.object({
query: z.string().describe('e.g. "for: me #Unresolved"'),
limit: z.number().optional(),
}),
run: ({ query, limit }) => yt.search(query, limit).then((r) => JSON.stringify(r)),
});
const createIssue = betaZodTool({
name: "create_issue",
description: "Create a YouTrack issue. Call this when the user asks to file or open a ticket.",
inputSchema: z.object({
project: z.string(),
summary: z.string(),
description: z.string().optional(),
}),
run: (input) => yt.createIssue(input).then((r) => JSON.stringify(r)),
});
// The tool runner drives the loop: Claude calls the tools, results feed back.
const finalMessage = await client.beta.messages.toolRunner({
model: "claude-opus-4-8",
max_tokens: 16000,
tools: [searchIssues, createIssue],
messages: [
{ role: "user", content: "File a bug in ACME: login button is unresponsive on Safari." },
],
});
console.log(finalMessage.content);Requires @anthropic-ai/sdk and zod. The same pattern works for any tool-calling model — TrackPilot just provides the typed YouTrack methods.
FAQ
What is TrackPilot?
TrackPilot is an AI-friendly CLI and importable ESM library for driving YouTrack Cloud. It reads issue specs, creates and updates tasks, comments, searches, logs work, and generates release diffs by extracting issue IDs from git history.
How do I install TrackPilot?
Run it without installing via npx trackpilot, pnpm dlx trackpilot, or yarn dlx trackpilot, or install it globally with npm i -g trackpilot. To use it as a library, add the trackpilot package to your project.
Can I use TrackPilot with AI models like Claude?
Yes. TrackPilot can run as a local MCP (Model Context Protocol) server with `trackpilot mcp`, exposing YouTrack read and write tools to clients like Claude Code and Claude Desktop. You can also point a coding agent at the JSON-returning CLI, or import the library and expose its methods as Claude API tools.
Where are my YouTrack credentials stored?
The CLI stores your token in the OS keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service). The non-secret base URL lives in a local config file. In CI, pass credentials via environment variables.