ðïļ Model Context Gateway (MCG) Enterprise Architecture Guide & System Specification¶
The Model Context Protocol (MCP) Router Gateway & Semantic Proxy is a C# ASP.NET Core gateway, OAuth 2.0 provider, and protocol multiplexer. It consolidates downstream MCP servers (e.g., Docker, Home Assistant, SQL databases, cloud APIs) into a unified, secure entry point for LLMs, IDEs, and autonomous agents.
This document is the architectural specification, detailing system context, component boundaries, frontend design, protocol multiplexing, authorization, subprocess lifecycles, database persistence, cryptographic pipelines, and operations.
ð Table of Contents¶
- Executive Summary & Architectural Tenets
- High-Level System Architecture & Context
- Client Ecosystem & Ingress
- 7-Layer Gateway Architecture
- System Context & Architecture Diagram
- Backend Component & Boundary Model
- Domain Components (
Components/) - Infrastructure Services (
Infrastructure/) - Core Protocol & Routing Engine (
Core/) - Architectural Dependency Rules
- Component Subsystem Diagram
- Frontend Component & Typed Architecture
- React 19 & Vite SPA Architecture
- Domain Component Decomposition
- Typed API Layer & Zustand State Stores
- Frontend Architecture & State Flow Diagram
- Protocol & Routing Engine Deep-Dive
- Meta-Mode Dynamic Capability Hiding (
/sse&/message) - Target-Specific Virtual Proxying (
/{targetServerId}) - JSON-RPC 2.0 In-Flight Multiplexing & ID Preservation
- Sequence Diagram: Stateful SSE Session Lifecycle
- Sequence Diagram: Stateless HTTP Stream Execution
- Authorization Pipeline & RBAC Decision Engine
- 4-Stage Hierarchical Decision Flow
- Scope Grammar & Resolution
- Admin SID Bypass & Database-Backed RBAC Evaluation
- Mermaid Authorization Decision Flowchart
- Transport Subsystem & Subprocess Lifecycle
- Strategy Pattern (
ITransport) - Subprocess STDIO Architecture & Security Hardening
- Child Process Tree Lifecycle & Signal Handling
- Stderr Log Capture & PII Token Masking
- Sequence Diagram: STDIO Subprocess Execution
- Database & Persistence Architecture
- Unified Entity-Relationship Diagram (Mermaid ERD)
- Engine Dialect Strategies (SQLite, MS SQL Server, MySQL)
- Secret Provider & Envelope Encryption Pipeline
- AES-256-GCM Envelope Encryption Specification
- Pluggable Retrievers & Dynamic Reload Without Restart
- Secret Resolution & Encryption Pipeline Flowchart
- Cross-References, Verification & Operational Guide
1. Executive Summary & Architectural Tenets¶
The Model Context Gateway (MCG) solves the Context Explosion & Security Fragmentation Problem in large-scale MCP deployments. Connecting directly to many independent MCP servers causes: 1. Context Window Saturation: Loading schemas for 300+ tools exhausts tokens. 2. Tool Selection Confusion: Overlapping tool names cause hallucinations and errors. 3. Security & Credential Sprawl: Plaintext credentials across client configurations are vulnerabilities. 4. Lack of Centralized Audit & Governance: Enterprise compliance requires unified auditing, identity attribution, PII redaction, and access control.
To address these challenges, Model Context Gateway (MCG) enforces seven core architectural tenets:
+---------------------------------------------------------------------------------------------------+
| CORE ARCHITECTURAL TENETS |
+---------------------------------------------------------------------------------------------------+
| 1. Sub-Millisecond Routing Decisions |
| Header inspection (Mcp-Method, Mcp-Name) and lightweight path resolution allow fast triage |
| without buffering large request bodies. |
| |
| 2. Zero Token Waste via Meta-Mode |
| Default client connections expose only two bootstrap tools: `search_tools` and `execute_tool`.|
| Target tools are ranked on-demand using local in-process ONNX embeddings or API embeddings. |
| |
| 3. Fail-Closed, Multi-Stage RBAC |
| All capability invocations pass through AppKey scope boundaries, identity group mappings, |
| and stored procedure RBAC evaluations. Any missing policy or exception results in DENY. |
| |
| 4. Strict Isolation & Concurrency Fidelity |
| Clients maintain separate session contexts. JSON-RPC request IDs (integer, string, GUID) are |
| faithfully preserved while being mapped upstream to prevent collisions in multiplexed streams.|
| |
| 5. Zero Credential Exposure (Environment-Only Injection) |
| Downstream secrets are fetched from Vault, Registry DPAPI, or Env, and injected into headers |
| or process environments. Credentials are NEVER passed via CLI arguments or logged to disk. |
| |
| 6. Pluggable, Strategy-Driven Subsystems |
| All major subsystems (`ITransport`, `IIdentityProvider`, `ISecretRetriever`, |
| `IDbConnectionFactory`, `IEmbeddingService`) are decoupled through strategy interfaces. |
| |
| 7. Observability & Mandatory PII Masking |
| Every client request, downstream execution, and admin modification is logged to audit tables |
| after passing through regex-based PII sanitization. |
+---------------------------------------------------------------------------------------------------+
2. High-Level System Architecture & Context¶
Client Ecosystem & Ingress¶
Model Context Gateway (MCG) supports:
- Cursor IDE: Connects over Server-Sent Events (
/sse) or target proxy routes (/{serverId}) using MCP extension settings. - Claude Desktop: Configured via
claude_desktop_config.jsonconnecting to SSE or local CLI bridges. - Antigravity CLI: Agentic coding assistant connecting to Meta-Mode
/ssewith automatic tool discovery and execution. - OpenClaw Agent: Dedicated autonomous agent host (
10.0.10.10) communicating over internal networks (net_cloud). - VS Code / Cline / Roo Code / Continue.dev: IDE extensions leveraging standard MCP SSE protocols.
- Custom SDKs & Scripts: Python (
mcplibrary), TypeScript/Node.js, cURL, LangChain, and AutoGen clients communicating over HTTP POST or SSE.
7-Layer Gateway Architecture¶
The router architecture is partitioned into seven layers:
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â LAYER 1: INGRESS & EDGE SECURITY â
â Reverse Proxy (Caddy/Nginx) âââš McpSpecMiddleware âââš McpAuthorizationSpecMiddleware â
ââââââââââââââââââââââââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââââââ
â
ââââââââââââââââââââââââââââââââââââââââââââââââââžâââââââââââââââââââââââââââââââââââââââââââââââââ
â LAYER 2: AUTHENTICATION & IDENTITY MAPPING â
â CompositeIdentityProvider âââš ActiveDirectory (LDAP SIDs) âââš OIDC Headers âââš AppKey Auth â
ââââââââââââââââââââââââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââââââ
â
ââââââââââââââââââââââââââââââââââââââââââââââââââžâââââââââââââââââââââââââââââââââââââââââââââââââ
â LAYER 3: PROTOCOL, SESSION & MULTIPLEXING ENGINE â
â ProxyEndpoints âââš SessionManager âââš ClientSession âââš JsonRpcStateManager & ID Rewriter â
ââââââââââââââââââââââââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââââââ
â
ââââââââââââââââââââââââââââââââââââââââââââââââââžâââââââââââââââââââââââââââââââââââââââââââââââââ
â LAYER 4: SEMANTIC INTELLIGENCE & META-MODE â
â DynamicEmbeddingService âââš OnnxEmbeddingService (all-MiniLM-L6-v2) âââš SemanticSearchServiceâ
ââââââââââââââââââââââââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââââââ
â
ââââââââââââââââââââââââââââââââââââââââââââââââââžâââââââââââââââââââââââââââââââââââââââââââââââââ
â LAYER 5: AUTHORIZATION & RBAC DECISION ENGINE â
â AppKey Scope Filter âââš Admin SID Bypass âââš Database RBAC (sp_EvaluateUserAccess) â
ââââââââââââââââââââââââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââââââ
â
ââââââââââââââââââââââââââââââââââââââââââââââââââžâââââââââââââââââââââââââââââââââââââââââââââââââ
â LAYER 6: PERSISTENCE & SECRET RESOLUTION â
â DbConnectionFactory (SQLite/MSSQL/MySQL) âââš CompositeSecretRetriever âââš AES-256-GCM Crypto â
ââââââââââââââââââââââââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââââââ
â
ââââââââââââââââââââââââââââââââââââââââââââââââââžâââââââââââââââââââââââââââââââââââââââââââââââââ
â LAYER 7: DOWNSTREAM MCP SERVER FLEET & TRANSPORTS â
â SseTransport (Duplex) âââš HttpTransport (Stateless) âââš StdioTransport (Subprocess NDJSON) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
System Context & Architecture Diagram¶
graph TD
subgraph Clients ["Client Ecosystem"]
Cursor["Cursor IDE"]
Claude["Claude Desktop"]
Antigravity["Antigravity CLI"]
OpenClaw["OpenClaw Agent (10.0.10.10)"]
VSCode["VS Code / Cline"]
CustomSDK["Custom HTTP/SSE Clients"]
end
subgraph Edge ["Layer 1: Ingress & Edge Security"]
Proxy["Reverse Proxy (Caddy / TinyAuth)"]
DualSpec["McpSpecMiddleware<br>(2026-07-28 Spec & Legacy Body Fallback)"]
AuthSpec["McpAuthorizationSpecMiddleware<br>(WWW-Authenticate Challenges)"]
end
subgraph AuthLayer ["Layer 2: Identity & Authentication"]
CompositeId["CompositeIdentityProvider"]
AD["ActiveDirectoryIdentityProvider<br>(LDAP Windows SIDs)"]
OIDC["OidcIdentityProvider<br>(Remote-User / Remote-Groups)"]
AppKeyAuth["AppKeyIdentityProvider<br>(KeyPrefix Index & SHA-256)"]
end
subgraph CoreEngine ["Layer 3 & 4: Protocol, Routing & Semantic Intelligence"]
ProxyEp["ProxyEndpoints<br>(/sse, /message, /{serverId})"]
SessionMgr["SessionManager"]
CSession["ClientSession (Partial Classes)"]
StateManager["JsonRpcStateManager<br>(Out-of-Order Demux & ID Rewriter)"]
SemanticEngine["DynamicEmbeddingService & SemanticSearchService<br>(Local ONNX & API Embeddings)"]
ToolRouting["ToolRoutingManager"]
end
subgraph SecurityRbac ["Layer 5: Authorization & Governance"]
SecHelper["SecurityValidationHelper<br>(Admin SIDs S-1-5-32-544 / CIDR Checks)"]
RbacProc["sp_EvaluateUserAccess<br>(GroupMappings & AccessPolicies)"]
AuditSvc["AuditLogger & PiiSanitizer<br>(sp_InsertAuditLog)"]
end
subgraph PersistenceLayer ["Layer 6: Persistence & Secret Resolution"]
DbFactory["DbConnectionFactory<br>(SQLite WAL / MS SQL / MySQL)"]
SecretComp["CompositeSecretRetriever<br>(5m In-Memory Sliding Cache)"]
VaultRetriever["VaultSecretRetriever (KV v2)"]
RegRetriever["WindowsRegistrySecretRetriever (DPAPI)"]
EnvRetriever["EnvironmentSecretRetriever"]
CryptoHelper["SymmetricEncryptionHelper<br>(AES-256-GCM Envelope Encryption)"]
end
subgraph Fleet ["Layer 7: Downstream MCP Server Fleet"]
SSETarget["SseTransport<br>(Docker Containers, Remote MCP)"]
HttpTarget["HttpTransport<br>(Serverless APIs, Webhooks)"]
StdioTarget["StdioTransport<br>(Local CLI Tools, uvx, npx)"]
NativeTools["Native In-Process Tools<br>(Plex, Overseerr, Custom)"]
end
Clients -->|HTTP / SSE / Bearer Key| Proxy
Proxy --> DualSpec
DualSpec --> AuthSpec
AuthSpec --> CompositeId
CompositeId --> AD
CompositeId --> OIDC
CompositeId --> AppKeyAuth
AuthSpec --> ProxyEp
ProxyEp --> SessionMgr
SessionMgr --> CSession
CSession --> StateManager
CSession --> SemanticEngine
CSession --> ToolRouting
CSession --> SecHelper
SecHelper --> RbacProc
RbacProc --> DbFactory
CSession --> AuditSvc
AuditSvc --> DbFactory
CSession --> SecretComp
SecretComp --> VaultRetriever
SecretComp --> RegRetriever
SecretComp --> EnvRetriever
SecretComp --> CryptoHelper
CSession --> SSETarget
CSession --> HttpTarget
CSession --> StdioTarget
CSession --> NativeTools
3. Backend Component & Boundary Model¶
The C# codebase is partitioned into three bounded contexts: Components/, Infrastructure/, and Core/.
âââ Components/
â âââ Servers/ # Upstream server registry, validation, health checks, discovery & MapServerEndpoints
â âââ Clients/ # Registered clients, credential service, OAuth endpoints & MapClientEndpoints
â âââ AppKeys/ # AppKey models, authorization keys, hashing, scope checks & MapAppKeyEndpoints
â âââ Providers/ # Auth/Secret provider settings, envelope crypto & MapProviderEndpoints
â âââ Authorization/ # Access policies, group mappings, RBAC evaluation & MapPolicyEndpoints
â âââ Capabilities/ # Native tools, virtual proxy execution, tool/prompt/resource handlers & MapCapabilityEndpoints
âââ Infrastructure/
â âââ Persistence/ # Dapper repositories, database connection factory, migrations & seeders
â âââ Transports/ # SSE, HTTP, STDIO, state manager & target proxy
â âââ Identity/ # Active Directory, OIDC, AppKey identity providers & LDAP service
â âââ Secrets/ # Vault, Windows Registry, Environment secret retrievers & encryption
â âââ Logging/ # Audit logger, PII sanitization & in-memory log providers
âââ Core/
âââ Protocol/ # JSON-RPC 2.0 protocol models & polymorphic converter
âââ Routing/ # ClientSession, SessionManager, BackendConnection & Semantic Search
Domain Components (Components/)¶
Servers:McpServer.cs: Data model representing upstream MCP servers, endpoints, transport types, categories, headers, and secret associations.ServerEndpoints.cs: Minimal API mapping for CRUD operations, inspections, and health states (GET /api/servers,POST /api/servers,DELETE /api/servers/{id}).ServerValidationHelper.cs: URL syntax checking, SSRF prevention, and parameter sanitization.DockerAutoDiscoveryService.cs: Dynamic label-based container discovery (mcp.enable=true,mcp.name,mcp.port).-
BackendHealthCheckService.cs: Background periodic health prober (15s HTTP GET + 30s JSON-RPC ping). -
Clients: ClientEndpoints.cs&ClientsController.cs: Client registration and OAuth client management.-
CredentialService.cs: Automated client configuration generation (claude_desktop_config.json, Cursor config, environment templates). -
AppKeys: AppKey.cs&AppKeyModels.cs: High-entropy machine keys (mcp-*-*-*), key prefixes (KeyPrefix), AES-256-GCM encrypted keys, scopes (ScopesJson), and attribution (OwnerSid).-
AppKeyEndpoints.cs&AppKeysController.cs: Endpoints for key minting, revocation, prefix lookups, and validation. -
Providers: ProviderEndpoints.cs&ProvidersController.cs: Management of Identity and Secret Provider configurations.-
ProviderConfigSecurityHelper.cs: Transparent encryption/decryption of provider JSON configuration payloads. -
Authorization: PolicyEndpoints.cs&PermissionsController.cs: Endpoints for RBAC policies and group mappings.-
SecurityValidationHelper.cs: CIDR subnet evaluation, private IP blocking, SSRF prevention, and Administrator SID verification (S-1-5-32-544). -
Capabilities: ProxyEndpoints.cs: Core HTTP/SSE entrypoints (/sse,/message,/{targetServerId}).CapabilityEndpoints.cs: Tool, prompt, resource, and custom file catalog management.CustomToolRegistry.cs: In-process native tools for Plex (PlexGetLibrarySectionsTool,PlexSearchLibraryTool,PlexGetSessionsTool, etc.) and Overseerr (SeerrSearchMediaTool,SeerrRequestMediaTool,SeerrGetRequestsTool, etc.).
Infrastructure Services (Infrastructure/)¶
Persistence:DbConnectionFactory.cs: Multi-database factory supporting SQLite (WAL), MS SQL Server (Microsoft.Data.SqlClient), and MySQL (MySqlConnector).Repositories.cs: High-performance Dapper repository layer.-
DatabaseSeederService.cs: Automatic in-process migrations, schema compatibility validation, and default configuration seeding. -
Transports: ITransport.cs: Unified abstraction for downstream transport channels.SseTransport.cs: Full-duplex persistent Server-Sent Events channel with POST message forwarding.HttpTransport.cs: Stateless half-duplex HTTP POST and chunked streaming transport.StdioTransport.cs: Subprocess STDIO transport communicating via newline-delimited JSON-RPC (NDJSON).-
JsonRpcStateManager.cs: Manages pending request completion sources (PendingRequestTcs), ID rewriting, cancellation tokens, and connection resets. -
Identity: CompositeIdentityProvider.cs: Aggregates Active Directory, OIDC, and AppKey authenticators.ActiveDirectoryIdentityProvider.cs&LdapActiveDirectoryService.cs: Resolves Windows Kerberos/NTLM caller SIDs via LDAP.-
OidcIdentityProvider.cs: Extracts authenticated user contexts from reverse-proxy headers (Remote-User,Remote-Groups,Remote-User-Sid). -
Secrets: CompositeSecretRetriever.cs: Dispatches to Vault, Windows Registry, or Environment retrievers with a 5-minute sliding in-memory cache.VaultSecretRetriever.cs: Fetches secrets from HashiCorp Vault KV v2 using AppRole or Token authentication.WindowsRegistrySecretRetriever.cs: Fetches Windows DPAPI-protected registry keys (HKLM/HKCU).EnvironmentSecretRetriever.cs: Reads container environment variables.-
SymmetricEncryptionHelper.cs: AES-256-GCM envelope encryption for database fields and config payloads. -
Logging: AuditLogger.cs: Writes structured invocation and admin audit trails.PiiSanitizer.cs: Regex sanitizer stripping Bearer tokens, API keys, passwords, and connection strings.InMemoryLogger.cs: Thread-safe ring buffer powering the real-time Test Bench UI console.
Core Protocol & Routing Engine (Core/)¶
ClientSession(Partial Class Architecture):ClientSession.cs: Main session lifecycle coordinator.ClientSession.Authorization.cs: Multi-stage RBAC authorization, caller identity resolution, and audit logging.ClientSession.BackendInitializer.cs: Asynchronous concurrent warming of downstream backend connections and tool schemas.ClientSession.ProxyForwarder.cs: Dispatches requests to downstream servers, tracks upstream GUIDs, and demultiplexes responses.ClientSession.JsonRpcRewriter.cs: UsesSystem.Text.Json.Nodes.JsonNodeto un-namespace tool names and rewrite message bodies safely without fragile string manipulation.-
ClientSession.NotificationBroadcaster.cs: Fan-out broadcasting of notifications across active client channels. -
Routing Coordinators: SessionManager.cs: Thread-safe tracking and cleanup of active client connections.BackendConnection.cs: Manages a single upstream server connection channel, health state, and cached capabilities.SemanticSearchService.cs: Hybrid BM25 keyword matching combined with cosine similarity vector scoring.DynamicEmbeddingService.cs,OnnxEmbeddingService.cs, andApiEmbeddingService.cs: Vector embedding calculation via local CPU ONNX runtime (all-MiniLM-L6-v2) or remote OpenAI-compatible APIs.ToolRoutingManager.cs,ResourceRoutingManager.cs,PromptRoutingManager.cs: Namespacing, un-namespacing, and routing of individual MCP capabilities.
Architectural Dependency Rules¶
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â ARCHITECTURAL BOUNDARY CONSTRAINTS â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââĪ
â 1. Core NEVER depends on specific database drivers or concrete transports. â
â Core interacts strictly through `IDbConnectionFactory`, `ITransport`, â
â and `ISecretRetriever`. â
â â
â 2. Infrastructure implements strategy interfaces defined in Core and DI. â
â All database dialects (SQLite, MSSQL, MySQL) adhere to common contracts.â
â â
â 3. Components expose Minimal API endpoints and controllers that consume â
â Core session managers, repositories, and security helpers. â
â â
â 4. No Raw String JSON Manipulation: All JSON-RPC modifications MUST use â
â `JsonNode`, `JsonObject`, or `JsonDocument` DOM trees. â
â â
â 5. Thread-Safe State: Shared state MUST use `ConcurrentDictionary` or â
â explicit monitor locks. Single-execution locks guard initialization. â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Component Subsystem Diagram¶
classDiagram
class ProxyEndpoints {
+MapProxyEndpoints()
}
class ServerEndpoints {
+MapServerEndpoints()
}
class AppKeyEndpoints {
+MapAppKeyEndpoints()
}
class PolicyEndpoints {
+MapPolicyEndpoints()
}
class CapabilityEndpoints {
+MapCapabilityEndpoints()
}
class SessionManager {
+CreateSessionAsync()
+GetSession()
+CloseSession()
}
class ClientSession {
<<partial>>
+ResolveUserIdentityAsync()
+IsUserAuthorizedAsync()
+CallToolAsync()
+ListToolsAsync()
+StartInitialization()
}
class BackendConnection {
+InitializeAsync()
+SendRequestAsync()
+CachedTools
}
class JsonRpcStateManager {
+CreateTrackedRequest()
+TryCompleteRequest()
+MarkDisconnected()
}
class ITransport {
<<interface>>
+InitializeAsync()
+SendRequestAsync()
+CloseAsync()
+IsHealthyAsync()
}
class SseTransport
class HttpTransport
class StdioTransport
ITransport <|.. SseTransport
ITransport <|.. HttpTransport
ITransport <|.. StdioTransport
class IDbConnectionFactory {
<<interface>>
+CreateConnection()
+ProviderName
}
class DbConnectionFactory
IDbConnectionFactory <|.. DbConnectionFactory
class ISecretRetriever {
<<interface>>
+GetSecretAsync()
}
class CompositeSecretRetriever
class VaultSecretRetriever
class WindowsRegistrySecretRetriever
class EnvironmentSecretRetriever
ISecretRetriever <|.. CompositeSecretRetriever
ISecretRetriever <|.. VaultSecretRetriever
ISecretRetriever <|.. WindowsRegistrySecretRetriever
ISecretRetriever <|.. EnvironmentSecretRetriever
class IEmbeddingService {
<<interface>>
+GenerateEmbeddingAsync()
}
class OnnxEmbeddingService
class ApiEmbeddingService
IEmbeddingService <|.. OnnxEmbeddingService
IEmbeddingService <|.. ApiEmbeddingService
ProxyEndpoints --> SessionManager
SessionManager --> ClientSession
ClientSession --> BackendConnection
BackendConnection --> ITransport
BackendConnection --> JsonRpcStateManager
ClientSession --> IEmbeddingService
ClientSession --> IDbConnectionFactory
ClientSession --> ISecretRetriever
4. Frontend Component & Typed Architecture¶
React 19 & Vite SPA Architecture¶
The web dashboard uses React 19, TypeScript, Vite, and Zustand. It features a dark-mode interface styled with CSS variables (variables.css, layout.css, dashboard.css, tester.css).
Domain Component Decomposition¶
frontend/src/
âââ api/ # Typed API Client Layer (Axios / Fetch Wrappers)
â âââ api.ts # Base API instance, headers & error handling
â âââ serverApi.ts # Server CRUD & discovery endpoints
â âââ clientApi.ts # Registered OAuth clients
â âââ appKeyApi.ts # AppKey minting, revocation & verification
â âââ securityApi.ts # Policies & group mappings
â âââ settingsApi.ts # Provider configs & system settings
â âââ userApi.ts # Authenticated user identity & version info
â âââ testbenchApi.ts # Tool execution, search simulation & log streaming
âââ components/ # Domain UI Component Trees
â âââ servers/ # DashboardView, ServerModal, ServerInspectModal, ServerCard
â âââ clients/ # RegisteredClientsCard, ClientSetupGuide, AppKeysCard, ClientModal
â âââ security/ # SecurityView, PolicyModal, MappingModal
â âââ settings/ # SettingsView, GeneralTab, IdentityAuthTab, SecretProvidersTab,
â â # AccessControlTab, CustomFilesTab, BackupsTab
â âââ testbench/ # TestBenchView (Interactive JSON Schema Form Builder, Console, & Log Stream)
â âââ shared/ # Header, Footer, Toasts, Modal, StatusBadge, PaginationToolbar
âââ stores/ # Centralized Zustand Reactive Stores
â âââ useServerStore.ts # Servers list, health states, filter queries
â âââ useClientStore.ts # Registered clients & setup guides
â âââ useAppKeyStore.ts # Active keys, key creation modal, copy buffer
â âââ useSettingsStore.ts # Provider configs, dynamic encryption flags
â âââ useUserStore.ts # Current user, roles, SIDs, version cache
â âââ useLogStore.ts # Real-time logs ring buffer & level filters
â âââ useToastStore.ts # Notification toast queue with auto-dismiss
âââ types/ # Canonical TypeScript Domain Interfaces
âââ server.ts, client.ts, appKey.ts, security.ts, settings.ts, user.ts, testbench.ts
Typed API Layer & Zustand State Stores¶
The frontend decouples UI rendering, API communication, and state management:
* useServerStore: Manages server inventory, search/category filtering, inspect modal state, and health check refresh intervals.
* useAppKeyStore: Handles key creation, reveals the raw secret once upon creation, and manages scope assignments.
* useSettingsStore: Coordinates secret and identity provider forms, toggles password masking, and encrypts configuration payloads.
* useLogStore: Receives streaming logs into an in-memory ring buffer for live filtering in the Test Bench.
Frontend Architecture & State Flow Diagram¶
graph TD
subgraph UIViews ["React 19 Views & Modals"]
App["App Root & Layout"]
Nav["Navigation Tabs (Overview, Security, TestBench, Settings)"]
DashView["DashboardView<br>(ServerCards, ServerControlsToolbar, StatsCard)"]
SecView["SecurityView<br>(RegisteredClientsCard, AppKeysCard, MappingModal, PolicyModal)"]
BenchView["TestBenchView<br>(SchemaFormBuilder, SearchSimulator, LogConsole)"]
SetView["SettingsView<br>(General, IdentityAuth, SecretProviders, AccessControl, CustomFiles, Backups)"]
end
subgraph Stores ["Zustand Reactive Stores"]
ServerStore["useServerStore"]
ClientStore["useClientStore"]
AppKeyStore["useAppKeyStore"]
SettingsStore["useSettingsStore"]
UserStore["useUserStore"]
LogStore["useLogStore"]
ToastStore["useToastStore"]
end
subgraph ApiLayer ["Typed API Client Layer"]
ServerApi["serverApi.ts"]
ClientApi["clientApi.ts"]
AppKeyApi["appKeyApi.ts"]
SecurityApi["securityApi.ts"]
SettingsApi["settingsApi.ts"]
UserApi["userApi.ts"]
TestBenchApi["testbenchApi.ts"]
end
subgraph BackendAPI ["Backend ASP.NET Core Minimal APIs"]
ApiServers["/api/servers"]
ApiClients["/api/clients"]
ApiKeys["/api/appkeys"]
ApiSecurity["/api/security/policies & mappings"]
ApiSettings["/api/settings & /api/providers"]
ApiUser["/api/user/me & /api/version"]
ApiLogs["/api/logs & /api/tester/call"]
end
App --> Nav
Nav --> DashView
Nav --> SecView
Nav --> BenchView
Nav --> SetView
DashView --> ServerStore
SecView --> ClientStore
SecView --> AppKeyStore
BenchView --> LogStore
SetView --> SettingsStore
App --> UserStore
App --> ToastStore
ServerStore --> ServerApi
ClientStore --> ClientApi
AppKeyStore --> AppKeyApi
SettingsStore --> SettingsApi
SettingsStore --> SecurityApi
UserStore --> UserApi
LogStore --> TestBenchApi
ServerApi --> ApiServers
ClientApi --> ApiClients
AppKeyApi --> ApiKeys
SecurityApi --> ApiSecurity
SettingsApi --> ApiSettings
UserApi --> ApiUser
TestBenchApi --> ApiLogs
5. Protocol & Routing Engine Deep-Dive¶
Meta-Mode Dynamic Capability Hiding (/sse & /message)¶
Exposing all tool definitions during the tools/list handshake overwhelms LLM context windows.
Meta-Mode Architecture:
1. Bootstrap Initialization: When a client connects to /sse with Meta-Mode enabled (the default), the router returns only two native gateway bootstrap tools:
- search_tools: Accepts a natural language query (e.g. "restart plex container") and returns relevant ranked tools.
- execute_tool: Executes a namespaced tool ({serverId}__{toolName}) with dynamic parameter forwarding.
2. Background Cache Pre-Warming: In the background, ClientSession.BackendInitializer.cs concurrently initializes all enabled downstream transports and caches their tool, prompt, and resource schemas.
3. Semantic Scoring & Ranking: When search_tools is called:
- The query is vectorized using DynamicEmbeddingService (local ONNX all-MiniLM-L6-v2 or remote API).
- SemanticSearchService scores cached tools using a hybrid formula: Score = (0.4 * KeywordScore) + (0.6 * VectorCosineSimilarity).
- Results are namespaced as {serverId}__{toolName} and returned to the client.
4. Execution Dispatch: When execute_tool is invoked:
- The router un-namespaces the tool name to identify the target server.
- Security policies and AppKey scopes are verified.
- Secrets are resolved and injected.
- The call is dispatched to the upstream transport, and the result is returned to the client.
Target-Specific Virtual Proxying (/{targetServerId})¶
For clients requiring direct interaction with a specific backend:
* The client connects to /{targetServerId}.
* The gateway validates AppKey scopes (server:{targetServerId}, category:{cat}, or *).
* Capabilities are proxied directly without Meta-Mode filtering; tool names remain un-namespaced.
JSON-RPC 2.0 In-Flight Multiplexing & ID Preservation¶
The router multiplexes client requests across backend connections while ensuring response isolation:
- Polymorphic Serialization:
JsonRpcMessageConverter.cshandles bidirectional serialization ofJsonRpcRequest,JsonRpcResponse,JsonRpcNotification, andJsonRpcError. - Client ID Preservation: The client's original ID (whether an integer
1, string"req-123", or GUID) is captured inPendingRequestTcs. - GUID Upstream Rewriting: To prevent ID collisions when multiple clients send requests with
id: 1to the same backend connection, the router rewrites the upstream request ID to a unique GUID (upstreamRequestId = Guid.NewGuid().ToString("N")). - Out-of-Order Response Demultiplexing: When the upstream backend responds,
JsonRpcStateManagermatches the GUID, restores the client's original ID onto the response object (response.Id = tracked.OriginalId), and fulfills the waitingTaskCompletionSource.
Sequence Diagram: Stateful SSE Session Lifecycle¶
sequenceDiagram
autonumber
actor Client as MCP Client (IDE / Agent)
participant Edge as McpSpecMiddleware
participant Proxy as ProxyEndpoints (/sse, /message)
participant SessionMgr as SessionManager
participant Session as ClientSession
participant Search as SemanticSearchService
participant StateMgr as JsonRpcStateManager
participant Upstream as Downstream MCP Server
Note over Client,Upstream: 1. Session Handshake & Connection Warming
Client->>Edge: GET /sse (Authorization: Bearer mcp-appkey-123)
Edge->>Edge: Validate Token & Resolve IdentityContext
Edge->>Proxy: Forward authorized request
Proxy->>SessionMgr: CreateSessionAsync(sessionId, responseStream)
SessionMgr->>Session: Instantiate ClientSession
Session-->>Proxy: Session Created (Guid: "sess-abc")
Proxy-->>Client: HTTP 200 OK (text/event-stream)<br>event: endpoint\ndata: /message?sessionId=sess-abc
par Async Background Warming
Session->>Upstream: InitializeAsync() & tools/list
Upstream-->>Session: Cached Tools & Capabilities
end
Note over Client,Upstream: 2. Capability Discovery (Meta-Mode)
Client->>Proxy: POST /message?sessionId=sess-abc (tools/list)
Proxy->>Session: ListToolsAsync()
Session-->>Proxy: Return Bootstrap Tools (search_tools, execute_tool)
Proxy-->>Client: HTTP 200 (tools: [search_tools, execute_tool])
Note over Client,Upstream: 3. Semantic Tool Search
Client->>Proxy: POST /message?sessionId=sess-abc (tools/call: search_tools, query="restart plex")
Proxy->>Session: CallToolAsync("search_tools")
Session->>Search: SearchToolsAsync("restart plex")
Search->>Search: Hybrid BM25 + ONNX Vector Ranking
Search-->>Session: Matches: ["plex__restart_server"]
Session-->>Client: HTTP 200 (tools: [plex__restart_server])
Note over Client,Upstream: 4. Tool Execution & Multiplexed Forwarding
Client->>Proxy: POST /message?sessionId=sess-abc (tools/call: execute_tool, name="plex__restart_server", id=1)
Proxy->>Session: CallToolAsync("execute_tool")
Session->>Session: Verify AppKey Scopes & RBAC (sp_EvaluateUserAccess)
Session->>Session: Un-namespace: Server="plex", Tool="restart_server"
Session->>StateMgr: CreateTrackedRequest(upstreamGuid="up-999", originalId=1)
Session->>Upstream: POST /message (tools/call: restart_server, id="up-999")
Upstream-->>Session: JSON-RPC Response (id="up-999", result={status: "restarted"})
Session->>StateMgr: TryCompleteRequest("up-999", response)
StateMgr->>StateMgr: Restore Original ID (id=1)
Session-->>Proxy: Tool Execution Result
Proxy-->>Client: HTTP 200 (id=1, result={content: [{type: "text", text: "Success"}]})
Note over Client,Upstream: 5. Session Termination
Client->>Proxy: Disconnect / Abort Connection
Proxy->>SessionMgr: CloseSession("sess-abc")
SessionMgr->>Session: DisposeAsync()
Session->>Upstream: CloseAsync() & Cleanup Transports
Sequence Diagram: Stateless HTTP Stream Execution¶
sequenceDiagram
autonumber
actor Client as Single-Shot Client / Webhook
participant Edge as McpSpecMiddleware
participant Proxy as ProxyEndpoints (/sse POST or /{serverId})
participant SessionMgr as SessionManager
participant Session as ClientSession (Global Stateless)
participant Rbac as RBAC & Security Validation
participant Secrets as CompositeSecretRetriever
participant Upstream as Target Backend Server
Client->>Edge: POST /sse (tools/call: docker__list_containers, id="stateless-1")
Edge->>Edge: Annotate Metadata (Mcp-Method: tools/call, Mcp-Name: docker__list_containers)
Edge->>Proxy: Forward Single-Shot POST Request
Proxy->>SessionMgr: GetSession("global-stateless-session")
SessionMgr-->>Proxy: Return Global Stateless ClientSession
Proxy->>Session: CallToolAsync("docker__list_containers")
Session->>Rbac: IsUserAuthorizedAsync("tools/call", "docker__list_containers")
Rbac-->>Session: Authorized (200 OK)
Session->>Secrets: GetSecretForProviderAsync("Vault", "secret/docker", "api_key")
Secrets-->>Session: Injected Bearer Token
Session->>Upstream: POST /message (tools/call: list_containers, id="guid-777")
Upstream-->>Session: HTTP 200 OK (id="guid-777", result={containers: [...]})
Session->>Session: Restore Original ID ("stateless-1")
Session-->>Proxy: Execution Output
Proxy-->>Client: HTTP 200 OK (application/json, id="stateless-1", result={...})
6. Authorization Pipeline & RBAC Decision Engine¶
4-Stage Hierarchical Decision Flow¶
Requests pass through four security stages:
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â STAGE 1: APPKEY SCOPE BOUNDARY (Fast-Path Key Filtering) â
â Does the caller's AppKey allow the requested target? â
â Grammar: `*`, `all`, `server:{id}`, `category:{cat}`, `tool:{id}`, â
â `prompt:{id}`, `resource:{id}` â
ââââââââââââââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââ
â Pass
ââââââââââââââââââââââââââââââââââââââââžâââââââââââââââââââââââââââââââââââââââ
â STAGE 2: IDENTITY RESOLUTION & GROUP MAPPING â
â Resolve caller username, Active Directory SIDs, and OIDC headers. â
â Translate external SIDs / groups to internal roles via `GroupMappings`. â
ââââââââââââââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââ
â
ââââââââââââââââââââââââââââââââââââââââžâââââââââââââââââââââââââââââââââââââââ
â STAGE 3: ADMINISTRATOR SID BYPASS CHECK â
â Does the caller possess the Admin SID (`S-1-5-32-544` / `full_admin`)? â
ââââââââââââââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââ
â No â Yes (Admin Bypass)
ââââââââââââââââââââžââââââââââââââââââââ âââââââââââžââââââââââââââââââââ
â STAGE 4: DATABASE-BACKED RBAC â â AUTHORIZED (200 OK) â
â - Explicit Deny overrides Allow â â Invocation Audit Logged â
â - Category & Server inheritance â âââââââââââââââââââââââââââââââ
â - Fail-Closed Default (DENY) â
ââââââââââââââââââââŽââââââââââââââââââââ
â Allowed
ââââââââââââââââââââžââââââââââââââââââââ
â AUTHORIZED (200 OK) â
â Invocation Audit Logged â
ââââââââââââââââââââââââââââââââââââââââ
Scope Grammar & Resolution¶
AppKeys support granular least-privilege scoping:
| Scope Pattern | Matches / Grants Access To |
|---|---|
* or all or mcp_client |
Full access to all servers, tools, prompts, and resources. |
server:{serverId} |
Full access to all tools, prompts, and resources under the specified server. |
category:{categoryName} |
Access to all servers tagged with the specified category (e.g. category:Media, category:Smarthome). |
tool:{toolName} |
Access to a specific un-namespaced or namespaced tool. |
prompt:{promptName} |
Access to a specific prompt template. |
resource:{uri} |
Access to a specific resource URI or wildcard pattern (mcp://docker/*). |
Admin SID Bypass & Database-Backed RBAC Evaluation¶
- Administrator SID Verification:
SecurityValidationHelper.IsAdminverifies whether the resolved caller principal contains the well-known Windows Built-in Administrators SID (S-1-5-32-544), thefull_admingroup role, or any SID configured inAdmin:GroupSid. Admin principals bypass database RBAC policy checks while their actions remain fully audited. - Database Stored Procedure Evaluation (
sp_EvaluateUserAccess): - For non-admin principals, the gateway executes
sp_EvaluateUserAccessacross MS SQL Server / MySQL, or direct parameterized queries on SQLite. - Explicit Deny Rule: If any policy matching the user's groups has
IsAllowed = 0, access is immediately denied. - Explicit Allow Rule: Access is permitted only if at least one matching policy has
IsAllowed = 1. - Fail-Closed Default: If no matching policies exist, or if a database failure occurs, access is denied (
403 Forbidden).
Mermaid Authorization Decision Flowchart¶
flowchart TD
Start(["Incoming MCP Request"]) --> ExtractAuth["Extract Authorization Headers / AppKey"]
ExtractAuth --> CheckAppKey{"Is AppKey Used?"}
CheckAppKey -- Yes --> ValidateScopes{"Check AppKey Scopes<br>(*, server:*, category:*, tool:*)"}
ValidateScopes -- Scope Violated --> DenyScope["403 Forbidden (Scope Violation)"]
ValidateScopes -- Scope Valid --> ResolveId["Resolve UserIdentityContext<br>(Username, SIDs, OIDC Groups)"]
CheckAppKey -- No --> ResolveId
ResolveId --> MapGroups["Query GroupMappings<br>(Translate External SIDs -> Internal Groups)"]
MapGroups --> CheckAdmin{"Is Caller Administrator?<br>(SID S-1-5-32-544 or full_admin)"}
CheckAdmin -- Yes (Admin Bypass) --> AuditAndAllow["Log Invocation Audit<br>(sp_InsertAuditLog)"] --> Allow(["200 OK / Route Execution"])
CheckAdmin -- No --> EvaluateRbac{"Evaluate DB Policies<br>(sp_EvaluateUserAccess)"}
EvaluateRbac -- "Explicit Deny (IsAllowed = 0)" --> DenyPolicy["403 Forbidden (Explicit Deny)"]
EvaluateRbac -- "No Matching Policies" --> DenyFailClosed["403 Forbidden (Fail-Closed Default)"]
EvaluateRbac -- "Explicit Allow (IsAllowed = 1)" --> AuditAndAllow
7. Transport Subsystem & Subprocess Lifecycle¶
Strategy Pattern (ITransport)¶
All downstream transports implement ITransport:
public interface ITransport : IAsyncDisposable
{
string TransportType { get; }
bool IsConnected { get; }
Task InitializeAsync(McpServer server, CancellationToken cancellationToken = default);
Task<JsonRpcResponse> SendRequestAsync(JsonRpcRequest request, CancellationToken cancellationToken = default);
Task SendNotificationAsync(JsonRpcNotification notification, CancellationToken cancellationToken = default);
Task CloseAsync(CancellationToken cancellationToken = default);
Task<bool> IsHealthyAsync(CancellationToken cancellationToken = default);
}
Subprocess STDIO Architecture & Security Hardening¶
The StdioTransport manages local executables, CLI tools, Python scripts (uvx), and Node packages (npx):
- Command Line Tokenization:
StdioTransport.ParseCommandLineparses single/double quoted paths and arguments cleanly into an executable and argument array. - Strict Process Security Policy:
UseShellExecute = falseandCreateNoWindow = true.- Executables are invoked directly without intermediate shells (
sh,bash,cmd.exe,powershell.exe) to prevent shell injection and command chaining attacks (&&,;,|). - Zero-Leakage Credential Injection:
- Downstream secrets resolved from Vault or Environment are injected strictly via
ProcessStartInfo.Environment. - Credentials are never passed as command-line arguments, preventing exposure in process tables (
ps aux,/proc/$PID/cmdline). - Stream Synchronization & Buffer Draining:
- Requests are written to
StandardInputas newline-delimited JSON (NDJSON) guarded by asynchronous write locks. StandardOutputis read line-by-line using asynchronous loops to prevent buffer deadlocks.
Child Process Tree Lifecycle & Signal Handling¶
stateDiagram-v2
[*] --> Starting: Spawn Process (UseShellExecute=false)
Starting --> Running: Redirect stdin/stdout/stderr & Inject Env Secrets
Running --> Executing: Write NDJSON Request to stdin
Executing --> Running: Read NDJSON Response from stdout
Running --> Draining: Gateway Shutdown / Session Close
Draining --> Terminated: Close stdin (EOF) -> Process Exits Cleanly
Running --> Killing: Timeout / Request Cancellation
Killing --> Terminated: Kill(entireProcessTree: true)
Terminated --> [*]: Dispose Process & Free Pipes
- Graceful Termination: The router closes
stdin, signaling EOF to the subprocess. - Process Tree Killing: If the subprocess fails to exit within the grace period (5 seconds),
process.Kill(entireProcessTree: true)terminates the entire process hierarchy, preventing orphaned worker threads.
Stderr Log Capture & PII Token Masking¶
- A background listener continuously drains
StandardError. - Lines are passed through
PiiSanitizer.SanitizePayloadto redact tokens before writing to application loggers.
Sequence Diagram: STDIO Subprocess Execution¶
sequenceDiagram
autonumber
participant Session as ClientSession
participant Transport as StdioTransport
participant Proc as Subprocess (stdin / stdout / stderr)
participant Pii as PiiSanitizer & Logger
participant State as JsonRpcStateManager
Session->>Transport: InitializeAsync(serverConfig)
Transport->>Transport: ParseCommandLine(serverConfig.Url)
Transport->>Transport: Inject Secrets into ProcessStartInfo.Environment
Transport->>Proc: Process.Start() (Redirect Standard Streams)
par Stderr Background Drainer
loop Continuous Drain
Proc-->>Transport: Read Stderr Line
Transport->>Pii: SanitizePayload(stderrLine)
Pii-->>Transport: Redacted Log Line
Transport->>Pii: LogDebug / LogWarning
end
end
Session->>Transport: SendRequestAsync(JsonRpcRequest: tools/call, id="up-42")
Transport->>State: CreateTrackedRequest("up-42")
Transport->>Proc: Write to stdin ("{\"jsonrpc\":\"2.0\",\"id\":\"up-42\",...}\n")
Transport->>Proc: Flush stdin
Proc-->>Transport: Read line from stdout ("{\"jsonrpc\":\"2.0\",\"id\":\"up-42\",\"result\":{...}}\n")
Transport->>State: TryCompleteRequest("up-42", response)
State-->>Session: Return JsonRpcResponse
8. Database & Persistence Architecture¶
Unified Entity-Relationship Diagram (Mermaid ERD)¶
For the standalone schema reference and column constraints catalog, see Canonical Data Model & Database ERD and Database Provider Support & Deployment Matrix.
erDiagram
Servers ||--o{ Tools : "exposes (FK: ServerId)"
Servers ||--o{ AccessPolicies : "governed by (TargetId)"
Servers ||--o{ AuditLogs : "generates (ServerCodeName)"
Servers }o--o| SecretProviders : "resolves credentials (SecretProvider)"
Tools ||--o{ ToolAccessPolicies : "governed by (FK: ToolId)"
Tools ||--o{ AccessPolicies : "governed by (TargetId)"
AdGroups ||--o{ ToolAccessPolicies : "assigned to (FK: GroupId)"
AdGroups ||--o{ GroupMappings : "maps external groups (InternalGroup)"
AppKeys ||--o{ AuditLogs : "attributed via (UserSid -> OwnerSid)"
Servers {
string Id PK "Server unique identifier (e.g. docker, plex)"
string DisplayName "Human-readable server name"
string Url "Endpoint URL or command string"
boolean Enabled "Active/inactive operational state"
boolean Hidden "Hidden from client discovery list"
string Type "Transport type: sse, http, stdio"
string SecretProvider "Provider: None, HashiCorpVault, WindowsRegistry, Environment"
string SecretItemKey "Target secret key identifier"
string SecretMount "Vault secret engine mount path"
string SecretPath "Vault secret subpath or registry key"
string SecretField "Vault secret JSON field key"
string AuthShape "Authentication shape: bearer, customHeader, query"
string CustomHeaderName "Custom HTTP header name if shape=customHeader"
string Categories "JSON array of category tags"
string ApiKey "Static API key (redacted in API)"
string HeadersJson "JSON dictionary of custom HTTP headers"
boolean AutoDiscovered "Flag indicating dynamic auto-discovery"
}
Settings {
string Id PK "Global singleton configuration ID"
string EmbeddingProvider "Embedding backend: local, openai, custom"
string EmbeddingApiUrl "Embedding inference API endpoint"
string EmbeddingApiKey "Encrypted embedding API key"
string EmbeddingApiModel "Embedding model name"
string EmbeddingModelDir "Filesystem directory for local ONNX model"
string UserSecretStorage "Storage mode for user personal secrets"
int GlobalMaxKeys "Maximum total active AppKeys allowed"
int UserMaxKeys "Maximum active AppKeys allowed per user"
}
SecretProviders {
int ProviderId PK "Provider integer surrogate key"
string ProviderName UK "Unique provider identifier (e.g. HashiCorpVault)"
string DisplayName "Human-readable provider name"
string EncryptedConfigJson "AES-256-GCM encrypted provider configuration"
boolean IsEnabled "Provider enabled state"
datetime UpdatedAt "Timestamp of last modification"
}
AuthProviderConfigs {
int AuthId PK "Auth provider surrogate key"
string ProviderName UK "Unique identity provider identifier (e.g. ActiveDirectory)"
string DisplayName "Human-readable identity provider name"
string UserHeader "HTTP header for username (default: Remote-User)"
string GroupsHeader "HTTP header for user groups (default: Remote-Groups)"
string EncryptedConfigJson "AES-256-GCM encrypted provider settings"
boolean IsEnabled "Identity provider enabled state"
datetime UpdatedAt "Timestamp of last modification"
}
AdGroups {
int GroupId PK "Group integer surrogate key"
string ObjectSid UK "Active Directory Security Identifier (SID)"
string GroupName "Active Directory / Enterprise group name"
string Description "Group description and purpose"
boolean IsActive "Group active state"
datetime CreatedAt "Timestamp of creation"
}
Tools {
int ToolId PK "Tool integer surrogate key"
string ServerId FK "Foreign key referencing Servers.Id"
string ToolName "MCP tool name (e.g. list_containers)"
string Description "Tool description shown to LLMs"
string InputSchemaJson "JSON Schema defining tool arguments"
string VaultSecretPath "Optional tool-specific secret path"
string SecretProvider "Tool-specific secret provider"
boolean IsEnabled "Tool enabled state"
datetime CreatedAt "Timestamp of tool discovery"
}
ToolAccessPolicies {
int ToolPolicyId PK "Surrogate policy primary key"
int ToolId FK "Foreign key referencing Tools.ToolId"
int GroupId FK "Foreign key referencing AdGroups.GroupId"
boolean IsAllowed "Allow (1) or Explicit Deny (0)"
int RateLimitPerMin "Rate limit allocations per minute"
datetime CreatedAt "Timestamp of policy creation"
}
AccessPolicies {
string Id PK "Policy unique GUID identifier"
string TargetId "Target server ID, category, or tool identifier"
string RequiredGroup "AD group, SID, or role required for access"
boolean IsAllowed "Allow (1) or Explicit Deny (0)"
datetime CreatedAt "Timestamp of policy assignment"
}
GroupMappings {
string Id PK "Mapping unique GUID identifier"
string ExternalId "External group claim or SSO header value"
string InternalGroup "Internal mapped router role / AD group"
datetime CreatedAt "Timestamp of mapping creation"
}
AppKeys {
string Id PK "AppKey unique GUID identifier"
string Name "Friendly application/client name"
string Username "Subject username associated with key"
string KeyPrefix UK "High-entropy random key prefix"
string EncryptedKey "Argon2id / PBKDF2 hash of secret key"
string ScopesJson "JSON array of allowed scopes (*, category:*, server:*)"
datetime ExpiresAt "Optional key expiration UTC timestamp"
datetime CreatedAt "Timestamp of key creation"
string OwnerSid "Target user SID (decoupled from admin creator)"
}
AuditLogs {
bigint AuditId PK "Audit entry sequential identifier"
string RequestId "Unique client request GUID"
string UserPrincipalName "Caller username or identity"
string UserSid "Caller Active Directory SID or AppKey OwnerSid"
string ServerCodeName "Target MCP server code name"
string ItemName "Target tool, prompt, or resource URI"
string RequestMethod "MCP method: tools/call, prompts/get, etc."
int ExecutionTimeMs "Total round-trip execution latency"
int StatusCode "HTTP or JSON-RPC status code"
string RequestPayload "Masked request payload"
string ResponsePayload "Masked response payload"
string ErrorMessage "Error message if invocation failed"
datetime Timestamp "UTC timestamp of execution"
}
AdminAuditLogs {
string Id PK "Admin audit GUID identifier"
string Username "Administrator username"
string Action "Administrative action performed"
string Target "Target configuration entity"
string Details "Detailed changes or audit payload"
boolean Success "Action success status"
string ErrorMessage "Error details if action failed"
datetime Timestamp "UTC timestamp of administrative action"
}
Engine Dialect Strategies (SQLite, MS SQL Server, MySQL)¶
| Persistence Dimension | ðŠķ SQLite (Default) | ðĒ Microsoft SQL Server | ðŽ MySQL / MariaDB |
|---|---|---|---|
| Provider Key | sqlite |
mssql |
mysql |
| Concurrency Mode | WAL (Write-Ahead Logging) | Row-Level Locking / Always On | InnoDB MVCC Transactions |
| Execution Paradigm | Direct SQL & Parameterized Dapper | T-SQL Stored Procedures (sp_*) |
Stored Procedures (sp_*) |
| Upsert Syntax | ON CONFLICT(Id) DO UPDATE |
IF EXISTS ... UPDATE ELSE INSERT |
ON DUPLICATE KEY UPDATE |
| Parameter Prefix | @Param |
@Param |
Strict p_Param |
| Timestamp Generation | CURRENT_TIMESTAMP (ISO-8601) |
SYSUTCDATETIME() (DATETIME2) |
CURRENT_TIMESTAMP / NOW() |
| DDL Migrations | In-Process Automatic (DatabaseSeederService) |
Scripted DDL (scripts/db/mssql/) |
Scripted DDL (scripts/db/mysql/) |
For comprehensive schema definitions, stored procedure listings, and migrations, see Database Provider Support & Deployment Matrix.
9. Secret Provider & Envelope Encryption Pipeline¶
AES-256-GCM Envelope Encryption Specification¶
Sensitive database columns (e.g. AppKeys.EncryptedKey, SecretProviders.EncryptedConfigJson, AuthProviderConfigs.EncryptedConfigJson, Servers.ApiKey) are protected using AES-256-GCM authenticated envelope encryption via SymmetricEncryptionHelper:
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â AES-256-GCM ENVELOPE PACKET FORMAT â
âââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââŽâââââââââââââââââââââââĪ
â Nonce (IV) [12 Bytes] â Auth Tag [16 Bytes] â Ciphertext [N Bytes] â
âââââââââââââââââââââââââââââīâââââââââââââââââââââââââââīâââââââââââââââââââââââ
âââââââââââââââââââââââ Base64 Encoded for Storage âââââââââââââââââââââââââš
- Nonce Generation: A cryptographically secure 12-byte random nonce is generated for every encryption operation using
RandomNumberGenerator.GetBytes(12). - Authenticated Tagging: AesGcm computes a 16-byte authentication tag over the ciphertext, guaranteeing tamper detection and payload integrity.
- Master Key Derivation (PBKDF2):
- Derives a 256-bit key from
MCG_SECRET,MCG_MASTER_KEY, orDB_ENCRYPTION_KEY. - Uses
Rfc2898DeriveBytes.Pbkdf2with 600,000 iterations of SHA-256 and a deployment-specific salt (_McpRouter_Salt_v2).
Pluggable Retrievers & Dynamic Reload Without Restart¶
When an administrator updates a Secret Provider in the Settings UI:
1. The frontend submits the updated credentials to POST /api/providers/secret.
2. ProviderConfigSecurityHelper encrypts the payload with AES-256-GCM and persists it to the database.
3. The in-memory cache in CompositeSecretRetriever is immediately invalidated.
4. Subsequent downstream requests fetch fresh tokens from HashiCorp Vault or the updated provider without requiring a container or service restart.
Secret Resolution & Encryption Pipeline Flowchart¶
flowchart TD
Request["Downstream Invocation Required"] --> CheckProv{"Server SecretProvider Type?"}
CheckProv -- "None / Direct ApiKey" --> DecryptDirect["Decrypt Server ApiKey via AES-256-GCM"]
CheckProv -- "Vault / HashiCorp" --> CheckCache["Check MemoryCache (10m TTL)"]
CheckProv -- "WindowsRegistry" --> CheckCache
CheckProv -- "Environment" --> CheckCache
CheckCache -- "Cache Hit" --> ReturnToken["Inject Bearer / Custom Header"]
CheckCache -- "Cache Miss" --> QueryProvider{"Dispatch Provider Retriever"}
QueryProvider -- Vault --> VaultCall["VaultSecretRetriever (KV v2 AppRole)"]
QueryProvider -- WindowsRegistry --> RegCall["WindowsRegistrySecretRetriever (DPAPI)"]
QueryProvider -- Environment --> EnvCall["EnvironmentSecretRetriever (Container Env)"]
VaultCall --> CacheResult["Store in MemoryCache (Sliding Expiry)"]
RegCall --> CacheResult
EnvCall --> CacheResult
DecryptDirect --> ReturnToken
CacheResult --> ReturnToken
ReturnToken --> Forward["Forward to Downstream Transport"]
For complete setup guides, AppRole configuration commands, and DPAPI registry recipes, see Enterprise Secret Providers & Key Management Guide.
10. Cross-References, Verification & Operational Guide¶
Documentation Navigation Matrix¶
| Topic / Focus Area | Target Specification Guide |
|---|---|
| Product Overview & Problem Statement | Evaluation & Product Overview Guide |
| AppKey Scopes & Authorization Rules | AppKey Scopes & Authorization Guide |
| Database Engines, Schemas & Stored Procs | Database Provider Support & Deployment Matrix |
| Transports, Concurrency & STDIO Subprocesses | Transport Capability & Configuration Guide |
| Vault, DPAPI & AES-256-GCM Encryption | Enterprise Secret Providers & Key Management Guide |
| CI Quality Gates, Static Analysis & Testing | CI Quality Gates & Verification Guide |
| Pairwise Integration Matrix & E2E Tests | Testing Matrix & Integration Guide |
| Living Software Requirements (SRS) & Test Catalog | Software Requirements & Test Verification Catalog |
| Test Catalog Architecture & Annotation Guide | Test Catalog & Annotation Guide |
| End-User Guides & Interactive UI Manual | Official User Guide Suite |
| Developer Environment & Coding Guidelines | Developer Guide & Local Setup |
| Operations, Deployment & Disaster Recovery | Operations & Production Runbook |
| Contributor Workflow & PR Standards | Contributing Guide |
| Core Documentation & Getting Started | Project Overview & Quickstart |
Verification & Test Suite Execution¶
All architectural contracts, concurrency guarantees, and security policies are validated by the comprehensive automated test suite:
Document Version: v5.0.0 | Maintained by the Model Context Gateway Architecture Group.