/** * 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 = { 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 = { 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; 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), }], }; }, ); }