@markcolabs/mcp 0.3.0 → 0.4.1
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.
- package/README.md +126 -186
- package/dist/index.d.ts +9 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -284
- package/dist/index.js.map +1 -1
- package/package.json +15 -13
- package/LICENSE-API.md +0 -111
- package/dist/disclaimers/ymyl.d.ts +0 -16
- package/dist/disclaimers/ymyl.d.ts.map +0 -1
- package/dist/disclaimers/ymyl.js +0 -20
- package/dist/disclaimers/ymyl.js.map +0 -1
- package/dist/engines/compoundInterest.d.ts +0 -75
- package/dist/engines/compoundInterest.d.ts.map +0 -1
- package/dist/engines/compoundInterest.js +0 -74
- package/dist/engines/compoundInterest.js.map +0 -1
- package/dist/engines/data/federalTax.d.ts +0 -47
- package/dist/engines/data/federalTax.d.ts.map +0 -1
- package/dist/engines/data/federalTax.js +0 -111
- package/dist/engines/data/federalTax.js.map +0 -1
- package/dist/engines/data/irs2026.d.ts +0 -137
- package/dist/engines/data/irs2026.d.ts.map +0 -1
- package/dist/engines/data/irs2026.js +0 -113
- package/dist/engines/data/irs2026.js.map +0 -1
- package/dist/engines/data/rmd2026.d.ts +0 -59
- package/dist/engines/data/rmd2026.d.ts.map +0 -1
- package/dist/engines/data/rmd2026.js +0 -75
- package/dist/engines/data/rmd2026.js.map +0 -1
- package/dist/engines/data/ssa.d.ts +0 -39
- package/dist/engines/data/ssa.d.ts.map +0 -1
- package/dist/engines/data/ssa.js +0 -55
- package/dist/engines/data/ssa.js.map +0 -1
- package/dist/engines/data/stateTax2026.d.ts +0 -114
- package/dist/engines/data/stateTax2026.d.ts.map +0 -1
- package/dist/engines/data/stateTax2026.js +0 -348
- package/dist/engines/data/stateTax2026.js.map +0 -1
- package/dist/engines/hsa.d.ts +0 -110
- package/dist/engines/hsa.d.ts.map +0 -1
- package/dist/engines/hsa.js +0 -83
- package/dist/engines/hsa.js.map +0 -1
- package/dist/engines/ira.d.ts +0 -115
- package/dist/engines/ira.d.ts.map +0 -1
- package/dist/engines/ira.js +0 -127
- package/dist/engines/ira.js.map +0 -1
- package/dist/engines/mortgage.d.ts +0 -70
- package/dist/engines/mortgage.d.ts.map +0 -1
- package/dist/engines/mortgage.js +0 -60
- package/dist/engines/mortgage.js.map +0 -1
- package/dist/engines/paycheck.d.ts +0 -128
- package/dist/engines/paycheck.d.ts.map +0 -1
- package/dist/engines/paycheck.js +0 -142
- package/dist/engines/paycheck.js.map +0 -1
- package/dist/engines/retirement401k.d.ts +0 -109
- package/dist/engines/retirement401k.d.ts.map +0 -1
- package/dist/engines/retirement401k.js +0 -130
- package/dist/engines/retirement401k.js.map +0 -1
- package/dist/engines/rmd.d.ts +0 -107
- package/dist/engines/rmd.d.ts.map +0 -1
- package/dist/engines/rmd.js +0 -109
- package/dist/engines/rmd.js.map +0 -1
- package/dist/engines/rothConversion.d.ts +0 -124
- package/dist/engines/rothConversion.d.ts.map +0 -1
- package/dist/engines/rothConversion.js +0 -145
- package/dist/engines/rothConversion.js.map +0 -1
- package/dist/engines/socialSecurity.d.ts +0 -63
- package/dist/engines/socialSecurity.d.ts.map +0 -1
- package/dist/engines/socialSecurity.js +0 -139
- package/dist/engines/socialSecurity.js.map +0 -1
- package/dist/envelope.d.ts +0 -76
- package/dist/envelope.d.ts.map +0 -1
- package/dist/envelope.js +0 -34
- package/dist/envelope.js.map +0 -1
- package/dist/shared/bounds.d.ts +0 -133
- package/dist/shared/bounds.d.ts.map +0 -1
- package/dist/shared/bounds.js +0 -206
- package/dist/shared/bounds.js.map +0 -1
- package/dist/tools/compoundInterest.d.ts +0 -48
- package/dist/tools/compoundInterest.d.ts.map +0 -1
- package/dist/tools/compoundInterest.js +0 -107
- package/dist/tools/compoundInterest.js.map +0 -1
- package/dist/tools/hsa.d.ts +0 -58
- package/dist/tools/hsa.d.ts.map +0 -1
- package/dist/tools/hsa.js +0 -129
- package/dist/tools/hsa.js.map +0 -1
- package/dist/tools/ira.d.ts +0 -55
- package/dist/tools/ira.d.ts.map +0 -1
- package/dist/tools/ira.js +0 -117
- package/dist/tools/ira.js.map +0 -1
- package/dist/tools/mortgage.d.ts +0 -51
- package/dist/tools/mortgage.d.ts.map +0 -1
- package/dist/tools/mortgage.js +0 -112
- package/dist/tools/mortgage.js.map +0 -1
- package/dist/tools/paycheck.d.ts +0 -61
- package/dist/tools/paycheck.d.ts.map +0 -1
- package/dist/tools/paycheck.js +0 -135
- package/dist/tools/paycheck.js.map +0 -1
- package/dist/tools/retirement401k.d.ts +0 -85
- package/dist/tools/retirement401k.d.ts.map +0 -1
- package/dist/tools/retirement401k.js +0 -141
- package/dist/tools/retirement401k.js.map +0 -1
- package/dist/tools/rmd.d.ts +0 -60
- package/dist/tools/rmd.d.ts.map +0 -1
- package/dist/tools/rmd.js +0 -130
- package/dist/tools/rmd.js.map +0 -1
- package/dist/tools/rothConversion.d.ts +0 -66
- package/dist/tools/rothConversion.d.ts.map +0 -1
- package/dist/tools/rothConversion.js +0 -141
- package/dist/tools/rothConversion.js.map +0 -1
- package/dist/tools/socialSecurity.d.ts +0 -51
- package/dist/tools/socialSecurity.d.ts.map +0 -1
- package/dist/tools/socialSecurity.js +0 -117
- package/dist/tools/socialSecurity.js.map +0 -1
- package/dist/util/zod-to-json-schema.d.ts +0 -28
- package/dist/util/zod-to-json-schema.d.ts.map +0 -1
- package/dist/util/zod-to-json-schema.js +0 -98
- package/dist/util/zod-to-json-schema.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,295 +1,67 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @markcolabs/mcp —
|
|
3
|
+
* @markcolabs/mcp v0.4.1 — stdio↔HTTPS shim.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* - 9 tools:
|
|
8
|
-
* dc.calculator.mortgage.monthlyPayment (S135 Item 5)
|
|
9
|
-
* dc.calculator.compoundInterest.futureValue (S135 Item 5)
|
|
10
|
-
* dc.calculator.retirement401k.projection (S136 Item 3, renamed v0.2.0 per ADR-0041 D2)
|
|
11
|
-
* dc.calculator.socialSecurity.estimatedBenefit (S136 Item 3, renamed v0.2.0 per ADR-0041 D2)
|
|
12
|
-
* dc.calculator.paycheck.netPay (S136 Item 3)
|
|
13
|
-
* dc.calculator.ira.contributionLimit (S141 Wave 1A)
|
|
14
|
-
* dc.calculator.rothConversion.taxImpact (S141 Wave 1A)
|
|
15
|
-
* dc.calculator.rmd.distributionAmount (S141 Wave 1B — new)
|
|
16
|
-
* dc.calculator.hsa.contributionLimit (S141 Wave 1B — new)
|
|
17
|
-
* - 1 resource: dc://disclaimers/ymyl (canonical YMYL disclaimer)
|
|
5
|
+
* Proxies MCP JSON-RPC messages from stdin to the hosted MCP server at
|
|
6
|
+
* mcp.digitalcalculator.info/mcp and writes responses back to stdout.
|
|
18
7
|
*
|
|
19
|
-
*
|
|
8
|
+
* Per ADR-0044a (ACCEPTED 2026-05-28): engine source lives in the private
|
|
9
|
+
* monorepo at infra/mcp/. This shim contains no calculation logic — it is
|
|
10
|
+
* a thin transport adapter only. MIT-licensed.
|
|
20
11
|
*
|
|
21
|
-
*
|
|
12
|
+
* Claude Desktop config:
|
|
13
|
+
* { "mcpServers": { "digitalcalculator": { "command": "npx", "args": ["-y", "@markcolabs/mcp"] } } }
|
|
22
14
|
*/
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export { execute as executeSocialSecurityTool } from "./tools/socialSecurity.js";
|
|
43
|
-
export { execute as executePaycheckTool } from "./tools/paycheck.js";
|
|
44
|
-
export { execute as executeIraTool } from "./tools/ira.js";
|
|
45
|
-
export { execute as executeRothConversionTool } from "./tools/rothConversion.js";
|
|
46
|
-
export { execute as executeRmdTool } from "./tools/rmd.js";
|
|
47
|
-
export { execute as executeHsaTool } from "./tools/hsa.js";
|
|
48
|
-
export * as mortgageEngine from "./engines/mortgage.js";
|
|
49
|
-
export * as compoundInterestEngine from "./engines/compoundInterest.js";
|
|
50
|
-
export * as retirement401kEngine from "./engines/retirement401k.js";
|
|
51
|
-
export * as socialSecurityEngine from "./engines/socialSecurity.js";
|
|
52
|
-
export * as paycheckEngine from "./engines/paycheck.js";
|
|
53
|
-
export * as iraEngine from "./engines/ira.js";
|
|
54
|
-
export * as rothConversionEngine from "./engines/rothConversion.js";
|
|
55
|
-
export * as rmdEngine from "./engines/rmd.js";
|
|
56
|
-
export * as hsaEngine from "./engines/hsa.js";
|
|
57
|
-
export * from "./envelope.js";
|
|
58
|
-
// ---------------------------------------------------------------------------
|
|
59
|
-
// Server setup
|
|
60
|
-
// ---------------------------------------------------------------------------
|
|
61
|
-
const server = new Server({
|
|
62
|
-
name: "@markcolabs/mcp",
|
|
63
|
-
version: "0.3.0",
|
|
64
|
-
}, {
|
|
65
|
-
capabilities: {
|
|
66
|
-
tools: {},
|
|
67
|
-
resources: {},
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
// ---------------------------------------------------------------------------
|
|
71
|
-
// tools/list
|
|
72
|
-
// ---------------------------------------------------------------------------
|
|
73
|
-
/**
|
|
74
|
-
* Tool annotations per Anthropic Claude Connectors Directory spec
|
|
75
|
-
* (MCP-AUDIT-023, S141 Item #5):
|
|
76
|
-
* - title: human-readable display name (sentence-case)
|
|
77
|
-
* - readOnlyHint: true — all our tools are pure functions, no mutation
|
|
78
|
-
* - destructiveHint: false — no tool modifies any state
|
|
79
|
-
*
|
|
80
|
-
* Applied uniformly across all 9 tools — the package is read-only by design
|
|
81
|
-
* (MCP-AUDIT-008 audit-bundle conclusion).
|
|
82
|
-
*/
|
|
83
|
-
const READ_ONLY_ANNOTATIONS = {
|
|
84
|
-
readOnlyHint: true,
|
|
85
|
-
destructiveHint: false,
|
|
86
|
-
};
|
|
87
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
88
|
-
return {
|
|
89
|
-
tools: [
|
|
90
|
-
{
|
|
91
|
-
name: mortgageTool.TOOL_NAME,
|
|
92
|
-
description: mortgageTool.TOOL_DESCRIPTION,
|
|
93
|
-
inputSchema: zodToJsonSchema(mortgageTool.MortgageMonthlyPaymentInputSchema),
|
|
94
|
-
annotations: {
|
|
95
|
-
title: "Mortgage Monthly Payment",
|
|
96
|
-
...READ_ONLY_ANNOTATIONS,
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: compoundInterestTool.TOOL_NAME,
|
|
101
|
-
description: compoundInterestTool.TOOL_DESCRIPTION,
|
|
102
|
-
inputSchema: zodToJsonSchema(compoundInterestTool.CompoundInterestFutureValueInputSchema),
|
|
103
|
-
annotations: {
|
|
104
|
-
title: "Compound Interest Future Value",
|
|
105
|
-
...READ_ONLY_ANNOTATIONS,
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
name: retirement401kTool.TOOL_NAME,
|
|
110
|
-
description: retirement401kTool.TOOL_DESCRIPTION,
|
|
111
|
-
inputSchema: zodToJsonSchema(retirement401kTool.Retirement401kProjectionInputSchema),
|
|
112
|
-
annotations: {
|
|
113
|
-
title: "401(k) Retirement Projection",
|
|
114
|
-
...READ_ONLY_ANNOTATIONS,
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
name: socialSecurityTool.TOOL_NAME,
|
|
119
|
-
description: socialSecurityTool.TOOL_DESCRIPTION,
|
|
120
|
-
inputSchema: zodToJsonSchema(socialSecurityTool.SocialSecurityEstimateInputSchema),
|
|
121
|
-
annotations: {
|
|
122
|
-
title: "Social Security Estimated Benefit",
|
|
123
|
-
...READ_ONLY_ANNOTATIONS,
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
name: paycheckTool.TOOL_NAME,
|
|
128
|
-
description: paycheckTool.TOOL_DESCRIPTION,
|
|
129
|
-
inputSchema: zodToJsonSchema(paycheckTool.PaycheckNetPayInputSchema),
|
|
130
|
-
annotations: {
|
|
131
|
-
title: "Paycheck Net Pay",
|
|
132
|
-
...READ_ONLY_ANNOTATIONS,
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
name: iraTool.TOOL_NAME,
|
|
137
|
-
description: iraTool.TOOL_DESCRIPTION,
|
|
138
|
-
inputSchema: zodToJsonSchema(iraTool.IraContributionLimitInputSchema),
|
|
139
|
-
annotations: {
|
|
140
|
-
title: "IRA Contribution Limit",
|
|
141
|
-
...READ_ONLY_ANNOTATIONS,
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
name: rothConversionTool.TOOL_NAME,
|
|
146
|
-
description: rothConversionTool.TOOL_DESCRIPTION,
|
|
147
|
-
inputSchema: zodToJsonSchema(rothConversionTool.RothConversionTaxImpactInputSchema),
|
|
148
|
-
annotations: {
|
|
149
|
-
title: "Roth Conversion Tax Impact",
|
|
150
|
-
...READ_ONLY_ANNOTATIONS,
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
name: rmdTool.TOOL_NAME,
|
|
155
|
-
description: rmdTool.TOOL_DESCRIPTION,
|
|
156
|
-
inputSchema: zodToJsonSchema(rmdTool.RmdDistributionAmountInputSchema),
|
|
157
|
-
annotations: {
|
|
158
|
-
title: "RMD Distribution Amount",
|
|
159
|
-
...READ_ONLY_ANNOTATIONS,
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
name: hsaTool.TOOL_NAME,
|
|
164
|
-
description: hsaTool.TOOL_DESCRIPTION,
|
|
165
|
-
inputSchema: zodToJsonSchema(hsaTool.HsaContributionLimitInputSchema),
|
|
166
|
-
annotations: {
|
|
167
|
-
title: "HSA Contribution Limit",
|
|
168
|
-
...READ_ONLY_ANNOTATIONS,
|
|
169
|
-
},
|
|
15
|
+
import * as readline from "readline";
|
|
16
|
+
import * as https from "https";
|
|
17
|
+
const MCP_ENDPOINT = "https://mcp.digitalcalculator.info/mcp";
|
|
18
|
+
const SESSION_ID = Math.random().toString(36).slice(2);
|
|
19
|
+
const PACKAGE_VERSION = "0.4.1";
|
|
20
|
+
const REQUEST_TIMEOUT_MS = 30_000;
|
|
21
|
+
function post(body) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const url = new URL(MCP_ENDPOINT);
|
|
24
|
+
const data = Buffer.from(body);
|
|
25
|
+
const req = https.request({
|
|
26
|
+
hostname: url.hostname,
|
|
27
|
+
path: url.pathname,
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: {
|
|
30
|
+
"Content-Type": "application/json",
|
|
31
|
+
"Content-Length": data.byteLength,
|
|
32
|
+
"Mcp-Session-Id": SESSION_ID,
|
|
33
|
+
"User-Agent": `@markcolabs/mcp/${PACKAGE_VERSION}`,
|
|
170
34
|
},
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
result = socialSecurityTool.execute(args);
|
|
192
|
-
break;
|
|
193
|
-
case paycheckTool.TOOL_NAME:
|
|
194
|
-
result = paycheckTool.execute(args);
|
|
195
|
-
break;
|
|
196
|
-
case iraTool.TOOL_NAME:
|
|
197
|
-
result = iraTool.execute(args);
|
|
198
|
-
break;
|
|
199
|
-
case rothConversionTool.TOOL_NAME:
|
|
200
|
-
result = rothConversionTool.execute(args);
|
|
201
|
-
break;
|
|
202
|
-
case rmdTool.TOOL_NAME:
|
|
203
|
-
result = rmdTool.execute(args);
|
|
204
|
-
break;
|
|
205
|
-
case hsaTool.TOOL_NAME:
|
|
206
|
-
result = hsaTool.execute(args);
|
|
207
|
-
break;
|
|
208
|
-
default:
|
|
209
|
-
return {
|
|
210
|
-
isError: true,
|
|
211
|
-
content: [
|
|
212
|
-
{
|
|
213
|
-
type: "text",
|
|
214
|
-
text: JSON.stringify({
|
|
215
|
-
error: {
|
|
216
|
-
code: "INPUT_VALIDATION",
|
|
217
|
-
message: `Unknown tool: ${name}`,
|
|
218
|
-
retriable: false,
|
|
219
|
-
},
|
|
220
|
-
}),
|
|
221
|
-
},
|
|
222
|
-
],
|
|
223
|
-
};
|
|
35
|
+
timeout: REQUEST_TIMEOUT_MS,
|
|
36
|
+
}, (res) => {
|
|
37
|
+
const chunks = [];
|
|
38
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
39
|
+
res.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
40
|
+
});
|
|
41
|
+
req.on("timeout", () => req.destroy(new Error(`Request timed out after ${REQUEST_TIMEOUT_MS / 1000}s`)));
|
|
42
|
+
req.on("error", reject);
|
|
43
|
+
req.write(data);
|
|
44
|
+
req.end();
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const rl = readline.createInterface({ input: process.stdin, terminal: false });
|
|
48
|
+
rl.on("line", async (line) => {
|
|
49
|
+
const trimmed = line.trim();
|
|
50
|
+
if (!trimmed)
|
|
51
|
+
return;
|
|
52
|
+
try {
|
|
53
|
+
const response = await post(trimmed);
|
|
54
|
+
process.stdout.write(response + "\n");
|
|
224
55
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
};
|
|
56
|
+
catch (err) {
|
|
57
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
58
|
+
const parsed = (() => { try {
|
|
59
|
+
return JSON.parse(trimmed);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return {};
|
|
63
|
+
} })();
|
|
64
|
+
process.stdout.write(JSON.stringify({ jsonrpc: "2.0", id: parsed.id ?? null, error: { code: -32603, message } }) + "\n");
|
|
234
65
|
}
|
|
235
|
-
return {
|
|
236
|
-
isError: true,
|
|
237
|
-
content: [
|
|
238
|
-
{
|
|
239
|
-
type: "text",
|
|
240
|
-
text: JSON.stringify(result.error),
|
|
241
|
-
},
|
|
242
|
-
],
|
|
243
|
-
};
|
|
244
|
-
});
|
|
245
|
-
// ---------------------------------------------------------------------------
|
|
246
|
-
// resources/list — exposes the canonical YMYL disclaimer (O5-KR2 stub)
|
|
247
|
-
// ---------------------------------------------------------------------------
|
|
248
|
-
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
249
|
-
return {
|
|
250
|
-
resources: [
|
|
251
|
-
{
|
|
252
|
-
uri: YMYL_DISCLAIMER_URI,
|
|
253
|
-
name: "Canonical YMYL Disclaimer",
|
|
254
|
-
description: "Single source of truth for the YMYL disclaimer string returned in every tool response.",
|
|
255
|
-
mimeType: "text/plain",
|
|
256
|
-
},
|
|
257
|
-
],
|
|
258
|
-
};
|
|
259
66
|
});
|
|
260
|
-
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
261
|
-
const { uri } = request.params;
|
|
262
|
-
if (uri === YMYL_DISCLAIMER_URI) {
|
|
263
|
-
return {
|
|
264
|
-
contents: [
|
|
265
|
-
{
|
|
266
|
-
uri,
|
|
267
|
-
mimeType: "text/plain",
|
|
268
|
-
text: YMYL_DISCLAIMER,
|
|
269
|
-
},
|
|
270
|
-
],
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
throw new Error(`Unknown resource: ${uri}`);
|
|
274
|
-
});
|
|
275
|
-
// ---------------------------------------------------------------------------
|
|
276
|
-
// Boot — only run when invoked directly (not when imported by tests).
|
|
277
|
-
// ---------------------------------------------------------------------------
|
|
278
|
-
async function main() {
|
|
279
|
-
const transport = new StdioServerTransport();
|
|
280
|
-
await server.connect(transport);
|
|
281
|
-
// eslint-disable-next-line no-console
|
|
282
|
-
console.error("[@markcolabs/mcp] v0.3.0 ready (stdio) — 9 tools registered.");
|
|
283
|
-
}
|
|
284
|
-
// Run only when invoked as a binary, not when imported by parity tests.
|
|
285
|
-
const isDirect = import.meta.url === `file://${process.argv[1]}` ||
|
|
286
|
-
process.argv[1]?.endsWith("dist/index.js") ||
|
|
287
|
-
process.argv[1]?.endsWith("dist\\index.js");
|
|
288
|
-
if (isDirect) {
|
|
289
|
-
main().catch((err) => {
|
|
290
|
-
// eslint-disable-next-line no-console
|
|
291
|
-
console.error("[@markcolabs/mcp] fatal:", err);
|
|
292
|
-
process.exit(1);
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
67
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markcolabs/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "MCP stdio↔HTTPS shim for digitalcalculator.info financial calculators. Proxies MCP JSON-RPC to the hosted server at mcp.digitalcalculator.info/mcp. Per ADR-0044a: engine source is private; this package is a thin transport adapter only.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
@@ -12,24 +12,17 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "tsc",
|
|
14
14
|
"start": "node ./dist/index.js",
|
|
15
|
-
"test": "vitest run",
|
|
16
|
-
"test:watch": "vitest",
|
|
17
15
|
"typecheck": "tsc --noEmit"
|
|
18
16
|
},
|
|
19
17
|
"files": [
|
|
20
18
|
"dist",
|
|
21
19
|
"README.md",
|
|
22
|
-
"LICENSE"
|
|
23
|
-
"LICENSE-API.md"
|
|
20
|
+
"LICENSE"
|
|
24
21
|
],
|
|
25
|
-
"dependencies": {
|
|
26
|
-
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
27
|
-
"zod": "^3.23.8"
|
|
28
|
-
},
|
|
22
|
+
"dependencies": {},
|
|
29
23
|
"devDependencies": {
|
|
30
24
|
"@types/node": "^20.12.7",
|
|
31
|
-
"typescript": "^5.4.5"
|
|
32
|
-
"vitest": "^4.0.18"
|
|
25
|
+
"typescript": "^5.4.5"
|
|
33
26
|
},
|
|
34
27
|
"engines": {
|
|
35
28
|
"node": ">=18.0.0"
|
|
@@ -50,8 +43,17 @@
|
|
|
50
43
|
"roth-conversion",
|
|
51
44
|
"rmd",
|
|
52
45
|
"hsa",
|
|
46
|
+
"inflation",
|
|
47
|
+
"savings",
|
|
53
48
|
"digitalcalculator",
|
|
54
|
-
"digitalcalculator.info"
|
|
49
|
+
"digitalcalculator.info",
|
|
50
|
+
"financial-planning",
|
|
51
|
+
"loan",
|
|
52
|
+
"retirement-planning",
|
|
53
|
+
"investment",
|
|
54
|
+
"debt",
|
|
55
|
+
"capital-gains",
|
|
56
|
+
"net-worth"
|
|
55
57
|
],
|
|
56
58
|
"author": "Markcolabs LLC",
|
|
57
59
|
"license": "MIT",
|
package/LICENSE-API.md
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
# Hosted API Terms — `mcp.digitalcalculator.info/mcp`
|
|
2
|
-
|
|
3
|
-
**Document**: LICENSE-API.md
|
|
4
|
-
**Applies to**: Use of the **hosted** MCP API at `https://mcp.digitalcalculator.info/mcp` operated by Markco Labs LLC.
|
|
5
|
-
**Does NOT apply to**: Self-hosted use of the `@markcolabs/mcp` source code, which is governed by the [MIT LICENSE](./LICENSE) that ships in this package.
|
|
6
|
-
|
|
7
|
-
These terms are distinct from, and complementary to, the MIT license that
|
|
8
|
-
governs the package source. The MIT license lets you copy, modify, and
|
|
9
|
-
redistribute the source — including running your own copy of the server on
|
|
10
|
-
your own infrastructure. These hosted-API terms govern how you may interact
|
|
11
|
-
with the Markco Labs–operated HTTP endpoint at the URL above.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 1. Scope
|
|
16
|
-
|
|
17
|
-
These terms apply **only** to HTTP requests made to
|
|
18
|
-
`https://mcp.digitalcalculator.info/mcp` (and any future host-name variants
|
|
19
|
-
operated by Markco Labs LLC for the same service).
|
|
20
|
-
|
|
21
|
-
If you `npm install @markcolabs/mcp` and run it locally over MCP stdio, or
|
|
22
|
-
deploy it to your own infrastructure, the MIT [LICENSE](./LICENSE) is the only
|
|
23
|
-
license that applies — these hosted-API terms do not bind you in that mode.
|
|
24
|
-
|
|
25
|
-
## 2. Acceptable Use
|
|
26
|
-
|
|
27
|
-
The hosted endpoint is free to use, without signup or API key, subject to the
|
|
28
|
-
following acceptable-use constraints:
|
|
29
|
-
|
|
30
|
-
- **No scraping at scale.** The endpoint is for interactive AI agent calls and
|
|
31
|
-
developer integrations. Bulk crawling of every input combination to build
|
|
32
|
-
derivative datasets is not permitted.
|
|
33
|
-
- **No resale of raw API output as a standalone product.** Embedding tool
|
|
34
|
-
responses inside a larger product (AI agent answers, calculators, dashboards)
|
|
35
|
-
is fine and encouraged. Selling the raw JSON responses as a paid feed is not.
|
|
36
|
-
- **No sole-authority financial decisions.** The tools return YMYL (Your Money
|
|
37
|
-
or Your Life) estimates with a canonical disclaimer (see
|
|
38
|
-
`packages/mcp/src/disclaimers/ymyl.ts`). Downstream products must surface
|
|
39
|
-
the disclaimer alongside the numbers and must not present the results as
|
|
40
|
-
professional financial, tax, legal, or investment advice. Verify all
|
|
41
|
-
outputs against the canonical methodology pages on
|
|
42
|
-
[www.digitalcalculator.info](https://www.digitalcalculator.info) before
|
|
43
|
-
acting on them.
|
|
44
|
-
- **No reverse-engineering of throttle behavior** to evade rate limits, and
|
|
45
|
-
no use of multiple IPs / clients to multiply effective throughput beyond
|
|
46
|
-
the published thresholds.
|
|
47
|
-
|
|
48
|
-
## 3. Rate Limits
|
|
49
|
-
|
|
50
|
-
The hosted endpoint enforces a per-IP rate limit:
|
|
51
|
-
|
|
52
|
-
- **100 requests per 5 minutes per source IP** (WAFv2-enforced floor).
|
|
53
|
-
- Bursts above this threshold receive HTTP 429 with the
|
|
54
|
-
`{"error":{"code":"RATE_LIMIT","retriable":true}}` envelope.
|
|
55
|
-
- Markco Labs reserves the right to tighten, loosen, or replace this throttle
|
|
56
|
-
at any time. Significant changes will be announced in the package CHANGELOG
|
|
57
|
-
and on the [/mcp/](https://www.digitalcalculator.info/mcp/) landing page.
|
|
58
|
-
|
|
59
|
-
Markco Labs reserves the right to suspend or block clients (by IP, ASN, or
|
|
60
|
-
other identifier) that materially exceed fair-share usage, generate abuse
|
|
61
|
-
patterns, or violate the acceptable-use terms above. Suspension decisions
|
|
62
|
-
are at Markco Labs' sole discretion.
|
|
63
|
-
|
|
64
|
-
## 4. No Warranty / Liability Limitation
|
|
65
|
-
|
|
66
|
-
THE HOSTED API IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
67
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
68
|
-
FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR ACCURACY OF THE
|
|
69
|
-
CALCULATIONS RETURNED.
|
|
70
|
-
|
|
71
|
-
Specifically:
|
|
72
|
-
|
|
73
|
-
- **No accuracy warranty for hosted output.** Although the engines that power
|
|
74
|
-
the hosted endpoint are parity-tested against the canonical calculators at
|
|
75
|
-
www.digitalcalculator.info on every release, the hosted endpoint is a
|
|
76
|
-
convenience surface. Authoritative results for any consequential financial
|
|
77
|
-
decision must be verified against the corresponding methodology page on the
|
|
78
|
-
main site (linked via the `methodology.url` field of every response
|
|
79
|
-
envelope).
|
|
80
|
-
- **No uptime SLA.** The hosted endpoint is offered free of charge and runs
|
|
81
|
-
on best-effort infrastructure. No service-level agreement is provided.
|
|
82
|
-
- **No liability for downstream use.** Markco Labs is not liable for any
|
|
83
|
-
damages — direct, indirect, incidental, special, consequential, or punitive
|
|
84
|
-
— arising from your use of the hosted endpoint, including but not limited
|
|
85
|
-
to losses caused by acting on inaccurate or out-of-date calculations.
|
|
86
|
-
|
|
87
|
-
Self-hosters running the MIT-licensed source independently are governed only
|
|
88
|
-
by the warranty disclaimer in the [LICENSE](./LICENSE) file — not by this
|
|
89
|
-
section.
|
|
90
|
-
|
|
91
|
-
## 5. Contact
|
|
92
|
-
|
|
93
|
-
- **Technical issues** (bugs, broken responses, integration questions): open
|
|
94
|
-
an issue at
|
|
95
|
-
[github.com/mark57-ux/digitalcalculator/issues](https://github.com/mark57-ux/digitalcalculator/issues).
|
|
96
|
-
Best-effort triage, no SLA.
|
|
97
|
-
- **Acceptable-use questions or abuse reports**: open a GitHub issue with the
|
|
98
|
-
`mcp-abuse` label, or use the contact path on
|
|
99
|
-
[www.digitalcalculator.info](https://www.digitalcalculator.info).
|
|
100
|
-
- **Content / accuracy concerns**: the canonical YMYL disclaimer policy
|
|
101
|
-
(see `packages/mcp/src/disclaimers/ymyl.ts` and the response envelope)
|
|
102
|
-
applies. Direct content/accuracy disputes to the corresponding calculator's
|
|
103
|
-
methodology page on www.digitalcalculator.info.
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
These terms may be updated from time to time. The version that applies to a
|
|
108
|
-
given request is the version that was current at the time the request was
|
|
109
|
-
served. Material changes are noted in `packages/mcp/CHANGELOG.md`.
|
|
110
|
-
|
|
111
|
-
Last updated: 2026-05-27 (v0.2.1 patch release).
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canonical YMYL disclaimer — single source of truth.
|
|
3
|
-
*
|
|
4
|
-
* Per ADR-0039 § 3 and § Implementation Notes / "YMYL disclaimer canonicalization":
|
|
5
|
-
* - Every ToolResult.disclaimer field embeds this exact string.
|
|
6
|
-
* - The same string is exposed as the `dc://disclaimers/ymyl` MCP resource.
|
|
7
|
-
* - Tools do NOT author their own disclaimers. All MCP responses use this constant.
|
|
8
|
-
*
|
|
9
|
-
* Authoring is owned by Content. Updates here propagate to every tool response.
|
|
10
|
-
*/
|
|
11
|
-
export declare const YMYL_DISCLAIMER: string;
|
|
12
|
-
/**
|
|
13
|
-
* MCP resource URI under which the disclaimer is exposed (O5-KR2).
|
|
14
|
-
*/
|
|
15
|
-
export declare const YMYL_DISCLAIMER_URI = "dc://disclaimers/ymyl";
|
|
16
|
-
//# sourceMappingURL=ymyl.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ymyl.d.ts","sourceRoot":"","sources":["../../src/disclaimers/ymyl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,QAKqE,CAAC;AAElG;;GAEG;AACH,eAAO,MAAM,mBAAmB,0BAA0B,CAAC"}
|
package/dist/disclaimers/ymyl.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canonical YMYL disclaimer — single source of truth.
|
|
3
|
-
*
|
|
4
|
-
* Per ADR-0039 § 3 and § Implementation Notes / "YMYL disclaimer canonicalization":
|
|
5
|
-
* - Every ToolResult.disclaimer field embeds this exact string.
|
|
6
|
-
* - The same string is exposed as the `dc://disclaimers/ymyl` MCP resource.
|
|
7
|
-
* - Tools do NOT author their own disclaimers. All MCP responses use this constant.
|
|
8
|
-
*
|
|
9
|
-
* Authoring is owned by Content. Updates here propagate to every tool response.
|
|
10
|
-
*/
|
|
11
|
-
export const YMYL_DISCLAIMER = "Estimates only — for educational purposes. Results are computed in USD using deterministic " +
|
|
12
|
-
"formulas and the inputs you provided. They do not constitute financial, tax, legal, or " +
|
|
13
|
-
"investment advice. Actual rates, fees, taxes, and outcomes vary by lender, jurisdiction, " +
|
|
14
|
-
"and personal circumstances. Verify with a licensed professional before making financial " +
|
|
15
|
-
"decisions. Source: digitalcalculator.info — see methodology link for formula and assumptions.";
|
|
16
|
-
/**
|
|
17
|
-
* MCP resource URI under which the disclaimer is exposed (O5-KR2).
|
|
18
|
-
*/
|
|
19
|
-
export const YMYL_DISCLAIMER_URI = "dc://disclaimers/ymyl";
|
|
20
|
-
//# sourceMappingURL=ymyl.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ymyl.js","sourceRoot":"","sources":["../../src/disclaimers/ymyl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,eAAe,GAC1B,6FAA6F;IAC7F,yFAAyF;IACzF,2FAA2F;IAC3F,0FAA0F;IAC1F,+FAA+F,CAAC;AAElG;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC"}
|