Initial commit — Performance West telecom compliance platform

Includes: API (Express/TypeScript), Astro site, Python workers,
document generators, FCC compliance tools, Canada CRTC formation,
Ansible infrastructure, and deployment scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
justin 2026-04-27 06:54:22 -05:00
commit f8cd37ac8c
1823 changed files with 145167 additions and 0 deletions

1184
mcp/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

41
mcp/package.json Normal file
View file

@ -0,0 +1,41 @@
{
"name": "@performancewest/mcp-server",
"version": "0.1.0",
"description": "MCP server for Performance West — business formation in all 50 US states, compliance consulting, contractor classification, CCPA audits, and more. AI agents can walk users through the formation questionnaire and place orders.",
"license": "MIT",
"type": "module",
"bin": {
"performancewest-mcp": "dist/index.js"
},
"files": ["dist"],
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"start": "node dist/index.js"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.27.1",
"zod": "^3.25.0"
},
"devDependencies": {
"@types/node": "^22.0.0",
"typescript": "^5.7.0"
},
"engines": {
"node": ">=20"
},
"keywords": [
"mcp",
"model-context-protocol",
"business-formation",
"llc",
"incorporation",
"compliance",
"performancewest"
],
"repository": {
"type": "git",
"url": "git+https://github.com/performancewest/mcp-server.git"
},
"homepage": "https://performancewest.net"
}

72
mcp/src/client.ts Normal file
View file

@ -0,0 +1,72 @@
/**
* HTTP client for the Performance West API.
* All MCP tools delegate to the API this keeps the MCP server
* stateless and avoids duplicating business logic.
*/
const DEFAULT_BASE_URL = "https://api.performancewest.net";
const baseUrl = process.env.PW_API_URL ?? DEFAULT_BASE_URL;
const apiKey = process.env.PW_API_KEY ?? "";
function buildUrl(
path: string,
params?: Record<string, string | number | undefined>,
): string {
const url = new URL(path, baseUrl);
if (params) {
for (const [k, v] of Object.entries(params)) {
if (v !== undefined && v !== "") {
url.searchParams.set(k, String(v));
}
}
}
return url.toString();
}
export interface ApiResponse<T = unknown> {
ok: boolean;
status: number;
data: T;
}
export async function apiGet<T = unknown>(
path: string,
params?: Record<string, string | number | undefined>,
): Promise<ApiResponse<T>> {
const url = buildUrl(path, params);
const headers: Record<string, string> = {
Accept: "application/json",
"User-Agent": "performancewest-mcp-server/0.1.0",
};
if (apiKey) {
headers["Authorization"] = `Bearer ${apiKey}`;
}
const res = await fetch(url, { headers });
const data = (await res.json()) as T;
return { ok: res.ok, status: res.status, data };
}
export async function apiPost<T = unknown>(
path: string,
body: Record<string, unknown>,
): Promise<ApiResponse<T>> {
const url = buildUrl(path);
const headers: Record<string, string> = {
Accept: "application/json",
"Content-Type": "application/json",
"User-Agent": "performancewest-mcp-server/0.1.0",
};
if (apiKey) {
headers["Authorization"] = `Bearer ${apiKey}`;
}
const res = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
});
const data = (await res.json()) as T;
return { ok: res.ok, status: res.status, data };
}

45
mcp/src/index.ts Normal file
View file

@ -0,0 +1,45 @@
#!/usr/bin/env node
/**
* Performance West MCP Server
*
* Exposes business formation (all 50 US states) and compliance consulting
* services as MCP tools for AI assistants (Claude, ChatGPT, Cursor, etc.).
*
* Tools:
* formation_guide Interactive questionnaire entity + state recommendation
* search_name Check business name availability
* create_formation_order Place a formation order ($179 basic / $399 complete)
* check_order_status Check order status by order number
* get_states List all 51 jurisdictions with fees
* get_state_info Detailed info for a specific state
* get_pricing Calculate total formation cost
* list_services List all 20+ compliance services
* get_service_info Detailed service info by slug
* validate_discount Validate a discount/referral code
*
* Transport: stdio (spawned by MCP client)
* Data source: Performance West API (HTTP)
* Config: PW_API_URL, PW_API_KEY env vars
*/
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { registerFormationTools } from "./tools/formation.js";
import { registerStateTools } from "./tools/states.js";
import { registerServiceTools } from "./tools/services.js";
const server = new McpServer({
name: "performancewest",
version: "0.1.0",
});
// Register all tools
registerFormationTools(server);
registerStateTools(server);
registerServiceTools(server);
// Connect via stdio
const transport = new StdioServerTransport();
await server.connect(transport);

381
mcp/src/tools/formation.ts Normal file
View file

@ -0,0 +1,381 @@
/**
* Formation tools the core business formation workflow.
*
* Tools:
* formation_guide Interactive questionnaire entity + state recommendation
* search_name Check business name availability in a state
* create_formation_order Place a complete formation order
* check_order_status Check status of an existing order
*/
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { apiGet, apiPost } from "../client.js";
// Recommendation logic (mirrors the website formation guide)
interface Recommendation {
entity_type: string;
entity_reason: string;
state: string;
state_name: string;
state_reason: string;
cost_basic: number;
cost_complete: number;
annual_cost: number;
notes: string[];
}
const STATE_NAMES: Record<string, string> = {
AL:"Alabama",AK:"Alaska",AZ:"Arizona",AR:"Arkansas",CA:"California",CO:"Colorado",
CT:"Connecticut",DE:"Delaware",FL:"Florida",GA:"Georgia",HI:"Hawaii",ID:"Idaho",
IL:"Illinois",IN:"Indiana",IA:"Iowa",KS:"Kansas",KY:"Kentucky",LA:"Louisiana",
ME:"Maine",MD:"Maryland",MA:"Massachusetts",MI:"Michigan",MN:"Minnesota",
MS:"Mississippi",MO:"Missouri",MT:"Montana",NE:"Nebraska",NV:"Nevada",
NH:"New Hampshire",NJ:"New Jersey",NM:"New Mexico",NY:"New York",NC:"North Carolina",
ND:"North Dakota",OH:"Ohio",OK:"Oklahoma",OR:"Oregon",PA:"Pennsylvania",
RI:"Rhode Island",SC:"South Carolina",SD:"South Dakota",TN:"Tennessee",TX:"Texas",
UT:"Utah",VT:"Vermont",VA:"Virginia",WA:"Washington",WV:"West Virginia",
WI:"Wisconsin",WY:"Wyoming",DC:"District of Columbia",
};
const STATE_FEES: Record<string, { llc: number; corp: number; annual: number }> = {
WY:{llc:100,corp:100,annual:60},DE:{llc:110,corp:89,annual:300},NV:{llc:425,corp:725,annual:350},
TX:{llc:300,corp:300,annual:0},FL:{llc:125,corp:70,annual:139},CA:{llc:70,corp:100,annual:800},
CO:{llc:50,corp:50,annual:25},MT:{llc:35,corp:70,annual:20},NM:{llc:50,corp:125,annual:0},
OH:{llc:99,corp:99,annual:0},UT:{llc:59,corp:59,annual:18},MA:{llc:500,corp:275,annual:500},
NY:{llc:200,corp:125,annual:9},SD:{llc:150,corp:150,annual:55},TN:{llc:300,corp:100,annual:300},
};
function recommend(answers: {
situation: string;
tax_id: string;
owners: string;
revenue: string;
operations: string;
home_state: string;
priorities: string[];
}): Recommendation {
let entity = "LLC";
let entityReason = "";
let state = "WY";
let stateReason = "";
const notes: string[] = [];
const p = answers.priorities || [];
// Entity type
if (answers.owners === "investors") {
entity = "C-Corporation";
entityReason = "C-Corporations are standard for raising investment capital. Investors expect the familiar stock structure.";
} else if (answers.revenue === "over_500k" && answers.owners === "single") {
entity = "LLC with S-Corp election";
entityReason = "At your revenue level, an S-Corp election saves significant self-employment taxes while keeping LLC flexibility.";
} else if (answers.revenue === "100k_500k") {
entity = "LLC (consider S-Corp later)";
entityReason = "An LLC provides liability protection and pass-through taxation. Consider S-Corp election as revenue grows.";
} else {
entity = "LLC";
entityReason = "An LLC provides personal liability protection, pass-through taxation, and flexible management. Best choice for most small businesses.";
}
// State
if (answers.owners === "investors") {
state = "DE";
stateReason = "Delaware's Court of Chancery and established corporate law make it standard for investor-backed companies.";
} else if (p.includes("privacy") && p.includes("no_income_tax")) {
state = "WY";
stateReason = "Wyoming: no income tax, strongest privacy (no public member disclosure), excellent asset protection, low cost.";
} else if (p.includes("low_cost") && answers.home_state) {
const hf = STATE_FEES[answers.home_state];
if (hf && hf.llc >= 175) {
state = "WY";
stateReason = `Your home state (${STATE_NAMES[answers.home_state]}) charges $${hf.llc} for LLC formation. Wyoming ($100) + foreign qualification is more cost-effective plus you get privacy and no income tax.`;
} else {
state = answers.home_state;
stateReason = `${STATE_NAMES[answers.home_state]} has reasonable formation costs. Forming in your home state avoids foreign qualification fees.`;
}
} else if (answers.home_state === "TX") {
state = p.includes("privacy") ? "WY" : "TX";
stateReason = state === "WY"
? "Wyoming adds privacy protections over Texas. Foreign qualification in TX is a one-time $750 fee."
: "Texas: no income tax, large economy, fast processing. No franchise tax unless revenue exceeds $2.47M.";
} else if (answers.home_state === "FL") {
state = p.includes("privacy") ? "WY" : "FL";
stateReason = state === "WY"
? "Wyoming adds privacy over Florida. FL foreign qualification is only $125 one-time."
: "Florida: no personal income tax. Corporate income tax only applies to C-Corps, not LLCs/S-Corps.";
} else if (answers.operations === "single_state" && answers.home_state) {
state = answers.home_state;
stateReason = `Operating in one state — forming in your home state (${STATE_NAMES[answers.home_state]}) avoids foreign qualification.`;
} else {
state = "WY";
stateReason = "Wyoming: no income tax, no franchise tax, strong privacy, excellent asset protection, fast processing, low cost.";
}
const sf = STATE_FEES[state] || { llc: 100, corp: 100, annual: 60 };
const isLLC = !entity.includes("C-Corp");
const stateFee = isLLC ? sf.llc : sf.corp;
return {
entity_type: entity,
entity_reason: entityReason,
state,
state_name: STATE_NAMES[state] || state,
state_reason: stateReason,
cost_basic: stateFee + 179,
cost_complete: stateFee + 399,
annual_cost: sf.annual,
notes,
};
}
export function registerFormationTools(server: McpServer): void {
// ── Formation Guide ──────────────────────────────────────────────
server.registerTool(
"formation_guide",
{
title: "Business Formation Guide",
description:
"Interactive questionnaire that recommends the best entity type (LLC, Corporation, S-Corp) " +
"and formation state based on the user's situation. Provide answers to get a personalized recommendation. " +
"Performance West offers business formation in all 50 US states from $179 (basic) or $399 (complete).",
inputSchema: {
situation: z.enum(["new_business", "restructure", "holding", "ecommerce"])
.describe("Business situation: new_business, restructure, holding, or ecommerce"),
tax_id: z.enum(["us_ssn", "has_itin", "needs_itin"])
.describe("Tax ID status: us_ssn (US citizen with SSN), has_itin (foreign with ITIN), needs_itin (foreign without ITIN)"),
owners: z.enum(["single", "multi", "investors"])
.describe("Number of owners: single, multi (multiple partners), or investors (raising VC/angel)"),
revenue: z.enum(["under_100k", "100k_500k", "over_500k"])
.describe("Expected annual revenue range"),
operations: z.enum(["single_state", "multi_state", "online_only"])
.describe("Where the business will operate"),
home_state: z.string().length(2)
.describe("Two-letter state code where the owner lives (e.g., TX, CA, FL)"),
priorities: z.array(z.enum(["low_cost", "privacy", "no_income_tax", "asset_protection", "corp_law", "simplicity"]))
.describe("What matters most (select all that apply)"),
},
},
async (args) => {
if (args.tax_id === "needs_itin") {
return {
content: [{
type: "text" as const,
text: JSON.stringify({
recommendation: "ITIN Required First",
message: "To form a US business and obtain an EIN, you need either an SSN or ITIN. " +
"Visit the IRS Acceptance Agent Program to find an authorized agent in your country: " +
"https://www.irs.gov/individuals/international-taxpayers/acceptance-agent-program",
next_step: "Once you have your ITIN, come back to form your business.",
performancewest_url: "https://performancewest.net/tools/formation-guide",
}, null, 2),
}],
};
}
const rec = recommend(args);
return {
content: [{
type: "text" as const,
text: JSON.stringify({
recommendation: {
entity_type: rec.entity_type,
entity_reason: rec.entity_reason,
formation_state: rec.state,
formation_state_name: rec.state_name,
state_reason: rec.state_reason,
estimated_cost_basic: `$${rec.cost_basic}`,
estimated_cost_complete: `$${rec.cost_complete}`,
annual_ongoing_cost: `$${rec.annual_cost}/year`,
notes: rec.notes,
},
pricing: {
basic: "$179 — Formation filing only",
complete: "$399 — Formation + EIN ($49) + Operating Agreement ($99) + 1st year Registered Agent ($99, $49 WY)",
},
next_steps: [
`Search for name availability in ${rec.state_name} using the search_name tool`,
"Place your order using the create_formation_order tool",
"Or visit https://performancewest.net/order/formation",
],
}, null, 2),
}],
};
},
);
// ── Name Search ──────────────────────────────────────────────────
server.registerTool(
"search_name",
{
title: "Search Business Name Availability",
description:
"Check if a business name is available in a specific US state. " +
"Returns availability status and similar existing names.",
inputSchema: {
state: z.string().length(2).describe("Two-letter state code (e.g., WY, DE, TX)"),
name: z.string().min(2).describe("Desired business name (e.g., 'Acme Holdings LLC')"),
},
},
async ({ state, name }) => {
const res = await apiGet<{ state_code: string; name: string; available: boolean | null; message: string; similar_names: string[] }>(
`/api/v1/states/${state.toUpperCase()}/name-search`,
{ name },
);
if (!res.ok) {
return { content: [{ type: "text" as const, text: `Name search failed: ${JSON.stringify(res.data)}` }], isError: true };
}
return {
content: [{
type: "text" as const,
text: JSON.stringify({
state: res.data.state_code,
name: res.data.name,
available: res.data.available,
message: res.data.message,
similar_names: res.data.similar_names,
next_step: res.data.available
? "Name is available! Use create_formation_order to place your order."
: "Name is taken. Try a different name.",
}, null, 2),
}],
};
},
);
// ── Create Formation Order ───────────────────────────────────────
server.registerTool(
"create_formation_order",
{
title: "Create Business Formation Order",
description:
"Place a complete business formation order. Creates an LLC, Corporation, or S-Corp in any US state. " +
"Basic tier: $179 (formation only). Complete tier: $399 (includes EIN + Operating Agreement + 1st year Registered Agent). " +
"State filing fees are additional and vary by state.",
inputSchema: {
customer_name: z.string().min(2).describe("Full name of the person placing the order"),
customer_email: z.string().email().describe("Email address for order confirmations and document delivery"),
customer_phone: z.string().optional().describe("Phone number (optional)"),
state_code: z.string().length(2).describe("Two-letter state code for formation (e.g., WY, DE, TX)"),
entity_type: z.enum(["llc", "corporation", "s_corp"]).describe("Entity type to form"),
entity_name: z.string().min(3).describe("Desired entity name (e.g., 'Acme Holdings LLC')"),
entity_name_alt: z.string().optional().describe("Backup name if primary is unavailable"),
management_type: z.enum(["member_managed", "manager_managed"]).optional()
.describe("LLC management type (default: member_managed)"),
principal_address: z.string().describe("Principal business address (street)"),
principal_city: z.string().describe("City"),
principal_state: z.string().length(2).describe("State code"),
principal_zip: z.string().describe("ZIP code"),
members: z.array(z.object({
name: z.string(),
address: z.string(),
city: z.string(),
state: z.string(),
zip: z.string(),
title: z.string().optional(),
ownership_pct: z.number().optional(),
})).min(1).describe("At least one member/officer with name, address, and ownership %"),
tier: z.enum(["basic", "complete"]).default("basic")
.describe("Pricing tier: basic ($179) or complete ($399 with EIN + OA + RA)"),
discount_code: z.string().optional().describe("Discount or referral code (optional)"),
},
},
async (args) => {
const isComplete = args.tier === "complete";
const serviceFee = isComplete ? 39900 : 17900;
const sf = STATE_FEES[args.state_code.toUpperCase()] || { llc: 100, corp: 100 };
const stateFee = (args.entity_type === "corporation" ? sf.corp : sf.llc) * 100;
const payload = {
customer_name: args.customer_name,
customer_email: args.customer_email,
customer_phone: args.customer_phone,
state_code: args.state_code.toUpperCase(),
entity_type: args.entity_type,
entity_name: args.entity_name,
entity_name_alt: args.entity_name_alt,
management_type: args.management_type || "member_managed",
principal_address: args.principal_address,
principal_city: args.principal_city,
principal_state: args.principal_state,
principal_zip: args.principal_zip,
members: args.members,
include_ra_service: isComplete,
include_ein: isComplete,
include_operating_agreement: isComplete,
expedited: false,
state_fee_cents: stateFee,
service_fee_cents: serviceFee,
expedited_fee_cents: 0,
total_cents: stateFee + serviceFee,
discount_code: args.discount_code,
tier: args.tier,
};
const res = await apiPost<{ success: boolean; order_number?: string; message?: string; error?: string; discount_applied?: unknown }>(
"/api/v1/formations",
payload,
);
if (!res.ok || !res.data.success) {
return {
content: [{ type: "text" as const, text: `Order failed: ${res.data.error || JSON.stringify(res.data)}` }],
isError: true,
};
}
return {
content: [{
type: "text" as const,
text: JSON.stringify({
success: true,
order_number: res.data.order_number,
message: res.data.message,
discount_applied: res.data.discount_applied,
next_steps: [
`Order ${res.data.order_number} has been placed.`,
`An email will be sent to ${args.customer_email} with a link to set up a portal account and track progress.`,
"Formation typically takes 1-5 business days depending on the state.",
`Use check_order_status with order number "${res.data.order_number}" to track progress.`,
],
portal_url: "https://performancewest.net/portal",
}, null, 2),
}],
};
},
);
// ── Check Order Status ───────────────────────────────────────────
server.registerTool(
"check_order_status",
{
title: "Check Formation Order Status",
description: "Check the current status of a business formation order by order number.",
inputSchema: {
order_number: z.string().describe("Order number (e.g., PW-2026-A1B2C3)"),
},
},
async ({ order_number }) => {
const res = await apiGet<{ order?: Record<string, unknown>; error?: string }>(
`/api/v1/formations/${encodeURIComponent(order_number)}`,
);
if (!res.ok) {
return {
content: [{ type: "text" as const, text: `Order not found: ${res.data.error || "Unknown error"}` }],
isError: true,
};
}
return {
content: [{
type: "text" as const,
text: JSON.stringify(res.data.order, null, 2),
}],
};
},
);
}

145
mcp/src/tools/services.ts Normal file
View file

@ -0,0 +1,145 @@
/**
* Compliance services tools list and describe our services.
*
* Tools:
* list_services List all 20+ compliance services with pricing
* get_service_info Detailed info about a specific service
* validate_discount Check if a discount code is valid
*/
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { apiGet } from "../client.js";
// Service catalog (embedded so MCP server works without API for basic info)
const SERVICES = [
{ slug: "flsa-audit", category: "Employment", name: "FLSA / Wage & Hour Audit", price: "$1,499", turnaround: "5-7 days" },
{ slug: "contractor-classification", category: "Employment", name: "Contractor Classification Review", price: "$499/worker", turnaround: "3-5 days" },
{ slug: "handbook-review", category: "Employment", name: "Employee Handbook Review", price: "$999", turnaround: "5-7 days" },
{ slug: "policy-development", category: "Employment", name: "Workplace Policy Development", price: "Custom quote", turnaround: "2-3 weeks" },
{ slug: "ccpa-audit", category: "Privacy", name: "CCPA/CPRA Compliance Audit", price: "$2,499", turnaround: "7-10 days" },
{ slug: "privacy-policy", category: "Privacy", name: "Privacy Policy Generation & Review", price: "$499", turnaround: "5-7 days" },
{ slug: "data-mapping", category: "Privacy", name: "Data Mapping & Inventory", price: "Custom quote", turnaround: "1-3 weeks" },
{ slug: "breach-response", category: "Privacy", name: "Breach Response Planning", price: "$1,999", turnaround: "2-3 weeks" },
{ slug: "consent-audit", category: "TCPA", name: "SMS/Call Consent Audit", price: "$1,299", turnaround: "5-7 days" },
{ slug: "dnc-compliance", category: "TCPA", name: "DNC List Compliance Review", price: "$799", turnaround: "3-5 days" },
{ slug: "campaign-review", category: "TCPA", name: "Marketing Campaign Compliance Review", price: "$599", turnaround: "2-3 days" },
{ slug: "fcc-499a", category: "Telecom", name: "FCC Form 499-A Filing Support", price: "$799", turnaround: "5-7 days" },
{ slug: "stir-shaken", category: "Telecom", name: "STIR/SHAKEN Implementation", price: "Custom quote", turnaround: "2-4 weeks" },
{ slug: "ipes-isp", category: "Telecom", name: "IPES & ISP Registrations", price: "$1,299", turnaround: "2-3 weeks" },
{ slug: "database-management", category: "Telecom", name: "Telecom Database Management", price: "$499/quarter", turnaround: "Ongoing" },
{ slug: "state-puc", category: "Telecom", name: "State PUC/PSC Filings", price: "$399/state", turnaround: "2-8 weeks" },
{ slug: "formation", category: "Corporate", name: "Business Formation (LLC/Corp)", price: "$179 basic / $399 complete", turnaround: "3-5 days" },
{ slug: "state-registration", category: "Corporate", name: "State Registration & Foreign Qualification", price: "$249/state", turnaround: "1-4 weeks" },
{ slug: "annual-reports", category: "Corporate", name: "Annual Report Filing", price: "$99/state/year", turnaround: "Filed before deadline" },
{ slug: "registered-agent", category: "Corporate", name: "Registered Agent Service", price: "$99/state/year ($49 WY)", turnaround: "Same-day forwarding" },
];
export function registerServiceTools(server: McpServer): void {
// ── List Services ────────────────────────────────────────────────
server.registerTool(
"list_services",
{
title: "List All Compliance Services",
description:
"List all Performance West compliance services with pricing, turnaround times, and categories. " +
"Services span: Employment (FLSA, contractor classification, handbooks), Data Privacy (CCPA, privacy policies), " +
"TCPA (SMS consent, DNC), Telecom (FCC 499A, STIR/SHAKEN), and Corporate (formation, registrations, RA).",
inputSchema: {
category: z.string().optional()
.describe("Filter by category: Employment, Privacy, TCPA, Telecom, Corporate (optional)"),
},
},
async ({ category }) => {
let filtered = SERVICES;
if (category) {
filtered = SERVICES.filter(s => s.category.toLowerCase() === category.toLowerCase());
}
return {
content: [{
type: "text" as const,
text: JSON.stringify({
count: filtered.length,
services: filtered,
website: "https://performancewest.net/services",
disclaimer: "Performance West provides compliance consulting, not legal advice.",
}, null, 2),
}],
};
},
);
// ── Get Service Info ─────────────────────────────────────────────
server.registerTool(
"get_service_info",
{
title: "Get Service Details",
description: "Get detailed information about a specific compliance service by slug.",
inputSchema: {
slug: z.string().describe("Service slug (e.g., 'flsa-audit', 'ccpa-audit', 'formation')"),
},
},
async ({ slug }) => {
const service = SERVICES.find(s => s.slug === slug.toLowerCase());
if (!service) {
return {
content: [{
type: "text" as const,
text: `Service '${slug}' not found. Use list_services to see available services.`,
}],
isError: true,
};
}
return {
content: [{
type: "text" as const,
text: JSON.stringify({
...service,
url: `https://performancewest.net/services/${service.category.toLowerCase()}/${service.slug}`,
order_url: service.slug === "formation"
? "https://performancewest.net/order/formation"
: "https://performancewest.net/contact",
}, null, 2),
}],
};
},
);
// ── Validate Discount Code ───────────────────────────────────────
server.registerTool(
"validate_discount",
{
title: "Validate Discount Code",
description: "Check if a discount or referral code is valid and what discount it provides.",
inputSchema: {
code: z.string().min(2).describe("Discount or referral code"),
service: z.string().optional().describe("Service slug to check scope (optional)"),
amount: z.number().optional().describe("Amount in cents to calculate discount against (optional)"),
},
},
async ({ code, service, amount }) => {
const res = await apiGet<{
valid: boolean;
code?: string;
discount_type?: string;
discount_value?: number;
discount_cents?: number;
description?: string;
error?: string;
}>(
`/api/v1/discount/${encodeURIComponent(code)}`,
{ service, amount: amount ? String(amount) : undefined },
);
return {
content: [{
type: "text" as const,
text: JSON.stringify(res.data, null, 2),
}],
};
},
);
}

158
mcp/src/tools/states.ts Normal file
View file

@ -0,0 +1,158 @@
/**
* State information tools fees, tax info, requirements.
*
* Tools:
* get_states List all 51 jurisdictions with fees
* get_state_info Detailed info for a specific state
* get_pricing Calculate total price for a specific formation
*/
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { apiGet } from "../client.js";
export function registerStateTools(server: McpServer): void {
// ── Get All States ───────────────────────────────────────────────
server.registerTool(
"get_states",
{
title: "List All US States for Formation",
description:
"Get a list of all 50 US states plus DC with formation fees, annual fees, " +
"tax information, and special requirements. Useful for comparing states.",
inputSchema: {},
},
async () => {
const res = await apiGet<{ states: Record<string, unknown>[] }>("/api/v1/states");
if (!res.ok) {
return { content: [{ type: "text" as const, text: "Failed to fetch state data" }], isError: true };
}
// Summarize for readability
const summary = (res.data.states || []).map((s: any) => ({
code: s.state_code,
name: s.state_name,
llc_fee: `$${(s.llc_formation_fee / 100).toFixed(0)}`,
corp_fee: `$${(s.corp_formation_fee / 100).toFixed(0)}`,
annual: s.llc_annual_fee ? `$${(s.llc_annual_fee / 100).toFixed(0)}/${s.llc_annual_period || "yr"}` : "None",
notes: s.notes || "",
}));
return {
content: [{
type: "text" as const,
text: JSON.stringify({
count: summary.length,
states: summary,
pricing_note: "State fees are pass-through. Our service fee: $179 (basic) or $399 (complete).",
}, null, 2),
}],
};
},
);
// ── Get State Info ───────────────────────────────────────────────
server.registerTool(
"get_state_info",
{
title: "Get State Formation Details",
description: "Get detailed formation information for a specific US state including fees, tax structure, processing time, and special requirements.",
inputSchema: {
state: z.string().length(2).describe("Two-letter state code (e.g., WY, DE, TX, CA)"),
},
},
async ({ state }) => {
const res = await apiGet<{ states: Record<string, unknown>[] }>(
"/api/v1/states",
);
if (!res.ok) {
return { content: [{ type: "text" as const, text: "Failed to fetch state data" }], isError: true };
}
const stateData = (res.data.states || []).find((s: any) => s.state_code === state.toUpperCase());
if (!stateData) {
return { content: [{ type: "text" as const, text: `State ${state} not found` }], isError: true };
}
return {
content: [{
type: "text" as const,
text: JSON.stringify(stateData, null, 2),
}],
};
},
);
// ── Get Pricing ──────────────────────────────────────────────────
server.registerTool(
"get_pricing",
{
title: "Calculate Formation Pricing",
description: "Calculate the total cost for a business formation including state fees, service fee, and optional add-ons.",
inputSchema: {
state: z.string().length(2).describe("Two-letter state code"),
entity_type: z.enum(["llc", "corporation", "s_corp"]).describe("Entity type"),
tier: z.enum(["basic", "complete"]).default("basic").describe("basic ($179) or complete ($399)"),
expedited: z.boolean().default(false).describe("Add expedited processing"),
discount_code: z.string().optional().describe("Discount code to apply"),
},
},
async ({ state, entity_type, tier, expedited, discount_code }) => {
const res = await apiGet<{ states: Record<string, unknown>[] }>("/api/v1/states");
if (!res.ok) {
return { content: [{ type: "text" as const, text: "Failed to fetch pricing data" }], isError: true };
}
const sd = (res.data.states || []).find((s: any) => s.state_code === state.toUpperCase()) as any;
if (!sd) {
return { content: [{ type: "text" as const, text: `State ${state} not found` }], isError: true };
}
const stateFee = entity_type === "corporation" ? sd.corp_formation_fee : sd.llc_formation_fee;
const serviceFee = tier === "complete" ? 39900 : 17900;
const expFee = expedited && sd.expedited_fee ? sd.expedited_fee : 0;
let discountCents = 0;
if (discount_code) {
const dcRes = await apiGet<{ valid: boolean; discount_cents?: number; description?: string }>(
`/api/v1/discount/${encodeURIComponent(discount_code)}`,
{ service: "formation", amount: String(serviceFee) },
);
if (dcRes.ok && dcRes.data.valid) {
discountCents = dcRes.data.discount_cents || 0;
}
}
const total = stateFee + serviceFee + expFee - discountCents;
const isComplete = tier === "complete";
return {
content: [{
type: "text" as const,
text: JSON.stringify({
state: sd.state_name,
entity_type,
tier,
breakdown: {
state_filing_fee: `$${(stateFee / 100).toFixed(2)}`,
service_fee: `$${(serviceFee / 100).toFixed(2)}` + (isComplete ? " (includes EIN + Operating Agreement + 1st yr RA)" : " (formation only)"),
expedited_fee: expedited ? `$${(expFee / 100).toFixed(2)}` : "Not selected",
discount: discountCents > 0 ? `-$${(discountCents / 100).toFixed(2)}` : "None",
total: `$${(total / 100).toFixed(2)}`,
},
ongoing_annual: `$${(sd.llc_annual_fee ? sd.llc_annual_fee / 100 : 0).toFixed(0)}/year`,
processing_time: `${sd.typical_processing_days || "3-7"} business days`,
special_requirements: [
sd.publication_required ? `Publication required (~$${(sd.publication_est_cost || 0) / 100})` : null,
sd.franchise_tax_required ? `Franchise tax: ${sd.franchise_tax_notes || "applies"}` : null,
sd.business_license_required ? `State business license: $${(sd.business_license_fee || 0) / 100}` : null,
].filter(Boolean),
}, null, 2),
}],
};
},
);
}

18
mcp/tsconfig.json Normal file
View file

@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"lib": ["ES2022"],
"outDir": "dist",
"rootDir": "src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}