HTTP & WebSocket reference
Server endpoints
The routes that serve apps, connect browsers and expose RCWeb services. Find request methods, parameters, response behaviour and examples in one reference.
- HTTP
- Pages, assets & services
- WebSocket
- Live browser communication
- MCP
- JSON-RPC browser control
Paths are relative to your RCWeb host. Local development normally uses http://localhost:8080.
Reading the reference
{name} marks a value to replace; * marks a resource path. WS means a GET request with a WebSocket upgrade, using ws:// or wss://.
Method badges show the intended request method. Static resources and well-known domain routes also support HEAD. Other handlers perform their own checks; do not assume every GET route accepts HEAD or that every endpoint returns JSON.
System Endpoints
#Site metadata, icons and domain-verification routes. These are separate from room communication.
| Path | Method | Description |
|---|---|---|
/favicon.ico |
GET | Returns the site favicon. |
/pwa-512x512.png, /apple-touch-icon-180x180.png |
GET | Root icon aliases served from the default viewer app (v). |
/robots.txt |
GET | Search engine crawler instructions. |
/sitemap.xml |
GET | XML sitemap for search engines. |
/humans.txt |
GET | Information about the people who built the site. |
/security.txt |
GET | Security contact information (RFC 9116). |
/ads.txt |
GET | Authorized Digital Sellers list. |
/.well-known/security.txt |
GET | Security contact text from the domain verification handler. |
/.well-known/check |
GET | Returns start-verification for domain setup checks. |
/.well-known/acme-challenge/{token} |
GET | Returns an active ACME challenge response; unknown tokens return 404. These well-known routes also support HEAD; other well-known paths return 404. |
Pages and Service Endpoints
#Documentation, static resources and utility services. Availability depends on the deployed resource archives or classpath.
| Path | Method | Description |
|---|---|---|
/speedtest, /speedtest/{bytes} |
GET | Random binary download data without gzip. Defaults to 1 MiB; a numeric byte count
is capped at 100 MiB. Example: /speedtest/1048576. |
/javadoc/* |
GET | Serves the project's Java documentation. |
/assets/* |
GET | Serves static assets (CSS, JS, images, etc.). |
/docs/* |
GET | Serves system documentation pages. |
/showcase/* |
GET | Showcase pages and assets. |
/mcp/* |
GET | MCP control interface, guides and assets, including /mcp/showcase/.
The JSON-RPC endpoint is /api/mcp. |
/appinfo, /mcpinfo, /aiinfo, /devinfo |
GET | Templated information pages for apps, MCP control, the AI app sandbox and development. |
/tncaptcha/* | GET | Temporal-noise CAPTCHA demonstration pages and assets. |
/tncaptcha.gif, /tncaptcha/tncaptcha.gif | GET | Generates an animated CAPTCHA image. Optional parameters include text, type, text-size, steps, noise and distance. Text is limited to 32 characters; the default is TNCAPTCHA. This route generates the image; it does not verify an answer. |
/docs, /showcase, /mcp and
/mcp/showcase and /tncaptcha redirect to their trailing-slash forms. Java documentation is served
under the singular /javadoc/ path when the documentation archive is available.
Monitoring and Cache Endpoints
#Operational endpoints for server health, logs and cache management. Access checks are specific to each route.
| Path | Method | Description |
|---|---|---|
/api/health-check |
GET | Returns JSON with a health object and Cache-Control: no-cache.
A valid administrator auth query token additionally includes room state. |
/api/health-check.websocket |
WS | Sends health history followed by JSON updates containing changed metrics. |
/api/http-request-log.websocket |
WS | Stream of incoming HTTP requests for monitoring. |
/api/websocket-frame-log.websocket |
WS | Stream of WebSocket frames for monitoring. |
/api/invalidate-cache |
GET | Invalidates resource, Javadoc and speed-test response caches and returns plain text
OK. This changes server cache state; it does not clear the external proxy cache. |
/stats |
GET | HTTP request summary page. Requires HTTP Basic authentication; otherwise returns 401
with a WWW-Authenticate challenge. |
Application Endpoints
#Routes used to load an app, obtain setup values and join its virtual room. The shared runtime handles setup and reconnection.
| Path | Method | Description |
|---|---|---|
/ |
GET | Default viewer app (v). Requests whose User-Agent contains
Bot redirect to /docs/. |
/{app}/ |
GET | Serves the app's index page. A recognized /{app} redirects to the
trailing-slash form. Room allocation happens through setup.js,
not an HTTP redirect to add r. |
/{app}/setup.js |
GET | Dynamic setup JavaScript loaded internally by comms.js. Populates app, room,
client, version, and WebSocket endpoint values on the global rc object.
Accepts r; missing or invalid rooms get a new ID. Every setup request
creates a new client ID and sets a Secure, HttpOnly room cookie. |
/{app}/app.websocket |
WS | The primary WebSocket connection for an app. Required: r (roomId) and
c (clientId). Relays JavaScript between clients in the room.
Present but invalid IDs return 400. Missing r or c bypasses
the upgrade route and falls through to static resource lookup. A full room sends a
room-full message and closes with code 1008; the current limit is 32 retained client
slots, including the reconnect grace period. |
/{app}/webmanifest.json |
GET | Dynamic PWA manifest from the app's template, with an app scope and a start URL
containing r. Missing or invalid rooms get a new ID. |
/{app}/appinfo |
GET | Renders the app's appinfo.md as HTML in the shared information-page template. |
/{app}/* |
GET | App resources such as scripts, styles, images and appinfo.md.
An app is recognized by its index.html; unknown apps return 404. |
Load /assets/core/comms.js before app code and let rc.connect() load setup.
Use setup values after rc.onConnected(). See the
runtime and app development guide for room communication APIs.
MCP Browser Control
#The MCP endpoint requires no persistent protocol session. It uses JSON-RPC 2.0 and protocol version 2025-11-25.
Room codes grant access to room operations; no account or bearer token is required.
It does not enumerate rooms. The MCP interface and
MCP information page explain browser control.
| Path | Method | Description |
|---|---|---|
/api/mcp |
POST | Supports initialize, ping, tools/list and
tools/call. Returns JSON; there is no GET/SSE stream or session ID. |
/api/mcp-result |
POST | Internal browser callback for a pending execution. Accepts
{"token":"...","ok":true,"value":...} or
{"token":"...","ok":false,"error":"..."}.
A one-use token correlates the reply; success returns 204, and expired,
unknown or already-used tokens return 410. |
Request contract
- Send
Content-Type: application/jsonand a JSON object, not a batch array. Requests need a string or numericid. Notifications whose method starts withnotifications/receive 202 without executing tools. - If supplied,
MCP-Protocol-Versionmust be2025-11-25. AnOriginheader must match the request scheme, host and port; requests without Origin are accepted. - Both endpoints limit request bodies to 256 KiB and return
Cache-Control: no-store. HTTP errors include 400 for invalid headers or callback data, 403 for a rejected Origin, 405 for non-POST requests, 413 for oversized bodies and 415 for a non-JSON content type. - JSON-RPC parse, request, method and parameter errors use HTTP 200 with an
errorobject (codes-32700,-32600,-32601and-32602). Tool failures instead returnresult.isError: true.
Tools
| Tool | Arguments | Behavior |
|---|---|---|
list_clients |
room |
Lists live browsers as {client, app} entries. Results include the
room and clients in structuredContent and JSON text in content. |
execute_javascript |
room, client, javascript, optional timeout_ms |
Runs an ES5 function body once in the exact connected browser, with access to
window, document and page globals. No wildcard or app-name targets.
Call reply(value) with JSON-serializable data or fail(message). |
The default execution timeout is 10,000 ms; timeout_ms accepts integers from 1 to
30,000. JavaScript and generated reply JSON are each limited to 65,536 characters.
At most 64 executions can wait concurrently. Only the first reply or failure counts;
returning from the function alone does not send a result. Asynchronous callbacks may reply later,
but must catch their own errors.
Example JSON request bodies
POST each object separately to /api/mcp. Use a room with a connected browser and replace
the example client ID with one returned by list_clients.
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {},
"clientInfo": {"name": "example-client", "version": "1.0"}
}
}{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {"name": "list_clients", "arguments": {"room": "test-0001"}}
}{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "execute_javascript",
"arguments": {
"room": "test-0001",
"client": "abcd2345",
"javascript": "reply({title: document.title, url: location.href});",
"timeout_ms": 10000
}
}
}External API and Resource Proxies
#Named APIs use /api/proxy/{target}. The server supplies configured keys from
api-keys.properties; unknown targets or missing required keys return 404
(API not available). Query parameters are forwarded for the data APIs below; the named OpenRouter and Gemini routes use fixed upstream paths.
Cache durations describe the server's proxy cache.
| Path | Method | Function and cache duration |
|---|---|---|
/api/proxy/nasa_apod |
GET | NASA Astronomy Picture of the Day; 24 hours. Key: nasa_apod. |
/api/proxy/unsplash_random |
GET | Random Unsplash photos, for example ?query=sky; 24 hours.
Key: unsplash_random. |
/api/proxy/pexels_videos |
GET | Pexels video search, for example ?query=sky; 24 hours.
Key: pexels_videos. |
/api/proxy/youtube_videos |
GET | YouTube video details, for example ?part=snippet&id=dQw4w9WgXcQ;
24 hours. Key: youtube_videos. |
/api/proxy/youtube_search |
GET | YouTube search, for example ?part=snippet&q=sky&type=video;
1 hour. Key: youtube_search. |
/api/proxy/openmeteo_forecast |
GET | Open-Meteo forecast, for example ?latitude=52.52&longitude=13.41;
1 hour. No key required. |
/api/proxy/thenewsapi_top |
GET | TheNewsAPI top news, for example ?country=us; 1 hour.
Key: thenewsapi_top. |
/api/proxy/openrouter/models | GET | OpenRouter model list; uncached. Requires the openrouter server key. An incoming Authorization header can override the key on this model-list route. |
/api/proxy/openrouter/chat/completions | POST | Forwards a chat-completion request to OpenRouter; uncached. Uses the configured openrouter server key. |
/api/proxy/openrouter/responses | POST | Forwards a Responses API request to OpenRouter; uncached. Uses the configured openrouter server key. |
/api/proxy/gemini/models |
GET | Gemini's OpenAI-compatible model list; uncached. Requires the gemini
server key. An incoming Authorization header can override the key for this route. |
/api/proxy/gemini/chat/completions |
POST | Forwards a JSON chat-completion request to Gemini's OpenAI-compatible endpoint;
uncached. Always uses the configured gemini server key. |
/api/basic-proxy/{url} |
GET | Fetches the absolute upstream URL following the prefix, including its query string; cache duration 60 seconds. |
/api/image-proxy/{url} |
GET | Same resource relay with a 24-hour cache, intended for images. It does not resize or transform images. |
For example, /api/basic-proxy/https://example.com/feed.xml places the full upstream
URL after the route prefix. The table shows intended usage; the proxy forwards the incoming
method and body on a cache miss. WebSocket upgrades are rejected. Cache entries are keyed by
target URL; hits include X-Cache-Hit: true and X-Cache-Expiry.
Named API proxies remove incoming Cookie, User-Agent and Authorization headers before adding provider credentials (with the OpenRouter and Gemini model-list overrides described above). The basic and image proxies use the generic forwarding handler and do not apply this named-API header filtering.
Browser File Relay
#Files are supplied by a browser in a room. These routes coordinate downloads and pending chunks; they are not persistent file storage.
| Path | Method | Description |
|---|---|---|
/x-file/{room}/{client}/{fileId}/{filename} |
GET | Requests a shared file from the source browser. The filename segment is optional.
Supports ETag validation (304) and a byte-range starting offset, for example
Range: bytes=1024- (206, streamed to the end of the file). |
/x-chunk/{room}/{client}/{chunkId} |
PUT | Source browser uploads bytes to the generated pending-chunk URL. Uses
Content-Type, body length and Content-Range for file metadata;
successful relay returns 204. Use the URL supplied by the runtime. |
/x-file/*, /x-chunk/* |
CORS preflight for a valid room/client path. Returns 204 and advertises GET and PUT. |
Both prefixes share the same handler. For correctly structured paths, invalid room or client IDs return 400; an unavailable
source client returns 503. The download can also include ?receiver={clientId}
to identify the receiving client.
Response and deployment notes
#Responses depend on the selected handler and deployment configuration. The status alone does not prove that a browser action completed.
| Status or signal | Where it occurs |
|---|---|
200 with an error body | MCP JSON-RPC errors use an error object. Tool failures use result.isError: true; check both layers. |
204 / 410 | An accepted MCP callback returns 204. Unknown, expired or already-used callback tokens return 410. |
400 / 404 | Invalid app WebSocket IDs return 400 when both parameters are present. Unknown apps/resources and unavailable named API targets return 404. |
401 / 403 | The stats page challenges missing or invalid Basic credentials with 401. MCP rejects a mismatched Origin with 403. |
405 / 415 | MCP requires POST and application/json. Unsupported methods and content types return 405 and 415 respectively. |
413 / 429 | MCP rejects bodies over 256 KiB with 413. Requests covered by the server request-rate check may receive 429. |
WebSocket close 1008 | A full room sends an explanatory message and closes the new connection. This is a WebSocket close code, not an HTTP response status. |
Routing and deployment
When encourageSecureConnections is enabled, application and API requests over HTTP redirect to HTTPS. API, file-relay and app requests pass through the request-rate check. Static documentation and information pages are routed before that check; well-known domain verification routes are handled before the HTTPS redirect.
Static resources, Javadoc archives and keyed APIs must exist in the deployment. A 404 from a named API can mean that the server lacks its configured key. Room operations, file transfers and MCP callbacks must reach the server instance holding the relevant connection or pending request.
Implementation sources
Java source paths below link to the corresponding API documentation.
src/main/java/net/targetr/rc/RootResponder.java: route selection, redirects and static resources.src/main/java/net/targetr/rc/mcp/McpHandler.java: JSON-RPC requests, tool arguments, callback tokens and limits.src/main/java/net/targetr/rc/util/ApiProxy.java: named upstream routes, key requirements and cache durations.src/main/java/net/targetr/rc/client/ClientFileProxy.java: browser-hosted downloads, chunk uploads and range handling.