@cyanheads/calculator-mcp-server 0.1.23 → 0.1.25
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/AGENTS.md +38 -22
- package/CLAUDE.md +38 -22
- package/README.md +2 -2
- package/dist/config/server-config.d.ts +5 -1
- package/dist/config/server-config.d.ts.map +1 -1
- package/dist/config/server-config.js +8 -6
- package/dist/config/server-config.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/resources/definitions/help.resource.d.ts +3 -1
- package/dist/mcp-server/resources/definitions/help.resource.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/calculate.tool.d.ts +16 -1
- package/dist/mcp-server/tools/definitions/calculate.tool.d.ts.map +1 -1
- package/package.json +7 -4
- package/server.json +3 -3
package/AGENTS.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** calculator-mcp-server
|
|
4
|
-
**Version:** 0.1.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.9.
|
|
4
|
+
**Version:** 0.1.25
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.9.13`
|
|
6
6
|
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/sdk` 1.29.0
|
|
8
8
|
**Zod:** 4.4.3
|
|
@@ -52,6 +52,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
52
52
|
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
53
53
|
- **Check `ctx.elicit` / `ctx.sample`** for presence before calling.
|
|
54
54
|
- **Secrets in env vars only** — never hardcoded.
|
|
55
|
+
- **Close the loop on issues.** When implementing work tracked by a GitHub issue, comment on the issue with what landed and close it. Do both — a comment without a close leaves stale issues open; a close without a comment leaves no record of what shipped. The comment is for future readers — state the concrete changes, not the conversation that produced them.
|
|
55
56
|
|
|
56
57
|
---
|
|
57
58
|
|
|
@@ -154,6 +155,11 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
154
155
|
| Property | Description |
|
|
155
156
|
|:---------|:------------|
|
|
156
157
|
| `ctx.log` | Request-scoped logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId. |
|
|
158
|
+
| `ctx.state` | Tenant-scoped KV — `.get(key)`, `.set(key, value, { ttl? })`, `.delete(key)`, `.list(prefix, { cursor, limit })`. Accepts any serializable value. |
|
|
159
|
+
| `ctx.elicit` | Ask user for structured input. **Check for presence first:** `if (ctx.elicit) { ... }` |
|
|
160
|
+
| `ctx.sample` | Request LLM completion from the client. **Check for presence first:** `if (ctx.sample) { ... }` |
|
|
161
|
+
| `ctx.signal` | `AbortSignal` for cancellation. |
|
|
162
|
+
| `ctx.progress` | Task progress (present when `task: true`) — `.setTotal(n)`, `.increment()`, `.update(message)`. |
|
|
157
163
|
| `ctx.requestId` | Unique request ID. |
|
|
158
164
|
| `ctx.tenantId` | Tenant ID from JWT or `'default'` for stdio. |
|
|
159
165
|
|
|
@@ -168,6 +174,8 @@ Handlers throw — the framework catches, classifies, and formats.
|
|
|
168
174
|
On the wire, tool errors mirror the success-path `format-parity` invariant — both `content[]` (markdown, read by clients like Claude Desktop) and `structuredContent.error` (JSON `{ code, message, data? }`, read by clients like Claude Code) carry the same payload, with `data.recovery.hint` mirrored into the markdown text when present.
|
|
169
175
|
|
|
170
176
|
```ts
|
|
177
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
178
|
+
|
|
171
179
|
errors: [
|
|
172
180
|
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
173
181
|
when: 'No item matched the query',
|
|
@@ -257,7 +265,9 @@ Available skills:
|
|
|
257
265
|
| `add-service` | Scaffold a new service integration |
|
|
258
266
|
| `add-test` | Scaffold test file for a tool, resource, or service |
|
|
259
267
|
| `field-test` | Exercise tools/resources/prompts with real inputs, verify behavior, report issues |
|
|
260
|
-
| `
|
|
268
|
+
| `code-simplifier` | Post-session code review and cleanup against `git diff` — modernize syntax, consolidate duplication, align with codebase |
|
|
269
|
+
| `git-wrapup` | Land working-tree changes as a versioned commit + annotated tag — version bump, changelog, verify, tag. Local only. |
|
|
270
|
+
| `tool-defs-analysis` | Read-only audit of MCP definition language across the surface — voice, leaks, defaults, recovery hints, output descriptions |
|
|
261
271
|
| `devcheck` | Lint, format, typecheck, audit |
|
|
262
272
|
| `security-pass` | Audit server for MCP-flavored security gaps: output injection, scope blast radius, input sinks, tenant isolation |
|
|
263
273
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
@@ -270,13 +280,12 @@ Available skills:
|
|
|
270
280
|
| `api-config` | AppConfig, parseConfig, env vars |
|
|
271
281
|
| `api-context` | Context interface, logger, state, progress |
|
|
272
282
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
273
|
-
| `api-linter` |
|
|
283
|
+
| `api-linter` | Definition linter rule catalog — invoked by `bun run lint:mcp` and `devcheck` |
|
|
274
284
|
| `api-services` | LLM, Speech, Graph services |
|
|
275
285
|
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
276
286
|
| `api-testing` | createMockContext, test patterns |
|
|
277
287
|
| `api-utils` | Formatting, parsing, security, pagination, scheduling, telemetry helpers |
|
|
278
288
|
| `api-workers` | Cloudflare Workers runtime |
|
|
279
|
-
| `migrate-mcp-ts-template` | Migrate a template fork to use `@cyanheads/mcp-ts-core` as a package |
|
|
280
289
|
|
|
281
290
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
|
282
291
|
|
|
@@ -311,30 +320,34 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
311
320
|
|
|
312
321
|
**Adding an env var requires both files:** `server.json` (`environmentVariables[]`) and `manifest.json` (`mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies env var names match.
|
|
313
322
|
|
|
314
|
-
**README install badges**
|
|
323
|
+
**README install badges** (Claude Desktop `.mcpb`, Cursor, VS Code) and the `base64` / `encodeURIComponent` config-generation commands are ship-time concerns — run the `polish-docs-meta` skill, which carries the badge format, layout, and generation snippets in `skills/polish-docs-meta/references/readme.md`.
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Changelog
|
|
328
|
+
|
|
329
|
+
Directory-based, grouped by minor series via the `.x` semver-wildcard convention. Source of truth: `changelog/<major.minor>.x/<version>.md` (e.g. `changelog/0.1.x/0.1.0.md`) — one file per release, shipped in the npm package. At release, author the per-version file with a concrete version and date, then run `bun run changelog:build` to regenerate the rollup. `changelog/template.md` is a **pristine format reference** — never edited or moved; read it for the frontmatter + section layout when scaffolding. `CHANGELOG.md` is a **navigation index** (header + link + summary per version), regenerated by `bun run changelog:build` — devcheck hard-fails on drift; never hand-edit it.
|
|
315
330
|
|
|
316
|
-
|
|
317
|
-
|:-------|:----------|
|
|
318
|
-
| Claude Desktop | Browser downloads `.mcpb` from latest GitHub Release; OS file handler routes to Claude Desktop. |
|
|
319
|
-
| Cursor | `https://cursor.com/en/install-mcp` with base64 JSON config. |
|
|
320
|
-
| VS Code | `vscode:mcp/install?...` wrapped in `https://vscode.dev/redirect?url=` (GitHub strips non-HTTP schemes). |
|
|
321
|
-
| Claude Code / Codex | CLI only — no URL scheme. |
|
|
331
|
+
Each per-version file opens with YAML frontmatter:
|
|
322
332
|
|
|
323
333
|
```markdown
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
334
|
+
---
|
|
335
|
+
summary: "One-line headline, ≤350 chars" # required — powers the rollup index
|
|
336
|
+
breaking: false # optional — true flags breaking changes
|
|
337
|
+
security: false # optional — true flags security fixes
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
# 0.1.0 — YYYY-MM-DD
|
|
341
|
+
...
|
|
327
342
|
```
|
|
328
343
|
|
|
329
|
-
|
|
344
|
+
`breaking: true` renders a `· ⚠️ Breaking` badge — use it when consumers must update code on upgrade (signature changes, removed APIs, config renames). `security: true` renders a `· 🛡️ Security` badge and pairs with a `## Security` body section. When both are set, badges render `· ⚠️ Breaking · 🛡️ Security`.
|
|
330
345
|
|
|
331
|
-
|
|
332
|
-
# Cursor
|
|
333
|
-
echo -n '{"command":"npx -y @cyanheads/calculator-mcp-server"}' | base64
|
|
346
|
+
`agent-notes` is an optional free-form field for maintenance agents processing the release downstream. Content here won't appear in the rendered CHANGELOG — it's consumed by agents running the `maintenance` skill. Use it for adoption instructions that don't fit the human-facing sections. Omit entirely when there's nothing to say.
|
|
334
347
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
348
|
+
**Section order** (Keep a Changelog): Added, Changed, Deprecated, Removed, Fixed, Security. Include only sections with entries — don't ship empty headers.
|
|
349
|
+
|
|
350
|
+
**Tag annotations** render as GitHub Release bodies via `--notes-from-tag`. They must be structured markdown — never a flat comma-separated string. Subject omits the version number (GitHub prepends it). See `changelog/template.md` for the full format reference.
|
|
338
351
|
|
|
339
352
|
---
|
|
340
353
|
|
|
@@ -397,4 +410,7 @@ import { getServerConfig } from '@/config/server-config.js';
|
|
|
397
410
|
- [ ] `format()` renders all data the LLM needs — different clients forward different surfaces (Claude Code → `structuredContent`, Claude Desktop → `content[]`); both must carry the same data
|
|
398
411
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
399
412
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
413
|
+
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = package name; `interface.shortDescription` from `package.json` description
|
|
414
|
+
- [ ] `.codex-plugin/mcp.json` updated — server name key matches `package.json` name; env vars added for any required API keys
|
|
415
|
+
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; inline `mcpServers` entry with server name key, env vars for any required API keys
|
|
400
416
|
- [ ] `bun run devcheck` passes
|
package/CLAUDE.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** calculator-mcp-server
|
|
4
|
-
**Version:** 0.1.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.9.
|
|
4
|
+
**Version:** 0.1.25
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.9.13`
|
|
6
6
|
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/sdk` 1.29.0
|
|
8
8
|
**Zod:** 4.4.3
|
|
@@ -52,6 +52,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
52
52
|
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
53
53
|
- **Check `ctx.elicit` / `ctx.sample`** for presence before calling.
|
|
54
54
|
- **Secrets in env vars only** — never hardcoded.
|
|
55
|
+
- **Close the loop on issues.** When implementing work tracked by a GitHub issue, comment on the issue with what landed and close it. Do both — a comment without a close leaves stale issues open; a close without a comment leaves no record of what shipped. The comment is for future readers — state the concrete changes, not the conversation that produced them.
|
|
55
56
|
|
|
56
57
|
---
|
|
57
58
|
|
|
@@ -154,6 +155,11 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
154
155
|
| Property | Description |
|
|
155
156
|
|:---------|:------------|
|
|
156
157
|
| `ctx.log` | Request-scoped logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId. |
|
|
158
|
+
| `ctx.state` | Tenant-scoped KV — `.get(key)`, `.set(key, value, { ttl? })`, `.delete(key)`, `.list(prefix, { cursor, limit })`. Accepts any serializable value. |
|
|
159
|
+
| `ctx.elicit` | Ask user for structured input. **Check for presence first:** `if (ctx.elicit) { ... }` |
|
|
160
|
+
| `ctx.sample` | Request LLM completion from the client. **Check for presence first:** `if (ctx.sample) { ... }` |
|
|
161
|
+
| `ctx.signal` | `AbortSignal` for cancellation. |
|
|
162
|
+
| `ctx.progress` | Task progress (present when `task: true`) — `.setTotal(n)`, `.increment()`, `.update(message)`. |
|
|
157
163
|
| `ctx.requestId` | Unique request ID. |
|
|
158
164
|
| `ctx.tenantId` | Tenant ID from JWT or `'default'` for stdio. |
|
|
159
165
|
|
|
@@ -168,6 +174,8 @@ Handlers throw — the framework catches, classifies, and formats.
|
|
|
168
174
|
On the wire, tool errors mirror the success-path `format-parity` invariant — both `content[]` (markdown, read by clients like Claude Desktop) and `structuredContent.error` (JSON `{ code, message, data? }`, read by clients like Claude Code) carry the same payload, with `data.recovery.hint` mirrored into the markdown text when present.
|
|
169
175
|
|
|
170
176
|
```ts
|
|
177
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
178
|
+
|
|
171
179
|
errors: [
|
|
172
180
|
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
173
181
|
when: 'No item matched the query',
|
|
@@ -257,7 +265,9 @@ Available skills:
|
|
|
257
265
|
| `add-service` | Scaffold a new service integration |
|
|
258
266
|
| `add-test` | Scaffold test file for a tool, resource, or service |
|
|
259
267
|
| `field-test` | Exercise tools/resources/prompts with real inputs, verify behavior, report issues |
|
|
260
|
-
| `
|
|
268
|
+
| `code-simplifier` | Post-session code review and cleanup against `git diff` — modernize syntax, consolidate duplication, align with codebase |
|
|
269
|
+
| `git-wrapup` | Land working-tree changes as a versioned commit + annotated tag — version bump, changelog, verify, tag. Local only. |
|
|
270
|
+
| `tool-defs-analysis` | Read-only audit of MCP definition language across the surface — voice, leaks, defaults, recovery hints, output descriptions |
|
|
261
271
|
| `devcheck` | Lint, format, typecheck, audit |
|
|
262
272
|
| `security-pass` | Audit server for MCP-flavored security gaps: output injection, scope blast radius, input sinks, tenant isolation |
|
|
263
273
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
@@ -270,13 +280,12 @@ Available skills:
|
|
|
270
280
|
| `api-config` | AppConfig, parseConfig, env vars |
|
|
271
281
|
| `api-context` | Context interface, logger, state, progress |
|
|
272
282
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
273
|
-
| `api-linter` |
|
|
283
|
+
| `api-linter` | Definition linter rule catalog — invoked by `bun run lint:mcp` and `devcheck` |
|
|
274
284
|
| `api-services` | LLM, Speech, Graph services |
|
|
275
285
|
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
276
286
|
| `api-testing` | createMockContext, test patterns |
|
|
277
287
|
| `api-utils` | Formatting, parsing, security, pagination, scheduling, telemetry helpers |
|
|
278
288
|
| `api-workers` | Cloudflare Workers runtime |
|
|
279
|
-
| `migrate-mcp-ts-template` | Migrate a template fork to use `@cyanheads/mcp-ts-core` as a package |
|
|
280
289
|
|
|
281
290
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
|
282
291
|
|
|
@@ -311,30 +320,34 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
311
320
|
|
|
312
321
|
**Adding an env var requires both files:** `server.json` (`environmentVariables[]`) and `manifest.json` (`mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies env var names match.
|
|
313
322
|
|
|
314
|
-
**README install badges**
|
|
323
|
+
**README install badges** (Claude Desktop `.mcpb`, Cursor, VS Code) and the `base64` / `encodeURIComponent` config-generation commands are ship-time concerns — run the `polish-docs-meta` skill, which carries the badge format, layout, and generation snippets in `skills/polish-docs-meta/references/readme.md`.
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Changelog
|
|
328
|
+
|
|
329
|
+
Directory-based, grouped by minor series via the `.x` semver-wildcard convention. Source of truth: `changelog/<major.minor>.x/<version>.md` (e.g. `changelog/0.1.x/0.1.0.md`) — one file per release, shipped in the npm package. At release, author the per-version file with a concrete version and date, then run `bun run changelog:build` to regenerate the rollup. `changelog/template.md` is a **pristine format reference** — never edited or moved; read it for the frontmatter + section layout when scaffolding. `CHANGELOG.md` is a **navigation index** (header + link + summary per version), regenerated by `bun run changelog:build` — devcheck hard-fails on drift; never hand-edit it.
|
|
315
330
|
|
|
316
|
-
|
|
317
|
-
|:-------|:----------|
|
|
318
|
-
| Claude Desktop | Browser downloads `.mcpb` from latest GitHub Release; OS file handler routes to Claude Desktop. |
|
|
319
|
-
| Cursor | `https://cursor.com/en/install-mcp` with base64 JSON config. |
|
|
320
|
-
| VS Code | `vscode:mcp/install?...` wrapped in `https://vscode.dev/redirect?url=` (GitHub strips non-HTTP schemes). |
|
|
321
|
-
| Claude Code / Codex | CLI only — no URL scheme. |
|
|
331
|
+
Each per-version file opens with YAML frontmatter:
|
|
322
332
|
|
|
323
333
|
```markdown
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
334
|
+
---
|
|
335
|
+
summary: "One-line headline, ≤350 chars" # required — powers the rollup index
|
|
336
|
+
breaking: false # optional — true flags breaking changes
|
|
337
|
+
security: false # optional — true flags security fixes
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
# 0.1.0 — YYYY-MM-DD
|
|
341
|
+
...
|
|
327
342
|
```
|
|
328
343
|
|
|
329
|
-
|
|
344
|
+
`breaking: true` renders a `· ⚠️ Breaking` badge — use it when consumers must update code on upgrade (signature changes, removed APIs, config renames). `security: true` renders a `· 🛡️ Security` badge and pairs with a `## Security` body section. When both are set, badges render `· ⚠️ Breaking · 🛡️ Security`.
|
|
330
345
|
|
|
331
|
-
|
|
332
|
-
# Cursor
|
|
333
|
-
echo -n '{"command":"npx -y @cyanheads/calculator-mcp-server"}' | base64
|
|
346
|
+
`agent-notes` is an optional free-form field for maintenance agents processing the release downstream. Content here won't appear in the rendered CHANGELOG — it's consumed by agents running the `maintenance` skill. Use it for adoption instructions that don't fit the human-facing sections. Omit entirely when there's nothing to say.
|
|
334
347
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
348
|
+
**Section order** (Keep a Changelog): Added, Changed, Deprecated, Removed, Fixed, Security. Include only sections with entries — don't ship empty headers.
|
|
349
|
+
|
|
350
|
+
**Tag annotations** render as GitHub Release bodies via `--notes-from-tag`. They must be structured markdown — never a flat comma-separated string. Subject omits the version number (GitHub prepends it). See `changelog/template.md` for the full format reference.
|
|
338
351
|
|
|
339
352
|
---
|
|
340
353
|
|
|
@@ -397,4 +410,7 @@ import { getServerConfig } from '@/config/server-config.js';
|
|
|
397
410
|
- [ ] `format()` renders all data the LLM needs — different clients forward different surfaces (Claude Code → `structuredContent`, Claude Desktop → `content[]`); both must carry the same data
|
|
398
411
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
399
412
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
413
|
+
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = package name; `interface.shortDescription` from `package.json` description
|
|
414
|
+
- [ ] `.codex-plugin/mcp.json` updated — server name key matches `package.json` name; env vars added for any required API keys
|
|
415
|
+
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; inline `mcpServers` entry with server name key, env vars for any required API keys
|
|
400
416
|
- [ ] `bun run devcheck` passes
|
package/README.md
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/calculator-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/calculator-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
14
|
<div align="center">
|
|
15
15
|
|
|
16
|
-
[](https://cursor.com/en/install-mcp?name=calculator-mcp-server&config=
|
|
16
|
+
[](https://github.com/cyanheads/calculator-mcp-server/releases/latest/download/calculator-mcp-server.mcpb) [](https://cursor.com/en/install-mcp?name=calculator-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvY2FsY3VsYXRvci1tY3Atc2VydmVyIl19) [](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22calculator-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads%2Fcalculator-mcp-server%22%5D%7D)
|
|
17
17
|
|
|
18
18
|
[](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
19
19
|
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
* @module config/server-config
|
|
4
4
|
*/
|
|
5
5
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
-
declare const ServerConfigSchema:
|
|
6
|
+
declare const ServerConfigSchema: z.ZodObject<{
|
|
7
|
+
maxExpressionLength: z.ZodPreprocess<z.ZodDefault<z.ZodCoercedNumber<unknown>>>;
|
|
8
|
+
evaluationTimeoutMs: z.ZodPreprocess<z.ZodDefault<z.ZodCoercedNumber<unknown>>>;
|
|
9
|
+
maxResultLength: z.ZodPreprocess<z.ZodDefault<z.ZodCoercedNumber<unknown>>>;
|
|
10
|
+
}, z.core.$strip>;
|
|
7
11
|
export type ServerConfig = z.infer<typeof ServerConfigSchema>;
|
|
8
12
|
/** Lazy-parsed server config from env vars. */
|
|
9
13
|
export declare function getServerConfig(): ServerConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAO3C,QAAA,MAAM,kBAAkB;;;;iBA+BtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,+CAA+C;AAC/C,wBAAgB,eAAe,IAAI,YAAY,CAO9C"}
|
|
@@ -4,28 +4,30 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
6
|
import { parseEnvConfig } from '@cyanheads/mcp-ts-core/config';
|
|
7
|
+
/** Strip MCPB placeholder strings (e.g. `${user_config.X}`) to undefined so .default() applies. */
|
|
8
|
+
const stripPlaceholder = (v) => typeof v === 'string' && v.startsWith('${') ? undefined : v;
|
|
7
9
|
const ServerConfigSchema = z.object({
|
|
8
|
-
maxExpressionLength: z.coerce
|
|
10
|
+
maxExpressionLength: z.preprocess(stripPlaceholder, z.coerce
|
|
9
11
|
.number()
|
|
10
12
|
.int()
|
|
11
13
|
.min(10)
|
|
12
14
|
.max(10_000)
|
|
13
15
|
.default(1000)
|
|
14
|
-
.describe('Maximum allowed expression string length (10–10,000)'),
|
|
15
|
-
evaluationTimeoutMs: z.coerce
|
|
16
|
+
.describe('Maximum allowed expression string length (10–10,000)')),
|
|
17
|
+
evaluationTimeoutMs: z.preprocess(stripPlaceholder, z.coerce
|
|
16
18
|
.number()
|
|
17
19
|
.int()
|
|
18
20
|
.min(100)
|
|
19
21
|
.max(30_000)
|
|
20
22
|
.default(5000)
|
|
21
|
-
.describe('Maximum evaluation time in milliseconds (100–30,000)'),
|
|
22
|
-
maxResultLength: z.coerce
|
|
23
|
+
.describe('Maximum evaluation time in milliseconds (100–30,000)')),
|
|
24
|
+
maxResultLength: z.preprocess(stripPlaceholder, z.coerce
|
|
23
25
|
.number()
|
|
24
26
|
.int()
|
|
25
27
|
.min(1_000)
|
|
26
28
|
.max(1_000_000)
|
|
27
29
|
.default(100_000)
|
|
28
|
-
.describe('Maximum result string length in characters (1,000–1,000,000)'),
|
|
30
|
+
.describe('Maximum result string length in characters (1,000–1,000,000)')),
|
|
29
31
|
});
|
|
30
32
|
let _config;
|
|
31
33
|
/** Lazy-parsed server config from env vars. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,mBAAmB,EAAE,CAAC,CAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,mGAAmG;AACnG,MAAM,gBAAgB,GAAG,CAAC,CAAU,EAAE,EAAE,CACtC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9D,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,mBAAmB,EAAE,CAAC,CAAC,UAAU,CAC/B,gBAAgB,EAChB,CAAC,CAAC,MAAM;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,EAAE,CAAC;SACP,GAAG,CAAC,MAAM,CAAC;SACX,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,sDAAsD,CAAC,CACpE;IACD,mBAAmB,EAAE,CAAC,CAAC,UAAU,CAC/B,gBAAgB,EAChB,CAAC,CAAC,MAAM;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,GAAG,CAAC;SACR,GAAG,CAAC,MAAM,CAAC;SACX,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,sDAAsD,CAAC,CACpE;IACD,eAAe,EAAE,CAAC,CAAC,UAAU,CAC3B,gBAAgB,EAChB,CAAC,CAAC,MAAM;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,KAAK,CAAC;SACV,GAAG,CAAC,SAAS,CAAC;SACd,OAAO,CAAC,OAAO,CAAC;SAChB,QAAQ,CAAC,8DAA8D,CAAC,CAC5E;CACF,CAAC,CAAC;AAIH,IAAI,OAAiC,CAAC;AAEtC,+CAA+C;AAC/C,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,cAAc,CAAC,kBAAkB,EAAE;QAC7C,mBAAmB,EAAE,4BAA4B;QACjD,mBAAmB,EAAE,4BAA4B;QACjD,eAAe,EAAE,wBAAwB;KAC1C,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ await createApp({
|
|
|
15
15
|
landing: {
|
|
16
16
|
repoRoot: 'https://github.com/cyanheads/calculator-mcp-server',
|
|
17
17
|
tagline: 'A hardened math.js calculator MCP server — evaluate, simplify, and differentiate expressions.',
|
|
18
|
+
requireAuth: false,
|
|
18
19
|
},
|
|
19
20
|
setup() {
|
|
20
21
|
initMathService(getServerConfig());
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,qDAAqD,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,kDAAkD,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,SAAS,CAAC;IACd,KAAK,EAAE,CAAC,aAAa,CAAC;IACtB,SAAS,EAAE,CAAC,YAAY,CAAC;IACzB,YAAY,EACV,wdAAwd;IAC1d,OAAO,EAAE;QACP,QAAQ,EAAE,oDAAoD;QAC9D,OAAO,EACL,+FAA+F;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,qDAAqD,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,kDAAkD,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,SAAS,CAAC;IACd,KAAK,EAAE,CAAC,aAAa,CAAC;IACtB,SAAS,EAAE,CAAC,YAAY,CAAC;IACzB,YAAY,EACV,wdAAwd;IAC1d,OAAO,EAAE;QACP,QAAQ,EAAE,oDAAoD;QAC9D,OAAO,EACL,+FAA+F;QACjG,WAAW,EAAE,KAAK;KACnB;IACD,KAAK;QACH,eAAe,CAAC,eAAe,EAAE,CAAC,CAAC;IACrC,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -2,5 +2,7 @@
|
|
|
2
2
|
* @fileoverview Help resource — static reference of available functions, operators, and syntax.
|
|
3
3
|
* @module mcp-server/resources/definitions/help.resource
|
|
4
4
|
*/
|
|
5
|
-
export declare const helpResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<ZodObject<
|
|
5
|
+
export declare const helpResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<Readonly<{
|
|
6
|
+
[k: string]: import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>;
|
|
7
|
+
}>, import("zod/v4/core").$strip>, undefined, undefined>;
|
|
6
8
|
//# sourceMappingURL=help.resource.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/help.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"help.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/help.resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,eAAO,MAAM,YAAY;;wDAWvB,CAAC"}
|
|
@@ -3,8 +3,23 @@
|
|
|
3
3
|
* Single tool covering 100% of the server's purpose.
|
|
4
4
|
* @module mcp-server/tools/definitions/calculate.tool
|
|
5
5
|
*/
|
|
6
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
7
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
-
export declare const calculateTool: import("@cyanheads/mcp-ts-core").ToolDefinition<
|
|
8
|
+
export declare const calculateTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
9
|
+
expression: z.ZodString;
|
|
10
|
+
operation: z.ZodDefault<z.ZodEnum<{
|
|
11
|
+
evaluate: "evaluate";
|
|
12
|
+
simplify: "simplify";
|
|
13
|
+
derivative: "derivative";
|
|
14
|
+
}>>;
|
|
15
|
+
variable: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>;
|
|
16
|
+
scope: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
17
|
+
precision: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodNumber]>>;
|
|
18
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
19
|
+
result: z.ZodString;
|
|
20
|
+
resultType: z.ZodString;
|
|
21
|
+
expression: z.ZodString;
|
|
22
|
+
}, z.core.$strip>, readonly [{
|
|
8
23
|
readonly reason: "empty_expression";
|
|
9
24
|
readonly code: JsonRpcErrorCode.ValidationError;
|
|
10
25
|
readonly when: "Expression is empty or whitespace-only.";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calculate.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/calculate.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"calculate.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/calculate.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqKxB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/calculator-mcp-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "Evaluate, simplify, and differentiate mathematical expressions via MCP. STDIO or Streamable HTTP.",
|
|
5
5
|
"mcpName": "io.github.cyanheads/calculator-mcp-server",
|
|
6
6
|
"type": "module",
|
|
@@ -38,7 +38,10 @@
|
|
|
38
38
|
"math",
|
|
39
39
|
"mathjs",
|
|
40
40
|
"llm-tools",
|
|
41
|
-
"typescript"
|
|
41
|
+
"typescript",
|
|
42
|
+
"bun",
|
|
43
|
+
"stdio",
|
|
44
|
+
"streamable-http"
|
|
42
45
|
],
|
|
43
46
|
"repository": {
|
|
44
47
|
"type": "git",
|
|
@@ -72,13 +75,13 @@
|
|
|
72
75
|
"zod": "^4.4.3"
|
|
73
76
|
},
|
|
74
77
|
"dependencies": {
|
|
75
|
-
"@cyanheads/mcp-ts-core": "^0.9.
|
|
78
|
+
"@cyanheads/mcp-ts-core": "^0.9.13",
|
|
76
79
|
"mathjs": "^15.2.0",
|
|
77
80
|
"pino-pretty": "^13.1.3",
|
|
78
81
|
"zod": "^4.4.3"
|
|
79
82
|
},
|
|
80
83
|
"devDependencies": {
|
|
81
|
-
"@biomejs/biome": "^2.4.
|
|
84
|
+
"@biomejs/biome": "^2.4.16",
|
|
82
85
|
"@types/node": "^25.9.1",
|
|
83
86
|
"depcheck": "^1.4.7",
|
|
84
87
|
"ignore": "^7.0.5",
|
package/server.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"url": "https://github.com/cyanheads/calculator-mcp-server",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.25",
|
|
10
10
|
"remotes": [
|
|
11
11
|
{
|
|
12
12
|
"type": "streamable-http",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
20
20
|
"identifier": "@cyanheads/calculator-mcp-server",
|
|
21
21
|
"runtimeHint": "bun",
|
|
22
|
-
"version": "0.1.
|
|
22
|
+
"version": "0.1.25",
|
|
23
23
|
"packageArguments": [
|
|
24
24
|
{
|
|
25
25
|
"type": "positional",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
70
70
|
"identifier": "@cyanheads/calculator-mcp-server",
|
|
71
71
|
"runtimeHint": "bun",
|
|
72
|
-
"version": "0.1.
|
|
72
|
+
"version": "0.1.25",
|
|
73
73
|
"packageArguments": [
|
|
74
74
|
{
|
|
75
75
|
"type": "positional",
|