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>
381 lines
17 KiB
TypeScript
381 lines
17 KiB
TypeScript
/**
|
|
* 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),
|
|
}],
|
|
};
|
|
},
|
|
);
|
|
}
|