Vertical SDK
Build domain-specific applications (verticals) that plug into MeetLoyd. A vertical packages MCP tools, tRPC APIs, databases, and UIs for a specific domain like wealth management, claims processing, or HR payroll.
Installation
pnpm add @meetloyd/vertical-sdk
Or scaffold a complete project:
npx create-meetloyd-vertical claims-management
npx create-meetloyd-vertical claims-management --scope cm --description "Insurance claims"
Quick Start
1. Define tools
import { defineTool, createToolRegistry } from "@meetloyd/vertical-sdk";
const registry = createToolRegistry("claims");
registry.register(
defineTool({
name: "claims_file_new",
description: "File a new insurance claim",
parameters: {
type: "object",
properties: {
policyNumber: { type: "string", description: "Policy number" },
description: { type: "string", description: "Claim description" },
amount: { type: "number", description: "Claimed amount" },
},
required: ["policyNumber", "description"],
},
handler: async (args) => {
// Your business logic here
return { claimId: "CLM-001", status: "filed" };
},
category: "claims",
})
);
export const claimsTools = registry.getAll();
2. Create the vertical entry point
import { defineVertical } from "@meetloyd/vertical-sdk";
import { claimsTools } from "./tools/index.js";
export default defineVertical({
name: "claims",
displayName: "Claims Management",
description: "Insurance claims processing and management",
version: "0.1.0",
scope: "@meetloyd/cm",
categories: ["insurance", "claims"],
tools: claimsTools,
});
3. Add a manifest
Create meetloyd.vertical.json at the root of your project:
{
"name": "claims",
"displayName": "Claims Management",
"description": "Insurance claims processing and management",
"version": "0.1.0",
"scope": "@meetloyd/cm",
"meetloyd": {
"minVersion": "0.1.0"
},
"entryPoints": {
"tools": "./packages/meetloyd-tools/dist/index.js",
"mcpServer": "./packages/mcp-server/dist/index.js",
"api": "./packages/api/dist/index.js",
"prismaSchema": "./packages/db/prisma/schema.prisma"
},
"capabilities": ["mcp-tools", "mcp-server", "trpc-api", "prisma-db"],
"categories": ["insurance", "claims"],
"compliance": ["Solvency II"],
"toolCategories": ["claims", "coverage", "assessment"]
}
Project Structure
The scaffolder creates this monorepo layout:
claims-management/
├── meetloyd.vertical.json # Platform manifest
├── package.json # Root workspace config
├── pnpm-workspace.yaml
├── turbo.json
├── tsconfig.json
└── packages/
├── core/ # Business logic
├── db/ # Prisma database layer
├── api/ # tRPC API routes
├── mcp-server/ # Standalone MCP server
├── meetloyd-tools/ # Tool definitions + vertical entry
└── web/ # Web UI components
API Reference
defineVertical(definition)
Creates a vertical that MeetLoyd can mount and discover.
import { defineVertical } from "@meetloyd/vertical-sdk";
export default defineVertical({
name: "claims", // kebab-case identifier
displayName: "Claims Management", // Human-readable name
description: "Insurance claims platform", // Short description
version: "0.1.0", // Semver
scope: "@meetloyd/cm", // npm scope
categories: ["insurance"], // Discovery categories
compliance: ["Solvency II"], // Compliance frameworks
tools: myTools, // MCPTool[]
resources: myResources, // MCPResource[] (optional)
prompts: myPrompts, // MCPPrompt[] (optional)
});
defineTool(options)
Defines a single MCP tool with type safety.
import { defineTool } from "@meetloyd/vertical-sdk";
const tool = defineTool({
name: "claims_check_coverage",
description: "Check if a policy covers a claim type",
parameters: {
type: "object",
properties: {
policyNumber: { type: "string" },
claimType: { type: "string", enum: ["fire", "theft", "flood"] },
},
required: ["policyNumber", "claimType"],
},
handler: async (args, context) => {
// context.userId, context.tenantId available
return { covered: true, deductible: 500 };
},
category: "coverage",
requiresAuth: true,
rateLimit: { maxCalls: 100, windowMs: 60000 },
});
Tool options:
| Field | Type | Description |
|---|---|---|
name | string | Unique tool name (prefix with vertical scope) |
description | string | What the tool does |
parameters | MCPToolParameters | JSON Schema input definition |
handler | (args, context?) => Promise<any> | Execution function |
category | string? | Tool category for filtering |
requiresAuth | boolean? | Requires authenticated user |
requiresApproval | boolean? | Triggers HITL approval |
requiredRoles | string[]? | Required RBAC roles |
rateLimit | { maxCalls, windowMs }? | Rate limiting |
governance | object? | Data classification, audit level, compliance |
createToolRegistry(prefix)
Creates a registry to manage tools for a vertical.
import { createToolRegistry } from "@meetloyd/vertical-sdk";
const registry = createToolRegistry("claims");
registry.register(tool1);
registry.register(tool2);
registry.registerAll([tool3, tool4]);
// Query
registry.getAll(); // MCPTool[]
registry.getByCategory("coverage"); // MCPTool[]
registry.getNames(); // string[]
registry.getStats(); // { coverage: 2, claims: 3 }
registry.getSchemas(); // Tool schemas (no handlers)
registry.size; // number
// Execute
await registry.execute("claims_file_new", { policyNumber: "P-123" });
createMCPServer(options)
Creates a pre-configured MCP server for standalone use.
import { createMCPServer } from "@meetloyd/vertical-sdk";
const { server, start } = createMCPServer({
name: "claims-mcp",
version: "0.1.0",
tools: registry.getAll(),
resources: myResources, // optional
});
start(); // Connects via stdio transport
createVerticalTRPC()
Creates a typed tRPC instance with auth middleware.
import { createVerticalTRPC } from "@meetloyd/vertical-sdk";
const t = createVerticalTRPC<{ userId?: string; tenantId?: string }>();
const appRouter = t.router({
getClaim: t.protectedProcedure // Requires userId
.input(z.object({ id: z.string() }))
.query(({ input }) => getClaim(input.id)),
listClaims: t.publicProcedure
.query(() => listAllClaims()),
});
createPrismaSingleton(key, factory)
Creates a global-safe Prisma client instance (avoids multiple clients in dev).
import { createPrismaSingleton } from "@meetloyd/vertical-sdk";
import { PrismaClient } from "@prisma/client";
export const prisma = createPrismaSingleton("claims", () =>
new PrismaClient()
);
Manifest Reference
The meetloyd.vertical.json file declares your vertical's capabilities to the platform.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Lowercase kebab-case identifier |
displayName | string | Yes | Human-readable name |
description | string | Yes | Short description |
version | string | Yes | Semver version |
scope | string | Yes | npm scope (must start with @meetloyd/) |
meetloyd.minVersion | string | Yes | Minimum platform version |
entryPoints.tools | string | No | Path to tools module |
entryPoints.mcpServer | string | No | Path to MCP server |
entryPoints.api | string | No | Path to tRPC router |
entryPoints.prismaSchema | string | No | Path to Prisma schema |
entryPoints.web | string | No | Path to web UI |
capabilities | string[] | Yes | mcp-tools, mcp-server, trpc-api, web-ui, prisma-db |
categories | string[] | Yes | Domain categories |
compliance | string[] | No | Compliance frameworks |
toolCategories | string[] | No | Tool category labels |
MCPContext
Every tool handler receives an optional MCPContext:
interface MCPContext {
userId?: string;
tenantId?: string;
agentId?: string;
teamId?: string;
runId?: string;
conversationId?: string;
vertical?: Record<string, unknown>; // Domain-specific state
metadata?: Record<string, unknown>;
}
Resources
Define data resources that agents can read:
import type { MCPResource } from "@meetloyd/vertical-sdk";
const policyResource: MCPResource = {
definition: {
uri: "claims://policies/{policyNumber}",
name: "Policy Details",
description: "Insurance policy information",
mimeType: "application/json",
},
handler: async (uri, context) => {
const policyNumber = uri.split("/").pop();
const policy = await getPolicy(policyNumber);
return { text: JSON.stringify(policy), mimeType: "application/json" };
},
};
export default defineVertical({
// ...
resources: [policyResource],
});
Governance
Tools support governance metadata for regulated industries:
defineTool({
name: "claims_approve_payout",
// ...
requiresApproval: true,
requiredRoles: ["claims_manager"],
rateLimit: { maxCalls: 10, windowMs: 3600000 },
governance: {
dataClassification: "confidential",
auditLevel: "full",
complianceFrameworks: ["Solvency II", "GDPR"],
},
});
Next Steps
- MCP Integration — How MCP tools work in MeetLoyd
- Custom Tools — Building tools without the SDK
- TypeScript SDK — Platform client SDK