Skip to content
reaatechREAATECH

@reaatech/multi-tenant-mcp-tenant-resolver

npm v0.1.0

Extracts tenant identity from MCP requests using header, JWT, or API key resolvers and propagates the context through `AsyncLocalStorage`. It provides a set of resolver classes and a `TenantContextStore` to enable implicit tenant access in downstream handlers.

@reaatech/multi-tenant-mcp-tenant-resolver

npm version License: MIT CI

Status: Pre-1.0 — APIs may change in minor versions. Pin to a specific version in production.

Resolve tenant identity from incoming MCP requests via headers, JWTs, or API keys, and propagate it through AsyncLocalStorage.

Installation

terminal
npm install @reaatech/multi-tenant-mcp-tenant-resolver
# or
pnpm add @reaatech/multi-tenant-mcp-tenant-resolver

For JWT support, install the optional jsonwebtoken peer:

terminal
pnpm add jsonwebtoken

Feature Overview

  • Plug-&-play resolvers — Header-based, JWT, and API-key resolvers ship out of the box; implement TenantResolver for custom auth flows.
  • ALS propagationTenantContextStore wraps AsyncLocalStorage so the tenant context is available to every downstream handler without explicit parameter threading.
  • Zero-copy metadata — Resolvers can attach claims (claimsToExpose) or lookup results directly to TenantContext.metadata.

Quick Start

typescript
import {
  HeaderTenantResolver,
  JWTTenantResolver,
  APIKeyTenantResolver,
  TenantContextStore,
} from '@reaatech/multi-tenant-mcp-tenant-resolver';
 
// Simple header-based (development / internal use)
const headerResolver = new HeaderTenantResolver({ header: 'x-tenant-id' });
 
// JWT-based (production)
const jwtResolver = new JWTTenantResolver({
  claim: 'tenant_id',
  secret: process.env.JWT_SECRET!,
  claimsToExpose: ['email', 'role'],
});
 
// API-key based (database-backed)
const apiKeyResolver = new APIKeyTenantResolver({
  headerName: 'x-api-key',
  lookup: async (key) => {
    const tenant = await db.findByApiKey(key);
    if (!tenant) return null;
    return { tenantId: tenant.id, metadata: { plan: tenant.plan }, resolvedAt: new Date() };
  },
});
 
const store = new TenantContextStore();
const ctx = jwtResolver.resolve({ headers: { authorization: 'Bearer <token>' } });
if (ctx) {
  store.run(ctx, () => {
    // All downstream code sees the resolved tenant via store.get()
  });
}

Exports

ExportKindDescription
TenantResolverInterfaceContract for resolving tenant identity from a request
HeaderTenantResolverClassExtract tenant ID from a named request header
JWTTenantResolverClassVerify and decode a JWT bearer token (requires jsonwebtoken)
APIKeyTenantResolverClassLook up a tenant by API key via a user-supplied async function
TenantContextStoreClassAsyncLocalStorage-backed store for tenant context propagation

License

MIT