cxws-mcp
cxws-mcp exposes the Codex standalone cloud-search endpoint as 11
intent-oriented MCP tools. It is a single Rust binary with stdio and MCP
Streamable HTTP transports. Each process uses the operator's own API base URL,
key, and model.
[!WARNING]
/alpha/searchis an experimental upstream API. Providers can remove it or change its schema.cxws-mcpfails clearly on incompatible responses and does not silently fall back to another search provider.
Requirements
- Rust 1.90 or newer to build from source
- An OpenAI-compatible provider that implements
<base-url>/alpha/search - A model accepted by that endpoint
Install
cargo install --path .
The binary is named cxws-mcp.
Configuration
CLI base URL and model values override their environment variables. The API key is environment-only so it does not appear in process listings or shell history. Logs go to stderr and never include the key or upstream response bodies.
Base URLs must use HTTPS. Plain HTTP is accepted automatically for localhost
and literal loopback addresses; use --allow-insecure-http for any other
operator-controlled HTTP endpoint. User information, query strings, and
fragments in the base URL are rejected. Upstream redirects are disabled.
Reqwest honors standard proxy variables such as HTTPS_PROXY and NO_PROXY.
Example:
export CXWS_BASE_URL='https://api.example.com/v1'
export CXWS_API_KEY='your-provider-key'
export CXWS_MODEL='your-search-capable-model'
Stdio
Start the server directly:
cxws-mcp stdio
Generic MCP client configuration:
{
"mcpServers": {
"cxws": {
"command": "cxws-mcp",
"args": ["stdio"],
"env": {
"CXWS_BASE_URL": "https://api.example.com/v1",
"CXWS_API_KEY": "your-provider-key",
"CXWS_MODEL": "your-search-capable-model"
}
}
}
}
Streamable HTTP
Start a loopback listener:
cxws-mcp http --listen 127.0.0.1:8787
Configure the MCP client with:
http://127.0.0.1:8787/mcp
Readiness is available at GET /healthz. The HTTP mode has no TLS or client
authentication and defaults to loopback. For remote use, place an authenticated
reverse proxy in front of it; see the Nginx guide.
The server uses tower-mcp for negotiated MCP protocol versions, including
stable 2025-11-25 initialization and the 2026-07-28 discovery lifecycle. It does
not implement the legacy standalone HTTP+SSE transport.
Tool Selection
The default tools are:
Search when no exact URL is known:
{
"queries": [
{"q": "OpenAI Codex official repository", "domains": ["github.com"]}
],
"response_length": "long"
}
Fetch an explicit URL directly:
{
"pages": [{"url": "https://github.com/openai/codex"}],
"response_length": "long"
}
Every successful result begins with a model-visible line and also returns structured content:
search_session_id: ws_550e8400-e29b-41d4-a716-446655440000
<search output>
{
"search_session_id": "ws_550e8400-e29b-41d4-a716-446655440000",
"output": "<search output>",
"results": [],
"results_omitted": false
}
Reuse that exact ID with a navigation tool when it refers to a previous
turn... result:
{
"search_session_id": "ws_550e8400-e29b-41d4-a716-446655440000",
"pages": [{"ref_id": "turn0search0"}]
}
Dependent navigation calls should be sequential. A pure URL passed to
web_search fails locally and tells the model to use web_fetch, without
spending upstream quota.
For 0.1 compatibility, set CXWS_EXPOSE_WEB_RUN=true or pass
--expose-web-run. The low-level tool is then appended as tool 12. Reconnect or
restart the MCP client after changing exposure so it refreshes tools/list.
Migration is direct: search_query -> web_search, literal open ->
web_fetch, referenced open/click/find/screenshot -> the matching
navigation tool, and image/finance/weather/sports/time fields -> their matching
search or lookup tool.
Limits
- four
web_search/image_searchqueries; four require medium or long output - 16 operations per call
- 20 domains per query
- 8 KiB per text operand and 64 KiB of context
- 1 MiB validated tool arguments and HTTP request bodies
- 120-second upstream request timeout
- 8 MiB total upstream response and 1 MiB plaintext output
- 2 MiB structured results; larger metadata is omitted with
results_omitted: true
The stdio transport is intended for trusted local clients. The transport can buffer a JSON line before semantic validation, so the 1 MiB raw HTTP limit has no exact pre-parse stdio equivalent.
Errors
The tools distinguish invalid arguments, authentication failures, rate limits,
timeouts, transport failures, malformed or oversized responses, and upstream
HTTP failures. A 404 advises checking both CXWS_BASE_URL and provider support
for /alpha/search. No request is retried automatically.
Development
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-targets
The paid smoke tests are ignored by default. Run them only with your own endpoint:
cargo test --test live_smoke -- --ignored --nocapture
The protocol design and implementation plan are under
docs/superpowers.
License
cxws-mcp is licensed under the GNU General Public License, version 3 only
(GPL-3.0-only). See LICENSE.