@cyanheads/exchange-rates-mcp-server 0.4.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/AGENTS.md +40 -15
- package/CLAUDE.md +40 -15
- package/README.md +87 -73
- package/changelog/0.4.x/0.4.1.md +27 -0
- package/changelog/template.md +9 -26
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-describe.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-describe.tool.js +2 -3
- package/dist/mcp-server/tools/definitions/fx-dataframe-describe.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-drop.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-drop.tool.js +2 -3
- package/dist/mcp-server/tools/definitions/fx-dataframe-drop.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-query.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-query.tool.js +2 -3
- package/dist/mcp-server/tools/definitions/fx-dataframe-query.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-get-timeseries.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-get-timeseries.tool.js +2 -5
- package/dist/mcp-server/tools/definitions/fx-get-timeseries.tool.js.map +1 -1
- package/dist/services/frankfurter/errors.d.ts +6 -1
- package/dist/services/frankfurter/errors.d.ts.map +1 -1
- package/dist/services/frankfurter/errors.js +6 -2
- package/dist/services/frankfurter/errors.js.map +1 -1
- package/dist/services/frankfurter/frankfurter-service.d.ts.map +1 -1
- package/dist/services/frankfurter/frankfurter-service.js +12 -4
- package/dist/services/frankfurter/frankfurter-service.js.map +1 -1
- package/package.json +8 -7
- package/server.json +3 -3
package/AGENTS.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** exchange-rates-mcp-server
|
|
4
|
-
**Version:** 0.4.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `0.
|
|
4
|
+
**Version:** 0.4.1
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `0.13.6`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.0.0
|
|
8
|
-
**Zod:** ^4.6.
|
|
8
|
+
**Zod:** ^4.6.5
|
|
9
9
|
|
|
10
10
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
11
11
|
|
|
@@ -163,6 +163,22 @@ await createApp({
|
|
|
163
163
|
|
|
164
164
|
`instructions` is optional server-level orientation, sent on every `initialize` as session-level context. Use it for deployment guidance (connection aliases, regional notes, scope hints) instead of repeating the same context across tool descriptions. Client adoption is uneven, but there's no downside when set.
|
|
165
165
|
|
|
166
|
+
### Session posture and shutdown
|
|
167
|
+
|
|
168
|
+
Two more `createApp()` options shape how the server runs rather than how it presents itself:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
await createApp({
|
|
172
|
+
sessionMode: 'stateless', // or { default: 'stateful', require: 'stateful' }
|
|
173
|
+
setup(core) { setCanvas(core.canvas); },
|
|
174
|
+
async teardown() { await stopMyWatcher(); },
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`sessionMode` declares the HTTP session posture in `src/` instead of leaving it to a deployment's `MCP_SESSION_MODE`, which still wins whenever it carries a meaningful value (an empty string and an unsubstituted `${…}` placeholder read as unset and fall through to the option). This server declares `stateless`: no handler calls `ctx.requestInput`, so nothing needs a session to resume. Add `require: 'stateful'` when a tool does ask the caller for input mid-handler: startup then fails with a `ConfigurationError` rather than serving a mode in which a 2025-era client can never answer the prompt. Stdio is never refused.
|
|
179
|
+
|
|
180
|
+
`teardown(core)` is the `setup()` counterpart — release a watcher, socket, or non-`unref()`'d timer there. It runs after the transport stops and before the logger closes, on every shutdown path, and a signal-triggered shutdown then exits the process explicitly (0, or 1 if a step never settles within the framework's 10 s ceiling). Nothing here declares one: `setup()` only hands `core.canvas` to the module accessor, and the canvas service is torn down by the framework.
|
|
181
|
+
|
|
166
182
|
---
|
|
167
183
|
|
|
168
184
|
## Context
|
|
@@ -187,7 +203,7 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
187
203
|
|
|
188
204
|
Handlers throw — the framework catches, classifies, and formats.
|
|
189
205
|
|
|
190
|
-
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable? }]` on `tool()` / `resource()` to receive `ctx.fail(reason, …)` typed against the reason union. TypeScript catches typos at compile time, `data.reason` is auto-populated for observability, linter enforces conformance against the handler body. `recovery` is required (≥ 5 words, lint-validated) — the single source of truth for the agent's next move. Pass `ctx.recoveryFor('reason')` as the throw's data to put it on the wire (`data.recovery.hint`, mirrored into `content[]` text); override with an explicit `{ recovery: { hint: '...' } }` when dynamic runtime context matters. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`, `RequestCancelled`) bubble freely and don't need declaring.
|
|
206
|
+
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable?, severity?, thrownBy? }]` on `tool()` / `resource()` to receive `ctx.fail(reason, …)` typed against the reason union. TypeScript catches typos at compile time, `data.reason` is auto-populated for observability, linter enforces conformance against the handler body. `recovery` is required (≥ 5 words, lint-validated) — the single source of truth for the agent's next move. Pass `ctx.recoveryFor('reason')` as the throw's data to put it on the wire (`data.recovery.hint`, mirrored into `content[]` text unless the message already contains it verbatim); override with an explicit `{ recovery: { hint: '...' } }` when dynamic runtime context matters. Forwarding it is lint-enforced per throw site (`error-contract-recovery-unforwarded`). Mark an entry the service layer throws with `thrownBy: 'service'` so `error-contract-unthrown` skips it — lint-only metadata, nothing at runtime reads it. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`, `RequestCancelled`) bubble freely and don't need declaring.
|
|
191
207
|
|
|
192
208
|
```ts
|
|
193
209
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
@@ -273,9 +289,9 @@ src/
|
|
|
273
289
|
|
|
274
290
|
## Skills
|
|
275
291
|
|
|
276
|
-
Skills are modular instructions in `skills/` at the project root. Read them directly when a task matches — e.g., `skills/add-tool/SKILL.md` when adding a tool. `bun run list-skills` prints the full registry.
|
|
292
|
+
Skills are modular instructions in `framework-skills/` at the project root. Read them directly when a task matches — e.g., `framework-skills/add-tool/SKILL.md` when adding a tool. `bun run list-skills` prints the full registry. The directory is deliberately not `skills/`: Claude Code and Codex auto-load a plugin's root `skills/`, so a server that ships `.claude-plugin/` or `.codex-plugin/` would hand these development skills to every agent that installs it. Keep `skills/` free for skills meant for those agents.
|
|
277
293
|
|
|
278
|
-
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). Skills then load as context without referencing `skills/` paths. After framework updates, run the `maintenance` skill — Phase B re-syncs the agent directory.
|
|
294
|
+
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). Skills then load as context without referencing `framework-skills/` paths. After framework updates, run the `maintenance` skill — Phase B re-syncs the agent directory.
|
|
279
295
|
|
|
280
296
|
Available skills:
|
|
281
297
|
|
|
@@ -295,7 +311,7 @@ Available skills:
|
|
|
295
311
|
| `code-simplifier` | Post-session cleanup against `git diff` — modernize syntax, consolidate duplication, align with the codebase |
|
|
296
312
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
297
313
|
| `git-wrapup` | Land working-tree changes as a commit stack — version bump, changelog, verify, commit by concern, release commit on top. No tag, no push to main; opens the release PR when the project declares release PR mode |
|
|
298
|
-
| `release-pr-review` | Review pass on an open release PR — simplifier + correctness review,
|
|
314
|
+
| `release-pr-review` | Review pass on an open release PR — simplifier + correctness review, fixes as ordinary commits on top of the stack, PR body kept in sync. Release PR mode only |
|
|
299
315
|
| `release-and-publish` | Fast-forward merge (release PR mode) + tag + push + npm + MCP Registry + GH Release + Docker. Picks up from `git-wrapup` |
|
|
300
316
|
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills to agent dirs |
|
|
301
317
|
| `orchestrations` | Chain task skills into a gated multi-phase pipeline — build-out, QA-fix, update-ship — when you can spawn sub-agents |
|
|
@@ -315,7 +331,7 @@ Available skills:
|
|
|
315
331
|
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
316
332
|
| `api-workers` | Cloudflare Workers runtime |
|
|
317
333
|
|
|
318
|
-
**Chaining skills into pipelines.** When the user wants a multi-phase effort — build this server out, QA-and-fix the surface, update-and-ship — *and you can spawn sub-agents*, `skills/orchestrations/SKILL.md` sequences the task skills above into a gated pipeline with verification at each step. Read it to drive the run. Optional: skip it if you can't orchestrate sub-agents, and ignore it entirely if you were *spawned* as one — you've already been scoped to a single phase.
|
|
334
|
+
**Chaining skills into pipelines.** When the user wants a multi-phase effort — build this server out, QA-and-fix the surface, update-and-ship — *and you can spawn sub-agents*, `framework-skills/orchestrations/SKILL.md` sequences the task skills above into a gated pipeline with verification at each step. Read it to drive the run. Optional: skip it if you can't orchestrate sub-agents, and ignore it entirely if you were *spawned* as one — you've already been scoped to a single phase.
|
|
319
335
|
|
|
320
336
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
|
321
337
|
|
|
@@ -331,7 +347,8 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
331
347
|
| `bun run rebuild` | Clean + build |
|
|
332
348
|
| `bun run clean` | Remove build artifacts |
|
|
333
349
|
| `bun run devcheck` | Lint + format + typecheck + security + changelog sync |
|
|
334
|
-
| `bun run audit:
|
|
350
|
+
| `bun run audit:fix` | `bun audit fix` — upgrade vulnerable packages to the lowest safe version within existing ranges (`--dry-run` previews, `--latest` rewrites ranges). First response when `devcheck` flags a transitive advisory; then `bun update <name>`, then `bun dedupe` |
|
|
351
|
+
| `bun run audit:refresh` | Delete `bun.lock` and reinstall. Last resort after `audit:fix`, `bun update <name>`, and `bun dedupe` — re-resolves every ranged dep (the framework pin included) and rewrites the lockfile as `lockfileVersion: 2` |
|
|
335
352
|
| `bun run lint:mcp` | Run the MCP definition linter standalone (rule catalog: `api-linter` skill) |
|
|
336
353
|
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity (run by devcheck) |
|
|
337
354
|
| `bun run list-skills` | Print the skill registry |
|
|
@@ -346,15 +363,17 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
346
363
|
| `bun run bundle` | Build, pack, and clean a `.mcpb` for one-click Claude Desktop install |
|
|
347
364
|
| `bun run publish-mcp` | Publish to MCP Registry via mcp-publisher |
|
|
348
365
|
|
|
366
|
+
**CI is one file.** `.github/workflows/codeql.yml` (scaffolded) is the only GitHub Actions workflow: CodeQL is GitHub-owned end to end, and the file runs only while the repo's CodeQL *default setup* is turned off. Verification — `devcheck`, tests, the release gates — runs locally; don't add a workflow that re-runs it.
|
|
367
|
+
|
|
349
368
|
---
|
|
350
369
|
|
|
351
370
|
## Bundling
|
|
352
371
|
|
|
353
|
-
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on. This server uses DataCanvas, so its bundle ships without the DuckDB native — `@duckdb/node-api` is an optional peer loaded lazily, so `fx_dataframe_*` report an actionable install hint and every other tool works normally. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
372
|
+
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`framework-skills/`, `skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on. This server uses DataCanvas, so its bundle ships without the DuckDB native — `@duckdb/node-api` is an optional peer loaded lazily, so `fx_dataframe_*` report an actionable install hint and every other tool works normally. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
354
373
|
|
|
355
|
-
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match.
|
|
374
|
+
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match, that every `user_config` option is wired into `mcp_config.env` as `"X": "${user_config.X}"` (the host substitutes nothing else — `"${X}"` reaches the server as that literal string), and that an optional string option carries `"default": ""`.
|
|
356
375
|
|
|
357
|
-
**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`.
|
|
376
|
+
**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 `framework-skills/polish-docs-meta/references/readme.md`.
|
|
358
377
|
|
|
359
378
|
---
|
|
360
379
|
|
|
@@ -385,6 +404,12 @@ security: false # optional — true ONLY for a source
|
|
|
385
404
|
|
|
386
405
|
---
|
|
387
406
|
|
|
407
|
+
## Publishing
|
|
408
|
+
|
|
409
|
+
**Every release goes through a release PR, straight-through** — `git-wrapup`'s "Release PR mode", mode `straight-through`. One run: `git-wrapup` lands the commit stack on `release/<version>`, pushes it, and opens the PR (title = the release commit subject, body = the changelog entry plus a gates section); `release-and-publish` then fast-forwards `main` locally with `git merge --ff-only`, creates the tag on `main`'s tip, pushes `main` and the tag, deletes the branch, and publishes. A caller's brief may run a given release as `gated` instead — a `release-pr-review` pass on the open PR before `release-and-publish`. **Never merge through the GitHub UI or `gh pr merge`**: squash and rebase-merge are disabled in the repo settings because both rewrite the stack (rebase-merge also strips the SSH signatures), and a merge commit breaks the linear history.
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
388
413
|
## Imports
|
|
389
414
|
|
|
390
415
|
```ts
|
|
@@ -411,7 +436,7 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
411
436
|
- [ ] If wrapping external API: tests include at least one sparse payload case with omitted upstream fields
|
|
412
437
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
413
438
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
414
|
-
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` =
|
|
415
|
-
- [ ] `.codex-plugin/mcp.json` updated — server name key
|
|
416
|
-
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; inline `mcpServers` entry
|
|
439
|
+
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = the unscoped repo name (never the npm scope — `lint:packaging` enforces this); `interface.shortDescription` from `package.json` description
|
|
440
|
+
- [ ] `.codex-plugin/mcp.json` updated — server name key is the unscoped repo name; every user-supplied variable (API key, contact email, instance URL) is listed in `env_vars` so Codex forwards it from the user's environment. Never write `"KEY": ""` into `env` — an empty value replaces the user's exported key and is read as unset
|
|
441
|
+
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `author`, `repository`, `license`, `keywords` from `package.json`; inline `mcpServers` entry keyed by the unscoped repo name. Every user-supplied variable is declared under `userConfig` (`type`, `title`, `description`; `sensitive: true` for keys and tokens; `required: true` or `default: ""`) and referenced from `env` as `"KEY": "${user_config.<option>}"` — mirror the `user_config` block in `manifest.json`. Never write `"KEY": ""` into `env`
|
|
417
442
|
- [ ] `npm run devcheck` passes
|
package/CLAUDE.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** exchange-rates-mcp-server
|
|
4
|
-
**Version:** 0.4.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `0.
|
|
4
|
+
**Version:** 0.4.1
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `0.13.6`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.0.0
|
|
8
|
-
**Zod:** ^4.6.
|
|
8
|
+
**Zod:** ^4.6.5
|
|
9
9
|
|
|
10
10
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
11
11
|
|
|
@@ -163,6 +163,22 @@ await createApp({
|
|
|
163
163
|
|
|
164
164
|
`instructions` is optional server-level orientation, sent on every `initialize` as session-level context. Use it for deployment guidance (connection aliases, regional notes, scope hints) instead of repeating the same context across tool descriptions. Client adoption is uneven, but there's no downside when set.
|
|
165
165
|
|
|
166
|
+
### Session posture and shutdown
|
|
167
|
+
|
|
168
|
+
Two more `createApp()` options shape how the server runs rather than how it presents itself:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
await createApp({
|
|
172
|
+
sessionMode: 'stateless', // or { default: 'stateful', require: 'stateful' }
|
|
173
|
+
setup(core) { setCanvas(core.canvas); },
|
|
174
|
+
async teardown() { await stopMyWatcher(); },
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`sessionMode` declares the HTTP session posture in `src/` instead of leaving it to a deployment's `MCP_SESSION_MODE`, which still wins whenever it carries a meaningful value (an empty string and an unsubstituted `${…}` placeholder read as unset and fall through to the option). This server declares `stateless`: no handler calls `ctx.requestInput`, so nothing needs a session to resume. Add `require: 'stateful'` when a tool does ask the caller for input mid-handler: startup then fails with a `ConfigurationError` rather than serving a mode in which a 2025-era client can never answer the prompt. Stdio is never refused.
|
|
179
|
+
|
|
180
|
+
`teardown(core)` is the `setup()` counterpart — release a watcher, socket, or non-`unref()`'d timer there. It runs after the transport stops and before the logger closes, on every shutdown path, and a signal-triggered shutdown then exits the process explicitly (0, or 1 if a step never settles within the framework's 10 s ceiling). Nothing here declares one: `setup()` only hands `core.canvas` to the module accessor, and the canvas service is torn down by the framework.
|
|
181
|
+
|
|
166
182
|
---
|
|
167
183
|
|
|
168
184
|
## Context
|
|
@@ -187,7 +203,7 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
187
203
|
|
|
188
204
|
Handlers throw — the framework catches, classifies, and formats.
|
|
189
205
|
|
|
190
|
-
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable? }]` on `tool()` / `resource()` to receive `ctx.fail(reason, …)` typed against the reason union. TypeScript catches typos at compile time, `data.reason` is auto-populated for observability, linter enforces conformance against the handler body. `recovery` is required (≥ 5 words, lint-validated) — the single source of truth for the agent's next move. Pass `ctx.recoveryFor('reason')` as the throw's data to put it on the wire (`data.recovery.hint`, mirrored into `content[]` text); override with an explicit `{ recovery: { hint: '...' } }` when dynamic runtime context matters. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`, `RequestCancelled`) bubble freely and don't need declaring.
|
|
206
|
+
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable?, severity?, thrownBy? }]` on `tool()` / `resource()` to receive `ctx.fail(reason, …)` typed against the reason union. TypeScript catches typos at compile time, `data.reason` is auto-populated for observability, linter enforces conformance against the handler body. `recovery` is required (≥ 5 words, lint-validated) — the single source of truth for the agent's next move. Pass `ctx.recoveryFor('reason')` as the throw's data to put it on the wire (`data.recovery.hint`, mirrored into `content[]` text unless the message already contains it verbatim); override with an explicit `{ recovery: { hint: '...' } }` when dynamic runtime context matters. Forwarding it is lint-enforced per throw site (`error-contract-recovery-unforwarded`). Mark an entry the service layer throws with `thrownBy: 'service'` so `error-contract-unthrown` skips it — lint-only metadata, nothing at runtime reads it. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`, `RequestCancelled`) bubble freely and don't need declaring.
|
|
191
207
|
|
|
192
208
|
```ts
|
|
193
209
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
@@ -273,9 +289,9 @@ src/
|
|
|
273
289
|
|
|
274
290
|
## Skills
|
|
275
291
|
|
|
276
|
-
Skills are modular instructions in `skills/` at the project root. Read them directly when a task matches — e.g., `skills/add-tool/SKILL.md` when adding a tool. `bun run list-skills` prints the full registry.
|
|
292
|
+
Skills are modular instructions in `framework-skills/` at the project root. Read them directly when a task matches — e.g., `framework-skills/add-tool/SKILL.md` when adding a tool. `bun run list-skills` prints the full registry. The directory is deliberately not `skills/`: Claude Code and Codex auto-load a plugin's root `skills/`, so a server that ships `.claude-plugin/` or `.codex-plugin/` would hand these development skills to every agent that installs it. Keep `skills/` free for skills meant for those agents.
|
|
277
293
|
|
|
278
|
-
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). Skills then load as context without referencing `skills/` paths. After framework updates, run the `maintenance` skill — Phase B re-syncs the agent directory.
|
|
294
|
+
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). Skills then load as context without referencing `framework-skills/` paths. After framework updates, run the `maintenance` skill — Phase B re-syncs the agent directory.
|
|
279
295
|
|
|
280
296
|
Available skills:
|
|
281
297
|
|
|
@@ -295,7 +311,7 @@ Available skills:
|
|
|
295
311
|
| `code-simplifier` | Post-session cleanup against `git diff` — modernize syntax, consolidate duplication, align with the codebase |
|
|
296
312
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
297
313
|
| `git-wrapup` | Land working-tree changes as a commit stack — version bump, changelog, verify, commit by concern, release commit on top. No tag, no push to main; opens the release PR when the project declares release PR mode |
|
|
298
|
-
| `release-pr-review` | Review pass on an open release PR — simplifier + correctness review,
|
|
314
|
+
| `release-pr-review` | Review pass on an open release PR — simplifier + correctness review, fixes as ordinary commits on top of the stack, PR body kept in sync. Release PR mode only |
|
|
299
315
|
| `release-and-publish` | Fast-forward merge (release PR mode) + tag + push + npm + MCP Registry + GH Release + Docker. Picks up from `git-wrapup` |
|
|
300
316
|
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills to agent dirs |
|
|
301
317
|
| `orchestrations` | Chain task skills into a gated multi-phase pipeline — build-out, QA-fix, update-ship — when you can spawn sub-agents |
|
|
@@ -315,7 +331,7 @@ Available skills:
|
|
|
315
331
|
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
316
332
|
| `api-workers` | Cloudflare Workers runtime |
|
|
317
333
|
|
|
318
|
-
**Chaining skills into pipelines.** When the user wants a multi-phase effort — build this server out, QA-and-fix the surface, update-and-ship — *and you can spawn sub-agents*, `skills/orchestrations/SKILL.md` sequences the task skills above into a gated pipeline with verification at each step. Read it to drive the run. Optional: skip it if you can't orchestrate sub-agents, and ignore it entirely if you were *spawned* as one — you've already been scoped to a single phase.
|
|
334
|
+
**Chaining skills into pipelines.** When the user wants a multi-phase effort — build this server out, QA-and-fix the surface, update-and-ship — *and you can spawn sub-agents*, `framework-skills/orchestrations/SKILL.md` sequences the task skills above into a gated pipeline with verification at each step. Read it to drive the run. Optional: skip it if you can't orchestrate sub-agents, and ignore it entirely if you were *spawned* as one — you've already been scoped to a single phase.
|
|
319
335
|
|
|
320
336
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
|
321
337
|
|
|
@@ -331,7 +347,8 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
331
347
|
| `bun run rebuild` | Clean + build |
|
|
332
348
|
| `bun run clean` | Remove build artifacts |
|
|
333
349
|
| `bun run devcheck` | Lint + format + typecheck + security + changelog sync |
|
|
334
|
-
| `bun run audit:
|
|
350
|
+
| `bun run audit:fix` | `bun audit fix` — upgrade vulnerable packages to the lowest safe version within existing ranges (`--dry-run` previews, `--latest` rewrites ranges). First response when `devcheck` flags a transitive advisory; then `bun update <name>`, then `bun dedupe` |
|
|
351
|
+
| `bun run audit:refresh` | Delete `bun.lock` and reinstall. Last resort after `audit:fix`, `bun update <name>`, and `bun dedupe` — re-resolves every ranged dep (the framework pin included) and rewrites the lockfile as `lockfileVersion: 2` |
|
|
335
352
|
| `bun run lint:mcp` | Run the MCP definition linter standalone (rule catalog: `api-linter` skill) |
|
|
336
353
|
| `bun run lint:packaging` | Packaging surface checks — `server.json`/`manifest.json` env-var parity (run by devcheck) |
|
|
337
354
|
| `bun run list-skills` | Print the skill registry |
|
|
@@ -346,15 +363,17 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
346
363
|
| `bun run bundle` | Build, pack, and clean a `.mcpb` for one-click Claude Desktop install |
|
|
347
364
|
| `bun run publish-mcp` | Publish to MCP Registry via mcp-publisher |
|
|
348
365
|
|
|
366
|
+
**CI is one file.** `.github/workflows/codeql.yml` (scaffolded) is the only GitHub Actions workflow: CodeQL is GitHub-owned end to end, and the file runs only while the repo's CodeQL *default setup* is turned off. Verification — `devcheck`, tests, the release gates — runs locally; don't add a workflow that re-runs it.
|
|
367
|
+
|
|
349
368
|
---
|
|
350
369
|
|
|
351
370
|
## Bundling
|
|
352
371
|
|
|
353
|
-
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on. This server uses DataCanvas, so its bundle ships without the DuckDB native — `@duckdb/node-api` is an optional peer loaded lazily, so `fx_dataframe_*` report an actionable install hint and every other tool works normally. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
372
|
+
`bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`framework-skills/`, `skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on. This server uses DataCanvas, so its bundle ships without the DuckDB native — `@duckdb/node-api` is an optional peer loaded lazily, so `fx_dataframe_*` report an actionable install hint and every other tool works normally. MCPB is stdio-only — HTTP and Cloudflare Workers deployments are unaffected. Consumers who don't need it can delete `manifest.json` and `.mcpbignore`; `lint:packaging` skips cleanly.
|
|
354
373
|
|
|
355
|
-
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match.
|
|
374
|
+
**Adding an env var requires both files:** `server.json` (registry discovery, `environmentVariables[]`) and `manifest.json` (bundle install UX, `mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match, that every `user_config` option is wired into `mcp_config.env` as `"X": "${user_config.X}"` (the host substitutes nothing else — `"${X}"` reaches the server as that literal string), and that an optional string option carries `"default": ""`.
|
|
356
375
|
|
|
357
|
-
**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`.
|
|
376
|
+
**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 `framework-skills/polish-docs-meta/references/readme.md`.
|
|
358
377
|
|
|
359
378
|
---
|
|
360
379
|
|
|
@@ -385,6 +404,12 @@ security: false # optional — true ONLY for a source
|
|
|
385
404
|
|
|
386
405
|
---
|
|
387
406
|
|
|
407
|
+
## Publishing
|
|
408
|
+
|
|
409
|
+
**Every release goes through a release PR, straight-through** — `git-wrapup`'s "Release PR mode", mode `straight-through`. One run: `git-wrapup` lands the commit stack on `release/<version>`, pushes it, and opens the PR (title = the release commit subject, body = the changelog entry plus a gates section); `release-and-publish` then fast-forwards `main` locally with `git merge --ff-only`, creates the tag on `main`'s tip, pushes `main` and the tag, deletes the branch, and publishes. A caller's brief may run a given release as `gated` instead — a `release-pr-review` pass on the open PR before `release-and-publish`. **Never merge through the GitHub UI or `gh pr merge`**: squash and rebase-merge are disabled in the repo settings because both rewrite the stack (rebase-merge also strips the SSH signatures), and a merge commit breaks the linear history.
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
388
413
|
## Imports
|
|
389
414
|
|
|
390
415
|
```ts
|
|
@@ -411,7 +436,7 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
411
436
|
- [ ] If wrapping external API: tests include at least one sparse payload case with omitted upstream fields
|
|
412
437
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
413
438
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
414
|
-
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` =
|
|
415
|
-
- [ ] `.codex-plugin/mcp.json` updated — server name key
|
|
416
|
-
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; inline `mcpServers` entry
|
|
439
|
+
- [ ] `.codex-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license` from `package.json`; `interface.displayName` = the unscoped repo name (never the npm scope — `lint:packaging` enforces this); `interface.shortDescription` from `package.json` description
|
|
440
|
+
- [ ] `.codex-plugin/mcp.json` updated — server name key is the unscoped repo name; every user-supplied variable (API key, contact email, instance URL) is listed in `env_vars` so Codex forwards it from the user's environment. Never write `"KEY": ""` into `env` — an empty value replaces the user's exported key and is read as unset
|
|
441
|
+
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `author`, `repository`, `license`, `keywords` from `package.json`; inline `mcpServers` entry keyed by the unscoped repo name. Every user-supplied variable is declared under `userConfig` (`type`, `title`, `description`; `sensitive: true` for keys and tokens; `required: true` or `default: ""`) and referenced from `env` as `"KEY": "${user_config.<option>}"` — mirror the `user_config` block in `manifest.json`. Never write `"KEY": ""` into `env`
|
|
417
442
|
- [ ] `npm run devcheck` passes
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/exchange-rates-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/exchange-rates-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -27,124 +27,138 @@
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## Overview
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
ECB reference exchange rates via Frankfurter — a keyless proxy covering ~30 currencies back to 1999-01-04. Convert amounts, disambiguate currency codes, and pull point-in-time or historical rates from any MCP client, with SQL analytics over long time-series when DataCanvas is enabled. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
### Tools
|
|
35
35
|
|
|
36
36
|
| Tool | Description |
|
|
37
|
-
|
|
38
|
-
| `fx_list_currencies` | List all ~30 ECB-supported ISO 4217 currencies with full names
|
|
39
|
-
| `fx_get_rates` | Snapshot of all
|
|
40
|
-
| `fx_get_rate` | Exchange rate for a single currency pair at latest or a historical date
|
|
41
|
-
| `fx_convert_currency` | Convert an amount between
|
|
42
|
-
| `fx_get_timeseries` | Historical daily rates for a currency pair over a date range
|
|
43
|
-
| `fx_dataframe_describe` | List DataCanvas tables and
|
|
44
|
-
| `fx_dataframe_query` | Run a read-only SQL SELECT against a DataCanvas table
|
|
45
|
-
| `fx_dataframe_drop` |
|
|
37
|
+
|:---|:---|
|
|
38
|
+
| `fx_list_currencies` | List all ~30 ECB-supported ISO 4217 currencies with full names |
|
|
39
|
+
| `fx_get_rates` | Snapshot of all rates for a base currency at latest or a historical date |
|
|
40
|
+
| `fx_get_rate` | Exchange rate for a single currency pair at latest or a historical date |
|
|
41
|
+
| `fx_convert_currency` | Convert an amount between two currencies at latest or a historical rate |
|
|
42
|
+
| `fx_get_timeseries` | Historical daily rates for a currency pair over a date range |
|
|
43
|
+
| `fx_dataframe_describe` | List DataCanvas tables and columns staged by a prior `fx_get_timeseries` call |
|
|
44
|
+
| `fx_dataframe_query` | Run a read-only SQL SELECT against a staged DataCanvas table |
|
|
45
|
+
| `fx_dataframe_drop` | Remove one staged DataCanvas table or view (opt-in, destructive) |
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
The three `fx_dataframe_*` tools need `CANVAS_PROVIDER_TYPE=duckdb` — unset, they're not advertised in `tools/list` at all, and `fx_get_timeseries` returns every range inline instead. `fx_dataframe_drop` additionally needs `FX_ENABLE_CANVAS_DROP=true`.
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
### Resources
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
| Resource | Description |
|
|
52
|
+
|:---|:---|
|
|
53
|
+
| `fx://currencies` | All supported currencies as a stable reference document |
|
|
54
|
+
| `fx://rates/latest/{base}` | Latest rates snapshot for a base currency as a stable URI |
|
|
53
55
|
|
|
54
|
-
|
|
56
|
+
All resource data is also reachable via tools — use `fx_list_currencies` or `fx_get_rates` for programmatic access.
|
|
55
57
|
|
|
56
|
-
|
|
58
|
+
## Capability reference
|
|
57
59
|
|
|
58
|
-
|
|
60
|
+
### `fx_list_currencies` <sub>tool</sub>
|
|
59
61
|
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
- Useful for seeding bulk comparison workflows or discovering what's available
|
|
62
|
+
- No input parameters
|
|
63
|
+
- Returns `[{ code, name }]` for all ~30 ECB-scoped currencies, sorted alphabetically by code
|
|
64
|
+
- ECB coverage shifts as currencies enter or exit scope — call this to validate a user-supplied code rather than hard-coding a list
|
|
64
65
|
|
|
65
66
|
---
|
|
66
67
|
|
|
67
|
-
### `
|
|
68
|
-
|
|
69
|
-
Point-in-time exchange rate for a single pair.
|
|
68
|
+
### `fx_get_rates` <sub>tool</sub>
|
|
70
69
|
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
70
|
+
- `base_currency` required; `date` optional (default latest, ECB data from 1999-01-04, no future dates); optional `symbols` array narrows the response and must name at least one code
|
|
71
|
+
- Returns a `rates` map (quote code → rate), the actual `rate_date`, and `date_snapped: true` when a weekend/holiday request snapped to the prior business day
|
|
72
|
+
- Naming the base currency in `symbols` is valid — answered locally with a rate of 1 rather than sent upstream
|
|
73
|
+
- Typed failures: `invalid_date_format`, `unsupported_currency`, `date_out_of_range`, `upstream_no_data`
|
|
75
74
|
|
|
76
75
|
---
|
|
77
76
|
|
|
78
|
-
### `
|
|
77
|
+
### `fx_get_rate` <sub>tool</sub>
|
|
79
78
|
|
|
80
|
-
|
|
79
|
+
- `base_currency`, `quote_currency` required; `date` optional (default latest, ECB data from 1999-01-04, no future dates)
|
|
80
|
+
- Returns `rate`, `rate_date`, and `date_snapped: true` when a weekend/holiday request snapped to the prior business day
|
|
81
|
+
- Cross-rates (neither side EUR) triangulate through EUR in one upstream call; a same-currency pair returns a rate of 1 without reaching the API, still dated to the real publication day
|
|
82
|
+
- Typed failures: `invalid_date_format`, `unsupported_currency`, `date_out_of_range`, `upstream_no_data`
|
|
83
|
+
|
|
84
|
+
---
|
|
81
85
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
-
|
|
86
|
+
### `fx_convert_currency` <sub>tool</sub>
|
|
87
|
+
|
|
88
|
+
- `base_currency`, `quote_currency`, `amount` (must be > 0) required; `date` optional (default latest, ECB data from 1999-01-04, no future dates)
|
|
89
|
+
- Handles EUR↔any, any↔EUR, and cross-rate pairs (e.g. USD→JPY) in a single upstream call
|
|
90
|
+
- Returns `quote_amount` (rounded to 6 decimal places), `rate`, `rate_date`, `date_snapped`, plus `rate_type` and `source` provenance
|
|
91
|
+
- Typed failures: `invalid_date_format`, `unsupported_currency`, `date_out_of_range`, `upstream_no_data`
|
|
85
92
|
|
|
86
93
|
---
|
|
87
94
|
|
|
88
|
-
### `fx_get_timeseries`
|
|
95
|
+
### `fx_get_timeseries` <sub>tool</sub>
|
|
89
96
|
|
|
90
|
-
|
|
97
|
+
- `base_currency`, `quote_currency`, `start_date`, `end_date` required (ECB data from 1999-01-04, no future dates, start ≤ end); optional `canvas_id` appends to an existing canvas
|
|
98
|
+
- Inline results page at 500 publication days — `rate_count` is always the range total; `truncated: true` plus `next_start_date` continue the page
|
|
99
|
+
- Ranges over `FX_TIMESERIES_CANVAS_THRESHOLD_DAYS` (default 90 days) spill to DataCanvas when configured — response carries `spilled: true`, `canvas_id`, `table_name`; without DataCanvas they're paged inline instead
|
|
100
|
+
- A same-currency pair returns a rate of 1 on each real ECB publication day in range, not a synthetic Mon–Fri loop
|
|
101
|
+
- An empty range (only weekends/holidays) returns `rate_count: 0` with an explanatory `notice`, distinguishable from an error
|
|
91
102
|
|
|
92
|
-
|
|
103
|
+
---
|
|
93
104
|
|
|
94
|
-
|
|
95
|
-
- Long ranges, **when DataCanvas is enabled** → a preview inline + `canvas_id`, `table_name`, `spilled: true`, and a `notice` naming `fx_dataframe_describe` then `fx_dataframe_query` — the full series is registered as a DuckDB-backed table
|
|
96
|
-
- Long ranges **without DataCanvas** → returned inline with `spilled: false`, paged (below), and a `notice` saying the threshold was crossed but no canvas was configured
|
|
97
|
-
- Inline results are paged at 500 publication days. `rate_count` is always the total for the requested range; when a page is cut short the response carries `truncated: true` and `next_start_date`. Call again with `start_date` set to `next_start_date` and the same `end_date` for the next page — the final page has `truncated: false` and no `next_start_date`
|
|
98
|
-
- Requesting the same currency on both sides returns a rate of 1 on each publication day in the range, taken from the ECB's real calendar rather than a synthetic Mon–Fri loop
|
|
105
|
+
### `fx_dataframe_describe` <sub>tool</sub>
|
|
99
106
|
|
|
100
|
-
|
|
107
|
+
- `canvas_id` required (from a prior `fx_get_timeseries` call)
|
|
108
|
+
- Returns each staged table's `kind`, `row_count`, and column schema (`name`, `type`, `nullable`), plus `expires_at`
|
|
109
|
+
- Required first step before `fx_dataframe_query`; needs `CANVAS_PROVIDER_TYPE=duckdb` — unregistered otherwise
|
|
110
|
+
- `canvas_not_found` when the ID doesn't exist or has expired
|
|
101
111
|
|
|
102
|
-
|
|
112
|
+
---
|
|
103
113
|
|
|
104
|
-
|
|
105
|
-
2. **`fx_dataframe_query`** — run arbitrary SQL SELECT against the registered table; supports aggregations, GROUP BY, window functions, JOINs across tables from multiple `fx_get_timeseries` calls. Returns at most `row_limit` rows (default 150, max 10,000) on both response surfaces; past that, `truncated: true` and a `notice` give the `ORDER BY <column> LIMIT <n> OFFSET <m>` shape for the next page (`ORDER BY` is required for stable paging). Cell values are escaped in the Markdown table so pipes, angle brackets, and line breaks stay inside their cell; `structuredContent` keeps the raw values
|
|
114
|
+
### `fx_dataframe_query` <sub>tool</sub>
|
|
106
115
|
|
|
107
|
-
|
|
116
|
+
- `canvas_id` and a read-only SQL `query` required; `row_limit` optional (1–10,000, default 150)
|
|
117
|
+
- Supports aggregations, GROUP BY, window functions, and JOINs across tables from multiple `fx_get_timeseries` calls
|
|
118
|
+
- Returns at most `row_limit` rows; `truncated: true` plus a `notice` give the `ORDER BY <column> LIMIT <n> OFFSET <m>` shape for the next page — ORDER BY is required for stable paging
|
|
119
|
+
- Markdown table cells are escaped so pipes, angle brackets, and line breaks stay inside their cell; `structuredContent` keeps raw values
|
|
120
|
+
- Needs `CANVAS_PROVIDER_TYPE=duckdb`; typed failures: `canvas_not_found`, `missing_table`, `invalid_query`
|
|
108
121
|
|
|
109
122
|
---
|
|
110
123
|
|
|
111
|
-
|
|
124
|
+
### `fx_dataframe_drop` <sub>tool</sub>
|
|
112
125
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
126
|
+
- `canvas_id` and exact `table_name` (from `fx_dataframe_describe`) required
|
|
127
|
+
- Removes one staged table or view; ECB rate data is untouched and the series can be re-staged via `fx_get_timeseries`
|
|
128
|
+
- Returns `dropped: true`/`false` depending on whether the table existed
|
|
129
|
+
- Disabled unless `FX_ENABLE_CANVAS_DROP=true` — listed with its enable hint but uncallable otherwise; also needs `CANVAS_PROVIDER_TYPE=duckdb`
|
|
117
130
|
|
|
118
|
-
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
### `fx://currencies` <sub>resource</sub>
|
|
134
|
+
|
|
135
|
+
- No parameters; returns `currencies`, `count`, `source` as `application/json` — the same payload as `fx_list_currencies`
|
|
136
|
+
- Listed as a single static resource
|
|
119
137
|
|
|
120
138
|
---
|
|
121
139
|
|
|
122
|
-
|
|
140
|
+
### `fx://rates/latest/{base}` <sub>resource</sub>
|
|
141
|
+
|
|
142
|
+
- `base` is an ISO 4217 currency code in the URI
|
|
143
|
+
- Returns `base_currency`, `rate_date`, a `rates` map, `rate_type`, and `source` for the latest ECB fix
|
|
144
|
+
- Listed with four sample URIs (EUR, USD, GBP, JPY) as discovery hints
|
|
123
145
|
|
|
124
|
-
|
|
146
|
+
## Features
|
|
125
147
|
|
|
126
|
-
-
|
|
127
|
-
- Unified error handling — handlers throw, framework catches, classifies, and formats
|
|
128
|
-
- Typed error contracts with recovery hints — `unsupported_currency`, `date_out_of_range`, `canvas_not_found`, `missing_table`, `invalid_query`
|
|
129
|
-
- Pluggable auth: `none`, `jwt`, `oauth`
|
|
130
|
-
- Structured logging with optional OpenTelemetry tracing
|
|
131
|
-
- STDIO and Streamable HTTP transports
|
|
148
|
+
Built on [`@cyanheads/mcp-ts-core`](https://github.com/cyanheads/mcp-ts-core): stdio and Streamable HTTP transports, pluggable auth (`none` / `jwt` / `oauth`), swappable storage (`in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`), structured logging with optional OpenTelemetry tracing.
|
|
132
149
|
|
|
133
|
-
ECB
|
|
150
|
+
ECB-specific:
|
|
134
151
|
|
|
135
152
|
- Keyless access via [Frankfurter](https://www.frankfurter.dev/) — a Cloudflare-fronted ECB proxy; no API keys required
|
|
136
153
|
- Cross-rate triangulation: any pair works — USD → JPY is one upstream call, cross-rated through EUR on Frankfurter's side
|
|
137
|
-
- Weekend/holiday date semantics: `date_snapped`
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
- DataCanvas integration: when enabled, `fx_get_timeseries` spills long ranges to DuckDB for aggregations and trend analysis
|
|
141
|
-
- Rate provenance on every response: `rate_type: "ECB reference (mid-market)"` and `source: "ECB via Frankfurter"` — explicitly mid-market, not tradeable bid/ask
|
|
154
|
+
- Weekend/holiday date semantics: `date_snapped` surfaces when the API returns a different date than requested
|
|
155
|
+
- Identity pairs never reach the upstream API: a currency against itself returns a rate of 1, dated to the day the ECB actually published for that currency rather than to the calendar date requested
|
|
156
|
+
- Long time-series spill to DataCanvas (DuckDB) when enabled, for SQL aggregation over the full range
|
|
142
157
|
|
|
143
158
|
Agent-friendly output:
|
|
144
159
|
|
|
145
|
-
- Rate provenance on every
|
|
160
|
+
- Rate provenance on every response — `rate_type`, `source`, `rate_date`, and `date_snapped` so agents can reason about trust and freshness
|
|
146
161
|
- Structured error contracts — typed `reason` fields (`unsupported_currency`, `date_out_of_range`, `invalid_query`, …) let callers branch on failure type, not string parsing
|
|
147
|
-
- Discriminated DataCanvas output — `spilled: true` plus `canvas_id` signal when a time-series was staged for SQL follow-up rather than returned inline
|
|
148
162
|
- Bounded responses — inline time-series pages continue from `next_start_date`, and SQL results cap at `row_limit`, so no call returns an unbounded payload
|
|
149
163
|
- Success-path `notice` enrichment — explains an empty series, where to continue a paged series, or which tools read a staged one, so a legitimate zero-result never reads as a failure
|
|
150
164
|
|
|
@@ -294,7 +308,7 @@ All configuration is validated at startup via Zod schemas. Environment variables
|
|
|
294
308
|
| `CANVAS_PROVIDER_TYPE` | Canvas engine. Set to `duckdb` to enable DataCanvas for `fx_get_timeseries` long-range spillover and to register the three `fx_dataframe_*` tools. At `none` they are skipped from `tools/list`. | `none` |
|
|
295
309
|
| `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
|
|
296
310
|
| `MCP_HTTP_PORT` | Port for HTTP server. | `3010` |
|
|
297
|
-
| `MCP_SESSION_MODE` | HTTP session mode: `auto`, `stateful`, or `stateless`.
|
|
311
|
+
| `MCP_SESSION_MODE` | HTTP session mode: `auto`, `stateful`, or `stateless`. The server declares `stateless` in code — no handler here asks the client for input mid-call, so nothing needs a session to resume — and setting this variable overrides that declaration. | `stateless` |
|
|
298
312
|
| `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
|
|
299
313
|
| `MCP_LOG_LEVEL` | Log level (RFC 5424: `debug`, `info`, `notice`, `warning`, `error`). | `info` |
|
|
300
314
|
| `OTEL_ENABLED` | Enable [OpenTelemetry instrumentation](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry). | `false` |
|
|
@@ -365,7 +379,7 @@ See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rule
|
|
|
365
379
|
|
|
366
380
|
## Contributing
|
|
367
381
|
|
|
368
|
-
Issues
|
|
382
|
+
Issues are welcome. Run checks and tests before submitting:
|
|
369
383
|
|
|
370
384
|
```sh
|
|
371
385
|
bun run devcheck
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Adopts mcp-ts-core 0.13.6: declares stateless session mode in source, validates canvas_id inputs against the minted shape at argument validation, and stops putting the upstream Frankfurter request URL — which carried caller currency codes/dates plus the configured API host — on client-facing error data."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.4.1 — 2026-09-19
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- **`sessionMode: 'stateless'` is now declared in `src/index.ts`** — the HTTP session posture no longer depends solely on `.env.example`/Dockerfile defaults; `MCP_SESSION_MODE` set in the environment still overrides it.
|
|
12
|
+
- **`canvas_id` inputs are validated against the minted `^[A-Za-z0-9_-]{10}$` shape** on `fx_dataframe_describe`, `fx_dataframe_query`, `fx_dataframe_drop`, and `fx_get_timeseries` — a malformed id is now rejected at argument validation instead of reaching the canvas registry, which could only report it as missing or expired.
|
|
13
|
+
- **Dev skill tree moved from `skills/` to `framework-skills/`** — a plugin's root `skills/` auto-loads for installers, which would hand these development skills to every agent that installs the server; not part of the published npm package.
|
|
14
|
+
- **`@cyanheads/mcp-ts-core` 0.12.8 → 0.13.6** — see Dependencies.
|
|
15
|
+
|
|
16
|
+
## Security
|
|
17
|
+
|
|
18
|
+
- **The upstream Frankfurter request URL no longer reaches client-facing error data.** `structuredContent.error.data` previously carried the full request URL on an upstream failure — the caller's currency codes and dates alongside the configured `FRANKFURTER_BASE_URL` host; the error message still names the service.
|
|
19
|
+
|
|
20
|
+
## Dependencies
|
|
21
|
+
|
|
22
|
+
- `@cyanheads/mcp-ts-core` 0.12.8 → 0.13.6
|
|
23
|
+
- `@duckdb/node-api` ^1.5.5-r.4 → ^1.5.5-r.5
|
|
24
|
+
- `zod` ^4.6.0 → ^4.6.5
|
|
25
|
+
- `@biomejs/biome` 2.5.12 → 2.5.14
|
|
26
|
+
- `tsc-alias` ^1.9.4 → ^1.9.5
|
|
27
|
+
- `vitest` ^5.0.0 → ^5.0.1
|
package/changelog/template.md
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
# Required. One-line GitHub Release-style headline. 350 character cap — a
|
|
8
8
|
# ceiling, not a target. Default short and scannable. Don't pad, don't stitch
|
|
9
|
-
# unrelated changes with commas/semicolons into an inventory — pick the
|
|
10
|
-
# headline
|
|
9
|
+
# unrelated changes with commas/semicolons into an inventory — pick the one
|
|
10
|
+
# headline the release is about. Quotes required: unquoted YAML treats
|
|
11
11
|
# `: ` inside the value as a key separator and fails GitHub's strict parser.
|
|
12
12
|
summary: ""
|
|
13
13
|
|
|
@@ -117,30 +117,13 @@ security: false
|
|
|
117
117
|
in that unrelated item's metadata.
|
|
118
118
|
|
|
119
119
|
TAG ANNOTATIONS — the annotated tag body renders as the GitHub Release body
|
|
120
|
-
via `gh release create --notes-from-tag`.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
Dependency bumps: ← section header
|
|
128
|
-
← blank line
|
|
129
|
-
- `@cyanheads/mcp-ts-core` ^0.9.1 → ^0.9.6 ← bullet
|
|
130
|
-
← blank line
|
|
131
|
-
Changed: ← only sections with entries
|
|
132
|
-
← blank line
|
|
133
|
-
- `format()` output includes `query` in text mode
|
|
134
|
-
← blank line
|
|
135
|
-
Added:
|
|
136
|
-
← blank line
|
|
137
|
-
- `manifest.json` scaffolded for MCPB bundle support
|
|
138
|
-
- Install badges (Claude Desktop, Cursor, VS Code)
|
|
139
|
-
← blank line
|
|
140
|
-
<N> tests pass; `bun run devcheck` clean. ← footer
|
|
141
|
-
|
|
142
|
-
Never a flat comma-separated string. Always structured markdown with
|
|
143
|
-
sections. The tag must scan well as a rendered GitHub Release page.
|
|
120
|
+
via `gh release create --notes-from-tag`. It is a condensed digest of this
|
|
121
|
+
entry, never a copy, and its format is owned by the `release-and-publish`
|
|
122
|
+
skill (step 4, "Create the annotated tag"): a short subject line without the
|
|
123
|
+
version, flat headline bullets — no Keep-a-Changelog section headers, no
|
|
124
|
+
gates line — at most one deps line, issue backlinks, and the changelog link
|
|
125
|
+
last. In release-PR mode the `git-wrapup` skill authors those bullets as the
|
|
126
|
+
PR body's `## Changes` and the tag copies them.
|
|
144
127
|
-->
|
|
145
128
|
|
|
146
129
|
## Added
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,13 @@ const canvasGate = {
|
|
|
23
23
|
await createApp({
|
|
24
24
|
name: 'exchange-rates-mcp-server',
|
|
25
25
|
title: 'exchange-rates-mcp-server',
|
|
26
|
+
/**
|
|
27
|
+
* No handler here asks the caller for input mid-call, so nothing needs a session
|
|
28
|
+
* to resume. Declared in source rather than left to `.env.example` and the
|
|
29
|
+
* Dockerfile alone, which a deployment can drop; `MCP_SESSION_MODE` still wins
|
|
30
|
+
* when it carries a value.
|
|
31
|
+
*/
|
|
32
|
+
sessionMode: 'stateless',
|
|
26
33
|
tools: [
|
|
27
34
|
fxListCurrencies,
|
|
28
35
|
fxGetRates,
|
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,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,eAAe,EACf,gBAAgB,GACjB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,KAAK,MAAM,CAAC;AAC5D,MAAM,UAAU,GAAG;IACjB,IAAI,EAAE,6BAA6B;IACnC,MAAM,EAAE,wFAAwF;CACxF,CAAC;AAEX,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,2BAA2B;IACjC,KAAK,EAAE,2BAA2B;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,eAAe,EACf,gBAAgB,GACjB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,KAAK,MAAM,CAAC;AAC5D,MAAM,UAAU,GAAG;IACjB,IAAI,EAAE,6BAA6B;IACnC,MAAM,EAAE,wFAAwF;CACxF,CAAC;AAEX,MAAM,SAAS,CAAC;IACd,IAAI,EAAE,2BAA2B;IACjC,KAAK,EAAE,2BAA2B;IAElC;;;;;OAKG;IACH,WAAW,EAAE,WAAW;IAExB,KAAK,EAAE;QACL,gBAAgB;QAChB,UAAU;QACV,SAAS;QACT,iBAAiB;QACjB,eAAe;QACf,aAAa,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,YAAY,CAAC,mBAAmB,EAAE,UAAU,CAAC;QACnF,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,YAAY,CAAC,gBAAgB,EAAE,UAAU,CAAC;QAC7E,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,YAAY,CAAC,eAAe,EAAE,UAAU,CAAC;KAC5E;IACD,SAAS,EAAE,CAAC,oBAAoB,EAAE,qBAAqB,CAAC;IACxD,OAAO,EAAE,EAAE;IAEX,YAAY,EACV,4FAA4F;QAC5F,uEAAuE;QACvE,mFAAmF;QACnF,4EAA4E;QAC5E,uGAAuG;QACvG,yFAAyF;QACzF,4GAA4G;QAC5G,2CAA2C;IAE7C,KAAK,CAAC,IAAI;QACR,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx-dataframe-describe.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-describe.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAgC,MAAM,+BAA+B,CAAC;AAG/F,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"fx-dataframe-describe.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-describe.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAgC,MAAM,+BAA+B,CAAC;AAG/F,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;cAoH9B,CAAC"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @module mcp-server/tools/definitions/fx-dataframe-describe.tool
|
|
4
4
|
*/
|
|
5
5
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { CanvasIdSchema } from '@cyanheads/mcp-ts-core/canvas';
|
|
6
7
|
import { JsonRpcErrorCode, McpError, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
7
8
|
import { getCanvas } from '../../../services/canvas/canvas-accessor.js';
|
|
8
9
|
export const fxDataframeDescribe = tool('fx_dataframe_describe', {
|
|
@@ -16,9 +17,7 @@ export const fxDataframeDescribe = tool('fx_dataframe_describe', {
|
|
|
16
17
|
openWorldHint: false,
|
|
17
18
|
},
|
|
18
19
|
input: z.object({
|
|
19
|
-
canvas_id:
|
|
20
|
-
.string()
|
|
21
|
-
.describe('Canvas ID returned by fx_get_timeseries. ' +
|
|
20
|
+
canvas_id: CanvasIdSchema.describe('Canvas ID returned by fx_get_timeseries. ' +
|
|
22
21
|
'Re-run fx_get_timeseries to obtain a fresh canvas_id if this one has expired.'),
|
|
23
22
|
}),
|
|
24
23
|
output: z.object({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx-dataframe-describe.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-describe.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"fx-dataframe-describe.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-describe.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx-dataframe-drop.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-drop.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"fx-dataframe-drop.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-drop.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,EAAE,gBAAgB,EAAY,MAAM,+BAA+B,CAAC;AAkG3E;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;cAKtB,CAAC"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @module mcp-server/tools/definitions/fx-dataframe-drop.tool
|
|
4
4
|
*/
|
|
5
5
|
import { disabledTool, tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { CanvasIdSchema } from '@cyanheads/mcp-ts-core/canvas';
|
|
6
7
|
import { JsonRpcErrorCode, McpError } from '@cyanheads/mcp-ts-core/errors';
|
|
7
8
|
import { getServerConfig } from '../../../config/server-config.js';
|
|
8
9
|
import { getCanvas } from '../../../services/canvas/canvas-accessor.js';
|
|
@@ -19,9 +20,7 @@ const fxDataframeDropDefinition = tool('fx_dataframe_drop', {
|
|
|
19
20
|
openWorldHint: false,
|
|
20
21
|
},
|
|
21
22
|
input: z.object({
|
|
22
|
-
canvas_id:
|
|
23
|
-
.string()
|
|
24
|
-
.describe('Canvas ID returned by fx_get_timeseries. ' +
|
|
23
|
+
canvas_id: CanvasIdSchema.describe('Canvas ID returned by fx_get_timeseries. ' +
|
|
25
24
|
'Re-run fx_get_timeseries to obtain a fresh canvas_id if this one has expired.'),
|
|
26
25
|
table_name: z
|
|
27
26
|
.string()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx-dataframe-drop.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-drop.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEjE,MAAM,yBAAyB,GAAG,IAAI,CAAC,mBAAmB,EAAE;IAC1D,WAAW,EACT,oFAAoF;QACpF,yFAAyF;QACzF,2DAA2D;QAC3D,gEAAgE;QAChE,iEAAiE;IACnE,WAAW,EAAE;QACX,YAAY,EAAE,KAAK;QACnB,eAAe,EAAE,IAAI;QACrB,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,KAAK;KACrB;IACD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,SAAS,EAAE,CAAC
|
|
1
|
+
{"version":3,"file":"fx-dataframe-drop.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-drop.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx-dataframe-query.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-query.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"fx-dataframe-query.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-query.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAMjD,OAAO,EAAE,gBAAgB,EAAgC,MAAM,+BAA+B,CAAC;AAa/F,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;EAsN3B,CAAC"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @module mcp-server/tools/definitions/fx-dataframe-query.tool
|
|
4
4
|
*/
|
|
5
5
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { CanvasIdSchema, } from '@cyanheads/mcp-ts-core/canvas';
|
|
6
7
|
import { JsonRpcErrorCode, McpError, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
7
8
|
import { getCanvas } from '../../../services/canvas/canvas-accessor.js';
|
|
8
9
|
import { escapeMarkdownTableCell } from '../../../utils/escape-markdown-table-cell.js';
|
|
@@ -26,9 +27,7 @@ export const fxDataframeQuery = tool('fx_dataframe_query', {
|
|
|
26
27
|
openWorldHint: false,
|
|
27
28
|
},
|
|
28
29
|
input: z.object({
|
|
29
|
-
canvas_id:
|
|
30
|
-
.string()
|
|
31
|
-
.describe('Canvas ID returned by fx_get_timeseries. ' +
|
|
30
|
+
canvas_id: CanvasIdSchema.describe('Canvas ID returned by fx_get_timeseries. ' +
|
|
32
31
|
'Re-run fx_get_timeseries to obtain a fresh canvas_id if this one has expired.'),
|
|
33
32
|
query: z
|
|
34
33
|
.string()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx-dataframe-query.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-query.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"fx-dataframe-query.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-dataframe-query.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx-get-timeseries.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-get-timeseries.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAkBjE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"fx-get-timeseries.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-get-timeseries.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAkBjE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuX1B,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module mcp-server/tools/definitions/fx-get-timeseries.tool
|
|
4
4
|
*/
|
|
5
5
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
-
import { spillover } from '@cyanheads/mcp-ts-core/canvas';
|
|
6
|
+
import { CanvasIdSchema, spillover } from '@cyanheads/mcp-ts-core/canvas';
|
|
7
7
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
8
8
|
import { getServerConfig } from '../../../config/server-config.js';
|
|
9
9
|
import { getCanvas } from '../../../services/canvas/canvas-accessor.js';
|
|
@@ -48,10 +48,7 @@ export const fxGetTimeseries = tool('fx_get_timeseries', {
|
|
|
48
48
|
end_date: z
|
|
49
49
|
.string()
|
|
50
50
|
.describe('ISO 8601 end date (YYYY-MM-DD). Must be >= start_date. Future dates are not supported.'),
|
|
51
|
-
canvas_id:
|
|
52
|
-
.string()
|
|
53
|
-
.optional()
|
|
54
|
-
.describe('Optional canvas ID from a prior call. Omit on the first call to start a fresh canvas; ' +
|
|
51
|
+
canvas_id: CanvasIdSchema.optional().describe('Optional canvas ID from a prior call. Omit on the first call to start a fresh canvas; ' +
|
|
55
52
|
'pass the returned canvas_id to append tables to an existing canvas.'),
|
|
56
53
|
}),
|
|
57
54
|
output: z.object({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx-get-timeseries.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-get-timeseries.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"fx-get-timeseries.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-get-timeseries.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AACzF,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,SAAS,GACV,MAAM,+CAA+C,CAAC;AAGvD;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,mBAAmB,EAAE;IACvD,WAAW,EACT,6EAA6E;QAC7E,4FAA4F;QAC5F,8FAA8F;QAC9F,kEAAkE;QAClE,iFAAiF;QACjF,2DAA2D,gBAAgB,qBAAqB;QAChG,2FAA2F;QAC3F,0FAA0F;QAC1F,2DAA2D;QAC3D,mGAAmG;QACnG,yFAAyF;QACzF,oGAAoG;QACpG,yFAAyF;IAC3F,WAAW,EAAE;QACX,YAAY,EAAE,IAAI;QAClB,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,IAAI;KACpB;IACD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,aAAa,EAAE,CAAC;aACb,MAAM,EAAE;aACR,QAAQ,CACP,qFAAqF,CACtF;QACH,cAAc,EAAE,CAAC;aACd,MAAM,EAAE;aACR,QAAQ,CACP,sFAAsF,CACvF;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,CACP,gEAAgE;YAC9D,oFAAoF,CACvF;QACH,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,CACP,wFAAwF,CACzF;QACH,SAAS,EAAE,cAAc,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAC3C,wFAAwF;YACtF,qEAAqE,CACxE;KACF,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QACzD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QAC3D,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,CACP,2FAA2F;YACzF,yFAAyF;YACzF,uCAAuC,CAC1C;QACH,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,CACP,4FAA4F;YAC1F,0FAA0F;YAC1F,iEAAiE,CACpE;QACH,KAAK,EAAE,CAAC;aACL,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;aAC9B,QAAQ,CACP,yFAAyF;YACvF,sEAAsE,gBAAgB,SAAS;YAC/F,2FAA2F;YAC3F,oFAAoF,CACvF;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,CACP,2FAA2F;YACzF,4FAA4F;YAC5F,wEAAwE,CAC3E;QACH,SAAS,EAAE,CAAC;aACT,OAAO,EAAE;aACT,QAAQ,CACP,2FAA2F;YACzF,2FAA2F;YAC3F,yBAAyB,CAC5B;QACH,eAAe,EAAE,CAAC;aACf,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,2FAA2F;YACzF,8FAA8F,CACjG;QACH,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,CACP,yFAAyF,CAC1F;QACH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;QACzF,OAAO,EAAE,CAAC;aACP,OAAO,EAAE;aACT,QAAQ,CACP,oFAAoF,CACrF;QACH,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,yFAAyF;YACvF,sDAAsD,CACzD;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,iFAAiF;YAC/E,kEAAkE,CACrE;KACJ,CAAC;IAEF,UAAU,EAAE;QACV,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,wFAAwF;YACtF,sFAAsF;YACtF,sFAAsF;YACtF,qFAAqF,CACxF;KACJ;IAED,MAAM,EAAE;QACN;YACE,MAAM,EAAE,qBAAqB;YAC7B,IAAI,EAAE,gBAAgB,CAAC,eAAe;YACtC,IAAI,EAAE,2EAA2E;YACjF,QAAQ,EAAE,0EAA0E;SACrF;QACD;YACE,MAAM,EAAE,sBAAsB;YAC9B,IAAI,EAAE,gBAAgB,CAAC,eAAe;YACtC,IAAI,EAAE,iEAAiE;YACvE,QAAQ,EAAE,kEAAkE;SAC7E;QACD;YACE,MAAM,EAAE,mBAAmB;YAC3B,IAAI,EAAE,gBAAgB,CAAC,eAAe;YACtC,IAAI,EAAE,+DAA+D;YACrE,QAAQ,EAAE,gEAAgE;SAC3E;QACD;YACE,MAAM,EAAE,eAAe;YACvB,IAAI,EAAE,gBAAgB,CAAC,eAAe;YACtC,IAAI,EAAE,+BAA+B;YACrC,QAAQ,EAAE,mDAAmD;SAC9D;QACD;YACE,MAAM,EAAE,kBAAkB;YAC1B,IAAI,EAAE,gBAAgB,CAAC,QAAQ;YAC/B,IAAI,EAAE,iFAAiF;YACvF,QAAQ,EAAE,yEAAyE;SACpF;KACF;IAED,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACtB,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEpD;;;;WAIG;QACH,KAAK,MAAM,KAAK,IAAI,CAAC,YAAY,EAAE,UAAU,CAAU,EAAE,CAAC;YACxD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtB,MAAM,GAAG,CAAC,IAAI,CACZ,qBAAqB,EACrB,GAAG,KAAK,KAAK,KAAK,4CAA4C,EAC9D,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC,qBAAqB,CAAC,EAAE,KAAK,EAAE,CACrD,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,UAAU,GAAG,cAAc,EAAE,CAAC;YACtC,MAAM,GAAG,CAAC,IAAI,CACZ,mBAAmB,EACnB,cAAc,KAAK,CAAC,UAAU,6BAA6B,cAAc,GAAG,EAC5E;gBACE,GAAG,GAAG,CAAC,WAAW,CAAC,mBAAmB,CAAC;aACxC,CACF,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,GAAG,KAAK,EAAE,CAAC;YAC3B,MAAM,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,YAAY,KAAK,CAAC,QAAQ,oBAAoB,EAAE;gBAClF,GAAG,GAAG,CAAC,WAAW,CAAC,mBAAmB,CAAC;aACxC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;YACtC,MAAM,GAAG,CAAC,IAAI,CACZ,eAAe,EACf,cAAc,KAAK,CAAC,UAAU,sBAAsB,KAAK,CAAC,QAAQ,GAAG,EACrE;gBACE,GAAG,GAAG,CAAC,WAAW,CAAC,eAAe,CAAC;aACpC,CACF,CAAC;QACJ,CAAC;QAED,sDAAsD;QACtD,MAAM,QAAQ,GAAG,UAAU,CAAC;QAC5B,MAAM,QAAQ,GACZ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC;QAE7F,IAAI,MAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,OAAO,CAAC,aAAa,CAClC,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,QAAQ,CACf,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,OAAO,EAAE,MAAM,KAAK,sBAAsB,EAAE,CAAC;gBAC/C,MAAM,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAG,GAAa,CAAC,OAAO,EAAE;oBAC7D,GAAG,GAAG,CAAC,WAAW,CAAC,sBAAsB,CAAC;oBAC1C,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,GAAG,0BAA0B,CAAC,GAAG,CAAC;iBACnC,CAAC,CAAC;YACL,CAAC;YACD,IAAI,OAAO,EAAE,MAAM,KAAK,kBAAkB,EAAE,CAAC;gBAC3C,MAAM,GAAG,CAAC,IAAI,CACZ,kBAAkB,EAClB,wBAAwB,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,cAAc,kBAAkB,KAAK,CAAC,UAAU,QAAQ,KAAK,CAAC,QAAQ,GAAG,EAC9H,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC,kBAAkB,CAAC,EAAE,CAC3C,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;QAEpE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE;YACjC,IAAI,EAAE,KAAK,CAAC,aAAa;YACzB,KAAK,EAAE,KAAK,CAAC,cAAc;YAC3B,KAAK,EAAE,WAAW;YAClB,GAAG,EAAE,SAAS;YACd,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ;SACT,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,gBAAgB,GAAG,QAAQ,GAAG,MAAM,CAAC,6BAA6B,CAAC;QAEzE,4FAA4F;QAC5F,MAAM,QAAQ,GAAG;YACf,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,EAAE;YAChD,cAAc,EAAE,KAAK,CAAC,cAAc,CAAC,WAAW,EAAE;YAClD,UAAU,EAAE,WAAW;YACvB,QAAQ,EAAE,SAAS;YACnB,SAAS,EAAE,4BAA4B;YACvC,MAAM,EAAE,qBAAqB;SAC9B,CAAC;QAEF,IAAI,MAAM,IAAI,IAAI,IAAI,gBAAgB,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAC5D,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,cAAc,CAAC,WAAW,EAAE,EAAE,CAAC;YAElG,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC;gBAClC,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,IAAI;gBACZ,SAAS;gBACT,YAAY,EAAE,MAAM,EAAE,sBAAsB;gBAC5C,MAAM,EAAE,GAAG,CAAC,MAAM;aACnB,CAAC,CAAC;YAEH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE;gBAChC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,SAAS;gBACT,QAAQ,EAAE,IAAI,CAAC,MAAM;gBACrB,OAAO,EAAE,WAAW,CAAC,OAAO;aAC7B,CAAC,CAAC;YAEH,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;gBACxB,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC;gBAChE,GAAG,CAAC,MAAM,CAAC,MAAM,CACf,UAAU,QAAQ,mBAAmB,WAAW,eAAe,QAAQ,CAAC,QAAQ,UAAU;oBACxF,4FAA4F;oBAC5F,0CAA0C,CAC7C,CAAC;gBACF,OAAO;oBACL,GAAG,QAAQ;oBACX,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;oBACrF,UAAU,EAAE,QAAQ;oBACpB,SAAS,EAAE,IAAI;oBACf,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,QAAQ,CAAC,QAAQ;oBAC5B,UAAU,EAAE,WAAW;iBACxB,CAAC;YACJ,CAAC;YACD,kFAAkF;QACpF,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAEvC;;;;WAIG;QACH,MAAM,QAAQ,GACZ,gBAAgB,IAAI,MAAM,IAAI,IAAI;YAChC,CAAC,CAAC,QAAQ,QAAQ,0BAA0B,MAAM,CAAC,6BAA6B,4BAA4B;gBAC1G,sGAAsG;gBACtG,uEAAuE;YACzE,CAAC,CAAC,SAAS,CAAC;QAEhB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,GAAG,CAAC,MAAM,CAAC,MAAM,CACf,wBAAwB,QAAQ,CAAC,aAAa,IAAI,QAAQ,CAAC,cAAc,gBAAgB;gBACvF,GAAG,KAAK,CAAC,UAAU,QAAQ,KAAK,CAAC,QAAQ,0DAA0D;gBACnG,+FAA+F;gBAC/F,8FAA8F,CACjG,CAAC;QACJ,CAAC;aAAM,IAAI,OAAO,EAAE,CAAC;YACnB,MAAM,QAAQ,GACZ,yBAAyB,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,MAAM,oBAAoB;gBAC1E,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,uCAAuC;gBAChF,cAAc,OAAO,CAAC,IAAI,iBAAiB,KAAK,CAAC,QAAQ,qBAAqB,CAAC;YACjF,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrE,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO;YACL,GAAG,QAAQ;YACX,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAClE,UAAU,EAAE,IAAI,CAAC,MAAM;YACvB,SAAS,EAAE,OAAO,KAAK,SAAS;YAChC,GAAG,CAAC,OAAO,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;YACjD,OAAO,EAAE,KAAK;SACf,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;QACjB,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QACxF,MAAM,KAAK,GAAa;YACtB,KAAK,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,cAAc,oBAAoB,MAAM,CAAC,UAAU,OAAO,MAAM,CAAC,QAAQ,EAAE;YAC/G,IAAI,MAAM,CAAC,UAAU,2CAA2C,MAAM,CAAC,SAAS,MAAM,MAAM,CAAC,MAAM,eAAe,MAAM,CAAC,OAAO,GAAG;YACnI,IAAI,WAAW,CAAC,MAAM,uBAAuB,MAAM,CAAC,SAAS,EAAE;gBAC7D,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,uBAAuB,MAAM,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;SACpF,CAAC;QAEF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CACR,oDAAoD,EACpD,gBAAgB,MAAM,CAAC,SAAS,IAAI,EACpC,YAAY,MAAM,CAAC,UAAU,IAAI,EACjC,sFAAsF;gBACpF,sFAAsF,CACzF,CAAC;QACJ,CAAC;QAED,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC;gBACvC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;QAED,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -40,8 +40,13 @@ export declare function unsupportedCurrency(field: string, rejected: string[], a
|
|
|
40
40
|
* The ECB published no rates for an otherwise well-formed request — most often a
|
|
41
41
|
* date that predates the requested currency's series (ILS and BRL start well after
|
|
42
42
|
* the 1999-01-04 ECB epoch).
|
|
43
|
+
*
|
|
44
|
+
* The upstream request URL is deliberately absent: `McpError.data` reaches the
|
|
45
|
+
* client as `structuredContent.error.data`, and the URL carries both the caller's
|
|
46
|
+
* inputs and the configured Frankfurter host. The calling tool re-raises with a
|
|
47
|
+
* message naming the pair and dates it asked for, which is the part a caller can act on.
|
|
43
48
|
*/
|
|
44
|
-
export declare function upstreamNoData(
|
|
49
|
+
export declare function upstreamNoData(): McpError;
|
|
45
50
|
/**
|
|
46
51
|
* Read the structured failure off a service-thrown error.
|
|
47
52
|
* Returns `undefined` for anything the service did not classify.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/services/frankfurter/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAA6B,MAAM,+BAA+B,CAAC;AAEpF;;;GAGG;AACH,QAAA,MAAM,eAAe,YACnB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,CACV,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,MAAM,EAAE,wBAAwB,CAAC;CAClC;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAMxE;AAED,mFAAmF;AACnF,MAAM,WAAW,wBAAwB;IACvC,0EAA0E;IAC1E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,4CAA4C;IAC5C,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,MAAM,EAAE,GACjB,QAAQ,CAWV;AAED
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/services/frankfurter/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAA6B,MAAM,+BAA+B,CAAC;AAEpF;;;GAGG;AACH,QAAA,MAAM,eAAe,YACnB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,CACV,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,MAAM,EAAE,wBAAwB,CAAC;CAClC;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAMxE;AAED,mFAAmF;AACnF,MAAM,WAAW,wBAAwB;IACvC,0EAA0E;IAC1E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,4CAA4C;IAC5C,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,MAAM,EAAE,GACjB,QAAQ,CAWV;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,IAAI,QAAQ,CAIzC;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CASxE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,GAAG,SAAS,CAK/F"}
|
|
@@ -45,11 +45,15 @@ export function unsupportedCurrency(field, rejected, accepted) {
|
|
|
45
45
|
* The ECB published no rates for an otherwise well-formed request — most often a
|
|
46
46
|
* date that predates the requested currency's series (ILS and BRL start well after
|
|
47
47
|
* the 1999-01-04 ECB epoch).
|
|
48
|
+
*
|
|
49
|
+
* The upstream request URL is deliberately absent: `McpError.data` reaches the
|
|
50
|
+
* client as `structuredContent.error.data`, and the URL carries both the caller's
|
|
51
|
+
* inputs and the configured Frankfurter host. The calling tool re-raises with a
|
|
52
|
+
* message naming the pair and dates it asked for, which is the part a caller can act on.
|
|
48
53
|
*/
|
|
49
|
-
export function upstreamNoData(
|
|
54
|
+
export function upstreamNoData() {
|
|
50
55
|
return notFound('The ECB published no rates for this request.', {
|
|
51
56
|
reason: 'upstream_no_data',
|
|
52
|
-
url,
|
|
53
57
|
});
|
|
54
58
|
}
|
|
55
59
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/services/frankfurter/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEpF;;;GAGG;AACH,MAAM,eAAe,GAAG;IACtB,qBAAqB;IACrB,sBAAsB;IACtB,kBAAkB;CACV,CAAC;AAYX,gEAAgE;AAChE,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,KAAa;IAC5D,OAAO,eAAe,CAAC,GAAG,KAAK,KAAK,KAAK,4CAA4C,EAAE;QACrF,KAAK;QACL,MAAM,EAAE,qBAAqB;QAC7B,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAUD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,QAAkB,EAClB,QAAkB;IAElB,MAAM,SAAS,GACb,QAAQ,CAAC,MAAM,KAAK,CAAC;QACnB,CAAC,CAAC,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,gCAAgC;QAC1D,CAAC,CAAC,GAAG,KAAK,6CAA6C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAClF,OAAO,eAAe,CAAC,GAAG,SAAS,cAAc,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACvE,cAAc,EAAE,QAAQ;QACxB,KAAK;QACL,MAAM,EAAE,sBAAsB;QAC9B,cAAc,EAAE,QAAQ;KACzB,CAAC,CAAC;AACL,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/services/frankfurter/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEpF;;;GAGG;AACH,MAAM,eAAe,GAAG;IACtB,qBAAqB;IACrB,sBAAsB;IACtB,kBAAkB;CACV,CAAC;AAYX,gEAAgE;AAChE,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,KAAa;IAC5D,OAAO,eAAe,CAAC,GAAG,KAAK,KAAK,KAAK,4CAA4C,EAAE;QACrF,KAAK;QACL,MAAM,EAAE,qBAAqB;QAC7B,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAUD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,QAAkB,EAClB,QAAkB;IAElB,MAAM,SAAS,GACb,QAAQ,CAAC,MAAM,KAAK,CAAC;QACnB,CAAC,CAAC,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,gCAAgC;QAC1D,CAAC,CAAC,GAAG,KAAK,6CAA6C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAClF,OAAO,eAAe,CAAC,GAAG,SAAS,cAAc,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACvE,cAAc,EAAE,QAAQ;QACxB,KAAK;QACL,MAAM,EAAE,sBAAsB;QAC9B,cAAc,EAAE,QAAQ;KACzB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,CAAC,8CAA8C,EAAE;QAC9D,MAAM,EAAE,kBAAkB;KAC3B,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;QAAE,OAAO;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAyD,CAAC;IAC7E,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,MAAM,CAAC,CAAC;IACvE,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO;IACjC,OAAO;QACL,GAAG,CAAC,OAAO,IAAI,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,KAAc;IACvD,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;QAAE,OAAO;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAqD,CAAC;IACzE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC;QAAE,OAAO;IACzF,OAAO,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC;AACtF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frankfurter-service.d.ts","sourceRoot":"","sources":["../../../src/services/frankfurter/frankfurter-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EACV,QAAQ,EAER,uBAAuB,EAEvB,YAAY,EAEZ,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,6EAA6E;AAC7E,QAAA,MAAM,cAAc,eAAe,CAAC;AAQpC;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIhD;AAkBD,6DAA6D;AAC7D,wBAAgB,qBAAqB,IAAI,kBAAkB,CAG1D;AAED,2CAA2C;AAC3C,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED,cAAM,kBAAkB;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,aAAa,CAAC,CAA8D;IAEpF,cAGC;IAID,wFAAwF;IAClF,cAAc,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAE1C;IAED,kFAAkF;YACpE,UAAU;IAaxB;;;;;OAKG;YACW,yBAAyB;IAcvC;;;;;;;;;;;;;;;;;;OAkBG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAgC9E;IAID;;;;;;;OAOG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA0B/F;IAID;;;;;;;;;;;;;;;OAeG;IACG,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,CAAC,CAyC3B;IAID,OAAO,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"frankfurter-service.d.ts","sourceRoot":"","sources":["../../../src/services/frankfurter/frankfurter-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EACV,QAAQ,EAER,uBAAuB,EAEvB,YAAY,EAEZ,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,6EAA6E;AAC7E,QAAA,MAAM,cAAc,eAAe,CAAC;AAQpC;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIhD;AAkBD,6DAA6D;AAC7D,wBAAgB,qBAAqB,IAAI,kBAAkB,CAG1D;AAED,2CAA2C;AAC3C,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED,cAAM,kBAAkB;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,aAAa,CAAC,CAA8D;IAEpF,cAGC;IAID,wFAAwF;IAClF,cAAc,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAE1C;IAED,kFAAkF;YACpE,UAAU;IAaxB;;;;;OAKG;YACW,yBAAyB;IAcvC;;;;;;;;;;;;;;;;;;OAkBG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAgC9E;IAID;;;;;;;OAOG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA0B/F;IAID;;;;;;;;;;;;;;;OAeG;IACG,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,CAAC,CAyC3B;IAID,OAAO,CAAC,SAAS;CA8ClB;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -127,7 +127,7 @@ class FrankfurterService {
|
|
|
127
127
|
const raw = await this.fetchJson(url);
|
|
128
128
|
const quotedRate = raw.rates[quoted];
|
|
129
129
|
if (quotedRate === undefined)
|
|
130
|
-
throw upstreamNoData(
|
|
130
|
+
throw upstreamNoData();
|
|
131
131
|
const rate = identity ? 1 : quotedRate;
|
|
132
132
|
const dateSnapped = date !== 'latest' && raw.date !== date;
|
|
133
133
|
return {
|
|
@@ -248,7 +248,15 @@ class FrankfurterService {
|
|
|
248
248
|
});
|
|
249
249
|
}
|
|
250
250
|
catch (err) {
|
|
251
|
-
|
|
251
|
+
/**
|
|
252
|
+
* `error.data` is forwarded to the client as `structuredContent.error.data`,
|
|
253
|
+
* and the request URL carries the caller's codes and dates plus whatever host
|
|
254
|
+
* `FRANKFURTER_BASE_URL` points at — so nothing thrown here puts it on the wire.
|
|
255
|
+
* The cause keeps the underlying fetch failure reachable server-side.
|
|
256
|
+
*/
|
|
257
|
+
throw serviceUnavailable(`Frankfurter API unreachable: ${err.message}`, undefined, {
|
|
258
|
+
cause: err,
|
|
259
|
+
});
|
|
252
260
|
}
|
|
253
261
|
if (!response.ok) {
|
|
254
262
|
/**
|
|
@@ -259,8 +267,8 @@ class FrankfurterService {
|
|
|
259
267
|
* input failure is surfaced immediately instead of burning retries.
|
|
260
268
|
*/
|
|
261
269
|
if (response.status === 404)
|
|
262
|
-
throw upstreamNoData(
|
|
263
|
-
throw await httpErrorFromResponse(response, {
|
|
270
|
+
throw upstreamNoData();
|
|
271
|
+
throw await httpErrorFromResponse(response, { service: 'Frankfurter' });
|
|
264
272
|
}
|
|
265
273
|
return response.json();
|
|
266
274
|
}, { maxRetries: 2, baseDelayMs: 500 });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frankfurter-service.js","sourceRoot":"","sources":["../../../src/services/frankfurter/frankfurter-service.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"frankfurter-service.js","sourceRoot":"","sources":["../../../src/services/frankfurter/frankfurter-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/exchange-rates-mcp-server",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"mcpName": "io.github.cyanheads/exchange-rates-mcp-server",
|
|
5
5
|
"description": "Convert currencies, get FX rates, and query historical ECB exchange rate data via MCP. STDIO or Streamable HTTP.",
|
|
6
6
|
"type": "module",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"rebuild": "bun run scripts/clean.ts && bun run scripts/build.ts",
|
|
25
25
|
"clean": "bun run scripts/clean.ts",
|
|
26
26
|
"devcheck": "bun run scripts/devcheck.ts",
|
|
27
|
+
"audit:fix": "bun audit fix",
|
|
27
28
|
"audit:refresh": "rm -f bun.lock && bun install && bun audit",
|
|
28
29
|
"tree": "bun run scripts/tree.ts",
|
|
29
30
|
"list-skills": "bun run scripts/list-skills.ts",
|
|
@@ -87,19 +88,19 @@
|
|
|
87
88
|
"access": "public"
|
|
88
89
|
},
|
|
89
90
|
"dependencies": {
|
|
90
|
-
"@cyanheads/mcp-ts-core": "0.
|
|
91
|
-
"@duckdb/node-api": "^1.5.5-r.
|
|
91
|
+
"@cyanheads/mcp-ts-core": "0.13.6",
|
|
92
|
+
"@duckdb/node-api": "^1.5.5-r.5",
|
|
92
93
|
"pino-pretty": "^13.1.3",
|
|
93
|
-
"zod": "^4.6.
|
|
94
|
+
"zod": "^4.6.5"
|
|
94
95
|
},
|
|
95
96
|
"devDependencies": {
|
|
96
|
-
"@biomejs/biome": "2.5.
|
|
97
|
+
"@biomejs/biome": "2.5.14",
|
|
97
98
|
"@socketsecurity/bun-security-scanner": "^1.1.2",
|
|
98
99
|
"@types/node": "26.5.1",
|
|
99
100
|
"depcheck": "^1.4.7",
|
|
100
101
|
"ignore": "^7.0.9",
|
|
101
|
-
"tsc-alias": "^1.9.
|
|
102
|
+
"tsc-alias": "^1.9.5",
|
|
102
103
|
"typescript": "^7.0.2",
|
|
103
|
-
"vitest": "^5.0.
|
|
104
|
+
"vitest": "^5.0.1"
|
|
104
105
|
}
|
|
105
106
|
}
|
package/server.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"url": "https://github.com/cyanheads/exchange-rates-mcp-server",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.4.
|
|
9
|
+
"version": "0.4.1",
|
|
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/exchange-rates-mcp-server",
|
|
21
21
|
"runtimeHint": "bun",
|
|
22
|
-
"version": "0.4.
|
|
22
|
+
"version": "0.4.1",
|
|
23
23
|
"packageArguments": [
|
|
24
24
|
{
|
|
25
25
|
"type": "positional",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
70
70
|
"identifier": "@cyanheads/exchange-rates-mcp-server",
|
|
71
71
|
"runtimeHint": "bun",
|
|
72
|
-
"version": "0.4.
|
|
72
|
+
"version": "0.4.1",
|
|
73
73
|
"packageArguments": [
|
|
74
74
|
{
|
|
75
75
|
"type": "positional",
|