Skip to content
Nauro

Guides

Connect your agent

Connect through hosted MCP, or install the CLI for a local repository.

On this page

Connect hosted MCP

Add the following URL as a custom MCP connector and sign in.

MCP URL
https://mcp.nauro.ai/mcp

Sign-in and context reads are verified with Claude.ai and ChatGPT. Follow the ChatGPT setup below. Other hosted clients need CIMD support or predefined OAuth credentials with an allowed callback. Automatic registration is unavailable.

Use Nauro in a repository

Run uv tool install nauro, then nauro adopt inside your Git repository.

Works with Claude Code, Cursor Desktop, and Codex. Open the CLI quickstart.

Verify your connection

Start a fresh agent session after setup. Ask: “Use Nauro to get the current context for my project.” Confirm that the agent calls get_context and returns the project you intended.

A successful sign-in connects your account. To make an existing local project available through hosted MCP, follow the cloud setup steps. If the agent cannot find your project, check that it is available under the same account. For local setup, run nauro status, restart the agent, and try the call again.

Need client-specific steps? See ChatGPT setup, Codex hosted setup, Cursor Desktop and Cloud, or seeding a project from chat.

ChatGPT

Your ChatGPT account and workspace must allow developer-mode apps. Create a new app with the MCP URL https://mcp.nauro.ai/mcp, then open Advanced OAuth settings.

  1. Select User-Defined OAuth Client as the registration method.
  2. Set the client ID to APBlni39X665FqI6GzCKjAeYOMVtgyF7. This is a public identifier.
  3. Leave the client secret blank. Set token endpoint authentication to none.
  4. Set scopes to openid profile email offline_access read:context write:context.
  5. Connect and select Google sign-in with the same identity you use for Nauro.

The callback shown in ChatGPT must be https://chatgpt.com/connector_platform_oauth_redirect. If an old app shows a different callback, create a new app with these settings.

Start a new chat with the app enabled. Ask it to call list_projects, then get_context for your project. If the project is missing, check your Nauro identity and whether the project is available through hosted MCP.

The requested scopes include read and write access. Each tool still applies Nauro’s access rules. Login and context reads have been verified. Automatic refresh and access with a second user remain under validation. If the connection expires, use Reconnect.

Connection reference and troubleshooting

Two connection planes: local stdio vs cloud connector

Nauro has two distinct transports for the same store and payloads:

  • Local. The stdio MCP server, spawned per-session by the agent client. It is canonical for any machine with a working copy.
  • Cloud. The hosted HTTP connector at https://mcp.nauro.ai/mcp, used from surfaces without a local checkout (claude.ai web) or from another machine.

The local MCP contract is stable as of 1.0. Nauro versions and operates the cloud connector separately.

stdio is the sole supported local transport; the former local FastAPI HTTP transport was retired (per the serve.py docstring). The cloud connector is HTTP and lives in a separate, private hosted server.

The stdio server resolves project context from the current directory’s .nauro/config.json; there is no --project flag on serve (one source of truth, per the serve.py docstring).

Commit .nauro/config.json as the portable project-identity pointer. Client wiring is machine-local because it records an absolute executable path. Setup regenerates that wiring per machine, adds its repo-local files to a managed .gitignore block, and refuses to write a machine-local path into a file already tracked by git.

Same store and payloads on both planes: the stdio server delegates to the transport-agnostic implementations in nauro.mcp.tools, which call into nauro_core.operations.

Local plane Cloud plane
Transport stdio (spawned per session) HTTP connector
Endpoint nauro serve --stdio https://mcp.nauro.ai/mcp
When to use Any machine with a working copy (canonical) Surfaces with no local checkout, or another machine
Project resolution From the cwd’s .nauro/config.json From the authenticated cloud project

The local stdio server registers 12 MCP tools (7 read, 5 write). The shared nauro_core.mcp_tools.ALL_TOOLS registry has 11 (8 read, 3 write); list_projects is hosted-only because local installs auto-resolve to the single project store. The local server adds update_stack and share_context, which write only through an attached generation replica and otherwise answer generation_required.

Counted the other way: the hosted HTTP server registers HOSTED_TOOLS, the 11 shared tools plus update_stack, share_context, and create_project, for 14. list_projects and create_project are hosted-only.

text · local stdio tools
get_context, get_raw_file, list_decisions, get_decision,
diff_since_last_session, search_decisions, check_decision,
propose_decision, flag_question, update_state,
update_stack, share_context   # write only through a generation replica

# list_projects (11th tool in nauro_core.mcp_tools.ALL_TOOLS) and
# create_project (HOSTED_TOOLS) are hosted-only

Source: serve.py; stdio_server.py (module docstring; run_stdio); nauro_core/mcp_tools.py (ALL_TOOLS, HOSTED_TOOLS); tools.py (module docstring).

The local stdio MCP server (nauro serve --stdio)

nauro serve --stdio calls run_stdio(), which runs a best-effort session-start pull (_pull_on_startup()), then mcp.run(transport="stdio"). The MCP client (Claude Code, Cursor, Codex) spawns this process and talks over stdin/stdout. Nauro sends no product analytics.

The --stdio flag is hidden and a no-op: it is accepted only for backward compatibility with installed client configs that spawn nauro serve --stdio. stdio is now the only transport (the serve Typer option is hidden=True with default True).

On startup, _pull_on_startup() resolves the project through the canonical two-tier waterfall: walk up to a .nauro/config.json, then try a v2 registry repo-path match. The v1 registry is not a resolution fallback.

If the project is cloud-mode with a stored token, it pulls the latest from remote (pull_before_session) before accepting tool calls. A generation replica instead refreshes its installed generation from the server (refresh_replica) and regenerates the refreshed guidance. It never raises: on failure the server logs a warning and starts with local state.

Store resolution inside tools starts from the cwd’s .nauro/config.json (walked up from the cwd; an explicit project_id must name that same project, otherwise the call fails with a mismatch), else an explicit project_id or project name looked up in the registry, else a registry repo-path match for the cwd. When unresolved, tools return a guidance envelope rather than crashing: the WELCOME_NO_PROJECT onboarding copy when no project is found, a disconnected diagnostic with recovery actions when a registered store is missing, or the resolution error text.

The FastMCP server is constructed as FastMCP("nauro", instructions=..., log_level="WARNING"); the instructions are MCP_INSTRUCTIONS_STATIC extended with the generation-replica reference guidance, and the server reports the nauro package version to connecting clients.

The "nauro" name pairs with the stdio entry’s command; behavioral guidance ships via MCP server instructions, not an injected CLAUDE.md block. Setup automatically strips Nauro’s retired marked block if it finds one. A separate Nauro-owned two-line CLAUDE.md bridge may import @AGENTS.md so Claude Code also sees the generated shared context.

python · stdio_server.py
def run_stdio() -> None:
    """Run the MCP server over stdio (called by `nauro serve --stdio`)."""
    from nauro.sync.generation_pool import reuse_generation_connections

    with reuse_generation_connections():
        try:
            _pull_on_startup()
            mcp.run(transport="stdio")
        finally:
            decision_session.close()

Source: serve.py; stdio_server.py (run_stdio, _pull_on_startup, FastMCP construction).

nauro setup [claude-code|cursor|codex|all]: what it writes

nauro setup wires the local stdio server into each surface’s config by writing the file directly, not by shelling out to the client’s own mcp add.

All surfaces use the same key name nauro and the same core entry: {"command": "<validated absolute path to nauro>", "args": ["serve", "--stdio"]}. Cursor’s entry also carries "type": "stdio", and the Codex entry adds startup_timeout_sec = 20 (a floor: a higher startup budget already in the entry is kept). _find_nauro_command probes candidates with --version and prefers a durable absolute pipx, uv tool, system, or equivalent install. For Claude Code and Codex, if only a working project-venv sibling is available, setup records it with a fragility warning; otherwise it records the best path it has and warns that MCP may not work, with bare nauro as the terminal fallback. Cursor takes no fallback: setup cursor fails when no working durable absolute nauro executable can be validated.

Subcommand Writes Key / scope Flags
setup claude-code <repo>/.mcp.json per registered repo path mcpServers.nauro (project scope) --project, --remove, --with-hooks
setup cursor ~/.cursor/mcp.json; removes an owned legacy <repo>/.cursor/mcp.json entry per registered repo mcpServers.nauro (user-global) --project, --remove
setup codex ~/.codex/config.toml [mcp_servers.nauro] (user-global) --remove, --with-hooks
setup all Claude Code + Cursor + Codex in one call, including per-repo .cursor/rules/ and (with --with-subagents) .cursor/agents/ files; refreshes Nauro-managed AGENTS.md all of the above --project, --remove, --with-subagents, --force-overwrite, --with-skills, --with-hooks

Adopt, setup, and incidental regeneration paths preserve an unmanaged AGENTS.md and warn. nauro sync is the sole explicit overwrite path. A # Manual section survives replacement.

setup claude-code automatically removes Nauro’s retired marked block from CLAUDE.md. When no CLAUDE.md exists, the shared AGENTS.md regeneration seam writes a Nauro-owned two-line bridge containing @AGENTS.md. An existing foreign CLAUDE.md is never modified: an existing live import is accepted, otherwise setup prints an advisory. Teardown removes only the validated Nauro-owned bridge. Setup also prunes a redundant user-scope HTTP nauro entry from ~/.claude.json; a user-defined stdio entry is left alone.

Standalone nauro setup codex --remove preserves the user-global entry while any Nauro project remains registered, including the current project when it is the only one. Clear it for the last project with nauro setup all --remove from that project. setup all continues across per-handler errors so partial coverage still reports progress.

--with-subagents (on setup all / adopt) installs the five bundled roles, planner, executor, reviewer, tech-lead, and investigator, on all three surfaces. Claude Code receives Markdown definitions in ~/.claude/agents/; Codex receives TOML definitions in ~/.codex/agents/; Cursor receives native custom-agent Markdown in <repo>/.cursor/agents/ for each registered repo. The investigator is a read-only role that studies Claude Code and Codex session logs for supported defects, repeated friction, and drift.

A differing Nauro-owned skill or agent definition is refreshed and its prior content is saved to a sibling .bak. --force-overwrite skips that backup and overwrites in place. Files outside Nauro’s owned names are left untouched.

Claude Code’s bundled definitions reference cloud tools through mcp__claude_ai_Nauro__*, so its remote connector must be named exactly Nauro. Codex and Cursor render the same role instructions in their native formats and do not share that connector-name constraint.

--with-hooks wires two surface-specific integrations. Claude Code gets an advisory UserPromptSubmit hook in <repo>/.claude/settings.local.json that retrieves related decisions for each turn. Codex gets SessionStart and SubagentStart hooks in <repo>/.codex/hooks.json that inject the Nauro protocol and current L0 context.

Both hook integrations are project-scoped, idempotent, and fail open. Removal strips only Nauro-authored entries. Codex skips new or changed hooks until the user reviews and trusts them through /hooks. Cursor has no hook integration.

json · <repo>/.mcp.json (Claude Code)
{
  "mcpServers": {
    "nauro": {
      "command": "<validated absolute path to nauro>",
      "args": ["serve", "--stdio"]
    }
  }
}
json · ~/.cursor/mcp.json (Cursor, user-global)
{
  "mcpServers": {
    "nauro": {
      "type": "stdio",
      "command": "<validated absolute path to nauro>",
      "args": ["serve", "--stdio"]
    }
  }
}
toml · ~/.codex/config.toml
[mcp_servers.nauro]
command = "<validated absolute path to nauro>"
args = ["serve", "--stdio"]
startup_timeout_sec = 20
shell
$ nauro setup all --with-skills --with-subagents # skills + workflow agents on all three surfaces
$ nauro setup all --with-hooks                 # optional Claude Code + Codex hooks
$ nauro status                                 # diagnose integration wiring
$ nauro doctor                                 # check store integrity

Source: setup.py (claude_code, cursor, codex, all_); integrations/orchestrator.py (setup_all_surfaces); integrations/json_mcp.py; integrations/cursor.py (configure_cursor); integrations/codex_config.py (CODEX_STARTUP_TIMEOUT_SEC); integrations/agents.py (materialize_agents, materialize_agents_cursor_for_repo); integrations/claude_hooks.py; integrations/codex_hooks.py.

Cursor Desktop and Cloud Agents

Desktop Cursor. Nauro writes the user-global ~/.cursor/mcp.json with an absolute path to the local nauro executable, so the wiring is shared by every Nauro project on the machine and never enters the repository. It is written only when a working durable absolute nauro executable validates; otherwise setup cursor fails and asks for pipx install nauro or uv tool install nauro. Once the global entry is written or already correct, the same run migrates legacy wiring in each registered repo: an installer-owned nauro entry in <repo>/.cursor/mcp.json is removed (and the file deleted when nothing else remains), a legacy file git already tracks is refused and left for you to untrack first, and an entry whose ownership is uncertain is preserved. Run nauro setup cursor on each machine, restart Cursor, and verify a real Nauro tool call.

Cursor receives Nauro skills as project rules under .cursor/rules/. Their description lets Cursor select a relevant rule, but you can invoke one explicitly in Agent chat by typing its filename as an @-mention, for example @nauro-adopt. This follows Cursor’s project-rule model. With --with-subagents, the workflow roles land as native custom agents under .cursor/agents/ in the same repo.

Commit .nauro/config.json so collaborators get the portable project identity. Never commit Nauro’s .cursor/mcp.json: the current wiring lives outside the repo in ~/.cursor/mcp.json, and a legacy per-repo copy records a machine-local path. Commit .cursor/rules/nauro-*.mdc and .cursor/agents/nauro-*.md only when collaborators should inherit the same workflow rules and agents, and review any local edits before publishing them. Rules carry instructions. They do not make an unavailable MCP server or workflow agent available.

Workflow scope. nauro-adopt, nauro-context, and nauro-interview run in the main Cursor agent when Nauro MCP is available. nauro-ship-task runs natively through the /nauro-planner, /nauro-executor, /nauro-reviewer, and /nauro-tech-lead custom agents installed under .cursor/agents/: it checks that those definitions exist and that Cursor can dispatch them, and fails closed otherwise. A Cursor .mdc rule does not satisfy that prerequisite, and the roles must not be reproduced inline. nauro-loop Program Delivery stays on hold on Cursor; it returns one launch prompt for Claude Code and stops.

Hosted Cursor OAuth is not yet verified with the current discovery route. It needs predefined client credentials, explicit scopes, and an allowed callback. Local stdio setup is unchanged.

Cloud Agents. A Cursor Cloud Agent runs in a separate VM and does not inherit the absolute executable path from Desktop Cursor. Configure Nauro separately through the MCP controls at cursor.com/agents. For the hosted Nauro connector, link and sync the project first through the cloud path. Start a new cloud run after configuration, then verify that the agent can call get_context. Cursor documents Cloud Agent MCP configuration in its Cloud Agent capabilities.

shell
$ nauro setup cursor
$ nauro status
# Restart Cursor, then type @nauro-adopt in Agent chat

Source: integrations/cursor.py (configure_cursor); integrations/orchestrator.py (cursor_surfaces); integrations/skills.py; integrations/agents.py (materialize_agents_cursor_for_repo); agents/__init__.py (render_agent); skills/__init__.py (Cursor ship-task and loop surface fragments); git_hygiene.py; Cursor Rules and Cloud Agent capabilities documentation.

nauro adopt: register and wire in one shot (existing repo)

nauro adopt bootstraps a project from an existing repo. It detects the repo root (or --repo), refuses non-git directories, guards against re-adopting (an existing .nauro/config.json), and runs a same-name collision pre-check against the local v2 registry (_check_collision via find_projects_by_name_v2).

Use nauro adopt --with-skills --with-subagents for the complete workflow: the opt-in skills on every surface plus the workflow agents for Claude Code, Codex, and Cursor. Plain nauro adopt is the minimal path: it wires MCP and installs the core nauro-adopt skill.

It then registers a v2 project (register_project_v2, mode=local), writes .nauro/config.json (save_repo_config), and scaffolds the store (scaffold_project_store), before wiring MCP and materializing skills across Claude Code, Cursor, and Codex via setup_all_surfaces.

After wiring, adopt smoke-tests the wired binary by booting <nauro> serve --stdio briefly (_smoke_test_wired_binary, default timeout 1.5s): a clean exit on stdin EOF (returncode 0) or a process still running at timeout is healthy; a non-zero exit before timeout (an import crash) prints a WARNING.

The closing message instructs the user to restart their agent and invoke /nauro-adopt in Claude Code or $nauro-adopt in Codex. In Cursor Agent chat, type @nauro-adopt.

Adopt preserves an unmanaged AGENTS.md and warns.

Flags: --name, --repo, --print-prompt (mutually exclusive with all other flags; prints the canonical /nauro-adopt skill body to stdout via load_adopt_body() for pasting into chat surfaces), --no-setup-and-skills (skip MCP wiring and skill materialization), --with-subagents, --force-overwrite, --with-skills, and the teardown trio --remove / --purge-store / --yes (next paragraph).

If the repo is already adopted and the caller passes --with-subagents / --with-skills / --force-overwrite, adopt installs just those artifacts onto the existing adoption (_install_into_adopted_repo via setup_all_surfaces, registration untouched) instead of dead-ending.

nauro adopt --remove is the inverse: after a confirmation prompt (--yes skips it) it un-wires the MCP, skill, subagent, and hook entries, strips the generated AGENTS.md (a # Manual section is preserved), deletes .nauro/config.json, and deregisters the repo. Only this repo is dropped when the project spans several, and the store is kept unless --purge-store is passed on the project’s last repo.

The always-installed skill set is SKILL_NAMES = ("nauro-adopt",); --with-skills additionally installs OPT_IN_SKILL_NAMES = ("nauro-ship-task", "nauro-context", "nauro-loop", "nauro-interview"). nauro-ship-task references the @nauro-* subagents and nauro-loop dispatches that chain, so passing --with-skills without --with-subagents prints SHIP_TASK_NEEDS_SUBAGENTS_NOTICE. nauro-context and nauro-interview have no bundled-subagent dependency.

shell
$ cd /path/to/repo
$ nauro adopt --with-skills --with-subagents
$ nauro status
# Restart, then use /nauro-adopt in Claude Code or $nauro-adopt in Codex

Source: adopt.py (adopt, _smoke_test_wired_binary, _check_collision, _install_into_adopted_repo, --print-prompt, load_adopt_body); integrations/skills.py (SKILL_NAMES, OPT_IN_SKILL_NAMES).

Cloud path: auth login → link --cloud → sync (distinct steps)

The cloud path is opt-in and reaches a project from surfaces without a local copy or from another machine. It is three separate steps.

Step 1, nauro auth login. An Auth0 Authorization Code + PKCE (S256) flow. It opens a browser, runs a localhost callback server on REDIRECT_PORT = 18457 (redirect_uri http://localhost:18457/callback), waits up to 120s for the code, exchanges it, and stores tokens in ~/.nauro/config.json under the "auth" key (with sub, sanitized_sub, user_id, access_token, refresh_token).

The public OAuth identifiers (not secrets) are DEFAULT_API_URL=https://mcp.nauro.ai, DEFAULT_AUTH0_AUDIENCE=https://mcp.nauro.ai/mcp, and AUTH0_SCOPES="openid profile email offline_access read:context write:context".

The closing message tells cloud users to add https://mcp.nauro.ai/mcp as a connector and, for Codex, to set mcp_oauth_callback_port = 8765 at the top of ~/.codex/config.toml.

Step 2, nauro link --cloud. A one-time, one-way promotion of the current repo’s local-only project to cloud. It reads the local-mode .nauro/config.json, requires auth (errors with "Run 'nauro auth login' first" otherwise), calls the remote POST /projects (create_project) to mint a cloud project_id, re-keys the local store directory and v2 registry entry under the new id (rename_project_id_v2, preserving repo_paths and store contents), and rewrites .nauro/config.json to mode=cloud with server_url=https://mcp.nauro.ai (DEFAULT_API_URL).

There is no inverse "unlink to local". The re-key is the irreversible step and persists before the push; the initial push (push_changed_files) is best-effort: a transient presign/S3 failure warns and exits 0, and nauro sync retries the upload.

Step 3, nauro sync. Captures a snapshot and explicitly replaces AGENTS.md in associated repos; it is the sole overwrite path, and a # Manual section survives replacement. With cloud sync configured it does a git-style pull-then-push: pull first (_pull_via_presign: GET /sync/manifest → POST /sync/presign → S3 GETs), then push (push_store_to_cloud).

For a local-only project it captures the snapshot and reports "local-only project; nothing to upload". On a generation replica, nauro sync instead refreshes the installed generation from the server and regenerates the refreshed guidance; it pushes no local files, and --push-only is refused there. Flags: --message/-m, --project, --status (on a replica, its refresh state), --push-only (push without pulling first). The MCP update_state tool records what changed; sync does not touch state_current.md.

nauro attach <project_id> is the cloud equivalent of init --add-repo: associate the current repo with an existing cloud project (membership is verified against GET /projects via list_projects before any local write), writing a cloud-mode .nauro/config.json. For a fresh start, nauro init --cloud <name> creates a cloud-scoped project up front.

After the steps, add https://mcp.nauro.ai/mcp as an MCP connector in your tool’s settings. Enter the URL exactly, with no trailing slash.

shell
$ nauro auth login
$ nauro link --cloud   # one-time: promote the local project to cloud
$ nauro sync
# then add https://mcp.nauro.ai/mcp as an MCP connector (no trailing slash)

Source: auth.py (login, DEFAULT_API_URL, DEFAULT_AUTH0_AUDIENCE, AUTH0_SCOPES, REDIRECT_PORT, REDIRECT_URI, closing message); link.py (link); sync.py (sync, _pull_via_presign, _pull_from_cloud); attach.py (attach); cloud_projects.py (create_project, list_projects); generation_reads.py (refresh_command).

Codex remote connector

Hosted Codex sign-in is not yet verified with the current discovery route. The client must support CIMD or predefined OAuth credentials. A fixed callback port alone does not enable sign-in.

  • Add the hosted connector under a name distinct from the local nauro stdio server: codex mcp add nauro-cloud --url https://mcp.nauro.ai/mcp.
  • Pin the OAuth callback port at the top of ~/.codex/config.toml: mcp_oauth_callback_port = 8765. Codex’s callback uses a fixed, pre-registered port; without this line Codex picks a random port and login fails. The closing message from nauro auth login also surfaces this requirement.
  • Requires Codex 0.131.0 or newer. Enter the URL exactly as shown, with no trailing slash. If login reports a callback-port error, free port 8765.
  • This is separate from nauro setup codex, which wires the local stdio server under [mcp_servers.nauro] in the same ~/.codex/config.toml. The remote connector (nauro-cloud) and the local stdio server (nauro) coexist under different names.
shell
$ codex mcp add nauro-cloud --url https://mcp.nauro.ai/mcp
toml · top of ~/.codex/config.toml
mcp_oauth_callback_port = 8765

Source: auth.py (login closing message); integrations/codex_config.py (_configure_codex, the local stdio entry under [mcp_servers.nauro]).

Chat surfaces (Claude.ai, ChatGPT)

Chat-paste mode does not create projects. First run nauro adopt --name <project> from a terminal: that registers the project, wires MCP across surfaces, and installs the skills.

Only then can the chat agent seed context.

After adoption, point the chat agent at docs/adopt-prompt.md. nauro adopt --print-prompt outputs the same canonical /nauro-adopt skill body to stdout (without the intro paragraph) for copy/paste.

Chat surfaces have no shell, so the skill operates only on content the user pastes (Step 3b) and only against an already-adopted project (verified in Step 3b). The code-evidence path (Step 4) and the targeted probes (Step 6b) are unavailable; the skill skips from Step 3b directly to Step 5.

On chat surfaces the skill passes the project’s id as the explicit project_id argument on every MCP call (propose_decision, update_state, flag_question, get_context, list_decisions, check_decision, get_decision).

Auto-resolve would otherwise route to the user’s default project, not the one being seeded when local and cloud projects coexist.

Reaching a project from a chat surface without a local copy still requires the cloud connector (https://mcp.nauro.ai/mcp) configured in that tool’s settings: the cloud path above must already be done.

shell
$ nauro adopt --name <your-project-name>   # register + wire MCP + install skills
# then in chat, follow docs/adopt-prompt.md (or: nauro adopt --print-prompt)

Source: docs/adopt-prompt.md (intro, Surface modes, Step 3b); adopt.py (--print-prompt, load_adopt_body).

Key facts and gotchas

  • The local stdio MCP entry is keyed nauro with core shape {"command": "<validated absolute path to nauro>", "args": ["serve", "--stdio"]} when a durable install is available; Cursor’s entry adds "type": "stdio" and Codex’s adds startup_timeout_sec = 20. Resolution validates candidates, prefers durable absolute paths, warns before recording a fragile working path, and uses bare nauro only as the warned terminal fallback; Cursor takes no fallback and fails without a validated durable absolute path.
  • setup writes config files directly: claude-code → <repo>/.mcp.json (project scope, per repo); cursor → ~/.cursor/mcp.json (user-global; owned legacy per-repo .cursor/mcp.json entries are migrated away); codex → ~/.codex/config.toml under [mcp_servers.nauro] (user-global, with startup_timeout_sec = 20).
  • The cloud connector URL is https://mcp.nauro.ai/mcp; enter it exactly, with no trailing slash.
  • Codex remote connector: codex mcp add nauro-cloud --url https://mcp.nauro.ai/mcp; requires mcp_oauth_callback_port = 8765 at the top of ~/.codex/config.toml; requires Codex 0.131.0 or newer.
  • auth.py constants: DEFAULT_API_URL=https://mcp.nauro.ai, DEFAULT_AUTH0_AUDIENCE=https://mcp.nauro.ai/mcp, REDIRECT_PORT=18457, REDIRECT_URI=http://localhost:18457/callback, AUTH0_SCOPES="openid profile email offline_access read:context write:context"; tokens are stored in ~/.nauro/config.json under "auth"; the callback timeout is 120s.
  • The cloud path is three distinct steps kept separate: nauro auth login → nauro link --cloud (one-time, one-way promotion; no inverse) → nauro sync.
  • The local stdio server registers 12 MCP tools (7 read, 5 write): the shared nauro_core.mcp_tools.ALL_TOOLS (11: 8 read, 3 write) minus list_projects, plus update_stack and share_context, which write only through an attached generation replica. The hosted server registers 14 (HOSTED_TOOLS); list_projects and create_project are hosted-only.
  • stdio is the only supported local transport (the FastAPI HTTP transport was retired); --stdio is a hidden no-op kept for backward compatibility; there is no --project flag on serve.
  • nauro adopt registers a v2 project (mode=local), wires all surfaces via setup_all_surfaces, smoke-tests the binary, and installs the nauro-adopt skill. Use /nauro-adopt in Claude Code, $nauro-adopt in Codex, or the installed rule in Cursor.
  • Complete workflow: nauro adopt --with-skills --with-subagents. The five roles (planner, executor, reviewer, tech-lead, investigator) install into ~/.claude/agents/ as Markdown, ~/.codex/agents/ as TOML, and <repo>/.cursor/agents/ as Cursor custom-agent Markdown; Cursor also receives skill rules under .cursor/rules/.
  • Claude Code’s workflow definitions require the remote connector name Nauro so their mcp__claude_ai_Nauro__* tools resolve. Codex and Cursor do not share that connector-name constraint.
  • nauro setup all --with-hooks writes Claude Code’s advisory UserPromptSubmit hook to <repo>/.claude/settings.local.json and Codex’s SessionStart / SubagentStart hooks to <repo>/.codex/hooks.json. Review new Codex hooks through /hooks.
  • Verification: nauro status diagnoses MCP and workflow wiring; nauro doctor checks store integrity. Start a fresh agent session for the final MCP check.
  • Chat surfaces: run nauro adopt in a terminal first (chat-paste mode does not create projects), then point the agent at docs/adopt-prompt.md; the skill passes an explicit project_id on every MCP call.
  • setup claude-code prunes a redundant user-scope HTTP nauro entry from ~/.claude.json because project-scope stdio is canonical and a same-name collision can resolve to the wrong store (only the HTTP/url entry is pruned; a user-defined stdio entry is left alone).

Gotchas to watch for:

  • The local stdio entry uses command/args (nauro serve --stdio), not a url; the url form (https://mcp.nauro.ai/mcp) is only for the hosted/remote connector. Do not present the cloud URL as the local .mcp.json value.
  • nauro setup codex (local stdio under [mcp_servers.nauro]) is a different thing from the Codex remote connector nauro-cloud added via codex mcp add --url. They coexist under different names in the same ~/.codex/config.toml.
  • link --cloud is one-way and irreversible: the re-key persists before the cloud push, and a failed push does not roll it back (it warns, exits 0, and you retry with nauro sync). There is no "unlink to local" command.
  • Codex’s 8765 port is Codex-side and unrelated to nauro’s own 18457 auth-login callback port.
  • Cloud-mode projects cannot be extended with init --add-repo; use nauro attach <project_id> instead.