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
8090with the Host port from the app’s Settings. On a compose install it isNORA_HOST_PORTin.env.onprem. - The Kubernetes path uses whatever hostname you set for
publicUrlin the Helm chart (for examplehttps://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 thenora-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].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
- Claude Code
- Codex CLI
- Cursor / other hosts
Alongside a SaaS entry
Register both with different aliases so tool names stay unambiguous.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=1is 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_URLto the LAN hostname (http://nora.internal:8090) so OAuth callbacks land somewhere reachable. PAT (Path C) also avoids the browser step entirely.
Troubleshooting
connection refusedonclaude mcp add. The stack isn’t up. Checkdocker psor the desktop app tray. The URL must include the scheme (http://), and the port must match whatNORA_HOST_PORTwas set to when the stack booted.- OAuth
/oauth/desktoppage doesn’t offer the “Open Nora” link. Either the server is running withNORA_DEPLOY_FLAVOR=saas(the compose default isonprem— 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_URLdoesn’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→ selectnora-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-localand 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.
Related
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.