hermes-yandex-disk
Your Yandex Disk, handed to the agent. It can walk the folders, read a file into the conversation, write the answer back, and give you a share link — without you opening a browser.
"Read me the March invoice in /Documents/Accounting." "Save these meeting notes to /Notes/2026/ and give me a link." "What's eating my Disk space? Move the old videos into /Archive." "Restore that file I deleted this morning."
- 🔒
YANDEX_DISK_ROOTsandboxes the agent to one folder of the Disk — every Disk path is checked against it, including ones the model invents and ones it copies back from an earlier result. Files on your own machine follow Hermes' rules instead: see Local files. - 🛟 Nothing is overwritten or destroyed by accident — writes, copies, moves and uploads
refuse an existing destination unless you pass
overwrite, deletes go to the bin by default, and the bin can be restored from. Replacing is never done by clearing the way first: an upload from aurlis staged beside the target and moved over it once Yandex has finished fetching, and a download writes beside the local file and moves over it once the transfer is complete. A transfer that fails costs you the new copy, never the one you already had. - 🎚
YANDEX_DISK_ACTIONSdecides what the agent may do at all — a tool outside the allow-list is never registered, so it cannot be called or talked into being called. - 📂 Fourteen tools over one credential — browse, read, write, upload, download, copy,
move, share and restore, all through the REST API — plus a fifteenth,
yadisk_search, wherever the token is allowed to use Yandex's search endpoint. - 🔑 One OAuth token, nothing proxied — the plugin talks to
cloud-api.yandex.netdirectly; no third-party service sees your files or your token.
Needs Hermes v2026.9.24 (0.21.5) or later. Checked on every pull request, weekly, and before
every release against Hermes v2026.9.24, the latest Hermes release and Hermes main, each
installed by its official installer; Python 3.11–3.14.
Quick start
# 1. Install the plugin into Hermes (other ways: see Installing). It asks for
# your token; issue one at https://yandex.ru/dev/disk/poligon/
# (scopes: cloud_api:disk.info, cloud_api:disk.read, cloud_api:disk.write)
hermes plugins install akinfold/hermes-yandex-disk/hermes_yandex_disk --enable
# 2. Skipped the question, or installed another way? Add the token yourself:
echo 'YANDEX_DISK_OAUTH_TOKEN=y0_your_token_here' >> ~/.hermes/.env
# 3. `--enable` already wrote this into ~/.hermes/config.yaml
plugins:
enabled: [yandex-disk]
Restart Hermes and ask it: "How much space is left on my Yandex Disk?"
Not ready to hand over write access? Add
YANDEX_DISK_ACTIONS=readto~/.hermes/.envand the agent gets a read-only Disk. See Choosing what the agent may do.
The tools
| Tool | What it does |
|---|---|
yadisk_disk_info |
Quota, used and bin space, account login |
yadisk_list |
List a folder, or show one file's metadata |
yadisk_search |
Find files by name or contents — only where the token may search (why) |
yadisk_read_file |
Read a text file's contents into the conversation |
yadisk_trash_list |
What is in the bin, and where each item came from |
yadisk_download |
Save a file from the Disk to the local machine (Local files) |
yadisk_mkdir |
Create a folder, parents included |
yadisk_write_file |
Create or replace a text file from the agent's own output |
yadisk_upload |
Upload a local file (Local files), or have Yandex fetch a public URL |
yadisk_copy |
Server-side copy — no bytes pass through your machine |
yadisk_move |
Move or rename |
yadisk_trash_restore |
Put something back where it was deleted from |
yadisk_publish |
Create or revoke a public share link |
yadisk_delete |
Delete to the bin, or permanently with permanently=true |
yadisk_trash_empty |
Destroy one bin item, or the whole bin |
Every read result carries the path the write tools take as input, so the agent can chain
them without guessing.
Changed in 0.6.0. The token is read from
YANDEX_DISK_OAUTH_TOKENonly: the aliasYANDEX_DISK_API_KEYis no longer accepted, so if your token is stored under that name, rename it. The plugin now declares that it needs Hermes v2026.9.24 (0.21.5) or later: an older Hermes that checks the floor (v2026.9.11 on) skips it at load, and earlier ones are not supported. Andyadisk_uploadandyadisk_downloadrefuse the local files Hermes' own file tools refuse — see Local files.
Changed in 0.5.0.
yadisk_uploadfrom aurlused to ignoreoverwrite. Yandex' fetch-from-internet endpoint has no such parameter and the plugin did not stand in for it, so an upload onto a path that was already taken did whatever the server decided — the API documentation does not say what. It is now refused unless you passoverwrite=true, the same as every other write. If anything of yours uploads by URL over a file that is already there, add the flag before upgrading.
Configuration
| Variable | Required | Default | Meaning |
|---|---|---|---|
YANDEX_DISK_OAUTH_TOKEN |
yes | — | OAuth token for the account |
YANDEX_DISK_ACTIONS |
no | all tools | Which tools get registered — see below |
YANDEX_DISK_ROOT |
no | whole disk | Confine every Disk path to this folder (local paths are unaffected) |
YANDEX_DISK_MAX_READ_BYTES |
no | 1048576 |
Largest file yadisk_read_file will pull into context |
YANDEX_DISK_MAX_DOWNLOAD_BYTES |
no | 268435456 |
Largest file yadisk_download will write locally |
YANDEX_DISK_TIMEOUT |
no | 30 |
Per-request timeout, in seconds |
YANDEX_DISK_BASE_URL |
no | https://cloud-api.yandex.net/v1/disk |
API base, for testing against a stub; the token goes to whatever it names |
Put them in ~/.hermes/.env — Hermes reads it in gateway and subprocess runs too — or export
them in the environment.
The two byte limits take a whole number of bytes and the timeout a number of seconds, fractions
allowed. A value that is not a number, or is zero or negative — 5MB, 60s, 0 — is ignored
without an error and the default applies.
Two further limits are fixed and cannot be configured. A request answered with 429, 500, 502,
503 or 504, or one that fails to connect, is retried up to three times (honouring Retry-After,
capped at 30 seconds), so a single call can take longer than YANDEX_DISK_TIMEOUT. Large copies,
moves, deletes, restores and bin operations run as deferred operations on Yandex's side; the
plugin waits up to 60 seconds for one to finish and then reports that it is still being
processed. Such an operation usually completes on its own, so check with yadisk_list before
retrying.
Confining the agent to one folder
YANDEX_DISK_ROOT=/Hermes
Every path the agent gives is then interpreted relative to disk:/Hermes, and anything that
resolves outside it — an absolute disk:/Private/..., a ../ climb, a path pasted from
somewhere else — is refused before a request is made. Results are rewritten so the agent never
sees the prefix: every path it gets back is relative to that folder — disk:/Hermes/notes.md
comes back as /notes.md — and can be handed straight to the next tool. The agent sees a disk
whose root is that folder. The bin is filtered the same way: items deleted from outside the
sandbox are neither listed nor restorable, and emptying the whole bin is refused, because the
bin is shared with the rest of the account.
Local files
Two tools reach past the Disk to the machine Hermes runs on: yadisk_upload with a
local_path reads a file there and sends it to Yandex, and yadisk_download writes one there.
A relative path is taken from the directory the Hermes process runs in, and ~ is expanded.
YANDEX_DISK_ROOT does not apply to these paths.
Before touching a local path, both tools ask Hermes' own file rules — the ones its file tools
follow — and refuse what those refuse. An upload is refused for Hermes' credential stores
(.env, auth.json and the like under ~/.hermes) and for any .env file anywhere. A
download is refused onto credential files (Hermes' .env, SSH and cloud-provider keys and
logins, and so on), into Hermes' session and token directories, onto your SSH client
configuration (Hermes' file tools write that only with a person's approval, which a tool
cannot ask for), and outside HERMES_WRITE_SAFE_ROOT when you have set it. Hermes does not document these rules for plugins, so a Hermes release could move them; the
plugin then falls back to refusing .env files in both directions, as it does outside Hermes.
They keep the agent from being talked into sending your Hermes keys to the Disk or replacing
them from it. They are not a sandbox: any other local file the Hermes process can read can be
uploaded, SSH keys included, and anything else the agent runs as your user, a terminal for
one, reaches the same files. To keep the agent off local files altogether, leave download
and upload out of YANDEX_DISK_ACTIONS:
YANDEX_DISK_ACTIONS=read,mkdir,write_file,copy,move,trash_restore
Choosing what the agent may do
YANDEX_DISK_ACTIONS=read,write # no deleting, no sharing
YANDEX_DISK_ACTIONS=read # a read-only Disk
YANDEX_DISK_ACTIONS=list,read_file # exactly two tools
| Group | Tools |
|---|---|
read |
disk_info, list, read_file, trash_list, and search when the token may use it |
download |
download (writes to the local machine) |
write |
mkdir, write_file, upload, copy, move, trash_restore |
share |
publish |
delete |
delete, trash_empty |
all |
everything — the default when the variable is unset |
search is capability-gated: Yandex grants its search endpoint per application rather than
per token scope, so the plugin probes it once at load and registers the tool only if the probe
succeeds. Granting read therefore also grants a whole-disk search wherever the token is
allowed to run one; name the tools individually to withhold it. The probe is one request that
waits two seconds at most, because Hermes gives a plugin ten seconds to load and drops every
tool of one that takes longer: if Yandex does not answer in time, search is simply missing
until the next start.
Groups and individual tool names mix freely, with or without the yadisk_ prefix, so you can
paste straight from the tool table above. A name that matches nothing is dropped: a typo can
only ever withhold a tool, never grant one, and a value naming nothing valid (none, say)
registers nothing at all. An empty or blank value counts as unset and therefore registers
every tool. Filtering happens when the plugin loads, so restart Hermes after changing it.
Getting the credential
- Open https://yandex.ru/dev/disk/poligon/ signed in as the account you want the agent to use, and issue a debug token — the fastest route, and what it gives you is an ordinary OAuth token.
- For a long-lived setup, register an app at https://oauth.yandex.ru/ with the scopes
cloud_api:disk.info,cloud_api:disk.readandcloud_api:disk.write, then run the usual OAuth flow.
Yandex Disk is free up to 5 GB and the API costs nothing to use. The token is the only credential needed — see Why REST and not WebDAV for why there is no app password to store.
Installing
A. From Git (recommended)
hermes plugins install akinfold/hermes-yandex-disk/hermes_yandex_disk --enable
Note the /hermes_yandex_disk at the end. The plugin lives in that directory, not
at the repository root, and Hermes reads the manifest from whatever you point it
at. Name the directory and the install is a plugin: Hermes prompts for
YANDEX_DISK_OAUTH_TOKEN, installs under the manifest name yandex-disk, and
--enable enables that name. It also scans only that directory, so the tests and
workflows in this repository stay out of the security report.
Point it at the repository root instead and Hermes copies a directory with no
manifest and no register(ctx) in it: it warns that it "may not be a valid Hermes
plugin", asks for no token, and does not enable the plugin. hermes plugins list
then still shows yandex-disk — the package nested in the clone is found — but
shows it as not enabled, which is the symptom to look for. If you installed
that way, remove ~/.hermes/plugins/hermes-yandex-disk and install again with the
directory named.
B. From PyPI — for a Hermes whose Python environment you manage yourself (your own
virtualenv, a Nix build): install hermes-yandex-disk into that environment, then enable the
plugin. Hermes finds it through the hermes_agent.plugins entry point.
hermes plugins enable yandex-disk
Not for a standard Hermes install. Since 24 September 2026 the official installer runs Hermes from environments its package manager builds and replaces, and Hermes does not support adding packages to them by hand: use A or C.
A Hermes in the older layout — one that runs from ~/.hermes/hermes-agent/venv and keeps its
own uv in ~/.hermes/bin, with no ~/.hermes/installs — takes the package like this:
~/.hermes/bin/uv pip install --python ~/.hermes/hermes-agent/venv/bin/python hermes-yandex-disk
hermes plugins enable yandex-disk
That layout is what the installer of Hermes v2026.9.24, the last release to build it, sets up, and what anything installed before that date and not updated since looks like. Tell it by those directories, not by the version number Hermes reports.
Switch such an install to A before you run hermes update: the update moves Hermes onto the
new environments, and a package installed this way does not come along. The loss is silent:
yandex-disk stays enabled in the configuration, but its tools are gone, and neither the
update nor hermes doctor mentions it. If you have already updated, install it with A now:
that brings the tools back and keeps your token in ~/.hermes/.env. A bare
pip install hermes-yandex-disk never reached Hermes at all — the pip on your PATH belongs
to some other Python.
Nothing asks for the token on this path — add it to ~/.hermes/.env as in the
Quick start.
C. Drop-in — download hermes-yandex-disk-plugin-<version>.zip from a
release, then unzip it into
~/.hermes/plugins/ and enable it:
unzip hermes-yandex-disk-plugin-<version>.zip -d ~/.hermes/plugins/
hermes plugins enable yandex-disk
You should end up with ~/.hermes/plugins/yandex-disk/plugin.yaml. Nothing asks for the
token here either: add it to ~/.hermes/.env yourself. The archive brings no dependencies;
the one the plugin needs, httpx, is a Hermes dependency already.
Upgrading
Upgrade the way you installed. From Git (A), Hermes installs the new version from the source it recorded:
hermes plugins update yandex-disk
Running the install command again with --force does the same by another route: it installs
what the default branch holds now, replaces the installed copy, and keeps your token. A Hermes
older than v2026.9.24 (0.21.5) cannot update an install from a plugin directory, and from 0.6.0
on the plugin does not support it either: update Hermes first.
hermes plugins install akinfold/hermes-yandex-disk/hermes_yandex_disk --enable --force
An install pinned to a commit with --ref stays on that commit through both:
hermes plugins update refuses to move it, and --force without a new --ref installs the
same commit again. hermes plugins list shows the pin in its Source column, as git pinned@
and the first eight characters of the commit. To move it, run the install command with
--force and the new commit, its full 40-character SHA, in place of <commit>:
hermes plugins install akinfold/hermes-yandex-disk/hermes_yandex_disk --enable --force --ref <commit>
Each of these scans the new version again. Unlike a first install, none of them stops to ask when Hermes' security scan reports a caution: for an install from a plugin directory, as here, they accept it and go on. A dangerous verdict still stops them.
Drop-in (C): unzip the new release's archive over the old one:
unzip -o hermes-yandex-disk-plugin-<version>.zip -d ~/.hermes/plugins/
From PyPI (B): upgrade the package in the same environment — in the older layout:
~/.hermes/bin/uv pip install --upgrade --python ~/.hermes/hermes-agent/venv/bin/python hermes-yandex-disk
A and C and their upgrades, moving a pinned install included, are checked before every
release by installing the build into a real Hermes exactly as written here: Hermes v2026.9.24,
the latest release, and main, each set up by its own official installer. The B install is
checked against Hermes v2026.9.24, the last release whose installer builds the older layout.
See Checking the install paths.
Why REST and not WebDAV
Yandex Disk exposes both a REST API and a WebDAV endpoint. This plugin is REST-only, because WebDAV covers strictly less: no bin, no public links, and no reporting for the deferred operations that large folder copies and deletes turn into. rclone's Yandex backend made the same call. The one thing WebDAV adds — an app-password login — is not worth a second stored credential for capabilities the REST API already has.
Development
python -m venv .venv && . .venv/bin/activate
pip install -e '.[dev]'
pytest --cov=hermes_yandex_disk --cov-report=term-missing # unit tests, no network
ruff check . && ruff format --check .
radon cc -s -n C hermes_yandex_disk # must print nothing
Running the live E2E tests
These create, publish and permanently delete real files. Use a throwaway Yandex account. Each test works inside its own
hermes-e2e-<id>folder, permanently deleted in teardown even when the test fails. Two things reach outside it: the bin tests pass their files through the account-wide bin and remove their own entries, and — only when the token is allowed to search — one test creates a single marker file in the disk root and permanently deletes it again.
Locally, put the token in ~/.yandex-disk-oauth (and optionally the login in
~/.yandex-disk-login) and run:
pytest -m e2e -v
The suite skips itself when no credentials are available, and an environment variable wins over
the file: YANDEX_DISK_OAUTH_TOKEN for the token and, optionally, YANDEX_DISK_E2E_LOGIN for the
account login the tests check yadisk_disk_info against. On GitHub Actions, run the E2E (live)
workflow manually; it reads the secrets YANDEX_DISK_OAUTH_TOKEN and, optionally,
YANDEX_DISK_E2E_LOGIN from the yandex-disk-e2e environment. It runs the plugin inside a real
Hermes, installed by its official installer, so the real credential resolver is exercised: the
latest Hermes release by default, and its hermes input switches to Hermes main or to no
Hermes at all. With Hermes, the tests run in Hermes' own Python, with this checkout on its
path rather than installed into Hermes' environment, and the run fails outright if the plugin
cannot import Hermes, rather than testing the plugin's stand-ins instead.
Checking the install paths
The install-marked tests in tests/install/ install the built plugin into a real Hermes,
set up by its official installer, by each route in Installing — running the
README's own commands, upgrades included — and then ask Hermes what it loaded: the plugin
must be listed as enabled, load without error, and give the agent its tools. They also check
that installing from the repository root still looks the way this README describes. A fast
unit test keeps the commands in the tests and in this README identical.
The Install check workflow runs them against Hermes v2026.9.24, the last release in the
older layout, against the latest Hermes release, and against Hermes main — on every pull
request, once a week, and on every release tag before anything is published: the GitHub
Release and the PyPI upload both wait for it. They install into a real ~/.hermes, so run
them yourself only in a container or VM — see the docstring of
tests/install/test_install.py.
Related Hermes plugins
Part of a family of Yandex plugins for Hermes Agent:
- hermes-yandex-mail — search, read, flag, move, and delete Yandex Mail messages over IMAP, and send over SMTP when sending is switched on.
- hermes-yandex-calendar — list, create, update, respond to, move, and delete Yandex Calendar events (CalDAV).
- hermes-yandex-search-api — Yandex web search backend and generative, cited answers for Hermes (Yandex Search API).
Contributing
See CONTRIBUTING.md. Please report security issues privately rather than as a public issue.
License
MIT — see LICENSE.
Metadata
Release files for hermes-yandex-disk 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| hermes_yandex_disk-0.6.0.tar.gz | 62.8 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hermes_yandex_disk-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 98.6 kB
Release files / hermes_yandex_disk-0.6.0.tar.gz
| Download URL | hermes_yandex_disk-0.6.0.tar.gz |
|---|---|
| Size | 62.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9535a36c291c9926acbfe0f0d2e10d72036e0b67d63fe09f889d9d060ace7d46
|
|
BLAKE2b-256 checksum How to use checksums |
34bb0fcd5e9eda02521ed7b1554f11ee91c160c8d3a3f244374235d9c25846e3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / hermes_yandex_disk-0.6.0-py3-none-any.whl
| Download URL | hermes_yandex_disk-0.6.0-py3-none-any.whl |
|---|---|
| Size | 35.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e3e3a0d03ec9b59d54d60ab1eb4f894d32bb5104df13ecc58cc4f968c9df7527
|
|
BLAKE2b-256 checksum How to use checksums |
ab917982e1308ac7937aae4c2480ce2b783310a4d29a99fc7b054b2b487ba51d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logSecurity for hermes-yandex-disk 0.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for hermes_yandex_disk-0.6.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.