Configuration & Environment
OAuth `scopes_supported` declaration includes wildcard / omnibus tokens (`*`, `all`, `full-access`, `<resource>:*`) — broad scopes amplify token-compromise blast radius and obscure the audit trail.
The official MCP security best practices forbid wildcard scopes outright (`*`, `all`, `full-access`) and resource-wildcards (`files:*`, `db:*`, `admin:*`). Each named scope is supposed to map 1:1 to a discrete capability; wildcards short-circuit that and make every issued token max-privilege by default. The fix is to enumerate specific scopes (`files:read`, `tools:call:safe-readers`).
MCP servers that proxy OAuth often inherit scope strings from the upstream IdP and expose them as their own. If the IdP supports a `*` or `all` scope, the proxy ends up offering it too. The right pattern is to filter out wildcard scopes at the proxy and only re-export specific named ones.
from fastmcp import FastMCP |
mcp = FastMCP("oauth-proxy") |
scopes_supported = ["files:*", "all", "*"] |
from fastmcp import FastMCP |
mcp = FastMCP("oauth-proxy") |
scopes_supported = [ |
"files:read", |
"files:write:owned", |
"tools:call:safe-readers", |
] |
Per-occurrence in MCP-server-context files. Fires on `scopes_supported` / `scopes` / `scope` array literals containing wildcard tokens, JSON-shape `"scopes_supported": [...]` with same, OAuth client `scope=` kwarg or `"scope":` dict-literal with wildcard, or space-separated scope strings with wildcard token. Wildcards detected: bare `*`, `all` (case-insensitive), `full-access` / `full_access` / `fullAccess`, `everything`, any `<word>:*` (e.g. `files:*`, `db:*`, `admin:*`, `read:*`, `write:*`).
See the full threat catalog for every documented detection.
MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.
Scan now