xray-mcp-monitor
MCP server for checking reachability of nodes inside an Xray subscription by fetching subscription URLs, parsing nodes, running TCP probes, and exposing tools for scheduled monitoring.
README
Xray MCP Monitor
xray-mcp-monitor is an MCP server for checking the reachability of nodes inside an Xray subscription.
It accepts an http or https subscription URL, parses common node formats, runs scheduled TCP probes against each matched node, and exposes the whole workflow through MCP tools.
Features
- Fetches Xray subscriptions from
httpandhttpsURLs - Parses raw URI lists and common base64-encoded subscription payloads
- Supports
vmess,vless,trojan,ss,socks,http, andhttps - Recognizes
hy2,hysteria,hysteria2, andtuic, but marks them unsupported for probing - Runs a background scheduler for recurring checks
- Persists monitor definitions and latest results to a local JSON state file
- Exposes both one-off checks and long-running monitors through MCP tools
- Works over
stdio,streamable-http, andsse
How It Works
- A client calls
register_subscription_monitororcheck_subscription_once. - The server fetches the subscription payload from the provided URL.
- The payload is parsed into Xray nodes.
- Each matched TCP node is checked with a direct
host:portTCP connection. - The result is returned to the MCP client, and scheduled monitors are stored in local state.
Limits
- This is a TCP reachability probe, not a full proxy or handshake validation.
- UDP-style protocols are currently not actively checked.
- Monitor state is local to the process and stored in a JSON file.
interval_secondsmust be at least10.timeout_secondsmust be greater than0.
Requirements
- Python
>=3.10 mcp[cli] >=1.27,<2
Install
Using pip:
python3 -m venv .venv
./.venv/bin/pip install -e .
Using uv:
uv sync
Run The Server
Stdio transport:
./.venv/bin/python -m xray_mcp_monitor.server
Streamable HTTP transport:
./.venv/bin/python -m xray_mcp_monitor.server --transport streamable-http
SSE transport:
./.venv/bin/python -m xray_mcp_monitor.server --transport sse
You can also use the installed console script:
./.venv/bin/xray-mcp-monitor
Manage scheduled checks without Codex:
./.venv/bin/xray-mcp-monitor-cli --help
Run the web dashboard:
./.venv/bin/xray-mcp-monitor-web --help
Environment Variables
export XRAY_MCP_TRANSPORT=stdio
export XRAY_MCP_HOST=127.0.0.1
export XRAY_MCP_PORT=8000
export XRAY_MCP_STATE_FILE=./xray_watch_state.json
XRAY_MCP_TRANSPORT: default transport when--transportis omittedXRAY_MCP_HOST: bind host for network transportsXRAY_MCP_PORT: bind port for network transportsXRAY_MCP_STATE_FILE: path to the persistent watch state JSON file
Run Without Codex
If you want the scheduler to keep running without an interactive Codex session, use the bundled CLI manager instead of the MCP transport.
Register a scheduled watch:
./.venv/bin/xray-mcp-monitor-cli \
--state-file /root/xray-mcp/.codex/xray_watch_state.json \
register "https://example.com/subscription" \
--interval-seconds 300 \
--timeout-seconds 5 \
--node-name-keyword hk
List stored watches:
./.venv/bin/xray-mcp-monitor-cli \
--state-file /root/xray-mcp/.codex/xray_watch_state.json \
list
Run the background scheduler as a long-lived process:
XRAY_MCP_STATE_FILE=/root/xray-mcp/.codex/xray_watch_state.json \
./.venv/bin/python -m xray_mcp_monitor.cli daemon
You can also use:
./.venv/bin/python -m xray_mcp_monitor cli list
The scheduler state is persisted in XRAY_MCP_STATE_FILE, so the daemon reloads existing watches on startup.
Web Dashboard
The project now includes a built-in local dashboard for creating and managing monitors in a browser.
Start it locally:
XRAY_MCP_STATE_FILE=/root/xray-mcp/.codex/xray_watch_state.json \
./.venv/bin/xray-mcp-monitor-web --host 127.0.0.1 --port 8080
Then open:
http://127.0.0.1:8080
The dashboard supports:
- creating scheduled monitors
- running one-off checks
- listing current monitor health
- enabling or disabling monitors
- running a monitor immediately
- removing monitors
If you prefer the module form:
./.venv/bin/python -m xray_mcp_monitor web --host 127.0.0.1 --port 8080
systemd Service
This repository includes a sample unit at deploy/systemd/xray-mcp-monitor.service.
Recommended install flow:
sudo mkdir -p /opt/xray-mcp /var/lib/xray-mcp-monitor
sudo cp -r /root/xray-mcp /opt/xray-mcp
cd /opt/xray-mcp
python3 -m venv .venv
./.venv/bin/pip install -e .
sudo cp deploy/systemd/xray-mcp-monitor.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now xray-mcp-monitor
After that:
sudo systemctl status xray-mcp-monitor
journalctl -u xray-mcp-monitor -f
Before enabling the service, edit the unit file paths if your checkout is not under /opt/xray-mcp.
systemd Web Service
A separate sample unit is included at deploy/systemd/xray-mcp-monitor-web.service.
Install it with:
sudo cp deploy/systemd/xray-mcp-monitor-web.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now xray-mcp-monitor-web
Check logs with:
sudo systemctl status xray-mcp-monitor-web
journalctl -u xray-mcp-monitor-web -f
If you expose it beyond localhost, put it behind a reverse proxy or a firewall. The current dashboard does not include authentication.
MCP Tools
register_subscription_monitor
Create a scheduled monitor and immediately run the first check.
Parameters:
subscription_url: strinterval_seconds: int = 300timeout_seconds: float = 5.0node_name_keyword: str | None = None
check_subscription_once
Fetch a subscription and run a one-time check without storing a monitor.
Parameters:
subscription_url: strtimeout_seconds: float = 5.0node_name_keyword: str | None = None
list_subscription_monitors
List all registered monitors.
get_subscription_monitor
Return one stored monitor and its latest result.
Parameters:
watch_id: str
run_monitor_now
Run a stored monitor immediately.
Parameters:
watch_id: str
set_monitor_enabled
Enable or disable a stored monitor.
Parameters:
watch_id: strenabled: bool
remove_subscription_monitor
Remove a stored monitor.
Parameters:
watch_id: str
Status Values
Watch-level statuses:
error: fetching the subscription failedempty: no nodes were foundno_match: nodes were parsed, but none matchednode_name_keywordhealthy: all matched nodes were reachablehealthy_with_warnings: all matched nodes were reachable, but some non-fatal parse warnings were recordeddegraded: some matched nodes were reachable and some were unreachablepartial: some matched nodes were reachable and some were unsupportedunsupported: all matched nodes were unsupported for probingdown: no matched nodes were reachable
Node-level statuses:
reachableunreachableunsupported
Example Tool Call
Input:
{
"subscription_url": "https://example.com/path/to/subscription",
"interval_seconds": 300,
"timeout_seconds": 5,
"node_name_keyword": "hk"
}
Useful response fields:
watch.watch_id: stable ID for later operationswatch.last_result: latest stored result for a scheduled monitorresult.status: current overall health stateresult.nodes: per-node reachability, latency, and error detailsresult.errors: parse or fetch warnings
Codex Integration
This repository already includes a project-scoped Codex MCP config at .codex/config.toml.
If you want to configure it manually, use:
[mcp_servers.xray_monitor]
command = "/path/to/xray-mcp/.venv/bin/python"
args = ["-m", "xray_mcp_monitor.server"]
cwd = "/path/to/xray-mcp"
startup_timeout_sec = 15
tool_timeout_sec = 120
enabled = true
[mcp_servers.xray_monitor.env]
XRAY_MCP_STATE_FILE = "/path/to/xray-mcp/.codex/xray_watch_state.json"
If you use the checked-in .codex/config.toml, update the paths if this repository is not located at /root/xray-mcp.
Then start Codex in this project:
codex -C /path/to/xray-mcp
Inside Codex, use /mcp to verify that xray_monitor is connected.
Claude Desktop Style Config
{
"mcpServers": {
"xray-monitor": {
"command": "/path/to/xray-mcp/.venv/bin/python",
"args": ["-m", "xray_mcp_monitor.server"],
"cwd": "/path/to/xray-mcp"
}
}
}
Development
Run tests:
./.venv/bin/python -m unittest discover -s tests
Useful local checks:
./.venv/bin/python -m xray_mcp_monitor.server --help
codex -C /path/to/xray-mcp mcp list
codex -C /path/to/xray-mcp mcp get xray_monitor
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.