zas-agent
Summary: This MCP server lets a coding agent send, read, edit and live-transfer files and notes in authorized Zas channels, under a revocable identity of its own.
Pair and inspect —
zas_statusshows pairing state, the running version and granted channels;zas_pairpairs (or replaces) the agent via an owner-approved link or code.Send files —
zas_send_fileuploads any readable file into a granted channel, with optional title and anexpires_in_dayslifetime that can only shorten it; long uploads return a job id.Send notes —
zas_send_noteposts plain text or a code snippet with a language, optional title, and a secret cover.Live transfers (Directo) —
zas_send_directsends device-to-device into a Directo-mode channel with nothing stored;zas_receive_directwaits for, takes and writes an incoming file to disk. Both offer a stored fallback (zas_send_direct_fallback/zas_receive_direct_fallback) after an in-flight failure.Read —
zas_list_itemslists up to 50 recent items (requires a read grant);zas_get_itemreturns a note as text or writes a file to disk without ever overwriting an existing file.Edit its own work —
zas_edit_itemchanges the title/text/language/secret cover of an item it sent, andzas_replace_fileswaps the bytes of its own file while keeping the item id, position and pin.Track long operations —
zas_jobslists sends and Directo transfers with their phases, endings, and the results behind returned job ids.Scope and limits — everything is encrypted locally before upload and marked with the agent's name; only granted channels,
read/sendswitches, ownership of items, and plan quotas apply.
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., "@zas-agentsend this README to my Zas code channel"
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.
zas-agent
An MCP server that lets a coding agent — Claude Code, Codex, or anything that speaks MCP — send files and notes into your Zas channels, and read items back out of them.
What is Zas
Zas moves things between your devices and the people you choose: files, photos, text, code. You put something into a channel on one device and use it on another. Whatever you do not pin leaves on its own after a few days, so there is nothing to tidy up later. Everything is encrypted on the device before it is uploaded: the database and the object storage receive encrypted bytes, not filenames, content or previews.
This package is the piece that lets a coding agent use your channels the way your other devices do, under an identity of its own that you approve, that you scope to the channels you choose, and that you can revoke.
Related MCP server: vnsh-mcp
What it does
Your coding agent gets thirteen tools. It can send a file or a note into a channel you picked, send or receive a file live through Directo, list what is in that channel, pull one item back onto disk, and change what it sent: an item's title or text, or the bytes under a file, keeping the item id. Everything it sends is encrypted on your machine before it leaves, lands in your account, and is marked in the channel as sent by that agent. The agent has an identity of its own and never holds your account key: pairing mints a key pair here, you approve it from the web app, and from then on it signs a challenge to get a short-lived session.
Install
Install Node.js LTS (22 or newer) and your agent's command-line tool first. Reopen your terminal after installing. Run these commands on the computer where you use the agent.
Choose your agent and pair it. On Windows (PowerShell or CMD):
Codex
npx.cmd -y zas-agent@latest pair --profile codexClaude Code
npx.cmd -y zas-agent@latest pair --profile claude-codeOpen the printed link, approve the channels, and enter the code in the terminal if the page shows one. Leave the terminal open until pairing finishes. Then run the matching registration command:
Codex
cmd /d /c codex mcp add zas "--" npx.cmd -y zas-agent@latest --profile codexClaude Code
cmd /d /c claude mcp add zas "--" npx.cmd -y zas-agent@latest --profile claude-codeOn macOS, Linux, or WSL, use npx in place of npx.cmd and omit
cmd /d /c . Pair and register in the same environment. Restart your agent
and ask it to send something to Zas.
If a command is not recognized, install Node.js or the named agent's CLI and
reopen the terminal. The first download needs internet access and may take a
few minutes. Use @latest as shown so npm requests the published package
instead of selecting an unbuilt local workspace.
What pairing does
zas-agent pair mints the key pair, registers the public halves, opens the
approval page in your browser, and waits. The terminal shows:
Open this page signed in to your Zas account:
https://zas.red/agents/pair?p=...#port=53211
Fingerprint: 1a2b 3c4d 5e6f 7a8b
Waiting for approval… (expires in 10 minutes)Signed in, name the agent and tick the channels it may use — sending is the
default, reading is a separate switch — and approve. Approval creates
nothing by itself: the page hands a one-time claim code to this terminal
over 127.0.0.1 (the port in the link), and the agent exists only once the
terminal claims with that code and the secret it holds. A link that reached
somebody else is approved on their machine, where nothing listens, and
expires with nothing created.
If the browser cannot reach the terminal — the link was opened on a phone,
or the browser refused the local connection — the page shows the code and
the terminal asks for it. Type it there and nowhere else: with that code,
another terminal that started a pairing could claim it. Pass --no-open or
set ZAS_NO_OPEN=1 to keep the browser closed; the link is printed either
way. The pairing is good for ten minutes before approval and five after;
past that, run the command again.
You can also start the flow from the coding agent with the zas_pair tool:
the first call hands back the URL, a later call says whether the approval
landed, and if the page shows a code, a call with code claims with it.
Updates
Automatic updates are on by default in published installations. While serving,
the agent checks npm's latest stable release in the background, at most once
per day. It installs newer releases in a separate directory and verifies that
the installed executable reports the expected version. The next agent launch
uses that release. Restart the MCP connection (or your coding agent) to apply it;
running transfers are never restarted by the updater. Pairing and channel grants
stay in place, and an offline or failed update leaves the current version usable.
zas-agent updates # show the setting and any release ready to use
zas-agent updates off # disable automatic downloads and staged launch selection
zas-agent updates on # enable them again
zas-agent update # check and stage a release nowUse npx -y zas-agent@latest in place of zas-agent if you have no global
installation. zas_status also reports the running version and staged update.
ZAS_AGENT_AUTO_UPDATE=0 disables the built-in updater; 1 enables it, overriding
the saved setting. An explicit update command can still download a release while
updates are off, but it will not be selected until updates are enabled again.
For a pinned installation, use an exact version in the launch command and disable
automatic updates. The documented npx ...@latest command still asks npm for the
latest package even when the built-in updater is off.
Updates require npm and install the official zas-agent package from
https://registry.npmjs.org, including its normal dependency installation scripts
and npm integrity checks. No administrator access is needed. Staged packages live
under ~/.zas/agent/.updates (or ZAS_AGENT_HOME/.updates); old installations are
retained and can be removed with the agent stopped. Source checkouts and prerelease
builds do not update themselves. Existing installations need to upgrade once to a
release containing this updater before these controls are available.
Why you can trust it
Every line here is a fact. The ones about this package you can check in this repository. Where a property is enforced by the Zas server, which is not open source, the sentence says so.
The agent has an identity of its own.
zas-agent pairgenerates two key pairs on your machine — X25519 to receive channel keys, P-256 to sign sign-ins — and the private halves never leave it. The agent never holds your account key, and the key-derivation service refuses account-key derivation to an agent (server-side).You approve it, and you choose the channels. Pairing never auto-approves. The approval page shows the harness, the host and the key fingerprint, and nothing exists until the terminal that started the pairing claims it with a code only the approving page received (server-side). A pairing link sent to you by someone else creates nothing on your account.
It holds one key per granted channel, and no key for any other. Each grant carries that channel's key sealed to the agent's X25519 public key. A channel you did not grant has no key here to decrypt with, and the server checks the live grant on every request (server-side).
No password and no API key. Signing in is a signed challenge traded for a one-hour token. There is no password, no API key and no refresh token on disk: the agent re-signs from its P-256 key when the token ages out.
Everything it sends is visible as its work. Every item carries the
>_agent mark and the agent's name, in the channel, on every device you read Zas from.You can revoke it at any time. Settings → Agents → the agent → Revoke. The session stops, its refresh tokens are revoked (server-side), and the next tool call answers "the owner revoked this agent". What it already sent stays where it is. You can also drop a single channel and keep the rest.
Content is encrypted on your machine before it leaves, the same way the app does it. The chunking, the manifest and the envelope formats under
src/shared/are the same modules the Zas web app ships. The server stores ciphertext and never sees a channel key, a channel name or item plaintext (server-side).The source is here, and the releases are built from it. Every npm release is published by the
release.ymlworkflow in this repository, with npm provenance, so the tarball on npm can be traced back to a commit and a workflow run.
What it cannot do
The package refuses some of these on its own, before a request is made. The ones marked (server-side) are enforced by the Zas server.
No channel you did not grant. Not by name, not by id.
No shared channel you joined, unless its owner allows it. You can grant a channel you joined, but the grant stays
grant_pendinguntil that channel's owner allows this agent in Zas. The plan also caps how many of these channels one agent holds: 2 on Free (server-side).No workspace channel, unless the organization allows agents. A channel an organization manages, or one you created inside its workspace, can be granted only while the organization is active and an admin turned agents on (server-side).
No reading unless the grant says so.
readis a separate switch fromsend; without it,zas_list_itemsandzas_get_itemare refused.No stored sending into a view-only channel, and none into a channel in Directo mode. Both are refused before a byte is uploaded. A channel in Directo mode takes
zas_send_direct, a live transfer that stores nothing.No changing what it did not send.
zas_edit_itemandzas_replace_fileact only on items carrying this agent's mark; anything else isnot_yours, and the server refuses it too (server-side). A replace is for agents only: no web or mobile client gets one. An item with a public share is not replaced until the share is removed.No receiving unless the grant says read. Receiving through Directo writes a file onto this machine, so
zas_receive_directtakes the samereadswitch as listing. And it only ever runs inside a tool call: the agent never watches your channels, so nothing arrives unasked.Nothing outside its allowlist. The API refuses an agent on every route that is not on a short, explicit list, and Firestore rules refuse it your account document, your devices, and any channel without an active read grant (server-side).
Rate limited by the server, on its own buckets, with the key-derivation budget charged to your account so ten agents are not ten times your own allowance (server-side).
As many agents as your plan or your organization allows (server-side).
Files up to 5 GiB, subject to your plan's limit. File sends and replacements hash incrementally and upload in bounded batches. A file changed during the transfer is refused before publication. Image previews still decode eligible images in memory; inputs over 80 MiB skip the preview.
The error vocabulary
The agent answers in a closed set of codes. Anything a server route says that
is not in this set collapses to upload_failed or network, so no raw server
string ever reaches a terminal.
Code | What it means |
| This agent is not paired yet. |
| An endpoint or emulator configuration could expose credentials. |
| A secret file is not private to its owner. |
| The OS secret store cannot save or open this profile. |
| The server-selected encryption key has no valid local pin. |
| The encryption service response failed verification. |
| The identity file on disk is damaged. |
| The owner revoked this agent. |
| Only the account owner can do that. |
| This agent has no access to that channel. |
| That channel belongs to somebody else, and its owner has not allowed this agent yet. |
| This agent cannot send to that channel. |
| This agent cannot read that channel. |
| That channel is in Directo mode. |
| That channel is not in Directo mode. |
| Nobody received the file within ten minutes; the offer was withdrawn. |
| Nobody offered a file through Directo while the call waited. |
| Another device received that file first. |
| The offer was cancelled from the other side. |
| The Directo transfer failed in flight. |
| That job is not a Directo transfer that failed in flight. |
| The file changed during the transfer; send it again. |
| The WebRTC engine could not be loaded on this machine. |
| Reliable delivery is not available right now. |
| The channel key changed; the owner refreshes it by opening Zas. |
| The account reached its storage limit. |
| The organization's plan is inactive, so sending to its channels is paused; the owner or a billing admin reactivates it. |
| Too many sends in a row. |
| The file is over the plan limit. |
| That item is already in the channel. |
| That item is not in the channel. |
| That item was not sent by this agent; it can only change its own items. |
| That item changed while this agent was working on it; read it again and retry. |
| That item is a file, not a note; only its title can change. |
| That item is a note, not a file. |
| That item has a public share; the owner removes the share first. |
| That file is no longer available. |
| The download destination could not be written. |
| The pairing expired; pair again. |
| The owner cancelled the pairing. |
| The code does not match. |
| Nobody has approved this pairing yet. |
| This pairing was already claimed; pair again. |
| The account cannot take another agent; the owner deletes one from Settings → Agents. |
| The plan allows fewer channels per agent than this pairing grants. |
| The plan allows this agent fewer channels of other people than this pairing asks for. |
| Agents are not enabled for this account yet. |
| The upload failed. |
| Zas did not answer correctly while preparing the file. |
| Zas cannot be reached. |
| Zas did not accept this agent session. |
| Zas rejected this agent's signature; pair it again. |
| The session token is missing; pair the agent again. |
| Something failed inside the agent. |
Every code comes back as one sentence in English, never as a stack trace.
Tools
Tool | What it does |
| Says whether this agent is paired with a Zas account, and lists the owner's channels it may send to or read from. |
| Pairs this agent with a Zas account. The first call returns a URL for the owner to open; a later call says whether they approved. If the page shows a code, a call with |
| Sends a file from this machine into one of the owner's channels. Returns the item id, or a job id when the upload takes longer than a minute. |
| Sends a note — plain text, or a code snippet with its language — into one of the owner's channels. |
| Sends a file through Directo: a live, device-to-device transfer into a channel in Directo mode. Nothing is stored. The owner presses Receive on another device within ten minutes; the call returns the result, or a job id after a minute. |
| After a Directo send failed in flight, delivers the same file through reliable delivery: encrypted on this machine, stored in Cloudflare R2 for up to 24 hours, off the owner's quota. The owner's choice; the model is told to ask. |
| Receives a file the owner sends through Directo, onto this machine. Waits for the offer, takes it, and writes the file to disk. Needs a grant that includes reading, and a channel in Directo mode. Returns the path written, or a job id after a minute. |
| After a Directo receive failed in flight, downloads the encrypted copy the sender chose to store, and decrypts it to the same destination. |
| Lists the most recent items in one of the owner's channels. Needs a grant that includes reading. |
| Fetches one item. A note comes back as text; a file is written to disk. It never overwrites, so the path it answers with can differ from the one you asked for. |
| Changes an item this agent sent, keeping its id: the title of a file or a note, or a note's text, language and secret cover. Needs a grant that includes reading and sending. The owner's activity log records it. |
| Replaces the bytes of a file this agent sent with a file from this machine, keeping the item id, its place in the channel and its pin. Returns the item id, or a job id after a minute. Refuses notes, shared items, and items sent by anyone else. |
| Lists the sends and Directo transfers this server started, newest first, with the phase each one reached — and where a |
Image previews are optional: JPEG, PNG, WebP, GIF and TIFF images up to 80 MiB and 16 million decoded pixels can receive a preview. Larger images and unsupported formats are still sent, without a preview.
Jobs belong to the running MCP process. Stored file sends use bounded memory, but upload progress is not saved across restarts. After a restart, retry the same send; its content, destination, title and lifetime identify the request so a lost completion response does not create a second item.
channel takes a channel name or a channel id. A name has to match exactly one
of the channels you granted; with exactly one grant, zas_send_file,
zas_send_note, zas_send_direct, zas_receive_direct, zas_edit_item and
zas_replace_file can leave it out.
A replace runs the same pipeline as a send — hash, key derivation, encryption,
then upload or proof per chunk — and posts the new set with the old one to
release. The server moves both sets, the account's storage tally and the item
in one transaction, so a failure leaves everything as it was; a chunk present
in both versions is neither uploaded nor released. Both tools read the item
first and write only over the version they read: an item that changed in
between answers stale, and nothing is lost.
Directo needs a native module, node-datachannel,
WebRTC for Node. npm installs a prebuilt binary for Windows, macOS and Linux;
the module loads the first time a Directo tool runs, and a machine where it
cannot load answers webrtc_unavailable. Every other tool works without it.
Two things worth knowing before you point a model at your account:
zas_send_fileandzas_send_directsend any file this process can read —~/.ssh/id_rsaand a.envincluded. Confirm with the owner before sending secrets, keys or credentials. Its tool description says so, so the model reads it too.zas_get_itemandzas_receive_directwrite a new file underdest, or under the system temp directory when you leavedestout. Neither ever overwrites an existing file: a name that is taken gets a suffix, and the path they answer with is the one they actually wrote.
Everything those tools touch lands inside your own account and your own machine. Revoking the agent stops all of them.
What it sends back
This package reports how it is used, so defects like a release that could not receive a file at all stop being invisible. It is on by default and it is yours to turn off:
npx -y zas-agent telemetry off # and `on` again, and `telemetry` to seeZAS_AGENT_TELEMETRY=0 and the cross-vendor DO_NOT_TRACK=1 do the same
without writing anything. The choice lives in ~/.zas/agent/settings.json and
covers every profile on the machine; pairing again does not reset it.
zas_status always says which way it is set.
What one report carries, and nothing else: the tool that ran, whether it worked, the closed error code when it did not, which of four duration buckets it fell in, and the package version. Item transfers also report item category, transport, byte counts, stage durations, and success/failure/cancellation, joined by a random per-attempt ID. No file name, no file contents, no path, no channel name, no error message, no stack.
Where it goes: to Zas, never to an analytics service directly. This package holds no analytics token and opens no connection to a third party, so no address of yours reaches one. The report is attributed to the Zas account the agent is paired with, which the server reads from the session — the request carries no account or content identifier. Nothing is reported before pairing, because until then there is no account it could belong to.
A report is never allowed to matter: it is sent after the answer, waited on for at most five seconds, tried once, and dropped in silence if it fails.
Data on disk
One directory per profile, so one machine can hold a Claude Code agent and a Codex agent side by side without either reading the other's keys:
OS | Path |
macOS, Linux |
|
Windows |
|
Profile metadata is written through temporary files and renamed into place, so a crash mid-write cannot leave half a file behind:
identity.json— the agent uid, the owner uid, the name, and the two key pairs. Back it up like a private key, or delete it and pair again.pending.json— a pairing that has not been claimed yet. Removed on completion, and on a pairing that expired or was cancelled.grants.json— a one-minute cache ofGET /v1/agents/me: which channels, and the sealed key for each. The channel name stays encrypted here. Disposable.fingerprints.json— hashes of what an identical send produced in the last ten minutes, so a retried tool call answers without touching the network. It stores hashes, never a title or a note's first line. Disposable.
One more file sits next to the profiles, in ~/.zas/agent/:
settings.json— whether this machine reports usage, and when the notice above was last printed. It belongs to the machine, not to a profile, so one decision covers every agent on it.
Private keys, polling secrets and legacy pairing codes migrate out of the old
JSON files on the next start. The replacement metadata is committed only after
storage succeeds. Windows uses current-user DPAPI and an owner-only directory
ACL without inherited grants. macOS uses Keychain; Linux uses Secret Service
through secret-tool when a desktop session and that tool are available. A
locked or failing desktop store must be unlocked or repaired before retrying.
Headless Linux uses a 0600 file in a 0700 directory. POSIX secret reads reject
files owned by another user, symlinks, hard links, and group/world permissions;
the error includes the chmod 600 repair command. zas_status reports the store.
Older agent versions cannot read the migrated secret references; keep the updated agent installed after migration. OS-protected profiles are not portable backups. Pair a new profile on another machine; do not copy its JSON files and expect them to sign in. OS protection does not prevent a process already running as your user from using your keys.
Deleting the directory removes the local references. Keychain/Secret Service
entries may remain under service red.zas.agent; remove those with the OS
credential manager when discarding a profile. It does not revoke
anything: the account side is closed from the web app, under
Settings → Agents → Revoke.
Pairing again
A pairing is one profile's key pair, not the machine and not the program. A
profile holds one agent. Running zas-agent pair in a profile that is already
paired opens a replacement: the terminal signs the request with the old
identity, the approval page says which agent it replaces and fills in its name
and channels, and the old agent is revoked in the same step that creates the
new one. Its row stays under Settings → Agents as revoked until you remove it,
and it keeps costing a slot until then. If the old agent was already revoked
or removed, pair says so and creates a new agent.
One machine that runs Claude Code and Codex has two profiles (claude-code
and codex), two agents, two approvals and two rows. Revoking one does not
touch the other. Two programs pointed at the same --profile act as one
agent: same keys, same channels, one row.
Configuration
Setting | Default | What it changes |
|
| Which identity directory this process uses. Letters, digits, |
|
| Where the profile directories live. |
| unset |
|
| unset |
|
|
| The web app the pairing URL points at. |
|
| The API. |
|
| The challenge and token routes. |
|
| The blind key-derivation service. |
|
| The project whose Firestore the read path queries. |
| unset |
|
| unset | Operator-provided JSON mapping key IDs to pinned base64 VOPRF public keys. Required when the server selects mode 1. |
| the public web key | The key used to exchange a custom token for a session. |
Only --profile, ZAS_AGENT_HOME and the two telemetry switches are worth
setting by hand. The rest exist
so the package can be pointed at a test deployment.
Saved API/token/OPRF bases are validated on every load. Non-loopback HTTP is
refused even with the dev flag. To run Firebase emulators, set both
FIREBASE_AUTH_EMULATOR_HOST and FIRESTORE_EMULATOR_HOST to loopback hosts,
all three Zas service bases to loopback, ZAS_FIREBASE_PROJECT to a demo-*
project, and ZAS_ALLOW_INSECURE_DEV=1. Production profiles cannot use these
emulators. Credential-bearing requests refuse redirects. Use a separate
profile for development; repair unsafe saved bases before loading an old one.
Development
git clone https://github.com/soke1556/zas-agent
cd zas-agent
npm ci
npm test
npm run typecheck
npm run build
node dist/cli.js --versionThis repository is the public mirror of the agent/ package of Zas's private
monorepo. It is produced by scripts/export-public.mjs, which builds the
package with esbuild and uses the build's own metafile to decide what to copy:
src/, test/, the package files, and the src/shared/* modules the
agent imports. Those shared modules are the client-side crypto and format code — the
chunker, the manifest, the envelope, the key derivation — that the Zas web app
also ships, which is why the encryption the agent performs is the encryption the
app performs. The Zas server is not open source.
Pull requests are welcome against this repository. The maintainer applies accepted changes back into the monorepo, and the next export brings them here. See CONTRIBUTING.md.
shared-source.json pins the shared modules and interoperability fixtures to
zas.web commit 46d727a870c64728b42b768950d55d7d7a575181. CI runs
npm run check:shared to detect drift using upstream Git blob IDs. Maintainers
with the private checkout can verify the pin against the actual commit with
npm run check:shared -- --source ../zas.web. Apply these agent changes back
to the monorepo before the next export.
This release follows the web reader phase: legacy/v1 and authenticated v2
envelopes can be read; application writers still produce v1. VOPRF mode is
selected by GET /v1/agents/me; mode 1 requires a local public-key pin and a
valid batch proof, with no downgrade on failure. Enabling production v2 writes
and coordinating VOPRF adoption across clients remain separate rollout work.
Security
Please report vulnerabilities privately. SECURITY.md says how, and what to expect.
License
MIT. See LICENSE.
Available Tools
13 toolszas_edit_itemA
Change an item this agent sent, keeping its id: the title of a file or a note, or a note's text, language and secret cover. Refuses items sent by anyone else. A file's bytes change with zas_replace_file. Needs a grant that includes reading and sending. Pass only the fields to change; an empty title clears it. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Item id, as `zas_list_items` reports it. | |
| lang | No | Language of the snippet, for highlighting (for example "ts", "py"). An empty string makes it plain text. | |
| text | No | New body, for a note. | |
| title | No | New label. An empty string clears it, so the file name or the first line shows again. | |
| secret | No | Hide the body behind a cover until the reader opens it. False removes the cover. | |
| channel | No | Channel name or id. Optional when the agent holds exactly one channel. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it discloses the ownership refusal, the required grant (read + send), the side effect that the owner sees a >_ agent mark with this agent's name on every device, and the destructive-ish semantics of an empty title clearing the label. It stops short of describing what an error or partial failure looks like, so it is not fully exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The primary action and its id-preserving nature are front-loaded, followed by exclusions, prerequisites, and side effects in a tight sequence. No sentence is padding; the owner-visibility note is a genuine behavioral disclosure, not filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter mutation tool with no annotations and no output schema, the description covers ownership, authorization, partial-update semantics, and visibility side effects. It omits error behavior and does not mention whether changing channel relocates the item, which is a modest remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds partial-update semantics ("Pass only the fields to change") and the empty-title clearing rule, which are behavioral rather than restatements. The channel parameter's role in moving an item is only covered by the schema, not the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (change) and resource (an item this agent sent) with the deliberate constraint that the id is preserved, and explicitly separates itself from the sibling that handles file bytes (zas_replace_file). An agent can distinguish this from zas_send_note and zas_replace_file without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternative explicitly ("A file's bytes change with zas_replace_file") and states the ownership precondition ("Refuses items sent by anyone else") plus the grant requirement. It also gives a usage rule for partial updates ("Pass only the fields to change"), leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_get_itemA
Fetch one item from a Zas channel. A note comes back as text; a file is written to disk. Returns the path written; it can differ from dest when a file with that name already exists. Writes a new file under dest (or the system temp directory); it never overwrites an existing file. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Item id, as `zas_list_items` reports it. | |
| dest | No | Where to write a file. A directory means "inside it". Defaults to a fresh temporary directory. | |
| channel | Yes | Channel name or id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden well: it discloses that files are written to disk, that dest defaults to a temp directory, that existing files are never overwritten, and that the returned path may differ from dest. It does not cover permissions, failure modes, or why the final sentence about what the owner sees applies to a fetch operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The key purpose is front-loaded, but the file-writing behavior is repeated across multiple sentences and the final sentence about the owner seeing every item this agent sends is off-topic for a get tool. Those issues make it less tight than it could be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter tool with no annotations and no output schema, the description explains the important side effect and return value well: notes come back as text, files are written without overwriting, and the written path is returned. It still leaves out error behavior and any channel access requirements.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds useful semantics for dest and the returned path, including temp default and non-overwrite behavior. It adds little beyond the schema for channel and id.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: fetch one item from a Zas channel. It also clarifies the two payload modes, note as text and file to disk, which distinguishes retrieval-by-id from list-oriented siblings such as zas_list_items.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies retrieval by item id, but does not say when to use this tool versus zas_list_items or direct-receive siblings. There are no explicit alternatives, prerequisites, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_jobsA
List the sends and Directo transfers this server started, newest first, with the phase each one reached and how it ended — including any job_id a send returned; a finished job keeps its result here. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations the description carries the full burden, and it does disclose meaningful traits: results are ordered newest-first, each entry carries the phase reached and how it ended, returned job_ids are surfaced, and completed jobs retain their results here. It also notes the visibility model (owner sees items with the agent mark/name on every device). It stops short of stating read-only safety, pagination, or result limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core action and ordering. The second sentence about owner visibility is the least essential and slightly tangential, but it is short and not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only list tool with no output schema and no annotations, the description covers the important ground: what is listed, ordering, per-item fields, job_id retention, and result persistence. Missing only operational details such as pagination or result-count limits.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4; there is no schema-level parameter meaning to add or compensate for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb ('List') and resource ('the sends and Directo transfers this server started'), plus the ordering ('newest first') and the fields surfaced (phase, outcome, job_id). It is clearly distinguishable from write-oriented siblings like zas_send_direct, though it never names a sibling to sharpen the boundary against zas_list_items or zas_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: 'a finished job keeps its result here' suggests this is where you check the outcome of a prior send, but there is no explicit when-to-use, when-not-to-use, or named alternative (e.g. zas_status) to route the agent. The final sentence adds context but not selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_list_itemsB
List the most recent items in one of the owner's Zas channels. Needs a grant that includes reading. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many items, 1 to 50. Defaults to 20. | |
| channel | Yes | Channel name or id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the read-grant requirement and that results are ordered most-recent-first, which is genuinely beyond the schema. However, the final sentence about the owner seeing sent items with the '>_ agent mark' describes send behavior, not this list tool, so it is confusing rather than informative; return format and pagination remain undisclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, but the last one is off-topic for a list operation and consumes space without helping the agent decide or invoke. The essential scoping and auth facts are front-loaded, so structure is sound; content economy is not.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only two-parameter tool this covers purpose, auth, and ordering. Missing are return-shape hints (what an 'item' contains), pagination or cursor behavior, and any note on erroring when the grant is absent or the channel is unknown — gaps that matter more because no annotations or output schema exist.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both `channel` and `limit` (1–50, default 20) are fully documented in the schema. The description adds only the implicit notion of recency ordering and no format or id-vs-name nuance. Baseline 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Uses a specific verb plus resource plus scope: 'List the most recent items in one of the owner's Zas channels.' An agent immediately knows this is a read-list operation scoped to a channel. It never distinguishes itself from siblings like zas_get_item or zas_receive_direct, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Needs a grant that includes reading' states an auth prerequisite, which is useful. But there is no guidance on when to choose this over zas_get_item (single item) or zas_receive_direct (direct messages), and no exclusions. Usage is implied by the purpose rather than explicitly directed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_pairA
Pair this agent with a Zas account. The first call returns a URL for the owner to open; a later call says whether they approved. If the page shows a code, call again with code. In a profile that is already paired, approval replaces the old agent. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | The code the pairing page shows when the browser could not reach this machine. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the whole burden, and it does disclose the important non-obvious traits: this is a multi-call asynchronous owner-approval handshake, re-pairing in an existing profile replaces the prior agent, and the owner sees this agent's mark and name on every device. It stops short of stating code expiry, rate limits, or what the first response contains besides a URL.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, the action and the flow front-loaded with the conditional `code` case placed where the agent will need it. The closing sentence on the agent mark is mild extra detail but earns its place as visible-behavior disclosure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-param pairing tool with no output schema and no annotations, the description covers the full interaction shape: initiation, polling, code fallback, and re-pairing semantics. Only the absence of any timeout or expiry guidance keeps it from being fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents `code` at 100% coverage, and the description adds why it exists: it is the fallback for when the browser cannot reach this machine. That contextualizes a parameter an agent might otherwise supply blindly, though it doesn't give format specifics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'Pair this agent with a Zas account.' That is unmistakably distinct from the send/receive/status siblings, which all operate on already-paired data. An agent can pick this tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Lays out the call sequence clearly: first call yields a URL for the owner, a later call reports approval, and a `code` argument is only needed when the page shows one. What's missing is any routing versus siblings (e.g. check zas_status first, or what to do if the profile is already paired beyond 'replaces the old agent').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_receive_directA
Receive a file the owner sends through Directo, straight onto this machine. Call it when the owner says they are sending you something: it waits for the offer, takes it, and writes the file to disk. Nothing is stored anywhere. Only for a channel in Directo mode, and only with a grant that includes reading. The call waits a minute and then returns a job id to check with zas_jobs; the wait for an offer alone can take ten minutes. Returns the path written; it never overwrites an existing file. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| dest | No | Where to write the file. A directory means "inside it". Defaults to a fresh temporary directory. | |
| channel | No | Channel name or id. Optional when the agent holds exactly one channel. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well: it discloses waiting behavior, a one-minute return with a job id, a possible ten-minute offer wait, no server-side storage, non-overwriting behavior, and the returned path. These are meaningful operational traits beyond the input schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and key constraints are front-loaded, and the async timing details are useful. However, the final sentence about the owner seeing items this agent sends is tangential for a receive tool and weakens the claim that every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex async receive operation with no output schema and no annotations, the description is largely complete: it covers prerequisites, waiting, job id follow-up, return path, and overwrite safety. It still omits failure/timeout behavior and does not name the fallback alternative.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both dest and channel are already documented in the schema. The description reinforces writing to disk and returning the path, but it does not add syntax or defaults beyond what the schema provides, making 3 the appropriate baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: receive a file the owner sends through Directo and write it to this machine. It clearly explains the receive/write flow, but it does not explicitly name the fallback sibling used in other modes, so sibling differentiation is only implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage conditions: call it when the owner says they are sending something, only for a channel in Directo mode, and only with a grant that includes reading. It does not explicitly point to zas_receive_direct_fallback as the alternative for other modes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_receive_direct_fallbackA
After a zas_receive_direct job failed in flight, download the encrypted copy the sender chose to store instead. It works only if the person who was sending picked reliable delivery for that transfer. The file is decrypted on this machine and written to the same destination. Pass the failed job’s id. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| job | Yes | The job id zas_receive_direct or zas_jobs reported for the receive that failed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description does real work: it discloses that the copy is decrypted locally, that it is written to the same destination as the failed receive, and the gating condition on the sender's delivery choice. It does not say what happens on failure (missing copy, wrong sender choice) or whether the write overwrites an existing file, which keeps it below a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core information (precondition, action, destination, parameter) is front-loaded and compact. The trailing sentence about the owner seeing agent-marked items is tangential to invoking this tool and slightly dilutes focus, but it is short and does not obscure the main instruction.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, no-output-schema recovery tool, the description covers the precondition, the action, the local decrypt/write behavior, and the argument. The main missing piece is error/edge behavior when the sender did not enable reliable delivery or the stored copy is unavailable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the only parameter's description already says 'the job id zas_receive_direct or zas_jobs reported for the receive that failed'. The description's 'Pass the failed job's id' restates that without adding format or sourcing detail, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific action (download the encrypted copy stored instead) and ties it directly to the recovery of a failed zas_receive_direct job, which cleanly separates it from the sibling zas_receive_direct and the other send/receive tools. An agent can tell exactly which operation this is without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the triggering condition ('After a zas_receive_direct job failed in flight') and the prerequisite that the sender chose reliable delivery, which is enough to route correctly. It stops short of naming what to do when that prerequisite is not met (e.g. retry zas_receive_direct or report failure), so it is not fully explicit about alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_replace_fileA
Replace the bytes of a file this agent sent with a file from this machine, keeping the item id, its place in the channel and its pin. Refuses items sent by anyone else, notes, and an item with a public share. Returns the item id, or a job id when the upload takes longer than a minute. Sends any file this process can read; confirm with the owner before sending secrets, keys or credentials. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Item id, as `zas_list_items` reports it. | |
| path | Yes | Absolute or relative path of the new file. | |
| title | No | New label. Defaults to the label the item has. | |
| channel | No | Channel name or id. Optional when the agent holds exactly one channel. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it explains preservation of item id/channel/pin, refusal conditions, return shape (item id or job id for uploads over a minute), and security cautions about secrets and owner visibility. This is rich behavioral context beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and then layers in constraints, return behavior, and visibility context without repetition. Every sentence adds useful information for an agent deciding whether and how to call the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the description explains the return value clearly (item id, or a job id for long uploads). Combined with refusal conditions and security notes, it is complete enough for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all four parameters, including 'title' and 'channel' that the description does not discuss. The description adds slight context that 'path' refers to a file readable by this process, but it largely relies on the schema for parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a precise verb ('Replace') and resource ('the bytes of a file this agent sent'), and clarifies that the existing item id, channel position, and pin are retained. This distinguishes it from sibling send operations that create new items.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states when the tool will refuse: items sent by anyone else, notes, and items with a public share. That gives strong negative guidance, but it does not explicitly name an alternative sibling such as zas_send_file for sending a new file instead of replacing an existing one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_send_directA
Send a file from this machine through Directo: a live, device-to-device transfer into one of the owner's channels that is in Directo mode. Nothing is stored. The owner has to press Receive on another device within ten minutes; the call waits a minute and then returns a job id to check with zas_jobs. Returns the transfer result, or a job id. Sends any file this process can read; confirm with the owner before sending secrets, keys or credentials. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute or relative path of the file to send. | |
| channel | No | Channel name or id. Optional when the agent holds exactly one channel. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does it well: nothing is stored, there is a ten-minute receive window, the call blocks for roughly a minute, and it returns either a result or a job id for zas_jobs. It also discloses the agent-attribution mark the owner sees and warns to confirm before sending secrets. Error behavior and what happens if the owner never presses Receive are left unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and the transport model, then timing, then the return contract, then safety. Mostly earns its place, but the return behavior is stated twice ('returns a job id to check with zas_jobs' and 'Returns the transfer result, or a job id'), which is a small redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema and no annotations, yet the description covers return shape (result or job id), the follow-up tool, the blocking latency, the human-in-the-loop requirement, and the sensitive-data caution. An agent has everything needed to call this correctly and interpret the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are already documented, establishing a baseline of 3. The description adds modest meaning — 'any file this process can read' clarifies the path scope, and the channel must be in Directo mode — but nothing about path formats, size limits, or what happens if multiple channels exist.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (send a file) plus the transport constraint: a live device-to-device transfer into a channel in Directo mode, with nothing stored. That distinguishes it from a stored-upload sibling in substance, though it never names zas_send_file or zas_send_direct_fallback as the alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Prerequisites are clear (channel must be in Directo mode, owner must press Receive within ten minutes, the call blocks for about a minute). What's missing is routing guidance: no statement of when to use this versus zas_send_file or zas_send_direct_fallback if the owner is unreachable or the channel isn't in Directo mode.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_send_direct_fallbackA
After a zas_send_direct job failed in flight, deliver the same file through reliable delivery instead. Zas encrypts the file on this machine and stores only that encrypted copy in Cloudflare R2 for up to 24 hours; it uses none of the owner's space, and the device that claimed the offer can download it later. This stops being Directo: the encrypted bytes pass through storage. Ask the owner before you use it; it is their choice. Pass the failed job's id. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| job | Yes | The job id zas_send_direct or zas_jobs reported for the Directo send that failed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well: it explains encryption on the local machine, storage of only the encrypted copy in Cloudflare R2 for up to 24 hours, no use of owner space, later download by the claiming device, and that bytes pass through storage rather than remaining purely Directo. It also discloses the consent requirement and that the owner sees the agent mark and agent name on every device.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and most sentences earn their place by clarifying the fallback behavior, consent requirement, parameter, and owner visibility. It is fairly long and somewhat jargon-heavy around "Directo", but the length is justified for a fallback operation with no annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-annotation fallback send tool with no output schema, the description covers the critical context: when it applies, what happens to the file, retention, privacy implications, consent, and parameter source. An agent has enough information to decide whether to use it and how to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one required parameter and schema description coverage is 100%, so the schema already explains that job is the failed Directo send id reported by zas_send_direct or zas_jobs. The description adds "Pass the failed job's id" but no further syntax or format detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: deliver the same file after a zas_send_direct job failed in flight. It explicitly distinguishes this fallback path from the original direct send, so an agent can tell exactly what the tool is for without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The trigger condition is explicit: use this only after a zas_send_direct job failed in flight and pass that failed job's id. It also adds a clear prerequisite to ask the owner first, though it does not explicitly say not to use this for brand-new sends where zas_send_direct or zas_send_file should be chosen.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_send_fileA
Send a file from this machine into one of the owner's Zas channels. Returns the item id, or a job id when the upload takes longer than a minute. A channel in Directo mode refuses this tool: use zas_send_direct there. Sends any file this process can read; confirm with the owner before sending secrets, keys or credentials. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute or relative path of the file to send. | |
| title | No | Label for the item. Defaults to the file name. | |
| channel | No | Channel name or id. Optional when the agent holds exactly one channel. | |
| expires_in_days | No | How many whole days the item should live for, at least 1. Leave it out for the account's normal life (5 days). It can only shorten an item, never extend one: a longer request is clamped to what the plan grants. Worth setting for output that is stale tomorrow, such as a build log or a test run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden well: it discloses the return contract (item id, or a job id when the upload exceeds a minute), the refusal behavior in Directo mode, and the visibility side effect (owner sees every item with the >_ agent mark and agent name on every device). It omits permission/size limits and any rate-limit or failure behavior, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the action, then return contract, then the routing exception, then the safety and visibility notes. Every sentence carries distinct information with no repetition of the schema or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description explains the two possible return values, the async case, and the visibility side effect, which is what an agent needs to act on the result. Remaining gaps are secondary: file size limits, permission requirements on the target channel, and how the job id is later resolved (presumably via zas_jobs).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and each of the four parameters is already documented in the schema, including the clamping behavior of expires_in_days. The description adds only a light constraint on path ("any file this process can read"), which is capability context rather than parameter syntax, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Send a file from this machine into one of the owner's Zas channels") and explicitly carves out the case where it does not apply ("A channel in Directo mode refuses this tool: use zas_send_direct there"). An agent can distinguish it from the direct-send siblings without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete when-not condition (Directo-mode channels) plus the named alternative, and adds a safety precondition ("confirm with the owner before sending secrets, keys or credentials"). It does not distinguish itself from other siblings like zas_replace_file or zas_send_note, so routing guidance is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_send_noteB
Send a note — plain text, or a code snippet with its language — into one of the owner's Zas channels. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | Language of the snippet, for highlighting (for example "ts", "py"). | |
| text | Yes | The body of the note. | |
| title | No | Label for the item. Defaults to the first line. | |
| secret | No | Hide the body behind a cover until the reader opens it. | |
| channel | No | Channel name or id. Optional when the agent holds exactly one channel. | |
| expires_in_days | No | How many whole days the item should live for, at least 1. Leave it out for the account's normal life (5 days). It can only shorten an item, never extend one: a longer request is clamped to what the plan grants. Worth setting for output that is stale tomorrow, such as a build log or a test run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose a genuinely non-obvious trait: everything sent is visible to the owner on every device and is stamped with the >_ agent mark and the agent's name. That is real value beyond the schema. However, it says nothing about permissions or auth needs, rate limits, failure behavior, or whether the call returns an identifier for the created item.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the action and destination, with no filler. The trailing visibility clause is slightly redundant ('owner sees every item' and 'on every device') but earns its place as the key trust signal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no annotations and no output schema, so the description must cover behavior, and it covers visibility but not the return value or error modes — notably whether an item id comes back that could feed zas_get_item or zas_edit_item. Parameter detail is fully carried by the schema, so the gap is behavioral rather than parametric.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all six parameters (including secret, expires_in_days, channel) are already documented in detail, which sets the baseline at 3. The description only adds the text-vs-snippet framing and the multi-channel destination, which is marginal over what the schema already conveys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Send a note') plus the payload variants it accepts (plain text or code snippet with language) and the destination (one of the owner's Zas channels). It does not name or contrast itself with siblings like zas_send_direct or zas_send_file, so the distinction between a channel note and a direct message is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit statement of when to use this tool versus zas_send_direct, zas_send_file, or zas_edit_item. The only conditional guidance ('Optional when the agent holds exactly one channel') lives in the schema, not the description, so an agent gets no routing help from the prose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zas_statusA
Say whether this agent is paired with a Zas account, and list the owner's channels it may send to or read from. The owner sees every item this agent sends with the >_ agent mark and this agent's name, on every device.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose a meaningful behavioral trait: the owner sees every item sent by this agent with the >_ agent mark and agent name on every device (an auditing/visibility property). It does not explicitly confirm the call is side-effect-free or describe behavior when unpaired.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose (pairing status plus channel list). The second sentence about owner-visible agent marking is somewhat tangential to invocation but adds legitimate context, so it earns its place without bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations and no output schema, the description must convey return content, and it does: pairing status plus the list of channels the agent may send to or read from. It omits the unpaired/error case and any note on caching or refresh, but is otherwise complete for a zero-parameter status tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters and schema coverage is 100%, so the baseline is 4 and there are no parameter semantics for the description to add. Nothing is missing on this dimension.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: reports whether the agent is paired with a Zas account and lists the owner's channels available for send/read. It is clearly distinguishable from zas_pair, but it never names a sibling or scope boundary explicitly, so it stops short of full differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is a status/introspection check, likely before sending. There is no explicit when-to-use, when-not, or alternative (e.g., 'use zas_pair if not yet paired'), so the guidance is adequate but thin.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v0.12.0- Changed
zas_edit_item1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
zas_get_item1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
zas_list_items1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
zas_pair1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
zas_receive_direct1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
zas_receive_direct_fallback1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
zas_replace_file1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
zas_send_direct1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
zas_send_direct_fallback1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
zas_send_file2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / expires_in_days / maximumAdded value: +9007199254740991
- Changed
zas_send_note2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / expires_in_days / maximumAdded value: +9007199254740991
13 tool updates
v0.10.0- First observed
zas_edit_item - First observed
zas_get_item - First observed
zas_jobs - First observed
zas_list_items - First observed
zas_pair - First observed
zas_receive_direct - First observed
zas_receive_direct_fallback - First observed
zas_replace_file - First observed
zas_send_direct - First observed
zas_send_direct_fallback - First observed
zas_send_file - First observed
zas_send_note - First observed
zas_status
TDQS
Scored across 13 tools
Most tools target distinct actions: pairing/status, sending notes/files, Directo transfers, receiving, job tracking, and item editing are separable. Some boundaries are subtle—especially zas_send_file vs zas_send_direct and the two fallback tools vs their primary operations—but descriptions clarify channel mode and failure context.
All tools use a consistent zas_ prefix and snake_case naming. Most follow a verb_noun pattern, with minor deviations such as zas_status and zas_jobs being noun-like, but the convention remains readable and predictable.
Thirteen tools is well within the appropriate range for this domain, covering pairing, sending, receiving, job tracking, and item lifecycle. The fallback and direct-transfer variants each earn their place by handling distinct operational modes.
The surface covers core lifecycle operations: pair/status, send note/file, direct send/receive, fallbacks, list/get/edit/replace items, and jobs. A notable gap is item deletion or unpairing, though agents can work around these for most workflows.
Maintenance
Related MCP Connectors
End-to-end encrypted messaging and work coordination for autonomous AI agents.
Encrypted A2A object storage for autonomous agent state and artifacts
Private memory, scratchpads, context export/restore and task handoff for AI agents.
Private, permanent encrypted storage for AI agents. Paid per call in USDC via x402.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables secure credential storage for AI agents by encrypting secrets and providing agent-invisible references, ensuring sensitive data never leaks to the model.MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to create, read, update, list, restore, and share encrypted workspaces and artifacts with version-aware writes, view-only links, and optional public documents.7 npmMIT
- AlicenseNot gradedqualityAmaintenanceLets agents create, read, update, list, and restore shared encrypted workspaces and artifacts, exchanging a single link that both people and other AI agents can open and edit. Content is encrypted client-side with version-checked writes, so concurrent writers can't silently clobber each other and links can be shared as read-only or editable.7 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to create, read, update, list, and restore end-to-end encrypted workspaces and artifacts that any other agent or person can access through one shareable link, with version-checked writes and read-only or public sharing variants.7 npmMIT