How the OpenHuman MCP Registry Manages Dynamic Servers and OAuth Flows
The OpenHuman MCP registry maintains an in-memory map of server entries and automates OAuth 2.0 authorization code exchanges, enabling runtime discovery and secure authentication without service restarts.
The MCP (Message Control Protocol) registry serves as the central nervous system for the OpenHuman framework, orchestrating how the system discovers, registers, and communicates with external services. According to the tinyhumansai/openhuman source code, this registry implements a plug-and-play architecture that allows dynamic servers—services added or removed at runtime—to integrate seamlessly while handling OAuth 2.0 flows transparently through automated token management.
Registry Architecture and Core Components
The registry implementation spans six modular files in src/openhuman/mcp/registry/,each handling distinct responsibilities:
- Registry Core (
mod.rs): Maintains the in-memory map ofMcpServerEntryobjects containing URL, client ID, scopes, and encrypted tokens. - Operations (
ops.rs): Exposes JSON-RPC methods likemcp_registry_add_serverandmcp_registry_list_serversfor runtime CRUD operations. - Schemas (
schemas.rs): Defines request/response types includingMcpRegistryAddServerInputandMcpRegistryListServersOutput. - Event Bus (
bus.rs): PublishesDomainEvent::McpServerAddedandDomainEvent::McpServerRemovedfor decoupled subsystem communication. - Setup Operations (
setup_ops.rs): Handles OAuth authorization code exchange, token refresh scheduling, and error propagation. - Helpers (
helpers.rs): Provides URL validation, redirect URI construction, and secure token persistence utilities.
Runtime Server Registration
Adding Servers via JSON-RPC
Clients interact with the registry through the mcp_registry_add_server RPC method. As implemented in src/openhuman/mcp/registry/ops.rs, the ops::add_server function processes an AddServerInput struct:
use openhuman::mcp::registry::ops::{self, AddServerInput};
let input = AddServerInput {
url: "https://api.example.mcp".into(),
client_id: "my-client-id".into(),
scopes: vec!["read".into(), "write".into()],
client_secret: Some("super-secret".into()),
requires_oauth: true,
};
match ops::add_server(&input) {
Ok(entry) => println!("Server added with id {}", entry.id),
Err(e) => eprintln!("Failed: {}", e),
}
When invoked, the function instantiates a new McpServerEntry, inserts it into the registry's internal map, and emits a DomainEvent::McpServerAdded event across the bus. If the server entry specifies requires_oauth: true, the registry automatically initiates the OAuth setup flow.
Schema Validation
The schemas.rs module validates incoming payloads against strict Rust types. A registration request must include the server URL and OAuth requirements, while the response returns the generated server ID and current authentication state.
OAuth 2.0 Flow Automation
The registry internalizes all OAuth complexity, implementing the authorization code flow without exposing credential handling to other components.
Authorization Code Exchange
When requires_oauth: true, the registry initiates a six-step process defined in setup_ops.rs:
- Redirect Generation:
helpers::create_oauth_redirect_uriconstructs the authorization URL with CSRF-protected state tokens. - User Authorization: The system redirects users to the external server's
/oauth/authorizeendpoint. - Callback Processing: Upon return to the
mcp/oauth/callbackendpoint,setup_ops::exchange_code_for_tokenexecutes. - Token Retrieval: The function POSTs the authorization code to the server's
/oauth/tokenendpoint. - Secure Storage: Access and refresh tokens encrypt into the
McpServerEntry::tokenfield. - Error Propagation: Failures generate
DomainEvent::McpOAuthErrorevents and returnMcpRegistryError::OAuthFailedvia JSON-RPC.
use openhuman::mcp::registry::setup_ops;
async fn oauth_callback(query: HashMap<String, String>) -> impl Responder {
let code = query.get("code").cloned().unwrap();
let state = query.get("state").cloned().unwrap();
match setup_ops::exchange_code_for_token(&code, &state).await {
Ok(_) => HttpResponse::Ok().body("Authorization successful!"),
Err(err) => HttpResponse::BadRequest().body(format!("OAuth error: {}", err)),
}
}
Automatic Token Refresh
The registry schedules background refresh tasks via setup_ops::schedule_refresh. This monitors token expiry and silently exchanges refresh tokens for new access credentials, updating the server entry without user intervention or service disruption.
Event-Driven Lifecycle Management
The bus.rs module implements a publish-subscribe pattern that decouples server management from client connections. Subscribers receive strongly-typed events:
bus::subscribe_global(|event| match event {
DomainEvent::McpServerAdded(entry) => client.connect(entry),
DomainEvent::McpServerRemoved(id) => client.disconnect(id),
DomainEvent::McpOAuthError{id, err} => ui.show_error(id, err),
_ => {}
});
This architecture enables hot-plugging: the MCP client connects immediately upon McpServerAdded and cleans up on McpServerRemoved without polling the registry. JavaScript clients can subscribe using:
import { subscribeGlobal } from '@openhuman/core/event_bus';
subscribeGlobal(event => {
if (event.type === 'McpServerAdded') {
console.log('New MCP server:', event.entry);
} else if (event.type === 'McpServerRemoved') {
console.log('MCP server removed:', event.id);
}
});
Runtime Query and Mutation Operations
Beyond registration, the registry supports full lifecycle management through additional RPC methods implemented in ops.rs:
mcp_registry_list_servers: Returns all active entries with their authentication states (authenticated: true/false).mcp_registry_remove_server: Deletes the entry, triggersDomainEvent::McpServerRemoved, and signals the client to close connections.mcp_registry_update_server: Modifies scopes, client IDs, or URLs. If OAuth parameters change, the registry automatically restarts the setup flow to re-authenticate.
Summary
- The OpenHuman MCP registry maintains an in-memory map of
McpServerEntryobjects insrc/openhuman/mcp/registry/mod.rs, tracking dynamic server configurations and encrypted OAuth tokens. - Runtime registration occurs through JSON-RPC methods like
mcp_registry_add_server, which validate input viaschemas.rsand emit lifecycle events viabus.rs. - OAuth 2.0 flows are fully automated in
setup_ops.rs, handling authorization code exchange, secure token storage, and background refresh without exposing credentials to other subsystems. - The event-driven architecture uses
DomainEventvariants to notify clients of server additions, removals, and authentication errors, enabling hot-pluggable service integration. - All CRUD operations support runtime modification of server configurations, with automatic re-authentication when OAuth scopes or credentials change.
Frequently Asked Questions
What is the MCP registry in OpenHuman?
The MCP registry is a centralized Rust module in the OpenHuman framework that manages connections to external MCP (Message Control Protocol) servers. It maintains an in-memory registry of server configurations, handles OAuth 2.0 authentication flows, and publishes lifecycle events to coordinate with other system components like the MCP client and UI dashboards.
How does the registry handle OAuth token expiration?
According to src/openhuman/mcp/registry/setup_ops.rs, the registry schedules automatic refresh tasks using setup_ops::schedule_refresh. This background process monitors token expiry times and silently exchanges refresh tokens for new access credentials, updating the encrypted McpServerEntry::token field without requiring user re-authentication or system restarts.
Can I add MCP servers while the OpenHuman system is running?
Yes. The registry supports dynamic server registration through the mcp_registry_add_server JSON-RPC method implemented in ops.rs. When called, the system immediately creates a McpServerEntry, emits a DomainEvent::McpServerAdded event, and—if OAuth is required—initiates the authorization flow, all without restarting the core application.
Which files should I examine to understand the registry's OAuth implementation?
The OAuth 2.0 implementation spans three primary files: src/openhuman/mcp/registry/setup_ops.rs contains the token exchange and refresh logic; src/openhuman/mcp/registry/helpers.rs provides URL validation and redirect construction; and src/openhuman/mcp/registry/mod.rs defines the McpServerEntry struct that stores encrypted tokens.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →