# mcp-await

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/ricardo-hdrn/mcp-await  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/mcp-await

## Description
Condition watcher for AI assistants — wait for ports, files, URLs, processes, and more

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "mcp-await": {
    "command": "npx",
    "args": ["-y","mcp-await"]
  }
}
```

## Documentation & README

# mcp-await

[![crates.io](https://img.shields.io/crates/v/mcp-await.svg)](https://crates.io/crates/mcp-await)
[![CI](https://github.com/ricardo-hdrn/mcp-await/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/ricardo-hdrn/mcp-await/actions/workflows/ci.yml)
[![license](https://img.shields.io/crates/l/mcp-await.svg)](LICENSE)

Condition watcher MCP server + CLI for AI CLI assistants (Claude Code, Codex, Cursor, etc.).

Instead of polling with `sleep` loops and `curl --retry` that waste API round-trips, call a wait tool once — it blocks until the condition is met and returns the result.

![demo](https://raw.githubusercontent.com/ricardo-hdrn/mcp-await/HEAD/docs/images/demo.gif)

## Installation

```bash
# Prebuilt binary (Linux, macOS, Windows) — download from GitHub Releases
# https://github.com/ricardo-hdrn/mcp-await/releases/latest

# From crates.io
cargo install mcp-await

# From source
git clone https://github.com/ricardo-hdrn/mcp-await.git
cd mcp-await
cargo build --release
```

## Quick Start

```bash
# Wait for a service to be ready
mcp-await port localhost 8080 --timeout 30

# Wait for a file to appear
mcp-await file /tmp/deploy.lock --event create --timeout 60

# Wait for a command to succeed
mcp-await cmd "curl -sf http://localhost:8080/health" --interval 2 --timeout 30
```

## Tools

| Tool | Key Params | How it watches |
|------|------------|----------------|
| `wait_for_port` | `host`, `port` | TCP dial loop, 500ms interval |
| `wait_for_file` | `path`, `event` (create/modify/delete) | inotify via `notify` crate, no polling |
| `wait_for_url` | `url`, `expected_status` (default 200) | `curl` loop, 2s interval (requires `curl`) |
| `wait_for_pid` | `pid` | `/proc/{pid}` check, 500ms interval |
| `wait_for_docker` | `container` | `docker wait` (requires `docker`) |
| `wait_for_gh_run` | `run_id`, `repo` (optional) | `gh run watch` (requires `gh`) |
| `wait_for_command` | `command`, `interval_seconds` (default 5) | Re-run via `sh -c` until exit 0 |
| `cancel_watch` | `watch_id` | Cancels a non-blocking watch |

All tools accept `timeout_seconds` (default: 300) and `blocking` (default: true).

## CLI Usage

The binary doubles as a standalone CLI tool:

```bash
# TCP port
mcp-await port localhost 5432 --timeout 30

# File events
mcp-await file /var/log/app.log --event modify --timeout 120
mcp-await file /tmp/flag --event create --timeout 60
mcp-await file /tmp/old.pid --event delete --timeout 30

# HTTP status
mcp-await url https://api.example.com/health --status 200 --timeout 120

# Process exit
mcp-await pid 12345 --timeout 300

# Docker container exit
mcp-await docker my-container --timeout 600

# GitHub Actions run
mcp-await gh-run 12345678 --repo owner/repo --timeout 1800

# Arbitrary shell command (exit 0 = success)
mcp-await cmd "test -f /tmp/ready" --interval 2 --timeout 30
```

### Exit Codes

| Code | Meaning |
|------|---------|
| 0 | Condition met (success) |
| 1 | Timeout |
| 2 | Error |

### Output Format

All commands output JSON:

```json
{
  "status": "success",
  "elapsed_seconds": 1.23,
  "detail": "localhost:8080 is accepting connections"
}
```

## MCP Server Setup

### Claude Code

Add to `~/.claude.json`:

```json
{
  "mcpServers": {
    "await": {
      "command": "/path/to/mcp-await"
    }
  }
}
```

The binary runs as a stdio MCP server when invoked without a subcommand (or with `mcp-await serve`).

### MCP Inspector

```bash
npx @modelcontextprotocol/inspector ./target/release/mcp-await
```

## Blocking vs Non-Blocking Mode

### Blocking (default)

The tool call holds until the condition is met, times out, or is cancelled. This is the simplest mode — the AI assistant waits for the result.

### Non-Blocking

Set `blocking: false` to get an immediate response with a `watch_id` and resource URI. The server monitors in the background and pushes a notification when done.

Flow:

1. Call `wait_for_port` with `blocking: false`
2. Get back immediately:
   ```json
   {"watch_id": "port-1", "resource": "watch://port-1", "status": "watching"}
   ```
3. Do other work while waiting
4. Receive `notifications/resources/updated` when the condition is met
5. Read `watch://port-1` for the full result

### Cancellation

Cancel any non-blocking watch with `cancel_watch`:

```json
{"watch_id": "port-1"}
```

## Resources

Non-blocking watches are exposed as MCP resources at `watch://{watch_id}`.

- `list_resources` — returns all active and completed watches
- `read_resource("watch://port-1")` — returns JSON with the watch status and result

## Reinforcing Agent Usage

Agents sometimes fall back to shell workarounds instead of using mcp-await. Add a snippet to your project's agent instructions file to reinforce the behavior:

| Agent | Instructions file |
|-------|-------------------|
| Claude Code | `CLAUDE.md` |
| Codex | `AGENTS.md` |
| Gemini CLI | `GEMINI.md` |
| Cursor | `.cursor/rules/` |
| Windsurf | `.windsurfrules` |

```markdown
## Waiting for conditions

Use mcp-await tools instead of shell workarounds:
- `wait_for_port` instead of `while ! nc ...; do sleep 1; done`
- `wait_for_url` instead of `curl --retry`
- `wait_for_file` instead of polling loops
- `wait_for_command` instead of `while ! cmd; do sleep N; done`

Prefer `blocking: false` when there is independent work to do in parallel.
```

## Roadmap

- [ ] Agent-level instructions to enforce mcp-await usage across all agents (system prompts, tool metadata hints)
- [ ] Broader agent compatibility testing (Codex, Gemini CLI, Cursor, Windsurf)

## Development

```bash
cargo build           # debug build
cargo build --release # release build
cargo test            # run tests
cargo clippy          # lint
cargo fmt             # format
```

## License

[MIT](https://github.com/ricardo-hdrn/mcp-await/blob/HEAD/LICENSE)

