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.
- 🧩 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-only
tracker_*,wiki_*,forms_*tools so agents explore safely; writes stay in the CLI/SDK. - 🛡️ 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, two env vars, go.
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.
Pick the surface that fits how you work.
CLI
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:
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 prettyMCP server (read-only)
Run it over stdio (needs the mcp extra):
ycli mcp startList the exposed tool names without running the server:
ycli mcp methodsPoint 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": "..."
}
}
}
}Python SDK
from ycli.yandex.tracker.client import TrackerClient
tracker = TrackerClient(oauth_token="…", organization_id="…")
issue = tracker.issues.get("TRACKER-1")
print(issue.summary)Claude Code plugin
/plugin marketplace add bim-ba/ycli
/plugin install yandex-360@ycli
Teaches an agent to drive Yandex 360 through ycli — including the real API quirks.
See plugins/yandex-360/.
| Skill | Use for |
|---|---|
yandex-360 |
Entry point — install + auth, pick a surface (CLI/MCP/SDK), route to a domain |
yandex-360-tracker |
Issues, epics, comments, transitions, links, worklog, changelog |
yandex-360-wiki |
Wiki pages, page tree, comments, attachments, YFM authoring |
yandex-360-forms |
Forms, questions/schema, responses, pagination |
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).
Reads ship across SDK + CLI + MCP; writes across SDK + CLI only (the MCP server is read-only by design).
| Resource | Operations | SDK | CLI | MCP |
|---|---|---|---|---|
| issues | get · full · search · list · count | ✅ | ✅ | ✅ |
| issues | create · update | ✅ | ✅ | — |
| comments | list | ✅ | ✅ | ✅ |
| comments | add | ✅ | ✅ | — |
| links | list | ✅ | ✅ | ✅ |
| links | add | ✅ | ✅ | — |
| transitions | list | ✅ | ✅ | ✅ |
| transitions | execute | ✅ | ✅ | — |
| worklog · changelog · priorities · issuetypes · linktypes | list | ✅ | ✅ | ✅ |
| Resource | Operations | SDK | CLI | MCP |
|---|---|---|---|---|
| pages | get · descendants | ✅ | ✅ | ✅ |
| pages | meta (metadata-only) | — | — | ✅ |
| pages | create · update | ✅ | ✅ | — |
| comments | list | ✅ | ✅ | ✅ |
| attachments | list | ✅ | ✅ | ✅ |
| Resource | Operations | SDK | CLI | MCP |
|---|---|---|---|---|
| me | get (whoami) | ✅ | ✅ | ✅ |
| surveys | list · get | ✅ | ✅ | ✅ |
| questions | list | ✅ | ✅ | ✅ |
| answers | list (drains all pages) | ✅ | ✅ | ✅ |
Mail and more — coming. See
docs/api-coverage.mdfor the full gap analysis and prioritized roadmap.
cp .env.example .envYANDEX_ID_OAUTH_TOKEN=... # get one at https://oauth.yandex.ru/
YANDEX_ID_ORGANIZATION_ID=... # from the Yandex 360 admin panelHeader casing differs per service (Tracker X-Org-ID, Wiki/Forms X-Org-Id) — ycli
handles it for you.
src/ycli/
├── cli.py # root Typer CLI → `ycli` / `yandex-cli`
├── mcp.py # root FastMCP server → `ycli mcp start` (read-only, `[mcp]` extra)
├── log.py # central loguru config
└── yandex/
├── tracker/ # per-domain SDK …
├── wiki/ # each resource group has:
└── forms/ # client.py · cli.py · mcp.py · models.py
plugins/yandex-360/ # distributable Claude Code plugin (skills + instructions)
docs/references/ # vendored Yandex API reference docs
uv sync --all-extras # --all-extras pulls in the `mcp` extra the tests exercise
uv run pytest # 100% coverage gate; HTTP stubbed with `responses` (no live network)See CONTRIBUTING.md for conventions. Contributions welcome — the coverage roadmap is a good place to find a first issue.
MIT © 2026 Sava Znatnov