Codex Test-Hub MCP
This document describes the current flow for connecting Codex in VS Code to a test hub through AdaOS Root MCP.
Recommended VS Code Setup
For the current VS Code Codex workflow, use the public Root MCP endpoint directly:
- MCP URL:
https://<zone>.api.inimatic.com/v1/root/mcp - bearer token env var:
ADAOS_ROOT_MCP_AUTH
In practice:
- Use
infra_access_skillto issue a fresh MCP session lease for the target. - Copy the returned
mcp_http_url. - Store the returned
access_tokenin the OS environment asADAOS_ROOT_MCP_AUTH. - Point the VS Code Codex MCP server config at that URL and env var.
On Windows:
Important:
setxupdates the user environment for new processes only.- already running VS Code, Codex, terminals, and MCP helper processes keep the old bearer
- after rotating the bearer, fully restart VS Code if Codex keeps using the previous token
- after switching a zone from the legacy backend-local Root MCP proxy to the native public Root MCP surface, issue a fresh bearer; old backend-local MCP session leases are not expected to remain valid
Endpoint modes
The public backend serves /v1/root/mcp as a native Root MCP HTTP/JSON-RPC
surface by default. It should not require direct HTTP access from the public
backend to a developer laptop's 127.0.0.1:8777.
The legacy upstream proxy for /v1/root/mcp -> ADAOS_BASE is intentionally
removed for the MVP. There is only one supported meaning for this endpoint:
native Root MCP.
If smoke returns 502, treat it as endpoint/deployment health first, not as
proof that the bearer is invalid.
If the response body contains adaos_root_mcp_upstream_failed, the request was
handled by an old backend build with the removed legacy proxy. Deploy a backend
revision that has native Root MCP only.
If you want to verify the issued bearer before wiring Codex, test it directly:
curl -i https://ru.api.inimatic.com/v1/root/mcp/foundation `
-H "Authorization: Bearer $env:ADAOS_ROOT_MCP_AUTH"
and:
curl -i https://ru.api.inimatic.com/v1/root/mcp `
-H "Authorization: Bearer $env:ADAOS_ROOT_MCP_AUTH" `
-H "Content-Type: application/json" `
-d '{"jsonrpc":"2.0","id":"1","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
The same checks are available through the CLI smoke command:
adaos dev root mcp smoke `
--mcp-http-url https://ru.api.inimatic.com/v1/root/mcp `
--auth-env-var ADAOS_ROOT_MCP_AUTH
The smoke command checks:
GET /foundation- JSON-RPC
initialize - JSON-RPC
tools/list - JSON-RPC
tools/callforget_status
It exits non-zero when any step fails and classifies common failure modes:
auth_failed: bearer was rejected with401or403endpoint_not_found: MCP endpoint route is missingupstream_unavailable: root/proxy/upstream returned5xx, including502jsonrpc_error: HTTP transport worked, but the MCP server returned a JSON-RPC error
Local Bridge Compatibility Path
A local stdio bridge remains available for workspaces that cannot use the
remote HTTP endpoint or that need workspace-local profile/token files:
Codex in VS Code -> local bridge -> RootMcpClient -> Root MCP API -> managed test hub
This keeps SDK internals private and preserves the original Phase 1
Root MCP Foundation workflow while the direct remote endpoint matures.
What This MVP Covers
- scoped Codex connection to one managed target, normally
hub:<subnet_id> - read-first operational methods for the target
- token issuance through the target's published
infra_access_skilltoken-management surface - profile and token files stored under the workspace-local
.adaos/mcp/directory
The bridge currently exposes these tools:
foundationget_architecture_catalogget_sdk_metadataget_template_catalogget_public_skill_registryget_public_scenario_registrylist_managed_targetsget_managed_targetget_operational_surfaceget_statusget_runtime_summaryget_activity_logget_capability_usage_summaryget_logsrun_healthchecksrecent_auditget_yjs_load_mark_historyget_yjs_logsget_skill_logsget_adaos_logsget_events_logsget_subnet_infoget_subnet_analysis_healthget_subnet_timelineget_subnet_diagnostics
Why Keep The Local Bridge
Codex can register MCP servers directly, and the public backend now exposes the native remote Root MCP HTTP endpoint. The local bridge is still useful when testing workspace-local SDK behavior, using local profile files, or comparing remote endpoint results with the embedded local registry path.
The bridge reads a workspace-local profile and token file, then translates MCP
tool calls into RootMcpClient calls.
Prerequisites
Before setup, make sure:
- the workspace is connected to the intended root
- the target test hub is visible as a managed target on root
infra_access_skillis published by the target if you want operational toolsadaos dev root loginhas been completed, or you haveROOT_TOKEN/ADAOS_ROOT_TOKEN
For get_logs and run_healthchecks, the target must currently publish infra_access_skill with execution_mode=local_process.
Local Bridge Setup
1. Prepare the Codex bridge profile
Run:
By default this will:
- infer
target_idashub:<subnet_id> - issue a bounded MCP access token for audience
codex-vscode - write a profile file under
.adaos/mcp/adaos-test-hub.profile.json - write a token file under
.adaos/mcp/adaos-test-hub.token - print the exact
codex mcp add ...command to register the bridge
Useful options:
adaos dev root mcp prepare-codex --target-id hub:test-subnet --ttl-seconds 14400
adaos dev root mcp prepare-codex --owner-token $env:ROOT_TOKEN
adaos dev root mcp prepare-codex --apply-codex
--apply-codex updates ~/.codex/config.toml automatically.
2. Register the bridge in Codex
Copy the command printed by prepare-codex, or run the same shape manually:
codex mcp add adaos-test-hub --env ADAOS_MCP_PROFILE=D:\git\adaos\.adaos\mcp\adaos-test-hub.profile.json -- D:\git\adaos\.venv\Scripts\python.exe -m adaos dev root mcp serve
The important parts are:
ADAOS_MCP_PROFILEpoints the bridge to the workspace-local profile JSON- the Python command starts the local bridge over
stdio
The token itself is not stored in ~/.codex/config.toml; the bridge reads it from the token file referenced by the profile.
Workspace Directories
The local bridge now uses explicit workspace-local directories with separate purposes:
.adaos/mcp/bridge profile and token files used by Codex.adaos/state/root_mcp/Root MCP state and cache such as descriptor cache, session registry, and control reports.adaos/logs/local AdaOS process logs for the current machine; this is not an MCP response cache
3. Verify the Codex registration
Then open Codex in VS Code and ask it to inspect the target. A good first prompt is:
Use the AdaOS test-hub MCP tools to inspect the target operational surface, status, and runtime summary.
In Codex tool traces you should see namespaced tools such as:
mcp__adaos-test-hub__get_operational_surfacemcp__adaos-test-hub__get_statusmcp__adaos-test-hub__get_runtime_summary
Rotation and Refresh
To rotate the token, run prepare-codex again:
The bridge reads the token file on each call, so token rotation does not require rewriting the server definition if the profile path stays the same.
To remove the Codex registration:
Troubleshooting
Target is not registered
The command defaults to --ensure-target, so it can create a minimal test-target record on root. If the real target state still does not show up, verify control reports and target registration.
Token issuance fails
prepare-codex uses the target-scoped hub.issue_access_token path. If this fails, the target usually has not published infra_access_skill token management yet.
Check:
get_operational_surface- target control reports on root
infra_access_skilldraft or installed state on the hub
Logs or healthchecks fail
Those methods currently depend on execution_mode=local_process. If the target publishes only reported_only, status and observability tools still work, but bounded execution tools do not.
The dedicated log tools such as get_adaos_logs, get_events_logs, get_skill_logs, and get_yjs_logs now default to scope=subnet_active. This is intended to avoid empty root_local answers masking a healthy hub-root observability path. Use scope=root_local only when you intentionally want logs from the local machine hosting the bridge or root service.
Those log tools now also return explicit provenance and health blocks. This makes it easier to tell whether you are reading root-local logs, healthy subnet-active aggregation, or a degraded/partial subnet-active result.
For Phase 7 subnet analysis, prefer get_subnet_analysis_health before deeper investigation. It summarizes whether current snapshot, session-registry, audit, and subnet_active log channels are trustworthy enough for memory or incident analysis.
Use get_activity_log for a compact audit-derived activity feed. Use get_subnet_timeline when you need the richer typed history view that separates event classes such as control-report ingest, profile operations, session activity, and target operations.
Use get_subnet_diagnostics when you need typed pressure-oriented projections rather than raw logs. It now summarizes compact route backlog and pending-ack state, selected YJS runtime pressure, and recent root-ingested memory-profile sessions for the current subnet.
Session-management views now normalize expired MCP session leases on read, so ordinary list/get flows should no longer keep stale active sessions visible after TTL expiry.
Current Boundaries
This MVP intentionally does not yet provide:
- arbitrary shell access
- unrestricted deploy or rollback operations
- a public SDK import path for external MCP clients
Those remain later phases of Root MCP Foundation.