[BUG] Claude Code marks an anonymous MCP server authenticated when it lists a tool

Status Open
Reported on v2.1.286
Maintainer reply None cached
Activity 0 comments · opened Oct 2, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

In Claude Code's /mcp detail view, an anonymous HTTP MCP server was labeled Auth: not authenticated when it listed zero tools and Auth: authenticated when it listed one tool. The server has no OAuth metadata or authentication endpoint, and no authentication action occurred. Returning to zero tools restored Auth: not authenticated.

This was reproduced in one Claude profile with fresh CLI processes. The observation shows that a nonempty tool list is sufficient to produce the authenticated label in that profile; it does not establish every condition that may affect the label.

What Should Happen?

The /mcp Auth label should reflect whether the server was authenticated. A tool list returned without authentication should not make the label say authenticated.

Error Messages/Logs

No error was shown. The unexpected result is the `/mcp` detail row: `Auth: authenticated` for the one-tool run.

Steps to Reproduce

  1. Save the following server as fake-mcp.mjs and the JSON block as mcp-config.json in the same directory.
{"mcpServers":{"anonymous-label-test":{"type":"http","url":"http://127.0.0.1:18765/mcp"}}}
import { createServer } from 'node:http'

const count = Number(process.argv[2] ?? 0)
if (![0, 1].includes(count)) throw new Error('tool count must be 0 or 1')
const port = 18765
const tool = { name: 'example', description: 'Return a fixed test value', inputSchema: { type: 'object', properties: {} } }

createServer(async (req, res) => {
  if (req.url !== '/mcp') { res.writeHead(404).end(); return }
  if (req.method !== 'POST') { res.writeHead(405, { Allow: 'POST' }).end(); return }
  let body = ''
  for await (const chunk of req) body += chunk
  let message
  try { message = JSON.parse(body) } catch { res.writeHead(400).end(); return }
  const { id, method } = message
  if (id == null) { res.writeHead(202).end(); return }
  let result
  if (method === 'initialize') {
    result = { protocolVersion: '2025-06-18', capabilities: { tools: { listChanged: false } }, serverInfo: { name: 'anonymous-label-test', version: '1.0.0' } }
  } else if (method === 'tools/list') {
    result = { tools: count ? [tool] : [] }
  } else if (method === 'tools/call') {
    result = { content: [{ type: 'text', text: 'example' }] }
  } else if (method === 'ping') {
    result = {}
  } else {
    res.writeHead(200, { 'Content-Type': 'application/json' }).end(JSON.stringify({ jsonrpc: '2.0', id, error: { code: -32601, message: 'Method not found' } }))
    return
  }
  res.writeHead(200, { 'Content-Type': 'application/json' }).end(JSON.stringify({ jsonrpc: '2.0', id, result }))
}).listen(port, '127.0.0.1', () => console.log(`fake MCP listening on 127.0.0.1:${port}; tools=${count}`))
  1. Start the server with node fake-mcp.mjs 0.
  2. In another terminal, run claude --strict-mcp-config --mcp-config ./mcp-config.json, open /mcp, and select anonymous-label-test.
  3. Record the Auth row, then exit Claude Code and stop the server.
  4. Start the same server with node fake-mcp.mjs 1. Run the same Claude command in a fresh process with the same config and profile, then inspect the Auth row again.
  5. Exit Claude Code, stop the server, and repeat with node fake-mcp.mjs 0.

Observed in Claude Code 2.1.286:

| tools/list response | /mcp status | /mcp Auth row |
|---|---|---|
| 0 tools | connected, no tools | not authenticated |
| 1 tool | connected, 1 tool | authenticated |
| 0 tools, repeated after the 1-tool run | connected, no tools | not authenticated |

The server response's tool count is the only changed variable. It has no OAuth metadata, login, token endpoint, or authentication action.

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.286

Platform

Other

Operating System

macOS

Terminal/Shell

iTerm2

Additional Information

This report covers the /mcp Auth label only. It does not claim that account/session-token effects were tested.

Related reports describe different status mismatches: #96738 shows Auth: ✔ while the MCP status is failed after OAuth; #17152 reports not authenticated for an HTTP server using a bearer-token header; #26917 concerns surfacing a sign-in requirement when tool discovery is unauthorized. This reproduction uses no OAuth and changes only the anonymous tool count.

View original on GitHub ↗