@lemayinc/create-cdi-server
v1.0.0
Published
Scaffold a Callable Data Infrastructure server with sovereignty tools, MTP receipts, and access control
Readme
@lemay/create-cdi-server
Scaffold a Callable Data Infrastructure server with the six mandatory sovereignty tools, MTP Receipt chain, access control, observability, and SQLite persistence in WAL mode.
CDI servers expose data as typed tool surfaces through the Model Context Protocol. Every tool invocation produces a cryptographic MTP Receipt. The six sovereignty rights defined in CDG-SPEC-001 are structurally enforced and cannot be disabled.
Quick Start
npx @lemay/create-cdi-server my-cdi-server
cd my-cdi-server
npm run devThe server starts on stdio, ready to accept MCP connections from Claude Desktop, Cursor, or any MCP-compatible client.
What You Get
The scaffolded project contains a complete CDI server with all seven layers of the CDI internal stack implemented:
Layer 1 — Domain Modeling. Core sovereignty types (Connection, AccessLogEntry, SovereigntyAction, DataInventoryEntry) with a template section for your domain-specific types. JSON Schema definitions for all tool inputs.
Layer 2 — Persistence. SQLite in WAL mode via better-sqlite3. Two databases: sovereign.db for domain data, receipts.db for the immutable MTP Receipt chain. Versioned migrations with a template section for your domain tables.
Layer 3 — Tool Surface. MCP server exposing all tools as callable operations. Twelve sovereignty and connection management tools implemented. A domain tools template for your custom operations.
Layer 6 — Access Control. Token-based authentication with scope-limited access per tool. Sovereignty tools restricted to the data owner. Token generation, validation, and revocation.
Layer 7 — Observability. Call tracking, latency measurement, error rates, and health summaries stored in the server state key-value store.
MTP Receipt Chain. Every tool invocation produces a cryptographic MTP Receipt signed with Ed25519. Receipts are append-only and link to their predecessors, forming an immutable audit trail.
The Six Sovereignty Rights
These tools are mandatory on every CDI server per CDG-SPEC-001. They cannot be disabled, restricted, or removed.
| Right | Tool | Description |
|-------|------|-------------|
| Ownership | owner_identity() | Assert the data owner's identity and sovereignty status |
| Access | owner_export(format) | Export complete data domain in JSON, CSV, or SQLite |
| Erasure | owner_delete(scope, verification) | Permanent deletion with cryptographic attestation |
| Portability | owner_migrate(target, auth) | Server-to-server migration to another CDI endpoint |
| Restriction | access_restrict(consumer, scope) | Modify access boundaries for a consumer |
| Transparency | access_log(time_range?, consumer?, domain?) | Query the immutable access audit trail |
Additionally, access_revoke(consumer) provides complete access termination with an MTP Receipt as proof.
Adding Your Domain
1. Define Domain Types
Edit src/cdi/domain/types.ts and add your types in the YOUR DOMAIN TYPES section:
export interface HealthRecord {
record_id: string;
patient_id: string;
provider: string;
record_type: string;
data: Record<string, unknown>;
recorded_at: string;
}2. Define Tool Schemas
Edit src/cdi/domain/schema.ts and add schemas in the YOUR DOMAIN TOOL SCHEMAS section, then add them to DOMAIN_TOOL_DEFINITIONS:
export const getHealthRecordSchema = {
type: "object" as const,
description: "Retrieve a health record by ID",
properties: {
record_id: { type: "string" as const, description: "The record identifier" },
},
required: ["record_id"] as const,
additionalProperties: false,
};
export const DOMAIN_TOOL_DEFINITIONS: ToolDefinition[] = [
{ name: "get_health_record", description: getHealthRecordSchema.description, inputSchema: getHealthRecordSchema },
];3. Add Domain Tables
Edit src/cdi/persistence/migrations.ts and add a new migration:
{
version: 2,
description: "Health records domain table",
sql: `
CREATE TABLE IF NOT EXISTS health_records (
record_id TEXT PRIMARY KEY,
patient_id TEXT NOT NULL,
provider TEXT NOT NULL,
record_type TEXT NOT NULL,
data TEXT NOT NULL DEFAULT '{}',
recorded_at TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_health_records_patient ON health_records(patient_id);
`,
},4. Implement Domain Tools
Edit src/cdi/tools/domain.ts and implement your tool functions. Every tool MUST create an MTP Receipt:
export async function getHealthRecord(ctx: DomainContext, recordId: string) {
const row = ctx.db.main.prepare("SELECT * FROM health_records WHERE record_id = ?").get(recordId);
const receipt = await createToolReceipt(
ctx.identity, "get_health_record", ctx.identity.did,
ReceiptOutcome.Fulfilled, { record_id: recordId }
);
ctx.receipts.append(receipt, "get_health_record");
ctx.db.appendAccessLog({
accessor_identity: ctx.identity.did, tool_invoked: "get_health_record",
data_domain: "health", terms: null, receipt_id: receipt.receipt_id,
outcome: AccessOutcome.Success,
});
return row;
}5. Route the Tool
Edit src/cdi/tools/domain.ts routeDomainToolCall to add your tool's case:
export async function routeDomainToolCall(ctx, toolName, args) {
switch (toolName) {
case "get_health_record":
return getHealthRecord(ctx, args.record_id as string);
default:
return null;
}
}Connecting to the Server
Claude Desktop
Add to your Claude Desktop MCP configuration:
{
"mcpServers": {
"my-cdi-server": {
"command": "npx",
"args": ["tsx", "src/index.ts"],
"cwd": "/path/to/my-cdi-server"
}
}
}Programmatic
The server uses stdio transport. Connect with any MCP client SDK:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const transport = new StdioClientTransport({
command: "npx", args: ["tsx", "src/index.ts"],
});
const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(transport);
const result = await client.callTool("owner_identity", {});Architecture
The Callable Data Architecture introduces a third state for data: neither at rest nor in transit, but callable. A CDI server is the atomic unit — a bounded data domain exposed through typed tools with JSON Schema inputs and documented return types.
The Massachusetts Transaction Protocol governs every interaction. MTP's four primitives (Offers, Requests, Terms, Receipts) provide the universal trust verification layer. Every tool invocation produces an MTP Receipt — cryptographic proof of what occurred, under what terms, with what outcome.
License
Filed under the Curtis License (LeMay American Innovation Protection License). All rights reserved. LeMay Inc., Billerica, Massachusetts.
