Skip to main content
Every Nora Local deployment — desktop, compose, Kubernetes, air-gap — exposes the same MCP server as SaaS at POST /api/v1/mcp on the on-prem host. Point your coding agent at the local URL and you get the identical tool surface (Flow CRUD, block ops, wiring, variables, publish, traces).

The URL

With the desktop app on its default settings, the URL is below. Every example on this page uses it.
  • If you changed the port, replace 8090 with the Host port from the app’s Settings. On a compose install it is NORA_HOST_PORT in .env.onprem.
  • The Kubernetes path uses whatever hostname you set for publicUrl in the Helm chart (for example https://nora.example.internal/api/v1/mcp). See Kubernetes (Helm).

Authenticating

The MCP endpoint has three auth paths. Which one to use depends on your environment.

Desktop app OAuth (macOS)

The best path when Nora Local runs as the desktop app. The OAuth handshake opens inside the Nora app itself — the app already has your login session, so there’s no browser round-trip.

Browser OAuth

Runs the OAuth handshake through your default browser. Right for compose / Kubernetes deployments accessed from the same machine.

Personal Access Token

Static Authorization: Bearer nora_pat_... header. Right for headless installs, air-gap without a browser, CI/scripts.

Path A — Desktop app OAuth (macOS)

New in 2026-09-29. When the on-prem server sees an authorize request from a loopback issuer, it redirects the browser to a small handoff page that offers [Open Nora to approve]. Clicking that opens the nora-local://oauth deep link, and the Nora desktop app renders the consent UI inside its own window using the existing app session — no separate login needed.
1

Register the server without a token

2

Trigger the OAuth flow

In Claude Code, run /mcp → select nora-local → [Authenticate]. The server returns 401 with WWW-Authenticate, Claude Code opens your browser at /oauth/desktop on the local server, and you click [Open Nora to approve] to hand consent off to the Nora app.The Nora app validates that the authorize URL points at this server (any other origin is rejected), preserves PKCE, state, and resource unchanged, and closes the window automatically once the callback fires.
Requirements: NORA_DEPLOY_FLAVOR=onprem (already set by the compose file) and the issuer is loopback (localhost / 127.0.0.1 / [::1]). On other platforms the handoff page also offers [Continue in browser] so no one gets stuck.

Path B — Browser OAuth

When the desktop app isn’t running (compose-only servers, Kubernetes), the OAuth flow completes in your default browser.
1

Register without a token

2

Trigger the OAuth flow

In Claude Code, run /mcp → select nora-local → [Authenticate]. Your browser opens the local server’s login page. Sign in and grant read · build · run.Codex CLI equivalent: codex mcp login nora-local. Cursor: Settings → MCP → nora-local → [Reconnect].
The OAuth callback URL comes from NORA_PUBLIC_URL (and NORA_OAUTH_REDIRECT_BASE). Both defaults now interpolate NORA_HOST_PORT (fix landed 2026-09-26), so a single port change flows through. When you front the stack with a real hostname or TLS proxy, set NORA_PUBLIC_URL=https://nora.example.internal in .env.onprem so the callback lands on the real URL.

Path C — Personal Access Token

For headless servers, air-gap installs without a browser, or scripts / CI.
1

Mint a PAT

From the SPA, open Settings → Personal Access Tokens and click [New token]. Give it a name, keep the default scopes (read · build · run), and copy the plaintext value — it’s shown once.Or use the CLI:
nora auth login mints a PAT via the loopback flow and stores it at ~/.config/nora/credentials.json (macOS: ~/Library/Application Support/nora/credentials.json).
2

Register with the PAT in a header

The PAT is stored in plaintext inside your MCP client’s config file (~/.claude.json, mcp_config.json, etc.). Keep those files chmod 0600 and never commit them.

Alongside a SaaS entry

Register both with different aliases so tool names stay unambiguous.
Claude Code prefixes each tool with the server alias, so nora_list_flows and nora-local_list_flows are cleanly separated. Each server prompts its own OAuth login the first time you use it.

What’s exposed

The tool surface is identical to SaaS — see MCP tool surface for the full list. Permissions mirror your Nora Local role: a Guest can only read; approval-gated actions still go through the approval flow when run over MCP.

Air-gap notes

Nothing about MCP requires internet access — the whole flow (OAuth handshake, tool calls) stays on your local host.
  • If NORA_AIRGAP=1 is on, the server still serves MCP normally. The boot probe only checks that the server can’t reach the public internet; it doesn’t restrict inbound traffic from the local browser or CLI.
  • For headless server installs where the target host has no browser, run the coding agent on a laptop that can reach the server over the LAN, and set NORA_PUBLIC_URL to the LAN hostname (http://nora.internal:8090) so OAuth callbacks land somewhere reachable. PAT (Path C) also avoids the browser step entirely.

Troubleshooting

  • connection refused on claude mcp add. The stack isn’t up. Check docker ps or the desktop app tray. The URL must include the scheme (http://), and the port must match what NORA_HOST_PORT was set to when the stack booted.
  • OAuth /oauth/desktop page doesn’t offer the “Open Nora” link. Either the server is running with NORA_DEPLOY_FLAVOR=saas (the compose default is onprem — check your .env.onprem), or the issuer isn’t loopback (you’re hitting a public hostname via reverse proxy). Use browser OAuth (Path B) or PAT (Path C) instead.
  • OAuth login page 404s or hangs after consent. NORA_PUBLIC_URL doesn’t match the URL your browser is on. Set it to the exact base URL (scheme + host + port) you’re using and restart the stack.
  • Nothing happens on the first tool call (OAuth path). OAuth doesn’t auto-launch. In Claude Code, run /mcp → select nora-local → [Authenticate].
  • 401 loop with a PAT header. The token was revoked, expired, or has a typo. Confirm on Settings → Personal Access Tokens in the SPA, then re-run claude mcp remove nora-local and add it again with a fresh token.
  • Tool list is empty after login. The account you signed in with has no workspace access on this server. Check permissions on the SPA (Settings → Members), then reconnect.

MCP (SaaS)

The same page for the hosted platform.nora.my server.

Settings — host port

Change NORA_HOST_PORT — the MCP URL follows.

Kubernetes (Helm)

publicUrl chart value and ingress setup.