ycli
Supports authenticating via Yandex Cloud service-account keys, minting IAM tokens (ServiceAccountAuth, enabled by the 'service-account' extra) so the toolkit can access Yandex 360 Tracker, Wiki, and Forms from service-account credentials.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@yclishow me the details of Yandex Tracker issue TRACKER-1"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ycli
One Yandex 360 toolkit — four ways to use it. Drive Tracker, Wiki, and Forms from a CLI, an MCP server, a Python SDK, or a Claude Code plugin. Built for AI agents first — pleasant for humans too.
English · Русский
🧩 One SDK, four surfaces — write logic once, use it as a CLI, an MCP server, a Python library, or a Claude Code plugin.
🤖 Agent-native — the MCP server exposes read and write
tracker_*,wiki_*,forms_*tools, one per SDK/CLI operation, plus a cross-cuttingstatustool (counts in Coverage), with honest annotations (reads are marked read-only; writes declare whether they are destructive/idempotent);ycli mcp start --read-onlyserves a reads-only view for cautious deployments, and--toolsets coreserves a curated everyday profile when a host limits how many tools it accepts.🛡️ Trustworthy — typed pydantic models, the real Yandex API quirks handled for you, and a test suite kept at 100% coverage.
⚡ Zero-friction start —
uv add yandex-cli,ycli auth login, go.
The full documentation (tutorial, how-to guides, the CLI, MCP and SDK reference) is at bim-ba.github.io/ycli.
Install
uv add yandex-cli # CLI + Python SDK
uv add 'yandex-cli[mcp]' # …plus the MCP server (`ycli mcp start`)Run it without installing, or install it as a standalone tool:
uvx yandex-cli --help # one-off, no install
uv tool install yandex-cli # persistent CLI
uv tool install 'yandex-cli[mcp]' # …with the MCP serverpip install yandex-cli works too. The CLI ships as both yandex-cli and the short ycli.
Using an AI harness (Claude Code, Claude Desktop, Cursor, VS Code, Codex, Gemini CLI, opencode, Docker)? See Install in your harness.
The SDK's ServiceAccountAuth (IAM tokens minted from a Yandex Cloud service-account key) needs
the service-account extra: uv add 'yandex-cli[service-account]'.
Related MCP server: Yandex Tracker MCP
Quick start
Pick the surface that fits how you work.
uv add yandex-cli
ycli --help
ycli tracker issues get TRACKER-1
ycli wiki pages get onboardingOutput formats — a global --format / -o picks how results print (the global options work before or after the subcommand: ycli -o json tracker issues get K = ycli tracker issues get K -o json; a command that declares an option of its own, like forms answers export --format, keeps it):
ycli tracker issues get TRACKER-1 # auto: a pretty table on a TTY…
ycli tracker issues get TRACKER-1 | jq . # …and raw JSON when piped (agent/script-safe)
ycli -o yaml wiki pages get onboarding # or: -o json | -o yaml | -o pretty
ycli --jq .summary tracker issues get TRACKER-1 # filter the JSON with jq; a string prints bare--jq EXPR runs a jq program over the command's JSON result and prints
like jq -r: a string comes out raw, anything else as one compact JSON value per line. It
cannot be combined with -o yaml / -o pretty, and it needs the jq Python package (a
dependency; it has no build for Windows on ARM).
Deleting asks first. A command that destroys data (every delete, clear, abort…) asks
DELETE <url> — this deletes data. Continue? on stderr when you are at a terminal, and exits 1
if you decline. In a script, a pipe or CI there is no one to ask, so it fails with exit 2 until
you pass --yes / -y: ycli tracker boards delete 7 --yes. Reads and ordinary writes never ask.
Preview a write. --dry-run sends nothing for any write: it prints the request instead
(method, URL, body; never your token), through the same -o / --jq output, and exits 0.
Reads still run, so a command that reads and then writes shows its first write only:
ycli tracker boards delete 7 --dry-run. (The two commands that ask the API itself to validate
a request, forms filling submit and wiki pages move, call that --validate-only.)
An endpoint ycli has not wrapped. ycli api PATH --service tracker|wiki|forms calls it like
gh api would, with the same auth, retries, output and exit codes:
ycli api issues/TRACKER-1 --service tracker --jq .summary # GET (the default method)
ycli api issues/TRACKER-1/comments --service tracker -F text=@note.md # POST: a field turns it into one
ycli api pages/descendants --service wiki -f slug=docs --paginate # every page, as one JSON arrayPATH is relative to the service's base URL; a full URL of a service needs no --service, and
any other host is refused (your token never goes elsewhere). -f key=value is a string, -F is
typed (true, null, numbers, JSON, @file for a file's text, key[sub]=v to nest, key[]=v
for an array); fields of a GET or DELETE go to the query string, otherwise to a JSON body (--input FILE sends a raw body instead). -H 'Name: value' adds a header, -X sets the method, and
--dry-run, --yes and --jq behave as everywhere. --paginate follows Tracker's Link: rel="next"
and Wiki's next_cursor; Forms pages its listings in more than one way, so pass its paging
parameters with -f yourself.
Run it over stdio (needs the mcp extra):
ycli mcp start # full read/write tool set (honest annotations)
ycli mcp start --read-only # reads-only view for cautious deploymentsServing every tool costs a large tools/list and some hosts cap a request (VS Code allows
128 tools), so pick what the session needs:
Flag | Serves |
| only those services ( |
| a curated everyday profile of about 40 tools (issues, comments, transitions, worklog, wiki pages and search, form reads) |
| add or hide single tools by name (unknown names fail at start) |
| no write tools; always wins over the flags above |
| lists a search tool and a call proxy instead of the tools; use it with a large set |
status_get is always served. The listing omits output schemas and doctest examples (results
still carry structuredContent), which cuts tools/list from about 1.9 MB to about 0.5 MB for
the full set.
For several users, serve it over HTTP: each MCP client signs its user in through Yandex ID (OAuth), and every tool call runs with that user's own Yandex token. Setup, including the Yandex OAuth app and the reverse proxy, is in Self-host over HTTP.
ycli mcp start --transport http --toolsets core # needs YCLI__MCP__BASE_URL and an OAuth appList the tool names a given set of flags exposes without running the server:
ycli mcp methods --toolsets core --read-onlyPoint an MCP client at it — no prior install needed via uvx (tools are namespaced
tracker_*, wiki_*, forms_*):
{
"mcpServers": {
"yandex": {
"command": "uvx",
"args": ["--from", "yandex-cli[mcp]", "ycli", "mcp", "start"],
"env": {
"YANDEX_ID_OAUTH_TOKEN": "...",
"YANDEX_ID_ORGANIZATION_ID": "..."
}
}
}
}from ycli.yandex.tracker.client import TrackerClient
tracker = TrackerClient(oauth_token="…", organization_id="…")
issue = tracker.issues.get("TRACKER-1")
print(issue.summary)/plugin marketplace add bim-ba/ycli
/plugin install yandex-360@ycliTeaches an agent to drive Yandex 360 through ycli — including the real API quirks.
See plugins/yandex-360/.
Skills (Claude Code plugin)
Skill | Use for |
| Entry point — install + auth, pick a surface (CLI/MCP/SDK), route to a domain |
| Issues, epics, comments, transitions, links, worklog, changelog |
| Wiki pages, page tree, comments, attachments, YFM authoring |
| Forms, questions/schema, responses, publishing |
The skills encode the read/write commands and the gnarly Yandex API quirks
(epic-vs-parent, transition discovery, permanent wiki slugs, fields= rules, Forms
host/header traps, answers pagination).
Configure
ycli reads two values from the environment (or a .env file — cp .env.example .env):
YANDEX_ID_OAUTH_TOKEN=... # a Yandex OAuth token with Tracker/Wiki/Forms access
YANDEX_ID_ORGANIZATION_ID=... # your Yandex 360 organization idycli sends the org id as X-Org-Id for every service (HTTP header names are case-insensitive
per RFC 9110, so one casing serves all).
Optional settings follow the YCLI__<GROUP>__<SETTING> pattern; ycli rejects an invalid value
at startup and names the variable:
Variable | Default | Meaning |
|
| Per-request timeout, seconds (> 0) |
|
| Retries for idempotent requests on 429/5xx (≥ 0) |
|
| Item cap for listings without |
|
|
|
|
|
|
Get your credentials
Yandex issues OAuth tokens only through a registered application, so it's a one-time app registration plus one command.
1. Register an OAuth app at oauth.yandex.ru and
grant it the Tracker, Wiki, and Forms permissions (read and write — the
CLI and the MCP server both write; the read scopes alone suffice only if you run the MCP
server with ycli mcp start --read-only). Put the ClientID — and the Client secret
if you want the headless flow — in your .env (ycli reads it from there):
YANDEX_OAUTH_CLIENT_ID=... # from your app
YANDEX_OAUTH_CLIENT_SECRET=... # optional — enables the headless device flow2. Log in. ycli auth login gets a token, detects your organization, and writes both
into .env:
ycli auth loginclient id + secret → the device flow: ycli prints a code and a
https://ya.ru/devicelink; approve there and it captures the token — no redirect, works over SSH.only the client id (or
--implicit) → the browser flow: ycli opens the Yandex authorize page; approve, then copy the token it displays and paste it back.
Check it any time with ycli auth status: it shows whose token it is (from Yandex ID), your
organization (its name needs the optional directory:read_organization scope; without it you
get the id and a note) and whether each service accepts the token. ycli tracker auth status
(or wiki, forms) probes just that one service. Both exit non-zero when a service rejects
the token.
Headless (device flow):
# 1. start the flow — returns a user_code + verification_url
curl -s -X POST https://oauth.yandex.ru/device/code -d "client_id=$YANDEX_OAUTH_CLIENT_ID"
# 2. open https://ya.ru/device, enter the user_code, approve
# 3. exchange the device_code for the token
curl -s -X POST https://oauth.yandex.ru/token \
-d grant_type=device_code -d "code=<device_code>" \
-d "client_id=$YANDEX_OAUTH_CLIENT_ID" -d "client_secret=$YANDEX_OAUTH_CLIENT_SECRET"Browser (implicit): open
https://oauth.yandex.ru/authorize?response_type=token&client_id=<ClientID> in a logged-in
browser, approve, and copy the token from the page. (Plain curl can't — implicit needs an
interactive browser session.)
Organization id: tracker.yandex.ru/admin/orgs → your organization → copy the identifier.
The Yandex documentation behind each step:
Step | Yandex docs |
Register the OAuth app | Registering an app (Yandex ID) |
Device flow ( | |
Browser flow ( | |
Token and organization header per service |
Exit codes
A failed ycli command exits with a code that says what kind of failure it was, so a script can branch without parsing the message.
Code | Meaning | When |
0 | ok | the command succeeded |
1 | failure | any other failure: a 4xx the API rejected, an unmapped error, a declined confirmation |
2 | usage | a bad command line or an invalid |
3 | not found | the API answered 404 (or the token cannot see the object) |
4 | auth | 401 / 403, or no credentials set |
5 | rate limited | the API answered 429 and the retries ran out (the hint shows |
6 | transient | a 5xx, a timeout or a lost connection: worth retrying later |
Coverage
ycli wraps 334 operations across 62 resources of the Tracker, Wiki, and Forms REST API. Every one is reachable from the Python SDK and the CLI, and 322 MCP tools serve them to agents (321 per service plus status_get).
Legend. ✅ in CLI or MCP means the resource is reachable on that surface; MCP tools carry honest hints (reads are
readOnlyHint, writes say whether they are destructive or idempotent), andycli mcp start --read-onlyserves only the reads. Resource and operation names link to the official Yandex API reference. A ✅ says ycli wraps the operation; where it differs from what Yandex publishes is listed under Against the published API. Generated from the code byscripts/gen_coverage.py; do not edit by hand.
Tracker
Issues & work items
Resource | Operations | CLI | MCP |
get · search · count · create · update · move · suggest · scroll_clear | ✅ | ✅ | |
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ | ||
list · download · download_thumbnail · get · delete · upload · upload_temp | ✅ | ✅ | |
✅ | ✅ |
Agile boards
Resource | Operations | CLI | MCP |
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ |
Dictionaries
Resource | Operations | CLI | MCP |
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ | ||
linktypes | list | ✅ | ✅ |
Fields, queues & structure
Resource | Operations | CLI | MCP |
list · get · create · edit · category_create · category_edit | ✅ | ✅ | |
✅ | ✅ | ||
list · create · edit · list_for_queue · get · delete · user_permissions · group_permissions | ✅ | ✅ | |
list · get · tags · versions · fields · create · delete · restore · set_permissions · tag_remove · version_create · version_get · version_edit · version_delete · user_permissions · group_permissions | ✅ | ✅ | |
list · get · for_queue · create · edit · edit_action · delete | ✅ | ✅ | |
✅ | ✅ |
Automation & bulk
Resource | Operations | CLI | MCP |
✅ | ✅ | ||
list · get · create · edit · webhook_log | ✅ | ✅ | |
get · create · logs · log_detail | ✅ | ✅ | |
✅ | ✅ | ||
update · move · transition · get · issues | ✅ | ✅ | |
✅ | ✅ |
Entities, users & search
Resource | Operations | CLI | MCP |
create · get · edit · delete · search · history · permissions · set_permissions · direct_permissions · set_direct_permissions · bulk_update · bulk_status · create_report · comments_list · comments_relative · comments_get · comments_create · comments_edit · comments_delete · checklists_create · checklists_edit · checklists_edit_item · checklists_delete · checklists_delete_item · checklists_move · links_list · links_create · links_delete · attachments_list · attachments_get · attachment_download · attachments_attach · attachments_delete | ✅ | ✅ | |
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ |
Wiki
Pages
Resource | Operations | CLI | MCP |
get_by_id · get · descendants · descendants_by_id · grids · create · update · delete · append_content · clone · move · revisions · backlinks | ✅ | ✅ | |
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ |
Collaboration
Resource | Operations | CLI | MCP |
list · thread · thread_get · create · delete | ✅ | ✅ | |
list · get · preview · download · download_by_url · delete · attach · upload | ✅ | ✅ | |
✅ | ✅ |
Grids (dynamic tables)
Resource | Operations | CLI | MCP |
get · create · update · delete · add_rows · remove_rows · move_rows · add_columns · remove_columns · move_columns · update_cells · clone · suggest_column · update_column · update_row | ✅ | ✅ |
Async & uploads
Resource | Operations | CLI | MCP |
✅ | ✅ | ||
✅ | ✅ |
Identity
Forms
Surveys & questions
Resource | Operations | CLI | MCP |
✅ | ✅ | ||
✅ | ✅ | ||
question_list · question_get · question_create · question_modify · question_delete · question_set_operator · page_list · page_get · page_create · page_modify · page_delete · page_set_operator · submit_list · submit_get · submit_create · submit_modify · submit_delete · submit_set_operator · hook_list · hook_get · hook_create · hook_modify · hook_delete · hook_set_operator | ✅ | ✅ | |
✅ | ✅ | ||
✅ | ✅ |
Responses & export
Resource | Operations | CLI | MCP |
get · list · list_all · export · export_results · download_export · integrations_list · delete · restore | ✅ | ✅ | |
✅ | ✅ |
Integrations
Resource | Operations | CLI | MCP |
✅ | ✅ | ||
✅ | ✅ | ||
✅ | ✅ | ||
list · get · status_get · restart · cancel · errors_list | ✅ | ✅ |
Distribution
Resource | Operations | CLI | MCP |
✅ | ✅ | ||
✅ | ✅ |
Media
Identity
Every resource and operation above deep-links to the Yandex API reference: 318 of 334 operations resolve to their own endpoint page and 15 to their resource's page. No public API reference exists yet for tracker.linktypes, tracker.linktypes.list, shown as plain text. See CONTRIBUTING.md for the intentional exclusions (UI-only endpoints with no public REST API) and per-method notes.
Against the published API
What ycli sends, replayed from its contract tests, compared with what Yandex publishes: the Wiki and Forms OpenAPI documents and Tracker's API reference (prose, so only operations and the query parameters a page lists are compared). The published side is the snapshot in scripts/api_snapshot/; a weekly job fetches it again and opens an issue when Yandex has changed it.
Service | Published | Wrapped | Not wrapped | Operations that differ | Source |
Tracker | 190 | 188 | 0 (+2 on purpose) | 25 | |
Wiki | 56 | 56 | 0 | 15 | |
Forms | 84 | 84 | 0 | 15 |
Not wrapped on purpose
Operation | Why |
| |
|
Sent by ycli, not published
ycli | Its request |
|
|
|
|
Parameters and fields
Operation | ycli | Difference |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
|
| query parameters ycli cannot send: |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
| query parameters ycli cannot send: | |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: | |
| query parameters ycli cannot send: |
Parameters and fields
Operation | ycli | Difference |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
|
| response fields ycli drops: |
|
| query parameters ycli cannot send: |
|
| response fields ycli drops: |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
|
| query parameters ycli cannot send: |
|
| response fields ycli drops: |
Parameters and fields
Operation | ycli | Difference |
|
| response fields ycli drops: |
|
| response fields ycli drops: |
|
| query parameters ycli cannot send: |
|
| response fields ycli drops: |
|
| response fields ycli drops: |
|
| response fields ycli drops: |
|
| query parameters ycli cannot send: |
|
| response fields ycli drops: |
|
| response fields ycli drops: |
|
| query parameters ycli sends that are not published: |
|
| query parameters ycli cannot send: |
|
| response fields ycli drops: |
|
| response fields ycli drops: |
|
| response fields ycli drops: |
|
| response fields ycli drops: |
Development
uv sync --all-extras # --all-extras pulls in the `mcp` extra the tests exercise
uv run pytest # 100% coverage gate; HTTP stubbed with `MockAPI` (no live network)The source layout and the invariants that keep it regular are in ARCHITECTURE.md; see CONTRIBUTING.md for conventions and how to add an endpoint. Contributions welcome.
License
MIT © 2026 Sava Znatnov
This server cannot be deployed
Maintenance
Related MCP Connectors
Exposes FEDLIN's public security scanners as agent-callable tools over Streamable HTTP.
A read-only verified record of agent-operable GTM tools: search, fetch, compare, track changes.
Anonymous public tools for FlightSweeper. See the published agent boundary before use.
Operate smplkit from your agent: feature flags, config, logging, audit, and scheduled jobs.
Related MCP Servers
- FlicenseAqualityDmaintenanceExposes Yandex Tracker's REST API v3 as tools for LLM clients, enabling issue management and queue operations via natural language.21-
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to manage Yandex Tracker tasks with tools for creating, reading, updating, and transitioning issues via a Streamable HTTP endpoint.-
- AlicenseNot gradedqualityAmaintenanceExposes selected operations of an existing REST/OpenAPI app as MCP tools with generated schemas, permission annotations, and a risk class, requiring explicit opt-in before anything is listed and a second flag for destructive calls. Enforces security-first guardrails such as environment-injected auth, a single confined base URL, timeouts, response caps, rate limiting, and a local test console for trying tools.MIT
- AlicenseNot gradedqualityCmaintenanceEnables read-only MCP access to Yandex Tracker for retrieving issues with comments and attachment metadata, searching issues, reading issue history, downloading attachments, and finding users. It also supports connection status checks and token configuration without exposing secrets.44 npmMIT