potal-mcp-server 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/build/index.js +94 -3
  2. package/package.json +6 -4
package/build/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * Calculates import duties, taxes (VAT/GST), customs fees, and shipping
7
7
  * for cross-border purchases across 240 countries and territories.
8
8
  *
9
- * Tools (9):
9
+ * Tools (10):
10
10
  * - calculate_landed_cost: Calculate total cost for international purchases (with 9-field classify support)
11
11
  * - classify_product: HS code classification via v3.3 GRI pipeline (9-field input)
12
12
  * - check_restrictions: Import restriction & compliance check
@@ -16,6 +16,7 @@
16
16
  * - list_supported_countries: Get all supported countries with tax info
17
17
  * - generate_document: Generate trade documents (CI/PL/C/O)
18
18
  * - compare_countries: Compare TLC across multiple destination countries (with 9-field classify)
19
+ * - check_us_nexus: US sales tax economic nexus check across 50 states + DC
19
20
  */
20
21
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
21
22
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -23,11 +24,11 @@ import { z } from "zod";
23
24
  // ─── Configuration ──────────────────────────────────────────
24
25
  const POTAL_API_BASE = "https://www.potal.app/api/v1";
25
26
  const API_KEY = process.env.POTAL_API_KEY || "";
26
- const USER_AGENT = "potal-mcp-server/1.4.1";
27
+ const USER_AGENT = "potal-mcp-server/1.4.3";
27
28
  // ─── Server Instance ────────────────────────────────────────
28
29
  const server = new McpServer({
29
30
  name: "potal",
30
- version: "1.4.1",
31
+ version: "1.4.3",
31
32
  });
32
33
  async function callPotalApi(endpoint, method = "GET", body) {
33
34
  const url = `${POTAL_API_BASE}${endpoint}`;
@@ -663,6 +664,96 @@ server.tool("compare_countries", "Compare Total Landed Cost across multiple dest
663
664
  content: [{ type: "text", text: lines.join("\n") }],
664
665
  };
665
666
  });
667
+ // ─── Tool: check_us_nexus ───────────────────────────────────
668
+ server.tool("check_us_nexus", "Check US sales tax economic nexus exposure across 50 states + DC. " +
669
+ "Given per-state sales amounts (and optional transaction counts), determine which states have " +
670
+ "triggered economic nexus (exceeded threshold), which are in the warning zone (≥80% of threshold), " +
671
+ "and which are safe. Based on post-Wayfair (2018) state thresholds — most states use $100K in sales " +
672
+ "or 200 transactions. California/Texas use $500K sales only. New York/Connecticut require both " +
673
+ "sales AND transaction thresholds. Alaska/Delaware/Montana/New Hampshire/Oregon have no state sales tax.", {
674
+ sales: z
675
+ .array(z.object({
676
+ state: z.string().describe("2-letter US state code (e.g., 'CA', 'TX', 'NY')"),
677
+ amount: z.number().describe("Sales amount in USD for the measurement period"),
678
+ transactions: z
679
+ .number()
680
+ .optional()
681
+ .describe("Number of transactions (required for NY, CT, and states with OR-logic)"),
682
+ }))
683
+ .describe("Array of per-state sales entries"),
684
+ measurementPeriod: z
685
+ .enum(["last_12_months", "previous_calendar_year", "current_calendar_year"])
686
+ .optional()
687
+ .describe("Measurement period for sales totals (default: last_12_months)"),
688
+ }, async (args) => {
689
+ if (!API_KEY) {
690
+ return {
691
+ content: [
692
+ {
693
+ type: "text",
694
+ text: "❌ POTAL API key is not configured. Set POTAL_API_KEY environment variable.",
695
+ },
696
+ ],
697
+ };
698
+ }
699
+ const result = await callPotalApi("/nexus/check", "POST", {
700
+ sales: args.sales,
701
+ measurementPeriod: args.measurementPeriod || "last_12_months",
702
+ });
703
+ if (!result.success || !result.data) {
704
+ return {
705
+ content: [
706
+ {
707
+ type: "text",
708
+ text: `❌ Nexus check failed: ${result.error || "Unknown error"}`,
709
+ },
710
+ ],
711
+ };
712
+ }
713
+ const d = result.data;
714
+ const triggered = d.triggered || [];
715
+ const warnings = d.warnings || [];
716
+ const safe = d.safe || [];
717
+ const summary = d.summary || {};
718
+ const lines = [];
719
+ lines.push(`## US Sales Tax Nexus Check\n`);
720
+ lines.push(`**Total states checked**: ${summary.totalStates || 0} | **Triggered**: ${summary.triggered || 0} | **Warning**: ${summary.warning || 0} | **Safe**: ${summary.safe || 0}\n`);
721
+ if (triggered.length > 0) {
722
+ lines.push(`### 🔴 Nexus Triggered (${triggered.length})`);
723
+ lines.push("| State | Amount | Threshold | Exceeded By | Reason |");
724
+ lines.push("|-------|--------|-----------|-------------|--------|");
725
+ for (const t of triggered) {
726
+ const state = `${t.state} (${t.stateName})`;
727
+ const amount = formatCurrency(Number(t.amount || 0));
728
+ const threshold = t.salesThreshold !== null ? formatCurrency(Number(t.salesThreshold)) : "—";
729
+ const exceededBy = formatCurrency(Number(t.exceededBy || 0));
730
+ const reason = String(t.reason || "").replace(/_/g, " ");
731
+ lines.push(`| ${state} | ${amount} | ${threshold} | ${exceededBy} | ${reason} |`);
732
+ }
733
+ lines.push("");
734
+ }
735
+ if (warnings.length > 0) {
736
+ lines.push(`### 🟡 Approaching Threshold (${warnings.length})`);
737
+ for (const w of warnings) {
738
+ lines.push(`- **${w.state}** (${w.stateName}): ${w.message}`);
739
+ }
740
+ lines.push("");
741
+ }
742
+ if (safe.length > 0 && triggered.length === 0 && warnings.length === 0) {
743
+ lines.push(`### 🟢 All States Safe`);
744
+ lines.push(`No economic nexus triggered across ${safe.length} state(s) checked.`);
745
+ lines.push("");
746
+ }
747
+ if (d.disclaimer) {
748
+ lines.push(`\n> ⚠️ ${d.disclaimer}`);
749
+ }
750
+ if (d.dataVersion) {
751
+ lines.push(`\n*Data version: ${d.dataVersion} | Last updated: ${d.dataLastUpdated}*`);
752
+ }
753
+ return {
754
+ content: [{ type: "text", text: lines.join("\n") }],
755
+ };
756
+ });
666
757
  // ─── Start Server ───────────────────────────────────────────
667
758
  async function main() {
668
759
  const transport = new StdioServerTransport();
package/package.json CHANGED
@@ -1,18 +1,20 @@
1
1
  {
2
2
  "name": "potal-mcp-server",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "mcpName": "io.github.soulmaten7/potal",
5
5
  "description": "Calculate total landed costs for cross-border commerce. 240 countries, 257M+ tariff records, 131K government tariff schedules, 1.36M product-HS mappings, 63 FTAs, 9-field 100% HS Code accuracy (GRI Pipeline), sanctions screening (21K+ entries). MCP server for Claude, Cursor, and any MCP-compatible AI.",
6
6
  "type": "module",
7
7
  "bin": {
8
- "potal-mcp-server": "./build/index.js"
8
+ "potal-mcp-server": "build/index.js"
9
9
  },
10
10
  "scripts": {
11
11
  "build": "tsc && chmod 755 build/index.js",
12
12
  "start": "node build/index.js",
13
13
  "dev": "tsx src/index.ts"
14
14
  },
15
- "files": ["build"],
15
+ "files": [
16
+ "build"
17
+ ],
16
18
  "keywords": [
17
19
  "mcp",
18
20
  "claude",
@@ -33,7 +35,7 @@
33
35
  "homepage": "https://potal.app",
34
36
  "repository": {
35
37
  "type": "git",
36
- "url": "https://github.com/soulmaten7/potal"
38
+ "url": "git+https://github.com/soulmaten7/potal.git"
37
39
  },
38
40
  "author": "POTAL",
39
41
  "license": "MIT",