Skip to main content
Glama

await-mcp

Block agent execution until a condition is met — no more sleep N loops or returning early.

Problem

When agents run long operations (cloud builds, CI tests, deployments), they either:

  1. sleep N then check — inaccurate, wastes turns, model may give up

  2. Return and let the user remind them — breaks automation

Related MCP server: mcp-await

Solution

An MCP server that provides blocking await tools. The agent calls a tool, and the MCP server blocks (polling internally) until the condition is met. The agent is "stuck" on the tool call until it returns.

Agent: Start build → build ID 12345
Agent: Wait for build → await_command("curl -sf .../build/12345 | grep -q done") → BLOCKS
  [progress] Check #1 (0s): exit=1, running...
  [progress] Check #2 (30s): exit=1, running...
  [progress] Check #3 (60s): exit=0, success!
Agent: Build succeeded! Proceeding...

How It Works

Key insight: MCP tool calls are blocking

MCP clients block on MCP tool calls — the agent loop awaits the tool result. The MCP server can hold the connection open as long as needed (up to the configured timeout).

Progress notifications

The client generates a progressToken for each MCP tool call and listens for notifications/progress. The server sends progress updates with this token, so the user sees real-time polling status in the UI.

Timeout configuration

Level

Default

Configurable via

MCP server (connection-level)

client-dependent

timeout in the client's MCP server config

Per-tool-call

1 hour (3600s)

timeout_seconds parameter in the tool call

Set a large connection-level timeout in your client config to allow very long operations.

Tools

await_command

Polls a shell command until it exits with code 0 (success) or 2 (failure).

  • Exit 0: condition met → return { status: "success" }

  • Exit 2: condition failed → return { status: "failed" }

  • Other exit code: still running → keep polling

  • Timeout: return { status: "timeout" }

{
  "command": "curl -sf https://ci.example.com/build/123/status | grep -q done",
  "timeout_seconds": 3600,
  "interval_seconds": 30
}

await_url

Polls a URL until it returns the expected HTTP status code.

{
  "url": "http://localhost:3000/health",
  "expected_status": 200,
  "body_contains": "ready",
  "timeout_seconds": 600,
  "interval_seconds": 10
}

await_file

Waits for a file to exist (and optionally contain specific content).

{
  "path": "/tmp/build-status",
  "contains": "SUCCESS",
  "timeout_seconds": 3600,
  "interval_seconds": 10
}

Installation

1. Clone and install dependencies

git clone https://github.com/adlternative/await-mcp.git
cd await-mcp
npm install

Requires Node.js 18+ (uses the built-in global fetch).

2. Register the MCP server with your client

Replace /path/to/await-mcp with the absolute path where you cloned the repo.

opencode

Add to your opencode.json (project) or ~/.config/opencode/opencode.json (global):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "await": {
      "type": "local",
      "command": ["node", "/path/to/await-mcp/server.mjs"],
      "enabled": true
    }
  }
}

See the opencode MCP docs for more options.

Claude Code

Register via the CLI:

claude mcp add await -- node /path/to/await-mcp/server.mjs

Or add it manually to your .mcp.json (project scope) or ~/.claude.json:

{
  "mcpServers": {
    "await": {
      "command": "node",
      "args": ["/path/to/await-mcp/server.mjs"]
    }
  }
}

Qoder CLI

Add to ~/.qoder/settings.json:

{
  "mcpServers": {
    "await": {
      "command": "node",
      "args": ["/path/to/await-mcp/server.mjs"],
      "cwd": "/path/to/await-mcp",
      "timeout": 7200000,
      "alwaysAllow": ["await_command", "await_url", "await_file"]
    }
  }
}
  • timeout: 7200000 — 2 hour max per tool call (overrides the default)

  • alwaysAllow — skip permission prompts for the await tools

Usage Examples

Cloud build

Use await_command to wait for the build to complete:
  command: "curl -sf https://ci.example.com/build/<id> | jq -e '.status == \"success\"' && exit 0 || exit 1"
  interval_seconds: 30
  timeout_seconds: 3600

Service health check

Use await_url to wait for the service to be ready:
  url: "https://my-service.example.com/health"
  expected_status: 200
  interval_seconds: 10
  timeout_seconds: 600

File-based signaling

Use await_file to wait for a status file:
  path: "/tmp/deploy-status"
  contains: "SUCCESS"
  interval_seconds: 5
  timeout_seconds: 1800

Architecture

┌──────────────┐     MCP (stdio)      ┌──────────────┐
│  MCP client  │ ◄──────────────────► │   await-mcp  │
│  (agent)     │                      │   (server)   │
│              │  tools/call ──────►  │              │
│   agent      │                      │  poll loop   │
│   blocked    │  ◄─ progress notif   │  run check   │
│   waiting    │                      │  sleep       │
│              │  ◄─ result ────────  │  return      │
│   continues  │                      │              │
└──────────────┘                      └──────────────┘

Why not just sleep?

  • sleep N is a guess — too short and you check too early, too long and you waste time

  • Each check is a separate agent turn, consuming tokens and risking the model giving up

  • await-mcp does the polling inside the MCP server, not in the agent loop

Future Improvements

  • await_webhook: Two-phase (register + wait) for push-based notifications from CI/CD

  • WebSocket support: For real-time push instead of polling

  • Composite conditions: Wait for multiple conditions (AND/OR)

License

MIT

Available Tools

3 tools
await_commandA

Block agent execution until a shell command exits with code 0 (success). The command is polled at regular intervals. The agent is stuck on this call until done.

Exit code convention:

  • Exit 0: condition met → return success

  • Exit 2: condition failed → return failure

  • Any other code: still running → keep polling

Use this to wait for long-running operations: cloud builds, CI/CD, deployments, etc. Example: await_command(command="curl -sf https://ci.example.com/build/123/status | grep -q done", interval_seconds=30)

ParametersJSON Schema
NameRequiredDescriptionDefault
commandYesShell command to check periodically. Exit 0 = success, exit 2 = failure, other = still running.
timeout_secondsNoMax wait time in seconds. Default 3600 (1 hour).
interval_secondsNoSeconds between checks. Default 30.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description discloses key behavior: blocking, polling at intervals, and the exit-code meaning (0 success, 2 failure, others continue). It does not state what happens on timeout, but the timeout_seconds schema description implies a limit, which is a minor omission.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-organized: a clear summary, typed exit-code bullets, a usage note, and an example. Every sentence earns its place, with no fluff or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 3-parameter tool with no output schema, the description covers purpose, usage, exit semantics, and an example. It could mention timeout behavior, but the schema's 'max wait time' field and the overall clarity make this a solid, near-complete description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description reiterates the exit-code convention already present in the command schema and provides an example using interval_seconds, but does not add deep new meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action: 'Block agent execution until a shell command exits with code 0'. It specifies the resource (shell command) and distinguishes from sibling tools (await_url, await_file) by focusing on commands. The exit-code convention adds precise scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Use this to wait for long-running operations: cloud builds, CI/CD, deployments, etc.' and gives a concrete example. It does not explicitly contrast with URL/file waiting, but the example and domain make the intended use clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

await_fileA

Block agent execution until a file exists and optionally contains a specific string. Useful for file-based signaling between processes (e.g., build status files).

Example: await_file(path="/tmp/build-status", contains="SUCCESS")

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesFile path to check.
containsNoIf set, file content must contain this string for success. If not set, file existence is enough.
timeout_secondsNoMax wait in seconds. Default 3600.
interval_secondsNoCheck interval in seconds. Default 10.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It clearly discloses that execution is blocked until a condition is met, which is a critical behavioral trait. It does not mention timeout/error behavior, but the schema provides the timeout_seconds parameter. The example further clarifies the expected usage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences plus an example. Every sentence adds value: it states the core behavior, gives a use case, and demonstrates usage. No redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 4 parameters, no output schema, and no annotations, the description covers the purpose, a use case, and an example. It doesn't explain return values on success/failure or timeout behavior, but the schema covers the timing parameters. This is sufficiently complete for a straightforward blocking wait operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage with descriptions for all four parameters, so baseline is 3. The description adds value by providing a concrete example (path and contains), illustrating how the parameters work together, and reinforcing that 'contains' is optional.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'block' and clearly identifies the resource (file) and condition (exists/contains string). It naturally distinguishes itself from the sibling tools await_command and await_url by focusing on file-based waiting.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states 'Useful for file-based signaling between processes (e.g., build status files)' giving clear when-to-use context. It does not explicitly exclude other tools, but the resource-specific focus makes the intended use obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

await_urlA

Block agent execution until a URL returns the expected HTTP status code. Optionally check that the response body contains a specific string. The agent is stuck on this call until the condition is met or timeout.

Example: await_url(url="http://localhost:3000/health", expected_status=200)

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesURL to poll.
body_containsNoIf set, response body must contain this string for success.
expected_statusNoExpected HTTP status code. Default 200.
timeout_secondsNoMax wait in seconds. Default 3600.
interval_secondsNoCheck interval in seconds. Default 30.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses key behavioral traits: blocking execution until condition or timeout, and optional body content checking. It also notes the agent is 'stuck' during the wait, which aligns with the blocking nature. Missing details about failure modes (e.g., unreachable URL) and polling interval behavior, but the schema covers interval.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two terse sentences plus an illustrative example. It front-loads the core behavior without wordiness, and every sentence contributes meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations and no output schema, the description covers the essential behaviors (blocking, timeout, body check) but omits what happens on timeout (e.g., error/return value) and does not reference sibling tools. It is mostly complete but leaves minor gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for all five parameters, so the baseline is 3. The description adds an example but does not explain parameters beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action (block agent execution), the resource (URL), and the specific condition (expected HTTP status code, optional body string). This distinguishes it from sibling await tools that target commands and files.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The context for using this tool is clear: wait for a URL to return a specific status. The example further illustrates a health-check scenario. However, it does not explicitly mention alternatives, exclusions, or when to prefer this over await_command/await_file.

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.

  1. 3 tool updatesv1.0.0
    • First observedawait_command
    • First observedawait_file
    • First observedawait_url

TDQS

A4.5/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct condition type: shell command, URL, or file. The purpose of each is clear, and there is no meaningful overlap in their intended use cases. An agent can easily select the right tool based on the resource it needs to wait on.

Naming Consistency5/5

All tools follow the consistent verb_noun pattern of 'await_' followed by the target resource (command, url, file). This makes the tool names predictable and easy to remember. The naming convention is uniform throughout the set.

Tool Count5/5

With three tools, the server is well-scoped for its purpose of providing wait-for-condition primitives. Each tool covers a distinct and common category of waiting (shell, HTTP, file), so the count feels neither thin nor excessive for the domain.

Completeness5/5

The three tools cover the primary methods for blocking on external signals: command exit status, URL availability/response, and file presence/content. This set provides a solid foundation for waiting on common CI/CD, deployment, and build scenarios. While a generic 'sleep' tool is absent, the command-based approach can handle arbitrary delays, making the surface reasonably complete.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Provides a simple 'wait' tool that introduces deliberate pauses into workflows executed by MCP clients, allowing time for asynchronous operations to complete before proceeding to the next step.
    1
    38 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides a wait tool for AI agents to pause execution until a time duration elapses or a process terminates, useful for polling and waiting for builds/deployments.
    6 npm
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Provides persistent goal-tracking with external evaluation for agentic CLIs, enabling run-until-done loops where an agent works across turns until a condition is met.
    4
    -