MCP servers

neondeck reads MCP server config from runtime-home mcp.json. Connected tools are registered with Flue as mcp__<server>__<tool> and appear in new Neon sessions after the registry refreshes.

Configuration

{
  "servers": {
    "linear": {
      "transport": "http",
      "url": "https://mcp.linear.app/mcp",
      "auth": { "kind": "oauth" }
    },
    "local-tools": {
      "transport": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/server.mjs"],
      "tools": {
        "approvalMode": "writes",
        "overrides": {
          "dangerous_tool": "deny"
        }
      }
    }
  }
}

HTTP servers must use https:// except loopback development hosts. Raw secrets are rejected. Header auth uses environment-variable references, and OAuth tokens are stored only in data/neondeck.db.

{
  "servers": {
    "internal": {
      "transport": "http",
      "url": "https://mcp.example.com/mcp",
      "auth": {
        "kind": "header",
        "headers": {
          "Authorization": { "env": "INTERNAL_MCP_AUTHORIZATION" }
        }
      }
    }
  }
}

Approval policy

MCP servers default to writes mode: tools explicitly annotated by the MCP server as read-only run immediately, while mutations and unannotated tools ask first. Use prompt to ask for every tool or approve to allow every tool. A per-tool override wins over the server mode:

{
  "tools": {
    "approvalMode": "writes",
    "overrides": {
      "search": "approve",
      "delete_project": "deny"
    }
  }
}

A pending request can be allowed once, allowed for the current chat, always allowed, or denied. Allow-once grants expire after 15 minutes, are bound to the exact arguments, and are consumed by one retry. Chat grants are bound to the requesting Flue conversation and remain valid for that chat. Always allow writes an exact per-tool override to mcp.json. Server and tool policy changes invalidate older pending and reusable grants.

MCP annotations are hints supplied by the server. Neondeck only uses an explicit readOnlyHint: true without a destructive hint for the writes shortcut; unannotated tools still ask. Use prompt for servers whose annotations you do not trust.

OAuth

OAuth servers start in needs-login until a user completes a state-bound authorization flow. By default the callback uses Neondeck's loopback origin. A dashboard served through an exact server.trustedOrigins entry instead uses that configured HTTPS origin, without trusting proxy-forwarded scheme headers. The callback exchanges the authorization code through the MCP SDK provider and stores client registration, PKCE verifier, discovery state, and tokens in SQLite.

neondeck mcp add linear --url https://mcp.linear.app/mcp --oauth
neondeck mcp policy linear --approval-mode writes
neondeck mcp policy linear --tool search=approve --tool delete_project=deny
neondeck mcp login linear
neondeck mcp logout linear --confirm

The dashboard Runtime Overview panel shows configured MCP servers, OAuth login/logout controls, the server-default approval mode, exact per-tool overrides, tool counts, connection errors, and pending MCP approvals. The MCP provider must accept the matching callback URL, such as https://example.exe.xyz/api/mcp/oauth/callback for the exe.dev nginx setup.

CLI and API

neondeck mcp list
neondeck mcp status [id]
neondeck mcp add <id> --url ... | --command ...
neondeck mcp enable <id>
neondeck mcp disable <id>
neondeck mcp tools <id>
neondeck mcp policy <id> --approval-mode prompt|writes|approve
neondeck mcp policy <id> --tool <name>=prompt|approve|deny|inherit
neondeck mcp approvals [--resolve <id> --approve [--scope once|chat|always]|--deny]
neondeck mcp audit
GET    /api/mcp/servers
POST   /api/mcp/servers
PATCH  /api/mcp/servers/:id
DELETE /api/mcp/servers/:id
GET    /api/mcp/servers/:id/tools
POST   /api/mcp/servers/:id/refresh
POST   /api/mcp/servers/:id/login
GET    /api/mcp/logins/:id
GET    /api/mcp/oauth/callback
POST   /api/mcp/servers/:id/logout
GET    /api/mcp/approvals
POST   /api/mcp/approvals/:id/resolve
GET    /api/mcp/audit

Agent boundary

Neon can use safe typed actions for HTTP/OAuth server setup and OAuth login starts. Stdio servers, header-authenticated servers, and tool approval policy are user-owned surfaces because they can spawn host processes or forward environment-backed secrets. Configure those through the CLI, local API, or direct mcp.json edits.