Skip to Content
DocsSDKsCore Concepts

Core Concepts

The @ithena-one/mcp-governance SDK introduces several key concepts built around the base @modelcontextprotocol/sdk.

1. GovernedServer

The GovernedServer is the central orchestrator for applying governance to your MCP server.

Key Responsibilities:

  • Wraps Base Server: Acts as a layer around a standard @modelcontextprotocol/sdk Server.
  • Applies Governance: Manages the execution of the Governance Pipeline (identity, RBAC, auditing, etc.).
  • Handles Handlers: You register your MCP request/notification handlers directly with GovernedServer.
  • Manages Lifecycle: Coordinates the initialize() and shutdown() methods of configured governance components via its internal LifecycleManager.

Basic Usage:

  1. Create a base MCP Server.
  2. Instantiate GovernedServer with the base server and GovernedServerOptions (containing your logger, stores, resolvers).
  3. Register handlers (e.g., setRequestHandler) on the GovernedServer instance.
  4. Use governedServer.connect(transport) and governedServer.close() for server lifecycle.

2. Governance Pipeline

This sequence of steps is executed by GovernedServer for every incoming message.

Request Pipeline

Setup Context

A unique eventId, request-scoped Logger, TraceContext, initial OperationContext, and AuditRecord are prepared.

Resolve Identity

Uses the configured IdentityResolver to determine the caller’s UserIdentity.

🚫

Failure (throwing AuthenticationError) typically stops the pipeline.

Check RBAC (Authorization)

If enableRbac is true:

  • Requires a resolved UserIdentity.
    🚫

    Missing identity results in AuthorizationError.

  • Derives the required permission (e.g., tool:call:my_tool) using derivePermission.
  • Fetches roles via RoleStore.
  • Checks permission against roles via PermissionStore.
    🚫

    If no role grants permission, AuthorizationError is thrown.

  • Records the authorization decision.

Run Post-Authorization Hook

If configured, this async hook (postAuthorizationHook) runs after successful authorization.

Resolve Credentials

Uses the configured CredentialResolver to fetch necessary secrets/credentials for the handler.

⚠️

Failure can stop the pipeline (CredentialResolutionError) depending on the failOnCredentialResolutionError option.

Execute Governed Handler

Your registered MCP handler (tool, resource, etc.) is called with enriched GovernedRequestHandlerExtra.

Perform Auditing

Assembles the final AuditRecord, sanitizes it (sanitizeForAudit), and logs it via AuditLogStore if auditing is enabled for the outcome.

Send Response/Error

Returns the handler’s result or a mapped JSON-RPC error.

Notification Pipeline

A simpler flow for notifications:

Setup Context

Similar to requests (eventId, Logger, TraceContext, etc.).

Resolve Identity (Optional)

Mainly for logging/auditing; failure usually doesn’t stop the pipeline.

Execute Governed Handler

Runs the registered notification handler, if any.

Perform Auditing

Logs the audit record if auditNotifications is true.

Context Immutability

Design Principle: To prevent unintended side effects between pipeline steps, the OperationContext passed through the various stages is treated as immutable.

Implementation:

  • The core context object created at the beginning of each step is shallowly frozen using Object.freeze().
  • The transportContext.headers object is wrapped in a Proxy that silently ignores any attempts to modify header values.
  • Goal: Ensures governance components don’t accidentally modify context affecting subsequent steps or the handler.
  • Shallow Freezing: Object.freeze() is shallow. Nested objects within the context might still be mutable.
  • Silent Proxy: The header proxy silently ignores modifications. This enforces immutability but could hide bugs if a component wrongly tries to change headers (no error is thrown).
  • Performance: Generally negligible overhead from Object.freeze and the proxy.

It’s recommended that tests for custom governance components consider scenarios involving attempted context modifications to ensure they behave as expected within this immutability model.

(Refer to the Mermaid diagram in README.md for a visual representation)

3. OperationContext

This object carries context throughout the governance pipeline stages for a single request/notification.

Key Properties:

  • eventId: Unique ID for this specific operation.
  • timestamp: When processing started.
  • transportContext: Info about the connection (type, headers, IP).
  • traceContext: Distributed tracing IDs (traceId, spanId).
  • logger: Request-scoped logger instance.
  • mcpMessage: The raw incoming MCP message.
  • serviceIdentifier: Optional server instance ID.
  • identity: (Added later) Resolved UserIdentity.
  • derivedPermission: (Added later) Permission string for RBAC checks.
  • roles: (Added later) Roles associated with the identity.

4. GovernedRequestHandlerExtra / GovernedNotificationHandlerExtra

These objects provide the enriched context directly to your MCP handlers.

Key Properties (Request Handler):

  • eventId: Unique operation ID.
  • logger: Request-scoped logger.
  • identity: Resolved UserIdentity (or null).
  • roles: Resolved roles (if RBAC enabled, otherwise empty array).
  • resolvedCredentials: Credentials from CredentialResolver.
  • traceContext: Distributed tracing info.
  • transportContext: Transport info.
  • signal: AbortSignal from the base SDK.
  • sessionId: Session ID from the transport.

(GovernedNotificationHandlerExtra contains a subset relevant to notifications.)

5. Lifecycle Management (LifecycleManager)

This internal helper manages the initialize() and shutdown() phases of your governance components.

  • Initialization: During GovernedServer.connect(), it calls the optional initialize() method on each component sequentially. If one fails, connection aborts, and already-initialized components are shut down.
  • Shutdown: During GovernedServer.close(), it calls the optional shutdown() method on all successfully initialized components in parallel. Errors are logged but don’t stop the overall shutdown.
Last updated on