agy-worker-mcp
This server lets you run the Google Antigravity CLI (agy) as detached, durable background worker jobs from any MCP client, with policy-gated permissions and full job/session management.
Start async
agyjobs with a prompt, permission profile, model/effort/mode, narrowing permissions, dry-run policy resolution, session continuation, JSON-schema output, and timeouts.Poll/wait for a job to finish and receive a compact judgement packet.
Retrieve full job results: broker verdict, agent self-report, and verification blockers with source, actionable flag, and remedy.
Read job logs as raw events, normalized lines, or stderr, using byte cursors or tail.
Queue follow-up turns on session-mode jobs and close stdin; cannot interrupt a running turn.
Cancel/kill running jobs and their whole process groups.
List running and recently finished jobs, filtered by lifecycle, workspace, session, or recency.
List, inspect, and close
agyconversations/sessions.Inspect server capabilities: models, profiles, discovered project root, limits, and version.
Jobs outlive the client connection: state lives in SQLite, output goes to files, and any client connected to the same project can monitor or take over jobs.
Allows running Google Antigravity CLI (agy) as an asynchronous worker agent, managing detached jobs with lifecycle state, permissions profiles, logs, and result retrieval from any MCP client.
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., "@agy-worker-mcpStart a job to research the codebase and summarize findings."
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.
Important — under active development (0.4.x). The permission model is a string classifier over tool calls — the same kind of boundary Claude Code and Codex use, not a kernel boundary. Allowed shell commands run without an OS sandbox by default since 0.2.1 (can be enabled with
sandbox: "seatbelt"). What the gate deliberately does not see is documented indocs/permissions.md; read it before starting. Point it only at projects you would let Claude Code work on unattended.
agy-worker-mcp
An MCP server that runs the Google Antigravity CLI (agy) as an asynchronous
worker agent, callable from Claude Code, Codex, and any other MCP client.
Unofficial. agy-worker-mcp is an independent, third-party MCP server. It is not affiliated with, endorsed by, or supported by Google. "Google", "Antigravity", "Gemini", and the
agycommand name are trademarks or product names of Google LLC and are used here only to identify the CLI this server drives. See Trademarks and terms.
Jobs are detached from the client that started them: a job's process outlives the MCP connection, its stdout/stderr are redirected to files rather than piped, and its state lives in a project-local SQLite database. Any client connected to the same project can start a job, watch it, take it over after its original caller disconnected, or resume its conversation later.
How it keeps a job honest: every tool call agy makes passes through our own
PreToolUse gate, which is the sole approval authority (agy's own engine is
off). What a job may do is set by two walls — the shipped profile, and a
human-owned per-project ceiling file that lives outside the workspace — and a
client request can only narrow within them. Allowed shell commands run without
an OS sandbox by default, as under Claude Code; a project can put a write-only
kernel boundary back with sandbox: "seatbelt". agy_ceiling, the shipped
agy-ceiling skill and the /agy-ceiling slash command let an agent or a user
propose that ceiling from the project's denial history — and nothing writes
the file without your approval. Version-by-version detail is in
CHANGELOG.md.
Why detached jobs
agy runs turns that take minutes to an hour. A plain stdio MCP server tied to
one client's process would lose the job the moment that client disconnects, and
would give a second client (Codex checking on a job Claude Code started) no way
to see it. Detaching the process, redirecting its output to disk, and
coordinating through SQLite makes the job durable and visible independent of
who is currently connected.
Related MCP server: mcp-job-queue
The one fact that matters most
agy's own exit code and status cannot be trusted. A permission denial —
and, on a job that runs sandboxed, an OS-sandbox block — surfaces as exit 0
/ status: SUCCESS. agy itself does not know it was blocked, and will often
report success after quietly failing or working around the block.
Every result this server returns carries a broker-computed outcome, derived
from actual events, exit status, and filesystem checks, kept deliberately
separate from agy's self-report (agent_report). Read outcome and
contract_status; never agent_report.status.
Requirements
Node.js ≥ 22.5, installed with a version manager. A root-owned global prefix (the official
.pkginstalls into/usr/local) makesnpm install -gfail withEACCES.The
agyCLI onPATH(developed and measured against agy 1.1.24–1.1.27; the hook contract re-checked against 1.2.1 — see docs/permissions.md).agy_capabilitiestells you whether the server can find it.
Install
npm install -g agy-worker-mcp
agy-worker-setupnpm install -g puts agy-worker-mcp, agy-worker-setup and the two helper
binaries (agy-worker-runner, agy-worker-gate) on your PATH.
agy-worker-setup then does the two things npm cannot:
writes a stable launcher at
~/.agy-worker/bin/agy-worker-mcpthat finds Node and this server itself at spawn time, andcopies the
agy-ceilingskill and the/agy-ceilingslash command into~/.claude/and~/.codex/(user scope by default;--scope projectputs them in./.claude/instead).
It never writes a client's config file, never overwrites an existing file
without --force, and --dry-run prints the plan. --link symlinks instead
of copying, so a package upgrade is picked up without re-running it.
--client claude|codex|all narrows what it touches.
Why the launcher
A GUI-launched client does not run your shell profile. It gets launchd's
PATH — /usr/bin:/bin:/usr/sbin:/sbin — where node does not exist if you
installed it with fnm, nvm, volta, asdf or mise. Registering the
command as agy-worker-mcp then works in a terminal and fails silently in the
app.
The launcher is a plain sh script with no dependency on PATH: it records
the Node and server paths that were live at install time, checks them, and
falls back to the newest version each common version manager has on disk. Point
your client at it rather than at a bare command:
claude mcp add agy --scope user -- ~/.agy-worker/bin/agy-worker-mcp# ~/.codex/config.toml
[mcp_servers.agy]
command = "/Users/you/.agy-worker/bin/agy-worker-mcp"agy-worker-setup prints both lines, filled in for your machine.
When something is wrong
agy-worker-setup --doctorchecks the launcher, the Node it resolves, whether agy is reachable and from
where, and what each client's config actually points at — which is usually the
answer when a server "does not start" with no error anywhere.
npm install -g github:thezoot3/agy-worker-mcp # builds on install (prepare)git clone https://github.com/thezoot3/agy-worker-mcp.git
cd agy-worker-mcp
npm install # `prepare` builds dist/ for you
claude mcp add agy --scope project -- node "$PWD/dist/server.js"A clone registered this way cannot run jobs in that same clone: agy_start
refuses a workspace that contains the gate binary (gate binary must not lie inside the workspace). Contributors who want to dogfood must register the
globally installed copy.
Registering by absolute path means the server runs whatever is in dist/ —
re-run npm run build after editing src/.
Check the registration with claude mcp list, and remove it with
claude mcp remove agy --scope user.
The server discovers the project root by walking up from its cwd to a git
root — a linked worktree resolves to the repository it belongs to, so every
worktree of one repository shares one ceiling, one lock domain and one database
— or honors AGY_WORKER_PROJECT as an override. Per-project state lives under
~/.agy-worker/projects/<hash>/, never inside your repository.
Quick start
agy_capabilities -- profiles, models, discovered root
agy_start { prompt, profile } -- returns job_id immediately
agy_wait { job_id, wait_ms } -- loop until lifecycle == "finished"
agy_result { job_id, section } -- verdict, verification, response text
agy_logs { job_id } -- only if you want the stream itselfagy_start with dry_run: true resolves configuration and policy without
spawning agy, so you can settle permissions before spending quota.
Need a job to see a toolchain that lives outside the workspace — ./gradlew
reading ~/.jdks, say? Add it to the project's own permission ceiling file
(~/.agy-worker/projects/<hash>/policy.json, agy_capabilities.ceiling.path
tells you the exact path), then ask for it in agy_start:
// ~/.agy-worker/projects/<hash>/policy.json
{ "version": 2, "read_roots": ["~/.jdks"] }agy_start { profile: "general_worker", permissions: { read_roots: ["~/.jdks"] }, ... }Without the matching ceiling entry, read_roots in the request is
dropped and reported in rejected_read_roots — see
docs/permissions.md for the full model.
When a job comes back blocked, agy_result's verification.blockers[] says
who refused. Each entry carries actionable (can a different agy_start lift
it) and remedy (what to change — for our own gate, the rule string the
effective allow list was missing). actionable: false means no agy_start
argument will help: the command tried to leave the workspace, the rule is not
in the project ceiling, or the ceiling forces the sandbox on — each of those is
a human editing policy.json, or a different command.
Tools
Tool | Role |
| Start a job, return |
| Long-poll until the job finishes or |
| Full, paged result: broker verdict, agent self-report, verification. |
| Raw or normalized event stream, by byte cursor or tail. |
| Queue a follow-up turn on a session-mode job. Cannot interrupt a running turn. |
| Kill a running job and its whole process group. |
| Running and recently finished jobs in this project. |
| List, inspect, or close |
| Models, profiles, the project ceiling as loaded, limits, discovered project root, server version. |
| Read-only: the ceiling, the effective policy, denial history, and a review of a draft ceiling. Never writes. |
| Remove a finished worktree job's worktree and delete its branch, once you have merged it. |
Parameter-level detail, the outcome vocabulary, and the two "blocked" classes
are in docs/tools.md.
Worktree isolation
agy_start { isolation: "worktree", prompt, profile: "general_worker" }puts the job in a fresh git worktree at <root>/.worktrees/agy-<job_id>, on
branch agy/<job_id>. Two jobs on one repository stop fighting over one tree,
and you can read a job's work before deciding to take it.
The job cannot commit — on a worktree job the gate denies git commit,
git merge, git rebase, git cherry-pick, git revert and git stash, and
no ceiling can lift them — so the branch is a proposal, not a fact. You merge
it:
git merge --squash agy/<job_id>
agy_release_workspace { job_id } # removes the worktree, deletes the branchA fresh worktree has no node_modules, so a JavaScript project's tests fail on
the first call. List what to link in the project ceiling:
{ "version": 2, "link_paths": ["node_modules"] }The server symlinks those in and widens the job's read roots to the real directory behind each link — writes through the link stay denied, so one job cannot corrupt what every other worktree and your own tree share. It is a ceiling key with no request field: a link is a read-root widening, and that is yours to decide.
agy_capabilities.worktrees lists worktrees still on disk. on_finish: "remove" cleans up automatically, but only when the worktree is clean and
its branch carries nothing the base does not already have — the default is
keep, because removal ends in git branch -D and deleting an unmerged
worktree destroys the job's entire output.
Permissions
Every tool call agy makes passes through our own PreToolUse hook, which
decides allow/deny and OS-sandbox bypass on every single call — agy's own
approval engine is disabled for every job (0.2.0), so our gate is the sole
authority. Three owners set the rules, each able to do one thing to the layer
below it: code (hard denies, the two shipped profiles — fixed), the
project's own ceiling file (~/.agy-worker/projects/<hash>/policy.json,
outside the workspace — widens what a job may ever ask for), and the parent
agent's agy_start.permissions (narrows within that ceiling, never widens
it).
Two profiles ship today:
research_readonly(default) — read-only workspace access and shallowgitinspection. No writes, no interpreters.general_worker— read/write inside the workspace,git,pytest, and the common build commands (./gradlew,gradle,mvn,npm test,npm run,javac,java).git push,curl, package installs,rm -rf, andsudoare denied by default — a project ceiling'sexceptionscan lift them, a client request never can — and an action that matches nothing is denied, never delegated toagy's own engine — a bound job's gate never answers "ask".
Client-requested permissions can only narrow the ceiling: allow is
intersected with it, deny always wins, sandbox: "seatbelt" | "agy" raises the OS
sandbox on for the job, and read_roots (extra --add-dir roots for a
toolchain outside the workspace) is intersected with the ceiling's own list.
The OS sandbox is off for allowed commands on general_worker (0.2.1) —
the gate's string match, not the kernel, is what bounds an allowed command,
same as Claude Code. It stays on for research_readonly, and a project can
force it on for every job with sandbox: "agy" in its ceiling file; expect
in-workspace builds, tests, and git commit to fail there on agy 1.1.24.
agy_start reports what the ceiling did to your request —
policy_summary (allow_count, bypass_sandbox, sandbox_forced_by) and a
source: "policy_ceiling" blocker per rejected rule. Watch for
allow_count: 0: a fully rejected allow request collapses the effective
list to empty and takes the profile's own defaults with it.
Full model — the three owners, the ceiling file schema, the gate's decision
order, containment, verify_command, and denial recovery — is in
docs/permissions.md.
Proposing a ceiling (skill)
The package ships a Claude Code skill, skills/agy-ceiling/SKILL.md, that
walks the parent agent through drafting a project ceiling from denial history
and the repository, validating it with agy_ceiling, and showing it to you —
and that forbids writing the file without your explicit approval of that
draft. The server has no code path that writes the ceiling at all; the skill is
the second wall.
For the case where you want the ceiling, not the agent, there is a slash
command, commands/agy-ceiling.md: /agy-ceiling cargo build, git push runs
the same procedure on demand, seeded with the commands you name, and still
stops for your answer before writing. agy-worker-setup installs both (see
Install); by hand it is a copy:
cp -R "$(npm root -g)/agy-worker-mcp/skills/agy-ceiling" .claude/skills/
cp "$(npm root -g)/agy-worker-mcp/commands/agy-ceiling.md" .claude/commands/Reports
Every finished job appends one summary line to
~/.agy-worker/projects/<key>/usage.jsonl — enums, counts, timings, tokens
and the rules it was denied, with no prompt, no response, no file path and no
command line in it. It exists because job directories are deleted after seven
days, and a ceiling recommendation is only as good as the history still on
disk. Nothing leaves the machine; AGY_WORKER_USAGE=off turns it off.
agy-worker-setup --report # the project: last 100 jobs
agy-worker-setup --report --job <job-id> # one job, for a bug reportBoth write one self-contained HTML file and print its path — no CDN, no font,
no external request of any kind, so it opens offline and no log content can
leave over the network. The project report's centrepiece is the table of
denied rules, in the same vocabulary agy_ceiling reads. The job report is
the bundle to attach to an issue: the verdict with contract_status shown
against agent_status, the blockers split by whether a different agy_start
could lift them, and the whole gate log — the allows included.
Prompts and response text are excluded unless --include-prompt; paths are
rewritten and recognisable secrets masked (--redact strict goes further).
Each report opens by saying what it contains, so you can read that before
attaching it anywhere. See
docs/operations.md.
Documentation
docs/tools.md— the eleven tools, parameter by parameter, and the result vocabularydocs/permissions.md— the three-owner permission model, the ceiling file, the gate's decision order, containment,verify_command, denial recoverydocs/operations.md— state layout, lifecycle, locks, timeouts, retention, the usage log and HTML reports, test suitesCHANGELOG.md— what changed in each version
Development
npm run typecheck # tsc --noEmit
npm test # vitest, against test/fake-agy — never the real agy binary
npm run build # emits dist/server.js, dist/runner.js, dist/gate.js, dist/setup.jsnpm test and CI run exclusively against the scripted fake in
test/fake-agy/; the real agy CLI is never invoked there,
since every invocation spends real quota. The real binary is exercised only by
the opt-in live suite:
npm run test:live # spends real agy quotaTrademarks and terms
agy-worker-mcp is an unofficial third-party integration; the name describes what
it drives, not who made it. Google, Antigravity, Gemini, and agy are Google LLC
trademarks; no license to those marks is granted or implied by this package.
This package launches the unmodified, officially installed agy binary as a
local subprocess on the user's own machine, using documented command-line flags
only (--print, --output-format, --add-dir, --model, --effort,
--print-timeout, --dangerously-skip-permissions) and the documented
.agents/hooks.json PreToolUse hook mechanism. Authentication stays entirely
inside agy (the user's own agy login); this package never reads, stores,
proxies, or forwards Antigravity credentials or tokens and never calls
Antigravity or Gemini backends itself. Model calls run inside agy's own harness,
and every job is charged to the user's own Antigravity plan quota. Multiple jobs
in parallel (limit max_running_jobs) consume quota faster than an interactive
session; keep parallelism modest.
Using this package means running agy under your own account. You are responsible for complying with the Google Antigravity Additional Terms of Service and the Antigravity FAQ on third-party tools. Google's terms forbid using third-party software with an Antigravity login to reach the models outside the official product, and Google has suspended accounts for that. This package is designed to stay on the "spawn the official CLI" side of that line, but the authors make no representation that Google agrees, and Google may change its terms. Users needing a different harness should use a Vertex AI or AI Studio API key as Google's FAQ suggests.
Provided "as is" under the MIT license; no warranty regarding compliance with any third-party terms.
License
MIT
Available Tools
9 toolsagy_cancelCancel jobADestructiveIdempotent
Kill a running job and its whole process group.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | ||
| reason | No | ||
| grace_ms | No | Milliseconds between SIGTERM and SIGKILL. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint and destructiveHint. The description adds concrete behavioral detail by specifying that it kills the entire process group, which goes beyond the generic destructive hint and clarifies the blast radius.
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 a single, focused sentence that conveys the core action and scope without any redundant words. It is highly efficient and easy to parse.
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?
Given the tool's simple nature, the description is adequate but incomplete. It lacks usage context, parameter explanations for job_id and reason, and any indication of return behavior, but the destructive/idempotent hints and process-group detail provide some context.
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?
Only grace_ms has a schema description; job_id and reason rely on name inference. The tool description does not explain any parameter meanings or relationships, and with only 33% schema coverage, this leaves important gaps for the agent.
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 the specific verb 'Kill' with the resource 'a running job' and clarifies the scope as 'its whole process group.' This clearly distinguishes it from siblings like agy_start and agy_wait, making the tool's purpose unmistakable.
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 description does not state when to use this tool versus alternatives, nor does it mention any exclusions or prerequisites. Usage must be inferred from the word 'running,' but no explicit guidance or sibling comparison is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agy_capabilitiesServer capabilitiesARead-onlyIdempotent
Report models, profiles, limits, discovered project root, and server version.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, covering the safety profile. The description adds no extra behavioral context beyond listing the report contents, which is minimal but not contradictory.
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?
A single, compact sentence that immediately states the tool's purpose and output contents. Every word earns its place with no 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?
For a zero-parameter read-only tool, the description fully specifies what information will be returned. No output schema exists, but the listed items (models, profiles, limits, project root, version) are sufficient for an agent to know what to expect.
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 are zero parameters, so the baseline for this dimension is 4. The description does not need to elaborate on parameter meanings since none 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?
The description clearly states the tool reports specific items (models, profiles, limits, discovered project root, server version) with a precise verb 'Report'. This differentiates it from sibling tools like agy_logs or agy_send, which handle other concerns.
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 description implies the tool is used to retrieve server capability information but does not explicitly state when to use it versus alternatives. Since it is a zero-parameter read-only capability query, usage context is intuitive but not explicitly articulated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agy_list_jobsList jobsBRead-onlyIdempotent
List running and recently finished jobs in this project.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | Exact match on the canonical workspace path. | |
| limit | No | ||
| since_ms | No | Only jobs created in the last N ms. | |
| lifecycle | No | Restrict to these lifecycle states. | |
| session_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds the scope of 'running and recently finished', but this conflicts somewhat with the lifecycle parameter which allows other states like 'queued' and 'canceling' – the description implies a fixed subset when the tool actually supports filtering. No contradiction with annotations, but behavioral details like default ordering or limits are absent.
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 a single sentence with no filler words, making it efficient and easy to parse. It front-loads the primary action and scope. Minor deduction for not using the available sentence to clarify the ambiguous 'recently finished'.
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 output schema and 5 parameters, the description is too sparse to fully specify behavior. It doesn't mention default limit, result ordering, whether the response is a list of job summaries or details, or how 'recently finished' is computed. Sibling tools like agy_cancel suggest mutation, but this list tool's interaction with them is not addressed. The annotations cover read-only, but contextual completeness for correct invocation is lacking.
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 60%, with 3 of 5 parameters described. The description does not add meaning beyond the schema; it only vaguely aligns with the lifecycle parameter. limit and session_id have no schema descriptions, and the tool description doesn't compensate for these gaps. Baseline 3 due to moderate schema coverage.
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 specific verb ('List') and resource ('jobs') and scopes to 'running and recently finished', making the core purpose clear. However, it does not differentiate from sibling tools like agy_result or agy_logs, and the meaning of 'recently finished' is ambiguous without a time frame.
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?
No guidance is given about when to use this tool versus alternatives such as agy_cancel or agy_wait. The description only states what it lists, leaving the agent to infer when this is the right tool. There is no mention of exclusions or conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agy_logsRead job logsARead-onlyIdempotent
Read raw events, normalized human-readable lines, or stderr for a job, by byte cursor or tail.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | ||
| stream | No | events = raw NDJSON, normalized = one readable line per meaningful step. Defaults to normalized. | |
| max_bytes | No | ||
| tail_lines | No | Last N lines. Mutually exclusive with after_cursor. | |
| after_cursor | No | Byte offset from a previous call. Mutually exclusive with tail_lines. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds useful behavioral context (stream types, byte cursor/tail modes) but doesn't disclose defaults (e.g., normalized stream), pagination behavior beyond cursor semantics, or response structure. This is adequate but not rich.
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?
A single sentence conveys the core purpose, stream options, and access methods with zero redundancy. Every word contributes information, and the most important distinctions are front-loaded.
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?
Given the tool's moderate complexity, no output schema, and annotations covering readonly/idempotent behavior, the description provides the essential information needed to understand what the tool does. Minor gaps like default stream selection are already captured in the schema's stream description. Overall, it is sufficiently complete for an agent to invoke 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?
Schema description coverage is 60% (stream, tail_lines, after_cursor have descriptions) while job_id and max_bytes lack descriptions. The description loosely maps to parameters via 'byte cursor or tail' and lists stream types, but adds no significant meaning beyond what the schema already provides for covered parameters and doesn't compensate for undocumented ones.
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 specific verb 'Read' with a clear resource 'raw events, normalized human-readable lines, or stderr for a job'. It distinguishes itself from sibling tools like agy_send or agy_cancel by focusing on reading logs, and mentions distinct stream types and access methods.
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?
No guidance is provided on when to use this tool versus alternatives like agy_result or agy_list_jobs. There is no mention of exclusions or prerequisites; the description only states capabilities, leaving the agent to infer appropriate usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agy_resultGet job resultARead-onlyIdempotent
Full, paged result of a finished job: broker summary, agent self-report, and verification (blockers[] with source / actionable / remedy for each thing that stood in the way).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Character count for the "response" section. | |
| job_id | Yes | ||
| offset | No | Character offset into the "response" section, for paging a long agent response. | |
| section | No | Which part to return. Defaults to summary. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is known. The description adds value by disclosing the paged nature, the sections available, and the structure of blockers (source/actionable/remedy), which goes beyond simple read-only hints.
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?
One compact sentence packed with useful information: it states the resource type, the paged nature, the three main components, and the blocker detail structure. No filler words; every phrase 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?
Given the parameter schema and annotations cover safety and parameter meanings, the description adds the essential conceptual model (what each section contains) and confirms paging capability. It doesn't explicitly mention return format (no output schema exists), but the description's breakdown of sections gives a good picture. It's slightly less complete because it doesn't state default section behavior, but the schema's property description already says 'Defaults to summary.'
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 75%, with limit, offset, and section having descriptions. The description adds meaning by explaining the 'response' section is paged and that blockers have specific fields, which helps understand the section parameter's impact. It doesn't fully compensate for the undocumented job_id parameter, but that parameter's meaning is obvious from context.
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 clearly states it returns the full, paged result of a finished job, enumerating specific components: broker summary, agent self-report, and verification with blockers. This specific verb and resource distinguishes it from siblings like agy_list_jobs (listing jobs) and agy_logs (logs).
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 description implies usage for finished jobs ('finished job'), which sets context for when to use it, but it doesn't explicitly contrast with siblings or state when not to use it (e.g., when job is still running, use agy_wait). The 'finished job' qualifier provides some exclusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agy_sendQueue follow-up turnA
Queue a follow-up turn on a session-mode job. Only takes effect after the in-flight turn finishes; there is no way to interrupt a running turn.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | The follow-up turn. Omit when only closing. | |
| close | No | Close stdin after this turn, ending the agy process at EOF. | |
| job_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only a title, so the description carries the full burden. It discloses key behavioral constraints: the queueing nature, that it takes effect only after the current turn finishes, and that there is no way to interrupt a running turn. This goes beyond typical schema details and informs the agent about timing and irreversibility of interruption. It does not mention whether the action is reversible or if it has side effects on job state, but the disclosure is sufficient for safe invocation.
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 two sentences of clear, front-loaded prose. It states the core action first, then provides the key constraint without any fluff or redundant details. Every word contributes to understanding the tool's behavior, making it an exemplar of conciseness.
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 tool with two optional parameters and one required parameter, the description covers the essential aspects: the action, the scope (session-mode job), and the timing/limitation. It does not explain the expected result or return value, but there is no output schema and the operation is simple enough that an agent can infer the outcome. The description is complete enough for correct invocation in most scenarios.
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 67% (two of three parameters explicitly described). The description does not add meaning beyond what the schema already provides for `text` and `close`, and `job_id` remains undocumented. However, the description's mention of 'session-mode job' gives context that the job must be in session mode, which is useful. With moderate coverage, this is an adequate score.
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 specifies the action ('Queue a follow-up turn') and the resource ('a session-mode job'), clearly distinguishing it from siblings like agy_cancel (which interrupts) and agy_start (which starts). The verb-noun combination is unambiguous and leaves no room for confusion with the other tools.
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 description states that it applies to session-mode jobs and that it only takes effect after the in-flight turn finishes, which implies when it should be used. However, it does not explicitly name alternatives or state when not to use this tool (e.g., if you need to cancel or interrupt a running turn). Given that siblings exist for cancellation and waiting, a clearer directive would elevate this to a 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agy_sessionsManage sessionsBRead-onlyIdempotent
List, inspect, or close agy conversations (sessions). A session is one agy conversation; a job is one turn.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| state | No | ||
| action | No | Defaults to list. | |
| session_id | No | Required for get and close. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description claims the tool can 'close' sessions, which is a mutating operation. However, annotations include readOnlyHint=true, indicating the operation should be read-only. This is a direct contradiction, making the behavioral information misleading.
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 concise and front-loaded: the first sentence lists the actions and resource, and the second clarifies domain vocabulary. No unnecessary words or 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?
The description covers the core actions but leaves parameter semantics incomplete, especially for limit and state. It also conflicts with the readOnly annotation, undermining reliability. Since there is no output schema, the description should clarify return behavior, but it does not. The tool is not fully specifiable from this description alone.
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 only 50%, and the tool description fails to compensate. It adds no meaning to 'limit' or 'state', which remain undocumented, and merely echoes 'action' and 'session_id' without additional insight. An agent would not know what values to pass for those parameters.
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 clearly states the tool's actions ('List, inspect, or close') on a specific resource (agy conversations/sessions). It also distinguishes sessions from jobs, helping disambiguate from sibling tools like agy_list_jobs.
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 description gives a useful context cue by defining sessions vs. jobs, but it does not explicitly state when to use this tool instead of siblings or when not to use it. Alternatives and exclusions are absent, so usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agy_startStart agy jobA
Begin a new agy job. Returns job_id immediately; never blocks — plus policy_summary and blockers[] for what the profile ceiling did to your permissions request. Use dry_run to resolve config and policy without spawning agy or spending quota.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | Workspace directory. Must be inside the project root. Defaults to the project root. | |
| mode | No | agy execution mode, e.g. accept-edits or plan. | |
| model | No | ||
| effort | No | ||
| prompt | Yes | Task for the agent. Sent as --print=<prompt>. | |
| dry_run | No | Resolve configuration and policy without spawning agy. Costs no quota. | |
| profile | No | Permission profile ceiling. research_readonly cannot write or run interpreters. Defaults to research_readonly. | |
| on_denial | No | What to do on the first policy denial. Default continue. | |
| session_id | No | Continue an existing agy conversation. Omit to create a new session. | |
| timeout_ms | No | ||
| json_schema | No | Path to a JSON schema for structured output. | |
| permissions | No | Narrowing only. allow is intersected with the profile ceiling; deny always wins. | |
| requested_by | No | ||
| session_mode | No | oneshot closes stdin after the prompt; session keeps it open for agy_send. | |
| parent_task_id | No | ||
| idle_timeout_ms | No | session_mode "session" only. Closes stdin (ending the process) after this many ms of no agy_send following the last completed turn. Does not affect timeout_ms/deadline_at — agy_send never extends those. Ignored for oneshot. | |
| expected_artifacts | No | Workspace-relative paths that must exist afterwards. Missing ones block verified_success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses key behaviors beyond the openWorldHint annotation: it returns job_id immediately, never blocks, and includes policy_summary and blockers[] in the response. It also explains that dry_run avoids spawning and quota usage. This gives the agent a clear model of the tool's execution and side effects.
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 three sentences, each carrying essential information: purpose, behavior, and dry_run alternative. It is front-loaded with the core action and avoids any filler or repetition.
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?
Given the tool's complexity (17 parameters, no output schema), the description provides crucial return-value context (job_id, policy_summary, blockers[]) that would otherwise be unknown. It also clarifies the non-blocking nature and cost behavior, covering the main aspects an agent needs for correct invocation and expectation setting.
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 71%, so the schema already documents most parameters. The description adds general context about the job start flow but does not elaborate on the undocumented parameters (e.g., mode, model, requested_by, parent_task_id). It does not significantly augment the schema descriptions, so a baseline score of 3 is appropriate.
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 begins with a specific verb and resource: 'Begin a new agy job.' It clearly differentiates this from sibling tools by noting immediate return and non-blocking behavior, and it contrasts with dry_run. This makes the tool's purpose unambiguous.
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 description gives explicit guidance on when to use dry_run versus actually starting a job, including the cost/quota implication. It implies the primary use case is starting a new job, but it does not explicitly contrast with continuing via sibling tools like agy_send or when to use session_id. Still, it provides sufficient context for typical invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agy_waitWait for job stateARead-onlyIdempotent
Long-poll a job until it FINISHES or wait_ms runs out — it does not return early on intermediate transitions like queued->running (200ms internal polling; wait_ms=0 for an immediate snapshot). A short wait_ms is a poll interval, not a change notification: each call blocks for the whole budget unless the job finished. Returns the judgement packet only, not full logs or the response text.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | ||
| wait_ms | No | Max time to block. 0 returns the current state immediately. | |
| after_cursor | No | Byte offset from a previous call, applied to the in-progress log tail. A finished job returns the full judgement packet and its end-of-stream cursor regardless. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide readOnlyHint and idempotentHint. The description adds substantial behavioral detail: internal polling at 200ms, no early return on intermediate transitions, wait_ms=0 as an immediate snapshot, how after_cursor applies to the log tail, and that only the judgement packet is returned. This far exceeds what annotations convey.
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 dense but every sentence carries operational information: blocking behavior, polling interval, wait_ms=0 semantics, return content scope. It is a bit long, but it avoids redundancy and front-loads the most critical behavioral caveat (does not return early on intermediate transitions) early. Slight over-length keeps it from a 5.
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?
Given the tool has no output schema, the description adequately explains the return payload ('judgement packet only, not full logs or the response text'). Combined with annotations covering safety, the description is sufficient for an agent to invoke it correctly. It lacks explicit mention of error handling or edge cases (e.g., job not found), but those are not essential for basic usage.
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?
With 67% schema coverage, the description compensates by explaining the behavioral semantics of wait_ms (blocking budget, 0 returns immediate snapshot) and after_cursor (byte offset applied to in-progress log tail, finished job returns full packet). This adds meaning beyond the schema descriptions, though job_id is not described beyond its presence in the required field.
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?
Description clearly states the tool's purpose: 'Long-poll a job until it FINISHES or wait_ms runs out'. It specifies a precise verb (long-poll), a resource (job), and the termination condition. It also differentiates from siblings by noting it returns only the judgement packet, not logs or response text, helping distinguish from agy_result and agy_logs.
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 description explains the blocking behavior and the meaning of wait_ms, which implies when to use it (e.g., to wait for a job to finish). However, it does not explicitly state when to use this tool versus alternatives like agy_result or agy_logs, or when not to use it. The usage context is present but left to inference.
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.
9 tool updates
v0.1.1- First observed
agy_cancel - First observed
agy_capabilities - First observed
agy_list_jobs - First observed
agy_logs - First observed
agy_result - First observed
agy_send - First observed
agy_sessions - First observed
agy_start - First observed
agy_wait
TDQS
Scored across 9 tools
Each tool targets a distinct aspect of job/session lifecycle: start, wait, result, logs, cancel, send, list, sessions, capabilities. No two tools overlap in purpose, making agent selection unambiguous.
All tools share the 'agy_' prefix and use lowercase_with_underscores, but the suffix mixes nouns (result, logs, sessions, capabilities) and verbs (send, cancel, wait, start). The pattern is predictable after exposure, though not strictly verb_noun throughout.
With 9 tools, the server is well-scoped for managing agy jobs and sessions. Each tool serves a necessary function without redundancy or bloat.
The tool surface covers the full job lifecycle: start, wait, retrieve result, read logs, cancel, list, send follow-ups, manage sessions, and inspect capabilities. No obvious dead ends or missing operations for the stated purpose.
Maintenance
Related MCP Connectors
Remote MCP for Antigravity agent run receipt MCP, structured receipts, audit logs, and reviewer-read
Remote MCP for Android CLI agent build gate, structured receipts, audit logs, and reviewer-ready evi
Remote MCP for AI Studio Android release gate MCP, structured receipts, audit logs, and reviewer-rea
Remote MCP for Gemini upgrade evals, prompt regressions, output diffs, and eval receipts.
Related MCP Servers
- AlicenseAqualityDmaintenanceWraps Google Antigravity CLI into 11 typed MCP tools, enabling any MCP client to invoke agy for code review, prototyping, execution, and long-running tasks.1123MIT
- AlicenseAqualityDmaintenanceEnables MCP clients to submit long-running jobs that are executed safely in isolated child processes with a durable SQLite queue, configurable timeouts, retries with backoff, and backpressure.5MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI clients to run Google Antigravity coding sub-agents as MCP tools, with synchronous and asynchronous execution, task polling, and sandboxed Docker workspace isolation.-
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to run declarative agents and DAG workflows as plain tools, with parallel nodes, review loops, and per-run least-privilege sandboxing.9 npmMIT