@yigitkonur/analytics-db-plane
v0.3.0
Published
Shared secretless analytics DB-plane core for marketing MCP servers.
Downloads
641
Readme
@yigitkonur/analytics-db-plane
Shared secretless analytics DB-plane SDK for MCP servers that provision per-user MotherDuck workspaces through a control plane.
What It Does
MCP servers need per-user analytics databases without holding admin credentials. This package provides the client-side SDK:
- Control-plane HTTP client —
HttpWorkspaceControlPlaneClientforPOST /bindandPOST /leasewith reachability probing - Bind/lease normalization — canonical shapes from heterogeneous control-plane responses (legacy string, structured JSON, mixed formats)
- Redis state helpers —
SecretlessJsonRecordStorepersists binding metadata without storing connection strings - Lease caching — in-memory TTL cache for active per-user database connections
- MCP resource builder —
buildCurrentWorkspaceResourcePayloadshapes workspace state for MCP resource responses
Installation
npm install @yigitkonur/analytics-db-planeExports
| Subpath | Purpose |
|---|---|
| @yigitkonur/analytics-db-plane | Barrel re-export of all subpaths |
| @yigitkonur/analytics-db-plane/core | Types (NormalizedBindResponse, WorkspaceLease), errors (ControlPlaneError), record/time helpers |
| @yigitkonur/analytics-db-plane/control-plane | HttpWorkspaceControlPlaneClient — sends bind/lease requests to the control plane |
| @yigitkonur/analytics-db-plane/redis | SecretlessJsonRecordStore — Redis-backed binding state (no tokens stored) |
| @yigitkonur/analytics-db-plane/sql | BindingLeaseCache — in-memory lease TTL cache with auto-refresh |
| @yigitkonur/analytics-db-plane/mcp | buildCurrentWorkspaceResourcePayload — MCP resource formatting |
| @yigitkonur/analytics-db-plane/testing | Test fixtures and doubles |
Usage
import { HttpWorkspaceControlPlaneClient } from '@yigitkonur/analytics-db-plane/control-plane';
const client = new HttpWorkspaceControlPlaneClient({
bindApiUrl: 'https://control-plane.example.com/bind',
leaseApiUrl: 'https://control-plane.example.com/lease',
bearerToken: process.env.CONTROL_PLANE_SECRET,
});
// Bind a workspace for a user
const { binding } = await client.bindWorkspace(
{ userId: '[email protected]', ensureExists: true },
{ ownerUserId: '[email protected]', bindingIdFallback: '[email protected]' },
);
// Get a lease (connection credentials)
const lease = await client.mintWorkspaceLease(
{ bindingId: binding.bindingId, mode: 'read_write', ttlSeconds: 300 },
{ bindingId: binding.bindingId, ttlSeconds: 300 },
);
// lease.connectionString → md:ws_abc123?motherduck_token=...
// lease.pg → { host, port, user, password, database }Design Principles
- Secretless — this SDK never holds admin tokens. It only receives per-user scoped tokens from the control plane via lease responses.
- Normalizing — control-plane APIs can return legacy string responses or structured JSON. The normalizer handles both and produces canonical types.
- Framework-free — zero dependencies on MCP SDK, Express, or any framework. Pure TypeScript.
- ESM-only —
"type": "module"with.jsextensions on relative imports.
Versioning
Automated via release-please. Push conventional commits to main:
feat:→ minor version bumpfix:→ patch version bumpfeat!:orBREAKING CHANGE:→ major version bump
Release-please opens a Release PR. Merging it publishes to npm automatically.
License
MIT
