YouTrack
Generic YouTrack REST JSON CLI with stdlib HTTP only. Reads cover the current user, projects, users, issues, comments, attachments, activity history, custom-field schema, and knowledge-base articles. Writes are intentionally gated.
For approval-first procedural guidance, read the matching reference before acting:
- issue creation:
references/create-issue.md; - Knowledge Base publication/update:
references/kb-article.md.
Local .env
The CLI automatically loads a private .env beside this SKILL.md through pass-cli. Copy .env.example to .env; never commit the real file.
A single .env may hold namespaced profiles. Select one explicitly:
uv run --python 3.13 python scripts/yt.py --profile work me
Without --profile, ordinary YOUTRACK_* variables are used.
Configuration
| Variable | Required | Default |
|---|---|---|
YOUTRACK_URL |
yes (or --url) |
none |
YOUTRACK_TOKEN |
yes | none |
YOUTRACK_PROJECT |
no | used as default --project |
YOUTRACK_ALLOW_WRITE |
no | false |
Use a token with the minimum scope needed. Never print or paste the token.
Secret setup
Before configuring credentials, ask which secret manager and local profile the user wants. Follow Secure secret profiles. Do not invent or publish profile names, hosts, templates, or secret references. If the user asks for the author's method, use a per-profile Proton Pass pointer file with process-scoped pass-cli run. Never request or display resolved values.
Run
From this skill directory:
uv run --python 3.13 python scripts/yt.py me
uv run --python 3.13 python scripts/yt.py projects --query Demo
uv run --python 3.13 python scripts/yt.py users --query alice
uv run --python 3.13 python scripts/yt.py issues --query "project: DEMO State: Open" --top 20
uv run --python 3.13 python scripts/yt.py issue DEMO-123
uv run --python 3.13 python scripts/yt.py comments DEMO-123
uv run --python 3.13 python scripts/yt.py fields --project DEMO
uv run --python 3.13 python scripts/yt.py articles --query "project: DEMO"
uv run --python 3.13 python scripts/yt.py article DEMO-A-1
Pass --url https://youtrack.example.net to override YOUTRACK_URL for one run. Global options such as --profile, --url, and --confirm-write go before the subcommand.
Write gate
Every mutation requires both of these:
YOUTRACK_ALLOW_WRITE=true- explicit
--confirm-write
Without both, create/update/comment/article mutations fail locally before any request is sent.
Reads
| Command | Purpose |
|---|---|
me |
current user |
projects --query Q [--top N] [--skip N] |
list/search projects |
users --query Q [--top N] [--skip N] |
list/search users |
issues --query Q [--top N] [--skip N] |
issue search |
issue ID |
one issue |
comments ID [--top N] [--skip N] |
issue comments |
attachments ID [--top N] [--skip N] |
issue attachments |
activities ID [--top N] [--skip N] |
issue activity/changelog |
fields --project KEY [--top N] [--skip N] |
project custom-field schema |
articles --query Q [--top N] [--skip N] |
article search |
article ID |
one article with content |
article-attachments ID [--top N] [--skip N] |
article attachments |
KEY can be a project short name or internal id. Output is UTF-8 JSON.
Controlled writes
YOUTRACK_ALLOW_WRITE=true \
uv run --python 3.13 python scripts/yt.py --confirm-write create \
--project DEMO \
--summary "Add generic YouTrack skill" \
--description @body.md
YOUTRACK_ALLOW_WRITE=true \
uv run --python 3.13 python scripts/yt.py --confirm-write update DEMO-123 \
--summary "Updated title"
YOUTRACK_ALLOW_WRITE=true \
uv run --python 3.13 python scripts/yt.py --confirm-write comment DEMO-123 \
--text "Done."
YOUTRACK_ALLOW_WRITE=true \
uv run --python 3.13 python scripts/yt.py --confirm-write article-create \
--project DEMO \
--summary "Runbook" \
--content @article.md
YOUTRACK_ALLOW_WRITE=true \
uv run --python 3.13 python scripts/yt.py --confirm-write article-update DEMO-A-1 \
--content @article.md
YOUTRACK_ALLOW_WRITE=true \
uv run --python 3.13 python scripts/yt.py --confirm-write attach DEMO-123 screenshot.png
YOUTRACK_ALLOW_WRITE=true \
uv run --python 3.13 python scripts/yt.py --confirm-write command \
--query "State Fixed" --issues DEMO-123
Additional controlled writes are comment-update, comment-delete, article-attach, and multi-issue command. Attachment uploads are bounded to 100 MiB combined per invocation.
--description, --text, --content, and --custom-fields accept a literal string, @file, or - for stdin.
Field discovery and selectors
Before creating an issue, inspect the project schema instead of hardcoding internal field values:
uv run --python 3.13 python scripts/yt.py fields --project DEMO
uv run --python 3.13 python scripts/yt.py users --query alice
create --custom-fields and update --custom-fields accept either raw YouTrack customFields JSON or selector objects that resolve against the live schema and user search results. For selector-based updates, pass --project or set YOUTRACK_PROJECT.
Example selectors:
[
{"name": "Priority", "$byName": "Critical"},
{"name": "Assignee", "$user": "alice"},
{"name": "Tags", "$byNames": ["api", "docs"]}
]
The CLI converts these to REST payloads using project field schema and user lookup, so agents can discover valid options first and avoid hardcoded ids.
Safety and behavior
- Uses Python stdlib
urllib; no MCP and no third-party HTTP client. - Uses UTF-8 JSON for stdin, files, stdout, and request bodies.
- Read commands support pagination with
--topand--skip. - Comment edits/deletes, attachment uploads, commands, and article attachment uploads use the same double gate as every other mutation.
- Helpful HTTP errors include status and server message when available.
- The token is read from
YOUTRACK_TOKENand is never printed. - Keep
--topbounded; the CLI rejects oversized page sizes.
Tests
uv run --python 3.13 python tests/test_yt.py