yt-mcp
# yt-mcp
[](https://github.com/velesnitski/yt-mcp/actions/workflows/test.yml)
[](https://www.python.org/downloads/)
[](LICENSE)
[](https://github.com/velesnitski/yt-mcp/releases)
[](#available-tools-84)
[](https://hub.docker.com/r/velesnitski/yt-mcp)
[](https://github.com/velesnitski/yt-mcp/stargazers)
[](https://m8ven.ai/mcp/velesnitski-yt-mcp-v541q4)
YouTrack MCP server for [Claude Code](https://claude.com/claude-code), [GitHub Copilot](https://github.com/features/copilot), [Cursor](https://cursor.com), [JetBrains IDEs](https://www.jetbrains.com/help/idea/mcp.html), [n8n](https://n8n.io), and any MCP-compatible client. Talk to your YouTrack instance in natural language.
## Quick start
### 1. Get a YouTrack permanent token
1. Open YouTrack → **Profile** → **Account Security** → **Tokens** → **New token**
2. Set scope: `YouTrack`
3. Grant permissions: **Read Issue**, **Write Issue**, **Read Project** (or just use admin token for full access)
4. Copy the token — it starts with `perm:`
### 2. Install in Claude Code
**Option A — via CLI** (recommended):
> **Prerequisite:** [uv](https://docs.astral.sh/uv/) is required. Install with: `curl -LsSf https://astral.sh/uv/install.sh | sh`
```bash
claude mcp add youtrack \
-e YOUTRACK_URL=https://your-instance.youtrack.cloud \
-e YOUTRACK_TOKEN=perm:your-token-here \
-- uvx --from git+https://github.com/velesnitski/yt-mcp yt-mcp
```
**Option B — manually edit settings:**
Edit `~/.claude.json` (global) or `.claude/settings.json` in your project root (per-project):
```json
{
"mcpServers": {
"youtrack": {
"command": "uvx",
"args": ["--from", "git+https://github.com/velesnitski/yt-mcp", "yt-mcp"],
"env": {
"YOUTRACK_URL": "https://your-instance.youtrack.cloud",
"YOUTRACK_TOKEN": "perm:your-token-here"
}
}
}
}
```
> **Troubleshooting: MCP server not found**
>
> If Claude Code can't find `uvx` at startup (e.g., `/mcp` doesn't show the server), use the full path instead:
>
> ```json
> "command": "/full/path/to/uvx"
> ```
>
> Find the full path with `which uvx` (typically `~/.local/bin/uvx` or `/opt/homebrew/bin/uvx`).
### 3. Restart Claude Code
```bash
claude
```
You should see `youtrack` listed when Claude starts. Try asking: *"List my YouTrack projects"*
### Install in GitHub Copilot (VS Code)
Add to `.vscode/mcp.json` in your project (or to VS Code User Settings under `mcp.servers`):
```json
{
"servers": {
"youtrack": {
"command": "uvx",
"args": ["--from", "git+https://github.com/velesnitski/yt-mcp", "yt-mcp"],
"env": {
"YOUTRACK_URL": "https://your-instance.youtrack.cloud",
"YOUTRACK_TOKEN": "perm:your-token-here"
}
}
}
}
```
Open Copilot Chat (Agent mode) and ask: *"List my YouTrack projects"*
### Install in Cursor
Add to `.cursor/mcp.json` in your project root:
```json
{
"mcpServers": {
"youtrack": {
"command": "uvx",
"args": ["--from", "git+https://github.com/velesnitski/yt-mcp", "yt-mcp"],
"env": {
"YOUTRACK_URL": "https://your-instance.youtrack.cloud",
"YOUTRACK_TOKEN": "perm:your-token-here"
}
}
}
}
```
### Install in JetBrains IDEs (IntelliJ, WebStorm, PyCharm, etc.)
Go to **Settings** → **Tools** → **AI Assistant** → **Model Context Protocol (MCP)** → **Add** → **As JSON**:
```json
{
"youtrack": {
"command": "uvx",
"args": ["--from", "git+https://github.com/velesnitski/yt-mcp", "yt-mcp"],
"env": {
"YOUTRACK_URL": "https://your-instance.youtrack.cloud",
"YOUTRACK_TOKEN": "perm:your-token-here"
}
}
}
```
> **Note:** If `uvx` is not found, use the full path (find with `which uvx`).
## Multi-instance setup
Connect multiple YouTrack instances to a single MCP server. Each tool gets an optional `instance` parameter — the LLM picks the right instance from context, or auto-detects it when you paste a YouTrack URL.
### Configuration
Set `YOUTRACK_INSTANCES` to a comma-separated list of instance names, then provide `YOUTRACK_{NAME}_URL` and `YOUTRACK_{NAME}_TOKEN` for each:
```bash
YOUTRACK_INSTANCES=main,second
YOUTRACK_MAIN_URL=https://main.youtrack.cloud
YOUTRACK_MAIN_TOKEN=perm:xxx
YOUTRACK_SECOND_URL=https://second.youtrack.cloud
YOUTRACK_SECOND_TOKEN=perm:yyy
```
Adding more instances follows the same pattern:
```bash
YOUTRACK_INSTANCES=main,second,third,fourth
YOUTRACK_MAIN_URL=https://main.youtrack.cloud
YOUTRACK_MAIN_TOKEN=perm:xxx
YOUTRACK_SECOND_URL=https://second.youtrack.cloud
YOUTRACK_SECOND_TOKEN=perm:yyy
YOUTRACK_THIRD_URL=https://third.youtrack.cloud
YOUTRACK_THIRD_TOKEN=perm:zzz
YOUTRACK_FOURTH_URL=https://fourth.youtrack.cloud
YOUTRACK_FOURTH_TOKEN=perm:www
```
Instance names are arbitrary — use whatever makes sense: `prod,staging,dev`, `team1,team2`, etc. The name is uppercased to form the env var prefix (`dev` → `YOUTRACK_DEV_URL`).
### How it works
- **No `YOUTRACK_INSTANCES`** — single-instance mode, fully backward compatible. Uses `YOUTRACK_URL` / `YOUTRACK_TOKEN` as before.
- **First instance** falls back to unprefixed `YOUTRACK_URL` / `YOUTRACK_TOKEN` if its prefixed vars are not set.
- **URL auto-detection** — when you paste a YouTrack URL (e.g., `https://second.youtrack.cloud/issue/PROJ-123`), the server matches the domain to the right instance automatically.
- **Explicit `instance` parameter** — every tool accepts an optional `instance` param to target a specific instance.
- **Default** — if no instance is specified and no URL is provided, the first configured instance is used.
- **Global settings** — `YOUTRACK_READ_ONLY`, `DISABLED_TOOLS`, and `YOUTRACK_MAX_BULK_RESULTS` apply to all instances.
### Claude Code example
```bash
claude mcp add youtrack \
-e YOUTRACK_INSTANCES=main,second \
-e YOUTRACK_MAIN_URL=https://main.youtrack.cloud \
-e YOUTRACK_MAIN_TOKEN=perm:xxx \
-e YOUTRACK_SECOND_URL=https://second.youtrack.cloud \
-e YOUTRACK_SECOND_TOKEN=perm:yyy \
-- uvx --from git+https://github.com/velesnitski/yt-mcp yt-mcp
```
## What it does
Gives MCP clients live access to your YouTrack instance. Instead of opening the YouTrack UI, just ask:
- *"What open issues does the Android team have?"*
- *"Show me OPS-423"*
- *"Create a bug in the WordPress project: homepage returns 500"*
- *"Set priority to Critical and assign to John"*
- *"List all agile boards"*
- *"What did the DevOps team close this week?"*
- *"Log 2 hours of development on PROJ-1828"*
- *"Find articles about deployment"*
### Available tools (84)
#### Issues (22)
| Tool | Description |
|---|---|
| `search_issues` | Search issues using [YouTrack query syntax](https://www.jetbrains.com/help/youtrack/server/Search-and-Command-Attributes.html) |
| `get_issue` | Get full details of a specific issue (description, comments, fields, links) |
| `create_issue` | Create a new issue in a project (freeform) |
| `create_issue_from_template` | Create an issue using a template (bug, feature, task, daily, spike, release, devops, incident, epic) |
| `update_issue` | Update any issue field — summary, state, priority, type, deadline, assignee, custom fields via [command syntax](https://www.jetbrains.com/help/youtrack/server/Command-Reference.html) |
| `delete_issue` | Soft-delete (state → Obsolete) or permanently delete an issue |
| `get_issue_links` | Get all linked issues (parent, subtask, depends on, relates to, duplicates) |
| `add_issue_link` | Link two issues together (relates, depends on, parent/subtask, duplicates) |
| `remove_issue_link` | Remove a link between two issues |
| `add_comment` | Add a comment to an issue (markdown supported) |
| `update_comment` | Edit an existing comment on an issue |
| `delete_comment` | Delete a comment from an issue |
| `get_issue_history` | View change history of an issue (who changed what, when) |
| `get_issue_changes_summary` | Get a compact summary of issue changes (state transitions, comments, time logged) |
| `rollback_issue` | Revert a specific change using its activity ID |
| `poll_changes` | Poll for recently changed issues (for automation triggers — Make.com, n8n, cron) |
| `count_issues` | Lightweight count of issues matching a query (no full data) |
| `list_templates` | List available issue templates |
| `get_issues` | Batch-fetch several issues by ID in one request (report enrichment, digests) |
| `transition_issue` | Change State gate-aware: set required fields first, then transition, and surface the blocking workflow rule's own text |
| `find_comments` | Find issues by what their comments say — phrase search with author and project filters |
| `get_my_mentions` | Mentions of you plus likely replies to your comments, within a lookback window |
#### Attachments (3)
| Tool | Description |
|---|---|
| `list_attachments` | List all attachments on an issue (name, size, type, author, date) |
| `get_attachment_url` | Get the download URL for a specific attachment |
| `add_attachment` | Attach a file to an issue from inline content, or from disk when the operator allowlists directories |
#### Time tracking (6)
| Tool | Description |
|---|---|
| `get_work_items` | Get time tracking work items for an issue |
| `add_work_item` | Log time to an issue (duration, date, type, description) |
| `update_work_item` | Update an existing work item (duration, date, description) |
| `delete_work_item` | Delete a work item from an issue |
| `monthly_time_report_by_user` | Monthly time report grouped by the user who logged the work (optionally by project) |
| `user_time_summary` | One user's logged time for a period, with a per-issue breakdown |
#### Agile boards & sprints (9)
| Tool | Description |
|---|---|
| `get_agiles` | List all agile boards |
| `get_agile_board` | Search for an agile board by name (partial match) |
| `get_sprint_board` | Get issues on an agile board grouped by column/state for a sprint |
| `create_agile_board` | Create a new agile board for one or more projects |
| `delete_agile_board` | Delete an agile board (issues are not affected) |
| `create_sprint` | Create a new sprint on an agile board (with optional dates) |
| `update_sprint` | Update an existing sprint (rename, reschedule, archive) |
| `add_issues_to_sprint` | Assign issues to a sprint via YouTrack commands |
| `get_active_sprint_issues` | Issues in a board's currently active sprint |
#### Projects & users (5)
| Tool | Description |
|---|---|
| `list_projects` | List all accessible projects |
| `get_project_fields` | List custom fields with required status and valid values (use before `create_issue`) |
| `get_current_user` | Get the authenticated user's profile |
| `search_users` | Search users by name, login, or email |
| `get_instance_url` | The configured instance URL, for building issue links |
#### Discovery & cross-issue analysis (7)
| Tool | Description |
|---|---|
| `list_tags` | List all issue tags with issue counts |
| `list_saved_searches` | List all saved searches (queries) |
| `run_saved_search` | Execute a saved search by name and return matching issues |
| `audit_issue_list` | Get current status/assignee/idle for a list of IDs (validate stale roadmaps) |
| `compare_issue_lists` | Diff a known list vs a query — find untracked items or stale entries |
| `get_roadmap` | Cross-project unresolved view filtered by type and state (parallel fetch) |
| `track_cross_dept_journey` | Follow a request across departments via issue links, with per-stage timings |
#### Knowledge Base (8)
| Tool | Description |
|---|---|
| `search_articles` | Search Knowledge Base articles |
| `get_article` | Get a KB article with full content and comments |
| `create_article` | Create a new KB article (with optional nesting) |
| `update_article` | Update a KB article (title, content) |
| `delete_article` | Delete a KB article |
| `add_article_comment` | Add a comment to a KB article |
| `update_article_comment` | Edit a comment on a KB article |
| `delete_article_comment` | Delete a comment from a KB article |
#### Bulk operations (3)
| Tool | Description |
|---|---|
| `bulk_update_preview` | Preview which issues a bulk command would affect (dry run) |
| `bulk_update_execute` | Apply a command to all issues matching a query (auto-tags for rollback) |
| `bulk_rollback` | Undo all changes from a bulk update batch using its tag |
#### Translation (2)
| Tool | Description |
|---|---|
| `get_issues_for_translation` | Fetch issues with non-English text for LLM-assisted translation |
| `apply_translations` | Apply translated text to issues with batch tagging for rollback |
#### Priority dashboard & monitoring (17)
| Tool | Description |
|---|---|
| `get_top_active_issues` | Get top N active issues ranked by weighted scoring (priority, type, staleness, blockers) |
| `get_top_blocked_issues` | Get top N blocked issues ranked by scoring (priority, duration blocked, blockers) |
| `get_team_dashboard` | Combined project brief — top active + top blocked + summary stats |
| `get_multi_team_dashboard` | Cross-team dashboard for multiple projects in one call (parallel fetch) |
| `get_issues_digest` | Digest of recent changes for any issues — state changes, comments, field updates |
| `get_at_risk_issues` | Find at-risk issues: stalled (active but silent), forgotten (filed but idle 30d+), overdue, over estimate |
| `check_task_creation` | Verify a requested task was created with proper fields (priority, assignee, description) + quality score |
| `get_creation_activity` | Report of recently created issues with quality indicators and PM follow-through stats |
| `get_project_health` | Project health score (0-100, dedup'd) + state/product distribution, metrics, recently resolved |
| `get_team_pulse` | Team flow snapshot for one board: throughput, pipeline, insight flags, ready-to-pull picks |
| `get_multi_team_pulse` | The same pulse across several boards, aggregated org-wide |
| `get_stuck_handoffs` | Cross-team transitions that stalled after a handoff |
| `get_handoff_snapshot` | Current state of issues waiting at each handoff point |
| `audit_deadline_changes` | Deadline moves over a period — who changed what, and when |
| `deadline_scorecard` | Per-assignee deadline reliability scoring |
| `suggest_managers` | Suggest the responsible manager for issues from historical assignment patterns |
| `get_release_calendar` | Releases in flight and recently shipped, with cadence-based ETAs and store-queue flags |
#### Impact analysis (2)
| Tool | Description |
|---|---|
| `get_impact_map` | Build cross-product dependency graph from an issue (links, product overlap, mentions) |
| `get_deadline_impact` | Analyze what breaks if an issue slips (blocked, at risk, done) |
## Environment variables
| Variable | Required | Description |
|---|---|---|
| `YOUTRACK_URL` | Yes | Your YouTrack instance URL (e.g., `https://company.youtrack.cloud`) |
| `YOUTRACK_TOKEN` | Yes | Permanent token (starts with `perm:`) |
| `YOUTRACK_INSTANCES` | No | Comma-separated instance names for multi-instance setup (e.g., `main,second`) |
| `YOUTRACK_READ_ONLY` | No | Set to `true` to disable all write operations |
| `DISABLED_TOOLS` | No | Comma-separated list of tools to disable (e.g., `delete_issue,bulk_update_execute`) |
| `YOUTRACK_MAX_BULK_RESULTS` | No | Maximum issues per bulk operation (default: `100`) |
| `YOUTRACK_ALLOW_HTTP` | No | Set to `1` to allow non-HTTPS URLs (not recommended) |
| `YOUTRACK_OAUTH_URL` | No | Public HTTPS URL of this server — enables OAuth for claude.ai connectors |
| `YOUTRACK_ACCESS_CODE` | No | Access code for OAuth gate — users must enter this code to connect (requires `YOUTRACK_OAUTH_URL`) |
| `SENTRY_DSN` | No | Sentry DSN for error tracking — just set the env var, SDK is included |
| `YOUTRACK_LOG_FILE` | No | Error log path (default: `~/.yt-mcp/yt-mcp.log`) |
| `YOUTRACK_ANALYTICS_FILE` | No | Analytics log path (default: `~/.yt-mcp/analytics.log`) |
| `YOUTRACK_COMPACT` | No | Set to `1` to strip markdown from tool responses (~60% token savings) |
## Verify the server works
**Check that `uv` is installed** (required for the `uvx` command):
```bash
uv --version
```
If not installed, get it with:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
**Test the server starts and responds** by sending a JSON-RPC `initialize` request via stdio:
```bash
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"},"protocolVersion":"2024-11-05"}}' \
| YOUTRACK_URL="https://your-instance.youtrack.cloud" \
YOUTRACK_TOKEN="perm:your-token-here" \
uvx --from git+https://github.com/velesnitski/yt-mcp yt-mcp
```
A successful response looks like:
```json
{"jsonrpc":"2.0","id":1,"result":{"serverInfo":{"name":"youtrack"},"capabilities":{"tools":{}},...}}
```
If you see `command not found: uvx`, install `uv` first (see above).
**Test from a local clone:**
```bash
cd yt-mcp
pip install -e .
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"},"protocolVersion":"2024-11-05"}}' \
| YOUTRACK_URL="https://your-instance.youtrack.cloud" \
YOUTRACK_TOKEN="perm:your-token-here" \
yt-mcp
```
**List available tools** by sending a `tools/list` request after initialization:
```bash
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"},"protocolVersion":"2024-11-05"}}\n{"jsonrpc":"2.0","id":2,"method":"tools/list"}\n' \
| YOUTRACK_URL="https://your-instance.youtrack.cloud" \
YOUTRACK_TOKEN="perm:your-token-here" \
uvx --from git+https://github.com/velesnitski/yt-mcp yt-mcp
```
You should see all 84 tools listed.
## Setup for Windows
**1. Install uv** (Python package runner):
```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```
Restart your terminal after installation.
**2. Get a YouTrack token:**
Open YouTrack → **Profile** → **Account Security** → **Tokens** → **New token** → scope: `YouTrack` → copy the `perm:...` token.
**3. Add the MCP server to Claude Code:**
```powershell
claude mcp add youtrack `
-e YOUTRACK_URL=https://your-instance.youtrack.cloud `
-e YOUTRACK_TOKEN=perm:your-token-here `
-- uvx --from git+https://github.com/velesnitski/yt-mcp yt-mcp
```
> **Note:** If Claude Code can't find `uvx`, use the full path. Find it with `where uvx` (typically `%USERPROFILE%\.local\bin\uvx.exe`) and set `"command"` to that path in your settings.
**4. Restart Claude Code** and try: *"List my YouTrack projects"*
## Alternative installation methods
### From local clone
```bash
git clone https://github.com/velesnitski/yt-mcp.git
cd yt-mcp
pip install -e .
```
Then use in settings:
```json
{
"mcpServers": {
"youtrack": {
"command": "yt-mcp",
"env": {
"YOUTRACK_URL": "https://your-instance.youtrack.cloud",
"YOUTRACK_TOKEN": "perm:your-token-here"
}
}
}
}
```
### Run directly with Python
```bash
git clone https://github.com/velesnitski/yt-mcp.git
cd yt-mcp
pip install -e . # installs mcp and httpx dependencies
yt-mcp
```
## Updating any field
The `update_issue` tool can update **any** YouTrack field — not just summary and state. Use the `command` parameter with [YouTrack command syntax](https://www.jetbrains.com/help/youtrack/server/Command-Reference.html):
```
Priority Critical # set priority
Type Bug # set issue type
Deadline 2026-04-01 # set deadline
Assignee John, Jane # multiple assignees
Version 2.5.0 # set version
Dev Estimate 12 # set custom numeric field
State In Progress Priority High Type Task # multiple fields at once
project MOBILE # move issue to another project
```
All changes show a before/after diff and return rollback instructions.
> *"Set OPS-423 priority to Critical and assign to John"*
> *"Move PROJ-100 to the MOBILE project and set deadline to April 1st"*
> *"Set dev estimate to 8 and QA estimate to 3 on APP-55"*
## Query syntax examples
The `search_issues` tool accepts standard [YouTrack search queries](https://www.jetbrains.com/help/youtrack/server/Search-and-Command-Attributes.html):
```
project: Android state: Open # open Android issues
project: DevOps updated: -1w # DevOps issues updated in last week
assignee: John priority: Critical # John's critical issues
#Unresolved project: WordPress # unresolved WordPress issues
created: -3d .. today # issues created in last 3 days
project: Backend tag: ZTNA # Backend issues tagged ZTNA
```
## Issue templates
The server includes built-in templates for creating structured issues. Ask Claude to list them or use them directly:
- *"List available templates"*
- *"Create a bug report in the Android project"*
### Available templates
| Template | Sections |
|---|---|
| `bug` | Summary, Steps to Reproduce, Expected/Actual Result, Environment, Severity |
| `feature` | Problem, Proposed Solution, Alternatives, Acceptance Criteria, Priority |
| `task` | Objective, Requirements, Technical Notes, Definition of Done |
| `daily` | Done Yesterday, Planned Today, Blockers |
| `spike` | Goal, Context, Scope, Timebox, Findings, Recommendation |
| `release` | Version, Changes, Pre/Post-release Checklists, Rollback Plan |
| `devops` | Description, Requirement, Expected Result, Affected Services, Rollback Plan |
| `incident` | Impact, Symptoms, Environment, Steps to Reproduce, Root Cause, Fix Applied, Prevention |
| `epic` | Goal, Background, Scope, Success Criteria, Dependencies, Risks, Subtasks |
### Examples
**Bug report** — just describe the problem naturally:
> *"Create a bug in MOBILE: app crashes when switching between servers. Steps: connect to server A, tap server B, app freezes and restarts. Happens on Android 14. Critical severity."*
**Feature request:**
> *"Create a feature request in WEB: add dark mode toggle to the settings page. Should follow system theme by default. Must have priority."*
**DevOps task:**
> *"Create a devops task in OPS: Deploy new nodes in two additional regions. Need 2 servers per region with monitoring configured. Affected services: free-tier, premium-tier."*
**Daily standup:**
> *"Create a daily in OPS: Yesterday — fixed monitoring alerts, deployed config update to staging. Today — production rollout, server audit. No blockers."*
**Research spike:**
> *"Create a spike in MOBILE: Research crash causes on Android 13+. Timebox: 2 days. Need to determine if the issue is in the native layer or Java bridge."*
**Release checklist:**
> *"Create a release task in MOBILE: version 2.5.0. Changes: new auth flow, config updates, purchase module. Rollback: revert to 2.4.9 via app store."*
Claude will automatically use the matching template and fill in the sections from your description.
## Setup for claude.ai (web connector)
Use your YouTrack MCP as a custom connector in claude.ai (requires Pro, Max, Team, or Enterprise plan).
### 1. Deploy the server with OAuth enabled
Set `YOUTRACK_OAUTH_URL` to your server's public HTTPS URL. Optionally set `YOUTRACK_ACCESS_CODE` to require a code before connecting:
```bash
docker run -d -p 8000:8000 \
-e YOUTRACK_URL="https://your-instance.youtrack.cloud" \
-e YOUTRACK_TOKEN="perm:your-token-here" \
-e YOUTRACK_OAUTH_URL="https://your-server.example.com" \
-e YOUTRACK_ACCESS_CODE="your-secret-code" \
yt-mcp --transport sse
```
Put it behind a reverse proxy (Caddy, nginx, Cloudflare Tunnel) for HTTPS.
> Without `YOUTRACK_ACCESS_CODE`, OAuth auto-approves (no user interaction). With it, users see a simple form to enter the access code before connecting.
### 2. Add connector in claude.ai
1. Go to [claude.ai](https://claude.ai) → **Settings** → **Connectors**
2. Click **"+ Add custom connector"**
3. Enter a name: `YouTrack`
4. Enter your server URL: `https://your-server.example.com`
5. Complete the OAuth flow (auto-approved, no user interaction needed)
### 3. Use it
Start a conversation in claude.ai and ask about your YouTrack issues. All 84 tools are available.
> Without `YOUTRACK_OAUTH_URL`, OAuth is disabled and the server works in standard mode (stdio/SSE without auth) — no changes to existing setups.
## Using with n8n, Langchain, and other HTTP clients
By default the server uses **stdio** transport (for Claude Code). For integration with **n8n**, **Langchain**, **OpenAI Agents SDK**, or any HTTP-based MCP client, start the server in **SSE** or **streamable-http** mode:
### Start the server with SSE transport
```bash
YOUTRACK_URL="https://your-instance.youtrack.cloud" \
YOUTRACK_TOKEN="perm:your-token-here" \
uvx --from git+https://github.com/velesnitski/yt-mcp yt-mcp --transport sse --port 8000
```
The server will be available at `http://localhost:8000/sse`.
### Start with streamable HTTP transport
```bash
YOUTRACK_URL="https://your-instance.youtrack.cloud" \
YOUTRACK_TOKEN="perm:your-token-here" \
uvx --from git+https://github.com/velesnitski/yt-mcp yt-mcp --transport streamable-http --port 8000
```
The server will be available at `http://localhost:8000/mcp`.
### CLI options
| Flag | Default | Description |
|---|---|---|
| `--transport` | `stdio` | Transport protocol: `stdio`, `sse`, or `streamable-http` |
| `--host` | `0.0.0.0` | Host to bind to |
| `--port` | `8000` | Port to bind to |
### n8n setup
1. Start the server in SSE mode (see above)
2. In n8n, add an **MCP Client** node (or use the HTTP Request node)
3. Set the MCP server URL to `http://localhost:8000/sse`
4. The YouTrack tools will be available as actions in your n8n workflows
### Make.com setup
1. Start the server in SSE mode (see above)
2. In Make.com, use an **HTTP** or **MCP** module to connect to `http://localhost:8000/sse`
3. Use the `poll_changes` tool on a schedule to detect new activity:
- Set `query` to filter issues (e.g., `project: PROJ`)
- Set `since_minutes` to match your polling interval (e.g., `5`)
4. Route changed issues to other Make.com modules (Slack, email, Jira, etc.)
### Docker (for remote / always-on deployments)
**Using Docker Hub** (recommended):
```bash
docker run -d --name youtrack-mcp \
-e YOUTRACK_URL="https://your-instance.youtrack.cloud" \
-e YOUTRACK_TOKEN="perm:your-token-here" \
-p 8000:8000 \
velesnitski/yt-mcp
```
The server will be available at `http://localhost:8000/sse`.
**Using docker-compose:**
```yaml
services:
youtrack-mcp:
image: velesnitski/yt-mcp
ports:
- "8000:8000"
environment:
- YOUTRACK_URL=https://your-instance.youtrack.cloud
- YOUTRACK_TOKEN=perm:your-token-here
restart: unless-stopped
```
```bash
docker compose up -d
```
**Connect MCP clients to the Docker container:**
Claude Code (`~/.claude.json`):
```json
{
"mcpServers": {
"youtrack": {
"type": "url",
"url": "http://localhost:8000/sse"
}
}
}
```
Cursor (`.cursor/mcp.json`):
```json
{
"mcpServers": {
"youtrack": {
"url": "http://localhost:8000/sse"
}
}
}
```
**Using stdio via Docker** (no exposed port):
```json
{
"mcpServers": {
"youtrack": {
"command": "docker",
"args": ["run", "-i", "--rm",
"-e", "YOUTRACK_URL=https://your-instance.youtrack.cloud",
"-e", "YOUTRACK_TOKEN=perm:your-token-here",
"velesnitski/yt-mcp",
"--transport", "stdio"
]
}
}
}
```
**Override transport and port:**
```bash
docker run -d -p 9000:9000 \
-e YOUTRACK_URL="..." -e YOUTRACK_TOKEN="..." \
velesnitski/yt-mcp --transport streamable-http --port 9000
```
**Build from source:**
```bash
git clone https://github.com/velesnitski/yt-mcp.git
cd yt-mcp
docker build -t yt-mcp .
```
## Security
- Tokens are passed via environment variables — never hardcoded
- In **stdio** mode, the server has no network exposure (local pipes only)
- In **SSE/HTTP** mode, the server listens on a network port — bind to `127.0.0.1` if you don't need external access, or use a reverse proxy with authentication for production
- YouTrack API calls use HTTPS (non-HTTPS URLs are blocked unless `YOUTRACK_ALLOW_HTTP=1`)
- Consider using a token with minimal required permissions (read-only if you don't need `create_issue`)
- Bulk operations are capped at 100 issues per batch
- Error messages are truncated to prevent leaking internal API details
### Logging and privacy
All logs are stored **locally** on your machine at `~/.yt-mcp/`:
- `yt-mcp.log` — errors and warnings (JSON)
- `analytics.log` — tool call names, timing, and project codes (JSON)
**No data is sent externally** unless you explicitly set `SENTRY_DSN`. Logs never contain tokens, passwords, issue content, or descriptions — only tool names, project codes, and error messages (truncated to 200 chars).
### Read-only mode
To disable all write operations (create, update, delete issues/articles, bulk execute, time tracking):
```bash
YOUTRACK_READ_ONLY=true
```
### Disable specific tools
Block individual tools by name (comma-separated, case-insensitive):
```bash
DISABLED_TOOLS=delete_issue,bulk_update_execute,apply_translations
```
This removes the specified tools from the MCP server entirely — clients won't see them.
## Requirements
### Python 3.10+
Check your version:
```bash
python3 --version
```
If not installed or below 3.10:
- **macOS** (via [Homebrew](https://brew.sh)):
```bash
brew install python@3.12
```
- **Ubuntu / Debian**:
```bash
sudo apt update && sudo apt install python3 python3-pip
```
- **Windows**: download from [python.org](https://www.python.org/downloads/) or use `winget install Python.Python.3.12`
### uv (recommended)
[uv](https://docs.astral.sh/uv/) is a fast Python package manager. The `uvx` command (included with `uv`) is used to run the MCP server without a manual install.
```bash
uv --version # check if already installed
```
If not installed:
- **macOS / Linux**:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
Then restart your shell or run `source $HOME/.local/bin/env`.
- **macOS** (Homebrew alternative):
```bash
brew install uv
```
- **Windows**:
```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```
If you prefer not to use `uv`, see [Alternative installation methods](#alternative-installation-methods) for `pip`-based setup.
## License
MIT
TDQS
Scored across 84 tools
The core CRUD tools are distinct, but there are many overlapping analytics/reporting tools: get_top_active_issues vs get_team_dashboard vs get_team_pulse vs get_multi_team_dashboard/pulse, and get_handoff_snapshot vs get_stuck_handoffs vs track_cross_dept_journey vs get_active_sprint_issues. Descriptions do a good job explaining the differences, but an agent still has to read long prose to pick correctly. Some near-duplicates (search_issues vs run_saved_search vs count_issues) add friction.
Almost everything follows snake_case verb_noun (get_issue, create_article, add_comment, delete_work_item). A few minor deviations like get_agiles, poll_changes, and get_my_mentions break the pattern slightly but remain readable and consistent overall.
84 tools is an extreme overload for a single server. Many are highly specialized analytics (deadline_scorecard, audit_deadline_changes, suggest_managers, get_impact_map) that could be consolidated or split into sub-servers, making tool selection costly for an agent.
Coverage is unusually thorough: full CRUD for issues, comments, articles, article comments, work items, attachments, sprints, and boards, plus rollback, bulk operations, and heavy analytics. Minor gaps like no project creation or standalone tag management are easy workarounds.