Skip to main content

hermes-yandex-disk

PyPI version CI E2E (live) Coverage CodeFactor Ruff License: MIT

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_ROOT sandboxes the agent to one folder — every path is checked against it, including ones the model invents and ones it copies back from an earlier result.
  • 🛟 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 a url is 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_ACTIONS decides 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.net directly; no third-party service sees your files or your token.

Checked before every release against 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=read to ~/.hermes/.env and 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_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
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, 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.5.0. yadisk_upload from a url used to ignore overwrite. 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 pass overwrite=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_API_KEY is also accepted)
YANDEX_DISK_ACTIONS no all tools Which tools get registered — see below
YANDEX_DISK_ROOT no whole disk Confine every tool to this folder
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

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.

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

  1. 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.
  2. For a long-lived setup, register an app at https://oauth.yandex.ru/ with the scopes cloud_api:disk.info, cloud_api:disk.read and cloud_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, which is what Hermes 0.21.5 and anything installed before that date and not updated since look like — 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

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. 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 0.21.5 and later install the new version from the source they recorded:

hermes plugins update yandex-disk

Older Hermes cannot update an install from a plugin directory, and no Hermes updates one pinned with --ref: run the install command again with --force, which replaces the installed copy and keeps your token.

hermes plugins install akinfold/hermes-yandex-disk/hermes_yandex_disk --enable --force

Both scan the new version again, but unlike a first install neither stops to ask when Hermes' security scan reports a caution.

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, are checked before every release by installing the build into a real Hermes — the latest release and main, each set up by its official installer — exactly as written here; the B install is checked on the latest release while it still has 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 the latest Hermes release and against Hermes main on every pull request, 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.

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.5.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hermes-yandex-disk 0.5.2
File Size Uploaded
hermes_yandex_disk-0.5.2.tar.gz 57.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hermes-yandex-disk 0.5.2
File Interpreter ABI Platform
hermes_yandex_disk-0.5.2-py3-none-any.whl Python 3 none any Details

Total release size: 89.7 kB

Release files / hermes_yandex_disk-0.5.2.tar.gz

Download URL hermes_yandex_disk-0.5.2.tar.gz
Size 57.1 kB
Tags Source
SHA-256 checksum
How to use checksums
d142f8c3e078c6ad43cd9cba6e2f780391a087542b4b52219898cf622669c0fc
BLAKE2b-256 checksum
How to use checksums
b072718ab245be81eef9e2daa79b4c43cc1dcd5be4b29e3016134f7c6668f252
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 27, 2026.

Transparency log

Release files / hermes_yandex_disk-0.5.2-py3-none-any.whl

Download URL hermes_yandex_disk-0.5.2-py3-none-any.whl
Size 32.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7d33f13c83964b8ea46277f47df28e5ad03997604a2e61bded24892483aa7d72
BLAKE2b-256 checksum
How to use checksums
354930c8467b11c1082fe63aff156ac758b391172886a3ff2968c6bb68d2ab37
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.5.2 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page