tariffmonitor-mcp 1.0.0

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 (3) hide show
  1. package/README.md +80 -0
  2. package/package.json +45 -0
  3. package/src/index.js +168 -0
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # tariffmonitor-mcp
2
+
3
+ MCP server for the **Tariff Exposure Monitor** — a live US import tariff calculator covering 19,856 HTS codes.
4
+
5
+ Give Claude (or any MCP-compatible AI) the ability to look up real stacked tariff rates and project the **November 10, 2026 cliff** impact on any product.
6
+
7
+ ## What it does
8
+
9
+ Two tools:
10
+
11
+ | Tool | What it does |
12
+ |---|---|
13
+ | `lookup_hts_code` | Search 19,856 HTS codes by description or numeric prefix |
14
+ | `calculate_tariff` | Returns stacked rate (base + Section 301 + IEEPA + reciprocal) + Nov 10 cliff projection. Optional: annual import volume → dollar impact |
15
+
16
+ Example exchange:
17
+ ```
18
+ You: What's the tariff on athletic footwear from China, and how does the cliff change my costs if I import $800k/year?
19
+
20
+ Claude: [uses calculate_tariff with hts_code="6404.11", origin_country="CN", annual_import_value_usd=800000]
21
+ HTS 6404110000 — Footwear with outer soles of rubber/plastics...
22
+ Rate stack:
23
+ Base rate (MFN): +20.00%
24
+ Section 301 (List 4A): +7.50%
25
+ IEEPA emergency tariff: +145.00%
26
+ Total current rate: 172.50%
27
+ Nov 10, 2026 cliff: 195.00% (+22.50pp jump)
28
+
29
+ Dollar impact at $800,000/yr import value:
30
+ Current annual duties: $1,380,000
31
+ Additional after Nov 10 cliff: $180,000/yr
32
+ ```
33
+
34
+ ## Install (Claude Desktop)
35
+
36
+ Add to your `claude_desktop_config.json`:
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "tariffmonitor": {
42
+ "command": "npx",
43
+ "args": ["-y", "tariffmonitor-mcp"]
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ Restart Claude Desktop. The `lookup_hts_code` and `calculate_tariff` tools appear automatically.
50
+
51
+ ## Install (Cursor / other MCP clients)
52
+
53
+ ```json
54
+ {
55
+ "mcp": {
56
+ "servers": {
57
+ "tariffmonitor": {
58
+ "command": "npx",
59
+ "args": ["-y", "tariffmonitor-mcp"]
60
+ }
61
+ }
62
+ }
63
+ }
64
+ ```
65
+
66
+ ## No API key required
67
+
68
+ The tool calls the free public API at adcreator-ai.com. No signup, no rate limits for reasonable use.
69
+
70
+ ## Related
71
+
72
+ - [Free tariff calculator](https://adcreator-ai.com/tariffs/calculator) — browser version
73
+ - [Free sample pack](https://scholar.0xpi.com/get/tariffmonitor) — 5 HTS codes with full cliff math PDF
74
+ - [Tariff Survival Kit ($39)](https://weaverdale5.gumroad.com/l/wmpath) — 67 HTS codes pre-computed + sourcing alternatives + Nov 10 action checklist
75
+
76
+ ## Affiliate program
77
+
78
+ Earn 35% on every sale. [Sign up here](https://app.gumroad.com/affiliates/products/wmpath).
79
+
80
+ Built by [Dale Weaver / 0xpi](https://0xpi.com).
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "tariffmonitor-mcp",
3
+ "version": "1.0.0",
4
+ "description": "Tariff Exposure Monitor — live US import tariff calculator MCP server. Looks up any HTS code, returns stacked rate (Section 301 + IEEPA + reciprocal), and projects the November 10, 2026 cliff jump. 19,856 HTS codes. Free, no signup.",
5
+ "type": "module",
6
+ "bin": {
7
+ "tariffmonitor-mcp": "src/index.js"
8
+ },
9
+ "main": "src/index.js",
10
+ "scripts": {
11
+ "start": "node src/index.js"
12
+ },
13
+ "keywords": [
14
+ "mcp",
15
+ "model-context-protocol",
16
+ "tariff",
17
+ "hts-code",
18
+ "import-duty",
19
+ "trade",
20
+ "section-301",
21
+ "ieepa",
22
+ "customs",
23
+ "ecommerce",
24
+ "shopify",
25
+ "amazon",
26
+ "importer",
27
+ "claude-desktop",
28
+ "cursor"
29
+ ],
30
+ "author": "Dale Weaver",
31
+ "license": "MIT",
32
+ "homepage": "https://scholar.0xpi.com/get/tariffmonitor",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/daleweaver1981/tariffmonitor-mcp"
36
+ },
37
+ "dependencies": {
38
+ "@modelcontextprotocol/sdk": "^1.29.0"
39
+ },
40
+ "files": [
41
+ "src/",
42
+ "README.md"
43
+ ],
44
+ "mcpName": "io.github.daleweaver1981/tariffmonitor-mcp"
45
+ }
package/src/index.js ADDED
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env node
2
+ // Tariff Exposure Monitor MCP server
3
+ //
4
+ // Exposes two tools:
5
+ // lookup_hts_code — search 19,856 HTS codes by description or prefix
6
+ // calculate_tariff — stacked rate (base + Section 301 + IEEPA + reciprocal)
7
+ // plus the November 10, 2026 cliff projection
8
+ //
9
+ // Data is served from adcreator-ai.com — free, no API key required.
10
+
11
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
12
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13
+ import {
14
+ ListToolsRequestSchema,
15
+ CallToolRequestSchema,
16
+ } from '@modelcontextprotocol/sdk/types.js';
17
+
18
+ const API_BASE = 'https://adcreator-ai.com/api/tem';
19
+ const PACK_URL = 'https://scholar.0xpi.com/get/tariffmonitor';
20
+ const BUY_URL = 'https://weaverdale5.gumroad.com/l/wmpath';
21
+
22
+ const server = new Server(
23
+ { name: 'tariffmonitor', version: '1.0.0' },
24
+ { capabilities: { tools: {} } }
25
+ );
26
+
27
+ async function apiFetch(path) {
28
+ const res = await fetch(`${API_BASE}${path}`, {
29
+ headers: { 'User-Agent': 'tariffmonitor-mcp/1.0.0' },
30
+ });
31
+ if (!res.ok) throw new Error(`API error ${res.status}`);
32
+ return res.json();
33
+ }
34
+
35
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
36
+ tools: [
37
+ {
38
+ name: 'lookup_hts_code',
39
+ description: 'Search for HTS (Harmonized Tariff Schedule) codes by description or numeric prefix. Returns up to 12 matching codes with descriptions. Use this before calculate_tariff when you only have a product description.',
40
+ inputSchema: {
41
+ type: 'object',
42
+ properties: {
43
+ query: {
44
+ type: 'string',
45
+ description: 'Product description (e.g. "athletic footwear") or HTS code prefix (e.g. "6404"). Min 2 characters.',
46
+ },
47
+ },
48
+ required: ['query'],
49
+ },
50
+ },
51
+ {
52
+ name: 'calculate_tariff',
53
+ description: 'Calculate the full stacked US import tariff rate for an HTS code from a specific origin country. Returns: base rate, each additional layer (Section 301, IEEPA, reciprocal), total current rate, and the projected rate after the November 10, 2026 cliff. Optionally computes dollar impact from annual import volume.',
54
+ inputSchema: {
55
+ type: 'object',
56
+ properties: {
57
+ hts_code: {
58
+ type: 'string',
59
+ description: 'HTS code — at least 6 digits, up to 10 (e.g. "6404.11" or "6404110000"). Dots and spaces are ignored.',
60
+ },
61
+ origin_country: {
62
+ type: 'string',
63
+ description: 'ISO-2 origin country code (e.g. "CN" for China, "VN" for Vietnam, "MX" for Mexico). Default: CN.',
64
+ default: 'CN',
65
+ },
66
+ annual_import_value_usd: {
67
+ type: 'number',
68
+ description: 'Optional. Your annual import value in USD. If provided, the response includes the dollar cost of current duties and the additional cost from the Nov 10 cliff.',
69
+ },
70
+ },
71
+ required: ['hts_code'],
72
+ },
73
+ },
74
+ ],
75
+ }));
76
+
77
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
78
+ const { name, arguments: args } = req.params;
79
+
80
+ if (name === 'lookup_hts_code') {
81
+ const query = String(args.query || '').trim();
82
+ if (query.length < 2) {
83
+ return { content: [{ type: 'text', text: 'Query must be at least 2 characters.' }] };
84
+ }
85
+ let data;
86
+ try {
87
+ data = await apiFetch('/hts/search?q=' + encodeURIComponent(query));
88
+ } catch (e) {
89
+ return { content: [{ type: 'text', text: 'Could not reach Tariff Monitor API: ' + e.message }] };
90
+ }
91
+ if (!data.ok || !data.results?.length) {
92
+ return { content: [{ type: 'text', text: 'No HTS codes found matching "' + query + '". Try a broader description or check the code prefix.' }] };
93
+ }
94
+ const rows = data.results.map(r => `${r.hts10} ${r.description}`).join('\n');
95
+ return {
96
+ content: [{
97
+ type: 'text',
98
+ text: `HTS codes matching "${query}":\n\n${rows}\n\nUse calculate_tariff with the most relevant code.`,
99
+ }],
100
+ };
101
+ }
102
+
103
+ if (name === 'calculate_tariff') {
104
+ const hts = String(args.hts_code || '').replace(/[^0-9]/g, '');
105
+ const country = String(args.origin_country || 'CN').toUpperCase().slice(0, 2);
106
+ const vol = Number(args.annual_import_value_usd) || 0;
107
+
108
+ if (hts.length < 6) {
109
+ return { content: [{ type: 'text', text: 'hts_code must be at least 6 digits. Use lookup_hts_code to find the right code.' }] };
110
+ }
111
+ if (!/^[A-Z]{2}$/.test(country)) {
112
+ return { content: [{ type: 'text', text: 'origin_country must be an ISO-2 code (e.g. CN, VN, MX, IN, KR, TW, DE, JP).' }] };
113
+ }
114
+
115
+ let d;
116
+ try {
117
+ d = await apiFetch(`/rate?hts=${encodeURIComponent(hts)}&country=${country}&explain=1${vol > 0 ? '&unit_cost=0' : ''}&utm_source=tariffmonitor-mcp`);
118
+ } catch (e) {
119
+ return { content: [{ type: 'text', text: 'Could not reach Tariff Monitor API: ' + e.message }] };
120
+ }
121
+
122
+ if (!d.ok) {
123
+ return { content: [{ type: 'text', text: `HTS code ${hts} not found in the current US schedule. Use lookup_hts_code to find the right code.` }] };
124
+ }
125
+
126
+ const layers = (d.layers || []).map(l =>
127
+ ` ${l.label}: +${Number(l.rate).toFixed(2)}%`
128
+ ).join('\n');
129
+
130
+ const cliffDelta = (d.cliff_total_rate - d.total_rate).toFixed(2);
131
+ const cliffLine = Number(cliffDelta) > 0
132
+ ? `\nNov 10, 2026 cliff: ${d.cliff_total_rate.toFixed(2)}% (+${cliffDelta}pp jump)`
133
+ : '\nNo cliff change projected for this code/country combination.';
134
+
135
+ let dollarLines = '';
136
+ if (vol > 0) {
137
+ const currentDuty = Math.round(d.total_rate / 100 * vol);
138
+ const cliffExtra = Number(cliffDelta) > 0 ? Math.round(Number(cliffDelta) / 100 * vol) : 0;
139
+ dollarLines = `\n\nDollar impact at $${vol.toLocaleString()}/yr import value:`
140
+ + `\n Current annual duties: $${currentDuty.toLocaleString()}`
141
+ + (cliffExtra > 0 ? `\n Additional after Nov 10 cliff: $${cliffExtra.toLocaleString()}/yr` : '');
142
+ }
143
+
144
+ const explainBlock = d.explanation ? `\n\nExplanation: ${d.explanation}` : '';
145
+
146
+ const text = [
147
+ `HTS ${d.hts10} — ${d.description}`,
148
+ `Origin: ${country}`,
149
+ '',
150
+ 'Rate stack:',
151
+ layers,
152
+ `Total current rate: ${d.total_rate.toFixed(2)}%`,
153
+ cliffLine,
154
+ dollarLines,
155
+ explainBlock,
156
+ '',
157
+ `Data source: ${PACK_URL}`,
158
+ `Full 67-code Survival Kit (pre-computed cliff math): ${BUY_URL}`,
159
+ ].join('\n').replace(/\n{3,}/g, '\n\n').trim();
160
+
161
+ return { content: [{ type: 'text', text }] };
162
+ }
163
+
164
+ return { content: [{ type: 'text', text: `Unknown tool: ${name}` }] };
165
+ });
166
+
167
+ const transport = new StdioServerTransport();
168
+ await server.connect(transport);