This guide covers local agent integration for Nomos using checked-in quickstart files, MCP stdio mode, and the official HTTP SDK adoption layer.
Unless otherwise stated, the examples here show how to route actions through Nomos. They do not, by themselves, prove full mediation in unmanaged local environments.
The checked-in configs and policy bundles referenced here are examples only. In real deployments, teams are expected to supply and customize their own configs and policies.
examples/configs/config.example.json demonstrates ordered multi-bundle loading with base.yaml, repo.yaml, dev.yaml, and purchase.yaml.
If you are starting from a fresh machine, install Nomos first:
go install ./cmd/nomosShared quickstart assets used below:
- Run a preflight check:
nomos doctor -c .\examples\quickstart\config.quickstart.json --format json- Start the MCP server:
nomos mcp -c .\examples\quickstart\config.quickstart.json- Register Nomos in Codex MCP configuration with the checked-in example:
- In Codex, issue one allowed and one denied request:
- allowed: ask to read
README.mdfrom the quickstart workspace - denied: ask to read
.envfrom the quickstart workspace
Expected behavior:
README.mdsucceeds underallow-root-markdown.envis denied underdeny-root-env
Troubleshooting:
- if MCP registration fails, confirm the command uses the current
mcp -c ...example and not stale flags - if actions are denied unexpectedly, confirm Codex is targeting
examples/quickstart/workspace - if you see no startup banner, check whether
--quietis set
- Run the same preflight:
nomos doctor -c .\examples\quickstart\config.quickstart.json --format json- Start the MCP server:
nomos mcp -c .\examples\quickstart\config.quickstart.json- Register Nomos using the checked-in example:
- In Claude Code, run the same two requests using canonical Nomos file resources:
- allowed: read
file://workspace/README.md - denied: read
file://workspace/.env
M41 shorthand note:
- Nomos now advertises compatibility-safe MCP tool names such as
nomos_fs_read,nomos_fs_write,nomos_apply_patch,nomos_exec, andnomos_http_request nomos run codexandnomos run claudeuse the friendly launcher surface:read_file,write_file,apply_patch,run_command, andhttp_request- legacy dotted names such as
nomos.fs_readremain accepted for backward compatibility - for
nomos_fs_readandnomos_fs_write, common workspace-relative inputs such asREADME.md,./README.md,.env, orsrc/app.pyare now accepted and adapted to canonicalfile://workspace/...resources - policy, explain, and audit still operate on the canonical normalized resource
- absolute host paths and traversal attempts remain rejected
Troubleshooting:
- if Claude Code cannot connect, verify the MCP command path points to
nomos - if the wrong workspace is used, confirm the config file is config.quickstart.json
- if startup fails while loading
examples/policies/safe.yaml, your installednomosrelease may be older than the policy language used by the current repo - if a file read still returns
normalization_error, retry with a workspace-relative path likeREADME.mdor the explicit canonical formfile://workspace/README.md - in unmanaged local sessions, disable direct built-in file tools if you want Nomos to be the practical side-effect boundary
Use the runnable local HTTP example:
- Start Nomos:
nomos serve -c .\examples\quickstart\config.quickstart.json- In a second terminal, run:
python .\examples\openai-compatible\nomos_http_loop.pyWhat it demonstrates:
- a tool loop sending one governed action that returns
ALLOW - a second governed action that returns
DENY - deterministic handling of both responses over the HTTP API
- the same HTTP path can now be wrapped with the official SDKs instead of handwritten headers and envelopes
For wrapper-based integration patterns that let you guard one tool at a time, see:
Troubleshooting:
- if the script returns
401, use the default checked-in keydev-api-key - if the script returns
connection refused, startnomos servefirst - if you want to point the example at a different host, set
NOMOS_BASE_URL
OpenClaw uses the same MCP stdio contract.
- Start Nomos with the checked-in multi-bundle example config:
nomos mcp -c .\examples\configs\config.example.json- Register Nomos in OpenClaw MCP server config with command
nomosand args:
mcp-c.\examples\configs\config.example.json
If you want to override the checked-in example policy set, add:
-p.\examples\policies\your-policy-bundle.json
Nomos can also sit in front of third-party MCP servers without changing the downstream MCP-native agent.
Use:
- examples/configs/config.mcp-gateway.example.json
- examples/policies/mcp-gateway.example.yaml
- docs/upstream-mcp-gateway.md
What this mode does:
- Nomos acts as the MCP server to the agent
- Nomos acts as an MCP client to configured upstream
stdioservers - forwarded upstream tools appear downstream as compatibility-safe names such as
upstream_<server>_<tool> - upstream
stdiocompatibility is hardened for ecosystem-standard newline-delimited JSON MCP servers, while framed upstream responses are still accepted for compatibility - each forwarded call is evaluated as:
action_type:mcp.callresource:mcp://<server>/<tool>
Example:
nomos mcp -c .\examples\configs\config.mcp-gateway.example.jsonIn this example:
upstream_retail_get_order_detailsis allowedupstream_retail_request_refundrequires approvalupstream_retail_issue_compensationis denied
MCP mode keeps stdout protocol-only. Human-readable status/logs are written to stderr.
New flags:
--log-level error|warn|info|debug(defaultinfo)--log-format text|json(defaulttext)--quiet(equivalent to error-only; suppresses startup banner)
Default MCP runtime output behavior:
- one ready banner line on stderr after startup
- errors on stderr
- no non-protocol text on stdout
nomos mcp now supports short aliases and env fallbacks with deterministic precedence.
Short flags:
-cfor--config-pfor--policy-bundle-lfor--log-level-qfor--quiet
Env fallbacks:
NOMOS_CONFIGNOMOS_POLICY_BUNDLENOMOS_LOG_LEVEL
Precedence:
- explicit CLI flag
- environment variable
- fail closed
Example:
nomos mcp -c .\examples\configs\config.example.json -p .\examples\policies\your-policy-bundle.json -l infoUse -p here only when you intentionally want to override the example config's bundled policy paths.
For shared enterprise deployments, Nomos can expose its downstream MCP surface over Streamable HTTP instead of requiring one local stdio subprocess per agent:
nomos mcp serve --http --listen 127.0.0.1:8090 -c .\examples\configs\config.mcp-serve-http.example.jsonUse this mode when:
- multiple remote agents need to share one Nomos deployment
- you want MCP session auth to reuse the same bearer, OIDC, or SPIFFE identity model as the HTTP gateway
- you are deploying Nomos behind a reverse proxy or ingress with TLS termination
Keep in mind:
- clients must authenticate before
initialize - tool listings are principal-scoped
- resumed requests must send the same
MCP-Session-Idand principal nomos mcpstdio mode remains the right choice for single-user local editor integrations
Use nomos doctor before connecting MCP clients to validate configuration and runtime readiness.
Examples:
nomos doctor -c .\examples\configs\config.example.json
nomos doctor -c .\examples\configs\config.example.json --format jsonExit codes:
0READY1NOT_READY2INTERNAL_ERROR
{
"mcpServers": {
"nomos": {
"command": "nomos",
"args": [
"mcp",
"-c",
".\\examples\\configs\\config.example.json"
]
}
}
}{
"approvals": {
"enabled": true,
"backend": "file",
"store_path": ".\\nomos-approvals.json",
"ttl_seconds": 900,
"webhook_token": "replace-me"
}
}Use nomos.capabilities to discover the current advisory capability contract for a principal/agent/environment under loaded policy.
Response fields:
enabled_tools: backward-compatible union of all currently usable or approval-gated tools.immediate_tools: tools with at least one policy path callable now without approval.approval_gated_tools: tools that are only available through approval-gated policy paths.mixed_tools: tools where some policy paths are callable now and others require approval.unavailable_tools: tools advertised through MCP but not currently authorized for this identity context.advertised_tools: the static MCPtools/listsurface.tool_states: per-tool machine-readable state (allow,require_approval,mixed,unavailable) plus immediate-callable and approval-required flags.contract_version: explicit capability contract version.capability_set_hash: deterministic hash of the surfaced capability contract for the current identity and runtime.advisory_only: alwaystrue; capability surfacing is not an authorization result.authorization_notice: reminder that live action authorization remains authoritative.tool_states[*].constraints: bounded safe summaries such as resource classes, host classes, exec classes, and approval scope classes.tool_advertisement_mode: how MCP tool advertisement relates to effective policy state. Current value:mcp_tools_list_static.sandbox_modes: available sandbox mode envelope (noneorsandboxedin current implementation).network_mode:denyorallowlistdepending on policy-derived capability.output_max_bytes,output_max_lines: output caps returned to the client.approvals_enabled: whether approval workflow is configured.assurance_level: runtime-derived assurance label for the current mediation environment.mediation_notice: human-readable warning when the current runtime is not strong mediation.
MCP surfacing semantics:
tools/listremains static for compatibility and always advertises the full Nomos tool surface.nomos.capabilitiesis the authoritative advisory contract for client UX, not for authorization.- final authorization is still performed per action with deny-wins semantics.
- clients should treat
capability_set_hashchanges as a cue to refresh UI state, not as a bypass of live authorization.
In unmanaged developer laptops, mediation is best-effort. Nomos cannot guarantee that all side effects are forced through the gateway.
Safe workflow recommendations:
- Keep policy deny-by-default and only allow required actions.
- Require approvals for high-risk actions (
process.exec,net.http_request, writes/patches in sensitive paths). - Use publish-boundary validation (
repo.validate_change_set) before creating PRs. - Keep audit enabled (
stdout+sqlite) and reviewaction.completedevents. - Avoid local direct credentials; pass only lease IDs in policy/executor metadata.
Operational note:
- Stronger enforcement guarantees are expected in controlled runtimes (
ci, containers, andk8srunners). - In local Claude Code or similar unmanaged setups, disable direct built-in file/shell tools if you want Nomos to be the only practical side-effect path.
- See
docs/assurance-levels.mdfor the current assurance labels and mediation coverage exposed in audit andnomos policy explain.