Skip to main content
Glama
slchenchn

notify-mcp

by slchenchn
README.md
# page-user — proactive push-notification MCP

English | [简体中文](README.zh-CN.md)

An MCP server that gives any MCP client (Claude Code, Codex CLI, …) a `page_user`
tool. The AI calls it to proactively push a short message to your phone via
Telegram — when a long task finishes, a run fails, it needs a decision, or you
asked for periodic progress. Each message carries the **machine name**, **which
CLI** sent it, a **session label**, and optional **tables** (rendered aligned).

```
Claude Code / Codex ── page_user(message, title?, host?, session?, agent?, table?, tag?) ──►
        (just a URL + token in config)                                                       │
                                                                                             ▼
                                              Cloudflare Worker (remote MCP) ──► Telegram
```

There are two flavors. The **Cloudflare remote MCP** is recommended; the original
**self-hosted Apprise gateway** is kept as a legacy alternative (see the end).

## Recommended: remote MCP on Cloudflare

The whole server is one Cloudflare Worker in [`cloudflare/`](./cloudflare) —
stateless MCP over Streamable HTTP, bearer auth, pushes straight to Telegram.
Nothing runs on your machines; you update every client at once by redeploying.

1. **Deploy** the Worker and set its secrets — full step-by-step in
   [`cloudflare/README.md`](./cloudflare/README.md). You end up with an endpoint
   like `https://<name>.<subdomain>.workers.dev/mcp` and a bearer `AUTH_TOKEN`.

2. **Register** with your CLIs on each machine:

   ```bash
   PAGE_USER_TOKEN=<AUTH_TOKEN> ./scripts/install_page_user.sh
   ```

   This removes any old `notify` server and adds `page-user` to Claude Code (user
   scope) and Codex (`~/.codex/config.toml`), baking in the machine's hostname
   (`X-Host`) and the CLI name (`X-Agent`). Override the endpoint with
   `PAGE_USER_URL` if you deployed under a different name.

3. **Verify**: `claude mcp list` (should show `page-user … ✔ Connected`) and
   `codex mcp list`.

> **Egress:** clients must be able to reach `*.workers.dev` (the default Worker
> domain is commonly blocked on direct connections — a working HTTP(S) proxy in
> the environment is enough; the CLIs inherit `HTTPS_PROXY`). If a machine can't
> reach `*.workers.dev` at all, bind a custom domain to the Worker instead.

### The tool

`page_user(message, title?, host?, session?, agent?, table?, tag?)` — pushes a
formatted notification. Only `message` is required; `host`/`agent` default to the
`X-Host`/`X-Agent` headers set at registration, `tag` selects a recipient group
(`TARGETS` secret), and `table` is rows of strings rendered as an aligned
monospace table. The model learns all of this from the tool's MCP schema — it
does not read this README. To change the tool or its guidance, edit
`cloudflare/worker.js` and `npx wrangler deploy`; all clients pick it up.

### Manual registration

```bash
# Claude Code (user scope):
claude mcp add --transport http page-user https://<name>.<subdomain>.workers.dev/mcp \
  -H "Authorization: Bearer <AUTH_TOKEN>" -H "X-Host: $(hostname)" -H "X-Agent: claude-code" -s user

# Codex — add to ~/.codex/config.toml:
# [mcp_servers.page-user]
# url = "https://<name>.<subdomain>.workers.dev/mcp"
# http_headers = { "Authorization" = "Bearer <AUTH_TOKEN>", "X-Host" = "<host>", "X-Agent" = "codex" }
```

---

## Legacy: self-hosted Apprise gateway

The original design is a thin Python MCP wrapper (`notify_mcp.py`, tool
`send_notification`) that POSTs to a self-hosted Apprise gateway (`server.py`),
which forwards to Telegram/Feishu/etc. Use this if you can't or don't want to use
Cloudflare. It is managed with [uv](https://docs.astral.sh/uv/):

```bash
uv sync --extra gateway       # wrapper + apprise
./scripts/start_gateway.sh    # run the gateway (needs ./token and ./targets.json)
./scripts/install_mcp.sh      # register the `notify` MCP with Claude Code + Codex
```

Details:

- [`docs/NOTIFY_GATEWAY.md`](./docs/NOTIFY_GATEWAY.md) — example gateway deployment (systemd, proxy, Telegram/Feishu).
- [`docs/MCP_INTROSPECTION.md`](./docs/MCP_INTROSPECTION.md) — how a client discovers the server's identity and tool.
- [`docs/ABOUT.txt`](./docs/ABOUT.txt) — short, human-friendly intro (中文).

## Unit tests (legacy Python code)

```bash
uv run pytest -q                 # no network needed
uv run pre-commit run --all-files  # ruff format/lint
```

TDQS

A4.5/5.0

Scored across 1 tool

Disambiguation5/5

Only one tool exists, so there is no possibility of confusion between tools. The purpose is clearly distinct by default.

Naming Consistency5/5

With a single tool, naming is trivially consistent. The name 'send_notification' follows a clear verb_noun pattern.

Tool Count3/5

One tool is borderline appropriate. The server's scope is limited to sending notifications, which could justify a single tool, but it feels thin compared to typical MCP servers that offer multiple operations.

Completeness2/5

The tool only sends notifications; there are no operations for managing recipients, viewing history, or configuring channels. While the core action is covered, significant gaps exist for a complete notification system.

Maintenance

ActivityInactive
ResponsivenessNo issues