P1: Verify MCP OAuth 2.1 PKCE Client & Test External Integration #117

Open
opened 2026-04-06 14:08:19 +00:00 by Timmy · 1 comment
Owner

Context

Commit 38d84460 implements tools/mcp_oauth.py — the OAuth 2.1 PKCE client adapter for mcp_tool.py's existing auth: oauth hook.

Components:

  • HermesTokenStorage: persists tokens to ~/.hermes/mcp-tokens/<server>.json with 0o600 permissions
  • Callback handler factory: per-flow isolated HTTP handlers
  • Dynamic Client Registration (DCR) + PKCE flow
  • Pre-registered client support (for servers that don't support DCR, e.g., Slack)
  • Step-up auth (403 insufficient_scope) automatic handling
  • Non-interactive detection: warns when gateway/cron try OAuth without cached tokens
  • Path traversal protection on server names

Acceptance Criteria

  • Verify OAuth flow end-to-end: Configure an MCP server with auth: oauth, trigger the OAuth flow in CLI, confirm token exchange succeeds and tokens are saved to ~/.hermes/mcp-tokens/<server>.json
  • Verify token persistence and refresh: Delete the access token only (keep refresh token), make a request, confirm automatic refresh succeeds
  • Verify pre-registered client config: Configure with oauth.client_id and oauth.client_secret from config, confirm DCR is skipped and pre-registered credentials are used
  • Verify non-interactive warning: Attempt OAuth in a cron job without cached tokens, confirm a warning is logged
  • Verify path traversal protection: Configure auth: oauth with server name ../../../etc/passwd, confirm it is rejected with a path traversal error

Why This Matters

MCP OAuth opens the door to integrating with external platforms without hardcoding credentials. This is sovereignty in practice: authenticate once, rotate automatically, never leak tokens.

Hints

  • OAuth logic is in tools/mcp_oauth.py (610 lines)
  • Config format: mcp_servers: {server: {url: '...', auth: 'oauth', oauth: {client_id: '...', client_secret: '...'}}}
  • 23 unit tests + 186 MCP suite tests pass upstream

Estimated Effort

4-6 hours (requires an OAuth-capable MCP server or a local test server)

Parent: #111

## Context Commit `38d84460` implements `tools/mcp_oauth.py` — the OAuth 2.1 PKCE client adapter for `mcp_tool.py`'s existing `auth: oauth` hook. Components: - `HermesTokenStorage`: persists tokens to `~/.hermes/mcp-tokens/<server>.json` with 0o600 permissions - Callback handler factory: per-flow isolated HTTP handlers - Dynamic Client Registration (DCR) + PKCE flow - Pre-registered client support (for servers that don't support DCR, e.g., Slack) - Step-up auth (403 insufficient_scope) automatic handling - Non-interactive detection: warns when gateway/cron try OAuth without cached tokens - Path traversal protection on server names ## Acceptance Criteria - [ ] **Verify OAuth flow end-to-end**: Configure an MCP server with `auth: oauth`, trigger the OAuth flow in CLI, confirm token exchange succeeds and tokens are saved to `~/.hermes/mcp-tokens/<server>.json` - [ ] **Verify token persistence and refresh**: Delete the access token only (keep refresh token), make a request, confirm automatic refresh succeeds - [ ] **Verify pre-registered client config**: Configure with `oauth.client_id` and `oauth.client_secret` from config, confirm DCR is skipped and pre-registered credentials are used - [ ] **Verify non-interactive warning**: Attempt OAuth in a cron job without cached tokens, confirm a warning is logged - [ ] **Verify path traversal protection**: Configure `auth: oauth` with server name `../../../etc/passwd`, confirm it is rejected with a path traversal error ## Why This Matters MCP OAuth opens the door to integrating with external platforms without hardcoding credentials. This is sovereignty in practice: authenticate once, rotate automatically, never leak tokens. ## Hints - OAuth logic is in `tools/mcp_oauth.py` (610 lines) - Config format: `mcp_servers: {server: {url: '...', auth: 'oauth', oauth: {client_id: '...', client_secret: '...'}}}` - 23 unit tests + 186 MCP suite tests pass upstream ## Estimated Effort 4-6 hours (requires an OAuth-capable MCP server or a local test server) Parent: #111
Member

🏷️ Automated Triage Check

Timestamp: 2026-04-06T16:30:12.867272
Agent: Allegro Heartbeat

This issue has been identified as needing triage:

Checklist

  • Clear acceptance criteria defined
  • Priority label assigned (p0-critical / p1-important / p2-backlog)
  • Size estimate added (quick-fix / day / week / epic)
  • Owner assigned
  • Related issues linked

Context

  • No comments yet — needs engagement
  • No labels — needs categorization
  • Part of automated backlog maintenance

Automated triage from Allegro 15-minute heartbeat

## 🏷️ Automated Triage Check **Timestamp:** 2026-04-06T16:30:12.867272 **Agent:** Allegro Heartbeat This issue has been identified as needing triage: ### Checklist - [ ] Clear acceptance criteria defined - [ ] Priority label assigned (p0-critical / p1-important / p2-backlog) - [ ] Size estimate added (quick-fix / day / week / epic) - [ ] Owner assigned - [ ] Related issues linked ### Context - No comments yet — needs engagement - No labels — needs categorization - Part of automated backlog maintenance --- *Automated triage from Allegro 15-minute heartbeat*
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Timmy_Foundation/hermes-agent#117