Skip to content

feat(cli): MCP server management CLI + OAuth 2.1 PKCE auth (#497, #690)#2021

Closed
imnotdev25 wants to merge 3 commits into
NousResearch:mainfrom
imnotdev25:main
Closed

feat(cli): MCP server management CLI + OAuth 2.1 PKCE auth (#497, #690)#2021
imnotdev25 wants to merge 3 commits into
NousResearch:mainfrom
imnotdev25:main

Conversation

@imnotdev25

@imnotdev25 imnotdev25 commented Mar 19, 2026

Copy link
Copy Markdown

What changed

OAuth 2.1 PKCE & Transport Upgrades (tools/mcp_oauth.py, tools/mcp_tool.py) — #497

  • RFC 7636 PKCE flow with S256 challenge for MCP HTTP servers
  • RFC 9728 Protected Resource Metadata discovery: Robustly identifies authorization servers via /.well-known/oauth-protected-resource or WWW-Authenticate response headers (handles external auth providers like Clerk).
  • RFC 8707 Resource Indicators: Added the resource parameter to authorization URLs to explicitly identify the target MCP server.
  • WAF Avoidance: Injected browser-like User-Agent (Hermes-Agent/1.0 (OAuth PKCE Client)) headers into all OAuth HTTP requests. This bypasses Cloudflare 403 Forbidden limits during dynamic client registration.
  • Safe Scope Registration: Restricts dynamic client registration to standard, safe scopes (openid profile email offline_access) to prevent registration rejections from identity providers advertising restricted scopes (e.g., public_metadata).
  • Strict Token Casing: Fixed handling of the Authorization header to always strictly enforce a capitalized Bearer prefix (resolves 401 Unauthorized disconnects for servers like Notion that return token_type: "bearer").
  • Transport Architecture: Intercepts mcp-[your-server] connections to attempt Streamable HTTP with an automatic fallback mechanism to SSE (Server-Sent Events). Enables compatibility with older v1 MCP endpoints (like alphaxiv).
  • Browser-based authorization with localhost callback and manual authorization fallback (headless/SSH environments).
  • Token caching in ~/.hermes/mcp-tokens/ (permissions 0600) and automatic token refresh with expiry buffer.

MCP CLI (hermes_cli/mcp_config.py & hermes_cli/main.py) — #690

  • hermes mcp add — discovery-first install: connect → discover tools → interactive selection → save
    • Supports --url (HTTP) and --command (stdio) transports
    • --auth oauth triggers OAuth PKCE flow during add
    • API keys stored in ~/.hermes/.env with ${ENV_VAR} interpolation in config
  • Dispatch Fixes: Corrected an argparse nested subparser bug that previously misrouted hermes mcp add to the chat REPL.
  • Error Surfacing: Implemented un-wrapping of anyio's opaque ExceptionGroup/TaskGroup errors. CLI now elegantly surfaces underlying HTTPStatusError messages (e.g. 401 Unauthorized).
  • hermes mcp remove — removes config entry + cleans up OAuth tokens
  • hermes mcp list — table view with transport, tool count, enabled/disabled status
  • hermes mcp test — connection test with latency, masked auth info, and tool listing
  • hermes mcp configure — interactive curses checklist to toggle which tools are enabled

Env var interpolation (tools/mcp_tool.py)

  • ${ENV_VAR} syntax in MCP server config values, resolved from os.environ + ~/.hermes/.env
  • Keeps API keys out of config.yaml

Documentation

  • Updated website/docs/user-guide/features/mcp.md — OAuth, CLI management, env vars, updated quick start
  • Updated website/docs/reference/cli-commands.md — full hermes mcp reference
  • Updated website/docs/reference/mcp-config-reference.md — auth key, OAuth, env vars
  • Updated README.md, AGENTS.md, cli-config.yaml.example

How to test

# Run the test suites
pytest tests/tools/test_mcp_oauth.py -v      # 44 tests — OAuth module
pytest tests/hermes_cli/test_mcp_config.py -v # 22 tests — MCP CLI

# Smoke test CLI
hermes mcp --help
hermes mcp add --help
hermes mcp list
hermes mcp test <configured-server>

Files changed (12 files, +2684 −10)

File Change
tools/mcp_oauth.py [NEW] OAuth 2.1 PKCE module (613 lines)
tools/mcp_tool.py _interpolate_env_vars() + env var resolution in _load_mcp_config()
hermes_cli/mcp_config.py [NEW] 5 MCP CLI subcommands (608 lines)
hermes_cli/main.py Argparse registration for hermes mcp
tests/tools/test_mcp_oauth.py [NEW] 44 OAuth tests (678 lines)
tests/hermes_cli/test_mcp_config.py [NEW] 22 MCP CLI tests (400 lines)
website/docs/user-guide/features/mcp.md OAuth, CLI management, env vars
website/docs/reference/cli-commands.md hermes mcp reference
website/docs/reference/mcp-config-reference.md auth key, OAuth, env vars
README.md Getting Started section
AGENTS.md Project structure
cli-config.yaml.example Env var interpolation + CLI examples

Platform tested

  • macOS (Apple Silicon)

Implements RFC 7636 PKCE flow for MCP HTTP servers that require
OAuth instead of static API keys. Handles server metadata discovery,
browser-based authorization, token caching (~/.hermes/mcp-tokens/),
and automatic token refresh.

Closes #497
@imnotdev25 imnotdev25 marked this pull request as draft March 19, 2026 06:48
Refactors Hermes CLI command execution to address nested subparser quirks and improve fallback behavior. Enhances OAuth flow for MCP servers with better error handling, scope management, and transport support, adding SSE fallback and improved metadata discovery. Updates dependencies for MCP SDK compatibility.
@imnotdev25 imnotdev25 marked this pull request as ready for review March 19, 2026 08:40
teknium1 added a commit that referenced this pull request Mar 22, 2026
Add hermes mcp add/remove/list/test/configure CLI for managing MCP
server connections interactively. Discovery-first 'add' flow connects,
discovers tools, and lets users select which to enable via curses checklist.

Add OAuth 2.1 PKCE authentication for MCP HTTP servers (RFC 7636).
Supports browser-based and manual (headless) authorization, token
caching with 0600 permissions, automatic refresh. Zero external deps.

Add ${ENV_VAR} interpolation in MCP server config values, resolved
from os.environ + ~/.hermes/.env at load time.

Core OAuth module from PR #2021 by @imnotdev25. CLI and mcp_tool
wiring rewritten against current main. Closes #497, #690.
teknium1 added a commit that referenced this pull request Mar 22, 2026
Add hermes mcp add/remove/list/test/configure CLI for managing MCP
server connections interactively. Discovery-first 'add' flow connects,
discovers tools, and lets users select which to enable via curses checklist.

Add OAuth 2.1 PKCE authentication for MCP HTTP servers (RFC 7636).
Supports browser-based and manual (headless) authorization, token
caching with 0600 permissions, automatic refresh. Zero external deps.

Add ${ENV_VAR} interpolation in MCP server config values, resolved
from os.environ + ~/.hermes/.env at load time.

Core OAuth module from PR #2021 by @imnotdev25. CLI and mcp_tool
wiring rewritten against current main. Closes #497, #690.
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #2465. Core OAuth module rewritten to use the MCP SDK's built-in OAuthClientProvider (210 lines vs 715). CLI and mcp_tool wiring written fresh against current main. Env var interpolation and argparse registration preserved. Thanks for the solid original implementation — the architecture was right, we just leaned on the SDK for the heavy lifting.

@teknium1 teknium1 closed this Mar 22, 2026
outsourc-e pushed a commit to outsourc-e/hermes-agent that referenced this pull request Mar 26, 2026
Add hermes mcp add/remove/list/test/configure CLI for managing MCP
server connections interactively. Discovery-first 'add' flow connects,
discovers tools, and lets users select which to enable via curses checklist.

Add OAuth 2.1 PKCE authentication for MCP HTTP servers (RFC 7636).
Supports browser-based and manual (headless) authorization, token
caching with 0600 permissions, automatic refresh. Zero external deps.

Add ${ENV_VAR} interpolation in MCP server config values, resolved
from os.environ + ~/.hermes/.env at load time.

Core OAuth module from PR NousResearch#2021 by @imnotdev25. CLI and mcp_tool
wiring rewritten against current main. Closes NousResearch#497, NousResearch#690.
angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 27, 2026
Add hermes mcp add/remove/list/test/configure CLI for managing MCP
server connections interactively. Discovery-first 'add' flow connects,
discovers tools, and lets users select which to enable via curses checklist.

Add OAuth 2.1 PKCE authentication for MCP HTTP servers (RFC 7636).
Supports browser-based and manual (headless) authorization, token
caching with 0600 permissions, automatic refresh. Zero external deps.

Add ${ENV_VAR} interpolation in MCP server config values, resolved
from os.environ + ~/.hermes/.env at load time.

Core OAuth module from PR NousResearch#2021 by @imnotdev25. CLI and mcp_tool
wiring rewritten against current main. Closes NousResearch#497, NousResearch#690.
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
Add hermes mcp add/remove/list/test/configure CLI for managing MCP
server connections interactively. Discovery-first 'add' flow connects,
discovers tools, and lets users select which to enable via curses checklist.

Add OAuth 2.1 PKCE authentication for MCP HTTP servers (RFC 7636).
Supports browser-based and manual (headless) authorization, token
caching with 0600 permissions, automatic refresh. Zero external deps.

Add ${ENV_VAR} interpolation in MCP server config values, resolved
from os.environ + ~/.hermes/.env at load time.

Core OAuth module from PR NousResearch#2021 by @imnotdev25. CLI and mcp_tool
wiring rewritten against current main. Closes NousResearch#497, NousResearch#690.
olympus-terminal pushed a commit to olympus-terminal/hermes-agent that referenced this pull request May 16, 2026
Add hermes mcp add/remove/list/test/configure CLI for managing MCP
server connections interactively. Discovery-first 'add' flow connects,
discovers tools, and lets users select which to enable via curses checklist.

Add OAuth 2.1 PKCE authentication for MCP HTTP servers (RFC 7636).
Supports browser-based and manual (headless) authorization, token
caching with 0600 permissions, automatic refresh. Zero external deps.

Add ${ENV_VAR} interpolation in MCP server config values, resolved
from os.environ + ~/.hermes/.env at load time.

Core OAuth module from PR NousResearch#2021 by @imnotdev25. CLI and mcp_tool
wiring rewritten against current main. Closes NousResearch#497, NousResearch#690.
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
Add hermes mcp add/remove/list/test/configure CLI for managing MCP
server connections interactively. Discovery-first 'add' flow connects,
discovers tools, and lets users select which to enable via curses checklist.

Add OAuth 2.1 PKCE authentication for MCP HTTP servers (RFC 7636).
Supports browser-based and manual (headless) authorization, token
caching with 0600 permissions, automatic refresh. Zero external deps.

Add ${ENV_VAR} interpolation in MCP server config values, resolved
from os.environ + ~/.hermes/.env at load time.

Core OAuth module from PR NousResearch#2021 by @imnotdev25. CLI and mcp_tool
wiring rewritten against current main. Closes NousResearch#497, NousResearch#690.
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
Add hermes mcp add/remove/list/test/configure CLI for managing MCP
server connections interactively. Discovery-first 'add' flow connects,
discovers tools, and lets users select which to enable via curses checklist.

Add OAuth 2.1 PKCE authentication for MCP HTTP servers (RFC 7636).
Supports browser-based and manual (headless) authorization, token
caching with 0600 permissions, automatic refresh. Zero external deps.

Add ${ENV_VAR} interpolation in MCP server config values, resolved
from os.environ + ~/.hermes/.env at load time.

Core OAuth module from PR NousResearch#2021 by @imnotdev25. CLI and mcp_tool
wiring rewritten against current main. Closes NousResearch#497, NousResearch#690.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants