Skip to main content
Rule ID: AE-MCP-003 · Severity: High · Category: MCP Safety · Auto-fixable: No

Why this rule

A public remote MCP server with no declared auth boundary accepts tool calls from any agent that can reach it. Charter checks whether the config declares that auth is required — the minimum signal that the server was configured with access control in mind. Without this declaration, there is no evidence that tool calls to the server are gated at all.

What triggers it

Charter inspects every remote HTTP or SSE server entry in tracked MCP configuration files. For each non-local remote server, it checks whether an auth header is declared in the server’s config block. Accepted auth header names (checked case-insensitively):
  • Authorization
  • X-Api-Key
  • Api-Key
  • X-Auth-Token
An environment variable reference such as "Bearer ${TOKEN}" counts as a valid declaration — Charter checks for the presence of an auth header, not the validity of the credential. Scanned files: .mcp.json, mcp.json, .cursor/mcp.json, .vscode/mcp.json, .gemini/settings.json Always exempt:
ExemptionReason
Local / internal originsLoopback, RFC 1918 private addresses, *.localhost, *.local, *.internal
Catalog OAuth vendor hostsSentry, Atlassian, Context7, and similar — they authenticate via OAuth flow, not a static config header
Dynamic ${VAR} URLNo parseable host — skipped

Examples

.mcp.json
{
  "mcpServers": {
    "self-hosted": {
      "type": "http",
      "url": "https://self-hosted.example.com/mcp"
    }
  }
}
# Remote server, no headers block — Charter cannot confirm auth is configured
# Fires High

How to fix

Add a headers block to the remote MCP server entry with an auth header that references an environment variable:
{
  "mcpServers": {
    "your-server": {
      "type": "http",
      "url": "https://your-mcp-server.example.com",
      "headers": {
        "Authorization": "Bearer ${MCP_SERVER_TOKEN}"
      }
    }
  }
}
If the server uses a different auth mechanism, use the appropriate header name (X-Api-Key, Api-Key, or X-Auth-Token) with the same env-reference pattern.
Use env var references for header values — never literal credentials. A literal credential in an auth header triggers AE-SEC-002 (Blocker, score cap ≤ 49).

Score impact

Each finding is High (−10). No hard cap (caps are reserved for raw-secret findings).

Edge cases

Local and internal origins never fire. Catalog OAuth vendor hosts never fire. An env-reference header value (${TOKEN}) satisfies the presence check — Charter does not validate the credential itself, only its declaration. A bare ${VAR} URL with no parseable host is skipped entirely.
  • AE-MCP-001 — MCP servers must be pinned to exact versions
  • AE-MCP-002 — remote MCP server origins must be trusted
  • AE-SEC-002 — no raw secrets in MCP config files

CLI

charter explain AE-MCP-003