ollama launch claude-desktop: Gateway-mode MITM by default + community-tutorial typosquat surface
NuClide Research, 2026-05-07
TL;DR
Two distinct findings from a primary-source review of Ollama v0.23.1’s ollama launch claude-desktop command:
DCWF KSAT coverage
Auto-derived from DCWF AI work-role rule files (ksat-tag).
- 672 (AI Test & Evaluation Specialist): K7004, S7070, S7075, T5904, T5919
- 733 (AI Risk & Ethics Specialist): S7067, T5854, T5868, T5882
- overlap (Common AI KSATs (all 5 roles)): K108, K1158, K1159, K22, K6311, K6935, S7065
-
Gateway-mode MITM by design. Running the command rewrites Claude Desktop into a “third-party inference” deployment with
inferenceGatewayBaseUrl: https://ollama.com. Every prompt and every response from that point forward transits Ollama Cloud as plaintext under the user’s bearer key. Consent is implicit in the act of running the command; the privacy implication is not surfaced in the success message (“Claude Desktop profile changed to Ollama Cloud”). -
Community-tutorial typosquat surface. The npm package name
mcp-server-ollama(referenced by GitHub Issue #16005, several “awesome-mcp-servers” indexes, and a number of tutorial blog posts) is not registered on the npm public registry.npx -y mcp-server-ollamareturns 404. Anyone who registers the package can publish code that gets auto-installed and executed as the operator user the next time Claude Desktop reads a tutorial-poisonedclaude_desktop_config.json. Several adjacent unclaimed names (@ollama/mcp-server,@modelcontextprotocol/server-ollama) compound the surface.
A third finding is that Issue #16005 itself is misframed: the bug reporter blames Ollama for writing the typosquat-vulnerable config, but the v0.23.1 source does not write mcpServers entries at all. The config the reporter saw most likely pre-existed from a tutorial they had previously followed; Ollama’s config-writer preserves keys it does not manage, creating a misattribution attack surface where the vendor inherits blame for content the vendor only failed to remove.
Background: what the command does
Ollama v0.23.0 (released 2026-05-03) introduced a new cmd/launch/ subcommand framework with 13 first-party launcher targets. v0.23.1 (2026-05-05) ships the launcher set used in the field today. The claude-desktop target lives in cmd/launch/claude_desktop.go (single commit, 2026-05-03).
The Run flow:
claudeDesktopSupported(). Guards against unsupported OSes.claudeDesktopTargetPaths(). Resolves Claude Desktop’s macOS~/Library/Application Support/Claude/andClaude-3p/profile directories, plus per-profileconfigLibrary/_meta.jsonandconfigLibrary/<profileID>.json. Windows and Nest-variant paths handled inclaudeDesktopWindowsPaths/Claude Nest-3p.claudeDesktopValidatedAPIKey(ctx, profilePaths). Reads any existing API key from a profile, validates againsthttps://ollama.com, prompts the operator if invalid (printed prompt: “Enter your Ollama API key (https://ollama.com/settings/keys):”).writeClaudeDesktopDeploymentMode(path, "3p"). SetsdeploymentMode: "3p"on the normal config.writeClaudeDesktopGatewayProfile(path, key, true). Writes the gateway block to the third-party profile config:
{
"deploymentMode": "3p",
"inferenceProvider": "gateway",
"inferenceGatewayBaseUrl": "https://ollama.com",
"inferenceGatewayApiKey": "<user's Ollama Cloud API key>",
"inferenceGatewayAuthScheme": "bearer",
"disableDeploymentModeChooser": true
}
claudeDesktopLaunchOrRestart("Restart Claude Desktop to use Ollama?"). Confirms with the operator and restarts the app.
The Restore flow (ollama launch claude-desktop --restore) reverses the deployment-mode chooser flag and removes the gateway entries, returning to direct-Anthropic mode.
Finding 1: gateway-mode MITM by design
What the gateway path means
After the command runs successfully, Claude Desktop’s inference pipeline routes through https://ollama.com/... instead of directly to Anthropic. Concretely:
- Every user prompt is sent as plaintext to ollama.com under the user’s bearer-auth Ollama Cloud key.
- Every model response is fetched from ollama.com.
- Tool-use payloads, attached files, MCP-server outputs, system prompts, and any other turn content all flow through ollama.com.
- Claude Desktop’s transport-layer encryption to ollama.com is TLS-as-usual; Ollama-the-company has plaintext access on the server side.
This is a feature, not a bug. It is how Ollama Cloud is intended to host Claude Desktop traffic for operators who prefer Ollama-managed billing or unified-API access. It is also a complete loss of the direct-to-Anthropic privacy posture that Claude Desktop has by default.
What the operator is told
The CLI prints exactly two strings on success:
Claude Desktop profile changed to Ollama Cloud.
To restore the usual Claude profile, run: ollama launch claude-desktop --restore
There is no language about plaintext interception, log retention, telemetry, jurisdiction (Ollama, Inc. is US-based), or training-data implications. An operator who runs ollama launch claude-desktop --yes to skip confirmation receives nothing more than “Claude Desktop profile changed to Ollama Cloud.”
Recommendation
Ollama should expand the success message to surface the trust-boundary shift. Suggested copy:
Claude Desktop profile changed to Ollama Cloud.
All Claude Desktop prompts, responses, attached files, and tool outputs will now route through ollama.com and are visible to Ollama, Inc. Ollama’s privacy policy and data-retention terms apply to your Claude Desktop traffic from now until you run
ollama launch claude-desktop --restore.To restore the direct-Anthropic profile, run: ollama launch claude-desktop —restore
The change is single-string and ships in the next firmware push. No protocol or schema modification required.
Finding 2: community-tutorial typosquat surface
The unclaimed package
The npm package name mcp-server-ollama (verbatim, no scope) is referenced across:
- GitHub Issue ollama/ollama#16005 (filed 2026-05-06)
ever-works/awesome-mcp-servers(catalog repo)andysingal/llm-course(tutorial)metorial/metorial-index(catalog)TensorBlock/awesome-mcp-servers- Multiple PyPI / GitHub catalog crawls that reference the name as if registered
The name is not registered. https://registry.npmjs.org/mcp-server-ollama returns HTTP 404 as of 2026-05-07.
Two adjacent names also unclaimed:
@ollama/mcp-server: 404@modelcontextprotocol/server-ollama: 404
Two adjacent names that ARE registered (and therefore not part of this surface):
ollama-mcp-server: 200mcp-ollama: 200
The exploit chain
A user who follows any tutorial directing them to write the following into ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"ollama": {
"command": "npx",
"args": ["-y", "mcp-server-ollama"]
}
}
}
…sees Claude Desktop attempt to launch the MCP server on next start. Today this fails silently (404 from npm registry). The moment any party publishes a package named mcp-server-ollama, Claude Desktop will:
npx -y mcp-server-ollama(auto-install with no prompt, because of-y)- Spawn the MCP server process under the operator user
- Wire its stdio into the Claude Desktop MCP transport
- Forward tool calls and responses bidirectionally
Whoever owns the package owns the operator’s Claude Desktop session: read every prompt, inject responses, exfiltrate clipboard via tool calls, write to disk via Claude’s built-in Filesystem tool surface, etc.
Why the surface persists
The npm registry permits anyone to register an unclaimed name. The MCP protocol specifies no signature or trust mechanism for command invocations. Claude Desktop reads claude_desktop_config.json and runs the listed commands without prompting the user for consent on each new MCP server. npx -y is the path-of-least-resistance install pattern repeated across community tutorials.
These four design choices compose into a typosquat-by-default architecture for any unclaimed package name that appears in a sufficiently-trafficked tutorial.
Recommendation
Two parties should act:
-
Ollama should claim
mcp-server-ollama,@ollama/mcp-server, and similar Ollama-namespaced MCP names with placeholder packages that loudly warn on invocation and direct the user to either the legitimate community bridge of choice (ollama-mcp-serverormcp-ollama) or to the gateway-mode flow that doesn’t require an MCP bridge at all. -
Anthropic should harden Claude Desktop’s MCP-launch path:
- Warn on first execution of any new
mcpServers[*].commandentry, naming the package and the registry it’d resolve from. - Surface
npx -yinvocations specifically as “downloading and executing arbitrary code from npm; confirm?”. - Optionally maintain a
mcpServersallow-list of known-safe packages that bypass the warning.
- Warn on first execution of any new
The third party (NuClide) will not register the unclaimed names. Speculatively claiming names creates registry pollution and shifts the failure mode from “silent 404” to “third-party-controlled placeholder”, neither of which is the right end-state. The right end-state is vendor-side fixes from the two parties above.
Finding 3: Issue #16005 is misframed
The reporter cites:
ollama launch claude-desktopwrites a configuration that references a non-existent npm package, causing the Claude Desktop integration to fail silently.
The v0.23.1 source does not write mcpServers entries at all (888 lines of claude_desktop.go have zero references to mcp, npx, mcpServers, or npm in any form). The config-writer (writeClaudeDesktopGatewayProfile) sets inferenceProvider, inferenceGatewayBaseUrl, inferenceGatewayApiKey, inferenceGatewayAuthScheme, and disableDeploymentModeChooser, then writes back via writeClaudeDesktopJSON. That writer reads the existing config (readClaudeDesktopJSONAllowMissing), updates the keys it manages, and re-serializes. Keys it does not manage are preserved as-is.
The most consistent explanation for what the reporter saw is that they had previously followed a tutorial that wrote an mcpServers.ollama entry pointing at mcp-server-ollama. When they then ran ollama launch claude-desktop, Ollama’s writer added the gateway keys and preserved the mcpServers entry the user already had. The reporter, on inspecting the post-launch config and finding mcp-server-ollama in it, attributed authorship to the most recent writer (Ollama). The actual authorship is whichever tutorial they followed earlier.
This is a misattribution attack surface: when a config-mutator preserves keys it doesn’t manage, downstream users may credit the mutator with content the mutator only failed to remove. From a security-research perspective the surface is benign (the user authored the bad key themselves), but from a product-trust perspective it is corrosive (the vendor inherits blame for community-tutorial pollution).
Recommendation
Ollama’s launcher should treat unrecognized top-level keys in claude_desktop_config.json as out-of-scope and either:
- Leave them alone (current behavior) and print a warning during the launch flow listing any such keys it found, so the user is aware that they exist and weren’t authored by Ollama.
- Or migrate to a
--profilestyle where Ollama writes a separate file (Claude Desktop-3p/claude_desktop_config.jsonis already partially this) and never touches the user’s primary config at all.
The first option is one fmt.Println + a json.Decode pass; the second already exists for the third-party profile and could be expanded.
Methodology Insight #11
Source code is authoritative; bug reports are framing. When a bug report claims that a vendor wrote
Xto a config, verify against the vendor’s source repository and current release tag before accepting the framing. Config mutators that preserve keys they don’t manage are a misattribution attack surface; the right verification path isgrepon the actual writer function, notcaton the post-mutation config.
This insight applies broadly:
- The Ulm CL1 case (Methodology Insight #10) was originally framed as “operator misconfiguration” by the SOC’s first-pass intake; source-of-truth verification of the vendor’s default systemd unit promoted the framing to “vendor-template default-no-auth”. Different actor, different fix path.
- The 2026-05-04 SUNY Buffalo State misroute (Insight #4) was framed by our own pipeline as “send to UB”; WHOIS source-of-truth verification rerouted to Buffalo State.
The pattern: always trace a claim back to the actor’s own primary record before crediting or blaming.
Disclosure plan
Three threads:
-
Comment on
ollama/ollama#16005, clarification post explaining that the v0.23.1 source does not writemcpServers; the reporter likely had a pre-existing tutorial-authored config; the real bug is the silent failure of the bridge they configured manually, not an Ollama-side bug. Suggest the maintainer mark the issue asnot-a-bugwith a note for future readers, or rename the issue to the actual problem (“Ollama’s launcher preserves unrecognized keys, creating misattribution risk”). -
Disclose to Ollama (
security@ollama.comor via their published security.txt if available). Two recommendations: (a) expand the success message to surface the gateway MITM, (b) claim Ollama-namespaced unclaimed npm names defensively. -
Disclose to Anthropic (
security@anthropic.com). Recommend Claude Desktop harden its MCP-launch path: warn on first execution of newmcpServers[*].commandentries, treatnpx -yspecifically, optionally allow-list known-safe packages.
NuClide will not register the unclaimed names speculatively.
IOCs
| Type | Value |
|---|---|
| Vulnerable command | ollama launch claude-desktop (v0.23.0+) |
| Config write path (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Config write path (third-party) | ~/Library/Application Support/Claude-3p/claude_desktop_config.json |
| Gateway endpoint | https://ollama.com |
| Gateway auth | Authorization: Bearer <user-supplied Ollama Cloud key> |
| Unclaimed npm names | mcp-server-ollama, @ollama/mcp-server, @modelcontextprotocol/server-ollama |
| Tutorial-poisoned config snippet | {"mcpServers":{"ollama":{"command":"npx","args":["-y","mcp-server-ollama"]}}} |
| Issue ref | github.com/ollama/ollama/issues/16005 |
References
- Ollama v0.23.1 source.
cmd/launch/claude_desktop.go - Ollama blog.
ollama launch(2026-01-23) - Claude Desktop integration docs. docs.ollama.com/integrations/claude-desktop
- Methodology Insight #10. vendor-template default-no-auth on research instruments
- Methodology Insight #4. WHOIS-driven contact resolution