@mcp-z/oauthCAUTION
Multi-account orchestration and secure token storage for OAuth-based MCP servers
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
Multi-account orchestration and secure token storage for OAuth-based MCP servers.
Common uses
- Add consistent account tools to MCP servers
- Store OAuth tokens with a shared config and storage backend
- Reuse the same account lifecycle across Google and Microsoft providers
- Resolve public Client ID Metadata Documents (CIMD) safely for authorization servers
Client ID Metadata Documents
createCimdResolver() resolves a public HTTPS client_id metadata document with SSRF protections: public-unicast DNS validation pinned into the request, no redirects, a 5 KiB JSON response limit, bounded caching, and per-client request limiting. Local development can explicitly allow HTTP loopback documents with allowHttpLoopback: true.
In production, route this traffic through an egress proxy or network policy that blocks internal destinations (for example, Smokescreen-style controls). That defense composes with the resolver's application-level checks.
Install
npm install @mcp-z/oauth
Optional storage backends:
npm install keyv-duckdb npm install keyv-file
Account tools and modes
Use AccountServer to add account tools to your MCP server.
Loopback mode (multi-account)
When using loopback OAuth, these tools are added:
account-meaccount-switchaccount-removeaccount-list
Stateless mode (DCR/bearer)
When using stateless auth (DCR/bearer tokens), only this tool is available:
account-me
Example
import { AccountServer } from '@mcp-z/oauth';
const { tools, prompts } = AccountServer.createStateless({ service: 'gmail' });
// Register these tools and prompts with your MCP server.Use createLoopback when the server manages multiple stored accounts. It requires a Keyv store, logger, and OAuth provider from your application. createStateless needs only the service name and reports the account represented by the MCP client's bearer token.
Logging helper
Use `sanitizeForL
c299dd3b51e8OBSERVED · 2026-10-11Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add oauth --env GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} --env JWT_PUBLIC_KEY=${JWT_PUBLIC_KEY} --env JWT_SECRET=${JWT_SECRET} --env SESSION_SECRET=${SESSION_SECRET} -- npx -y @mcp-z/[email protected]{
"mcpServers": {
"oauth": {
"command": "npx",
"args": [
"-y",
"@mcp-z/[email protected]"
],
"env": {
"GOOGLE_CLIENT_SECRET": "${GOOGLE_CLIENT_SECRET}",
"JWT_PUBLIC_KEY": "${JWT_PUBLIC_KEY}",
"JWT_SECRET": "${JWT_SECRET}",
"SESSION_SECRET": "${SESSION_SECRET}"
}
}
}
}Exposed tools (1)
1 read · 0 write · 0 destructive.
| Tool | Risk | Description |
|---|---|---|
points | read | Key points to include |
Trust audit
CAUTIONgrade B · trust 83/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (5 observation(s))
- Network
- declared (1 observation(s))
- Shell
- declared (1 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (17)
const SECRET = 'test-jwt-secret-0123456789-abcdefgh';
const token = issueToken('HS256', { secret: 'other-secret-0123456789-0123456789' });.depcheckrc
.ncurc.json
import { addAccount, getAccountInfo, getActiveAccount, getLinkedAccounts, removeAccount, setAccountInfo, setActiveAccount } from '../../account-utils.ts';import type { AccountInfo, McpPrompt, McpTool } from '../../types.ts';import { getAccountInfo, getActiveAccount, getToken } from '../../account-utils.ts';import type { CachedToken, McpPrompt, McpTool } from '../../types.ts';import { getAccountInfo, getLinkedAccounts } from '../../account-utils.ts';for (const address of ['10.0.0.1', '172.16.0.1', '192.168.0.1', '127.0.0.1', '169.254.169.254', '0.0.0.0', '100.64.0.1', '224.0.0.1', '::1', 'fc00::1', 'fe80::1', '::ffff:127.0.0.1']) {callback(null, [{ address: lookups === 1 ? '127.0.0.1' : '169.254.169.254', family: 4 }]);jwksUrl = `http://127.0.0.1:${address.port}/jwks.json`;await test(`http://127.0.0.1:${address.port}`);const clientId = `http://127.0.0.1:${req.socket.localPort}/metadata`;res.writeHead(302, { location: 'http://127.0.0.1/private' });const clientId = `http://127.0.0.1:${req.socket.localPort}/metadata`;@modelcontextprotocol/server, ipaddr.js, keyv, zod, @types/mocha, @types/node, node-version-use, ts-dev-stack
Gates applied: no_behavioural_pass.
c299dd3b51e8full audit observations/trust-audit/mcp-server/mcp-z__oauth.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | c299dd3b51e8 | CAUTION | B | 83 | first audit |
Questions
What is the @mcp-z/oauth MCP server?
Multi-account orchestration and secure token storage for OAuth-based MCP servers
What tools does @mcp-z/oauth expose?
1 in total: 1 read-only, 0 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.
Is @mcp-z/oauth safe to connect to an agent?
With care. The audit graded it B (83/100) and found 17 things worth knowing before you trust this server, listed below with the exact line each was found on.
What credentials does @mcp-z/oauth need?
It reads GOOGLE_CLIENT_SECRET, JWT_PUBLIC_KEY, JWT_SECRET and SESSION_SECRET from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How current is this page?
The grade is for one exact copy of the source (c299dd3b51e8), read on 2026-10-11. The repository is watched and re-audited when it changes.