@commoditypriceapi/mcp 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -221,7 +221,9 @@ Try these after setup:
221
221
 
222
222
  ## Tool Reference
223
223
 
224
- All 8 tools map 1:1 to CommodityPriceAPI v3 endpoints. Tools that take `symbols` accept a comma-separated list (e.g. `XAU,XAG,BRENTOIL-SPOT`). Use `list_symbols` to look up valid symbols — there are 148 across Metals, Energy, Agriculture, and more.
224
+ All 8 tools map 1:1 to CommodityPriceAPI v3 endpoints. Tools that take `symbols` accept a comma-separated list (e.g. `XAU,XAG,XPT,BRENTOIL-SPOT`). Use `list_symbols` to look up valid symbols — there are 245 across Metals, Energy, Agriculture, and more.
225
+
226
+ Precious metals use ISO 4217 codes: `XAU` (gold), `XAG` (silver), `XPT` (platinum), `XPD` (palladium). Copper is `XCU`. The retired codes `PL`, `PA`, and `HG` still work on v3 — they are auto-resolved to the new symbol (see the note below).
225
227
 
226
228
  ### get_latest_rates
227
229
 
@@ -231,8 +233,15 @@ All 8 tools map 1:1 to CommodityPriceAPI v3 endpoints. Tools that take `symbols`
231
233
  |-----------|----------|-------------|
232
234
  | `symbols` | Yes | Comma-separated symbols, e.g. `XAU,XAG,BRENTOIL-SPOT` |
233
235
  | `quote` | No | Target quote currency (e.g. `EUR`). Premium/Plus plans only; omit for each symbol's default currency. |
236
+ | `metadata` | No | `true` (default) or `false`. `false` omits the `metadata` map (per-symbol unit and quote currency) from the response. |
237
+
238
+ Note on `unresolved`: v3 appends an `unresolved` map, keyed by the symbol you typed, in three cases. The same applies to `get_historical_rates`, `get_time_series`, and `get_fluctuation`.
234
239
 
235
- Note: if some symbols in a multi-symbol request are invalid, the API returns the valid rates (HTTP 206) plus an `unresolved` map — one entry per missing symbol with a message and, where available, `suggestions` ("did you mean"). If no symbol resolves, the tool returns a `SYMBOL_NOT_FOUND` error carrying the same `unresolved` map. The same applies to `get_historical_rates`, `get_time_series`, and `get_fluctuation`.
240
+ | Case | HTTP | What the entry holds |
241
+ |------|------|----------------------|
242
+ | Symbol is not a catalogue code but has exactly one match (e.g. `GOLD`, or retired `PL`) | `200` | `message` + `resolvedTo` — the rate was returned under `resolvedTo` in `rates`. Informational, not a failure. |
243
+ | Some symbols could not be returned | `206` | `message` + optional `suggestions` ("did you mean"). Valid rates are still in `rates`. |
244
+ | No symbol resolved | `404` | Tool returns a `SYMBOL_NOT_FOUND` error carrying the same `unresolved` map. |
236
245
 
237
246
  ### get_gold_price
238
247
 
@@ -241,14 +250,18 @@ Note: if some symbols in a multi-symbol request are invalid, the API returns the
241
250
  | Parameter | Required | Description |
242
251
  |-----------|----------|-------------|
243
252
  | `quote` | No | Target quote currency. Premium/Plus plans only. |
253
+ | `include` | No | `gram`, `carat`, or `tola` — adds a per-gram rate, per-gram rates at each purity from 24k to 8k, or a per-tola rate alongside the ounce rate. |
254
+ | `metadata` | No | `true` (default) or `false`. `false` omits the `metadata` map (per-symbol unit and quote currency) from the response. |
244
255
 
245
256
  ### get_silver_price
246
257
 
247
- `GET /v3/rates/latest/xag` — shortcut for the latest silver (XAG) rate.
258
+ `GET /v3/rates/latest/xag` — shortcut for the latest silver (XAG) rate, including bid/ask.
248
259
 
249
260
  | Parameter | Required | Description |
250
261
  |-----------|----------|-------------|
251
262
  | `quote` | No | Target quote currency. Premium/Plus plans only. |
263
+ | `include` | No | `gram`, `carat`, or `tola` — adds a per-gram, per-carat, or per-tola rate alongside the ounce rate. |
264
+ | `metadata` | No | `true` (default) or `false`. `false` omits the `metadata` map (per-symbol unit and quote currency) from the response. |
252
265
 
253
266
  ### get_historical_rates
254
267
 
@@ -292,7 +305,8 @@ Note: if some symbols in a multi-symbol request are invalid, the API returns the
292
305
  ### Live prices
293
306
 
294
307
  - What's the current gold price?
295
- - Get the latest prices for silver, copper, and WTI crude.
308
+ - What's gold per gram right now?
309
+ - Get the latest prices for silver, platinum, copper, and WTI crude.
296
310
  - What's gold trading at in euros?
297
311
 
298
312
  ### Historical data
@@ -385,6 +399,35 @@ The text answers show what a client might say; exact wording depends on the mode
385
399
  }
386
400
  ```
387
401
 
402
+ ### Auto-resolved symbol
403
+
404
+ **Prompt:** What's the price of GOLD and platinum?
405
+
406
+ **Example answer:** Gold (XAU) is $4,386.23 and platinum (XPT) is $1,412.50 per troy ounce. Note: `GOLD` isn't a symbol code, so the API returned it under `XAU`.
407
+
408
+ ```json
409
+ {
410
+ "success": true,
411
+ "timestamp": 1786617187,
412
+ "rates": {
413
+ "XAU": 4386.23,
414
+ "XPT": 1412.5
415
+ },
416
+ "metadata": {
417
+ "XAU": { "unit": "T.oz", "quote": "USD" },
418
+ "XPT": { "unit": "T.oz", "quote": "USD" }
419
+ },
420
+ "unresolved": {
421
+ "GOLD": {
422
+ "message": "GOLD is not a symbol code used by this API. Gold is available as \"XAU\", so its rate was returned under that symbol.",
423
+ "resolvedTo": "XAU"
424
+ }
425
+ }
426
+ }
427
+ ```
428
+
429
+ Status is `200` — an entry with `resolvedTo` never downgrades the response.
430
+
388
431
  ## Error Codes
389
432
 
390
433
  Tool calls never crash the server. Upstream errors are returned as structured tool results with `error`, `code`, `message`, and a `guidance` field so the client can explain what went wrong instead of echoing a status code.
@@ -457,7 +500,7 @@ COMMODITYPRICEAPI_KEY=<YOUR_KEY> npx @modelcontextprotocol/inspector node dist/c
457
500
 
458
501
  **401 errors:** Check that `COMMODITYPRICEAPI_KEY` is set in your MCP client config's `env` block.
459
502
 
460
- **A symbol is missing from a multi-symbol response:** Look at the `unresolved` map in the result — each missing symbol has a message and usually `suggestions` (e.g. `BRENTOIL` → `BRENTOIL-SPOT`). If there are no suggestions, call `list_symbols` to find the correct symbol.
503
+ **A symbol is missing from a multi-symbol response:** Look at the `unresolved` map in the result. If the entry has `resolvedTo`, nothing is missing — the rate is in `rates` under that symbol (e.g. `GOLD` → `XAU`, `PL` → `XPT`). Otherwise each missing symbol has a message and usually `suggestions` (e.g. `OIL` → `WTIOIL-SPOT`, `BRENTOIL-SPOT`, …). If there are no suggestions, call `list_symbols` to find the correct symbol.
461
504
 
462
505
  **499 timeouts:** The upstream API did not respond in time. Increase `COMMODITYPRICEAPI_REQUEST_TIMEOUT_MS` (default: 15000 ms).
463
506
 
package/dist/client.js CHANGED
@@ -26,8 +26,10 @@ function getApiKey() {
26
26
  * param, since the upstream API accepts either.
27
27
  *
28
28
  * v3 answers 206 (still `response.ok`) with an `unresolved` map appended to
29
- * the body when some requested symbols could not be returned; the body is
30
- * passed through as-is so tool results include those suggestions.
29
+ * the body when some requested symbols could not be returned, and 200 with an
30
+ * `unresolved` map when a symbol was auto-resolved to its single match
31
+ * (`resolvedTo`). The body is passed through as-is so tool results include
32
+ * those notes and suggestions.
31
33
  */
32
34
  export async function callCommodityApi(path, params = {}) {
33
35
  const apiKey = getApiKey();
package/dist/server.js CHANGED
@@ -3,8 +3,28 @@ import { z } from "zod";
3
3
  import { callCommodityApi, CommodityApiError } from "./client.js";
4
4
  const symbolsParam = z
5
5
  .string()
6
- .describe("Comma-separated commodity symbols, e.g. 'XAU,XAG,BRENTOIL-SPOT'. See the list_symbols tool for valid values. If some symbols cannot be resolved, the response still succeeds (HTTP 206) with the valid rates plus an 'unresolved' map giving a message and 'did you mean' suggestions for each missing symbol. If none resolve, the error result carries the same 'unresolved' map.");
6
+ .describe("Comma-separated commodity symbols, e.g. 'XAU,XAG,XPT,BRENTOIL-SPOT'. Precious metals use ISO 4217 codes (XAU gold, XAG silver, XPT platinum, XPD palladium); copper is XCU. See the list_symbols tool for valid values. " +
7
+ "The response may include an 'unresolved' map keyed by the symbol you typed. Three cases: " +
8
+ "(1) HTTP 200 with an entry carrying 'resolvedTo' — the symbol was not a catalogue code but had exactly one match (e.g. GOLD -> XAU, retired PL -> XPT), so its rate was returned under the 'resolvedTo' symbol in 'rates'; this is informational, not a failure. " +
9
+ "(2) HTTP 206 — some symbols could not be returned; each entry has a message and, where available, 'did you mean' suggestions, while the valid rates are still in 'rates'. " +
10
+ "(3) If none resolve, the error result carries the same 'unresolved' map.");
7
11
  const dateParam = z.string().describe("Date in YYYY-MM-DD format.");
12
+ const quoteParam = z
13
+ .string()
14
+ .optional()
15
+ .describe("Target quote currency code (e.g. 'USD', 'EUR'). Premium/Plus plans only; omit to use each symbol's default currency.");
16
+ const includeParam = z
17
+ .enum(["gram", "carat", "tola"])
18
+ .optional()
19
+ .describe("Add a per-unit breakdown alongside the per-troy-ounce rate: 'gram' adds a per-gram rate, 'tola' adds a per-tola rate, 'carat' adds per-gram rates at each purity from 24k down to 8k. Omit for the ounce rate only.");
20
+ const metadataParam = z
21
+ .boolean()
22
+ .optional()
23
+ .describe("Whether to include the 'metadata' map (per-symbol unit and quote currency) in the response. Defaults to true. Set false to omit it and get a smaller payload.");
24
+ /** v3 only honours an explicit `metadata=false`; anything else is the default (true). */
25
+ function metadataFlag(metadata) {
26
+ return metadata === false ? "false" : undefined;
27
+ }
8
28
  function textResult(data) {
9
29
  return {
10
30
  content: [
@@ -65,7 +85,7 @@ function guidanceFor(code, errorType) {
65
85
  export function createServer() {
66
86
  const server = new McpServer({
67
87
  name: "commoditypriceapi-mcp",
68
- version: "1.1.0",
88
+ version: "1.2.1",
69
89
  });
70
90
  server.registerTool("get_usage", {
71
91
  title: "Get API usage",
@@ -82,7 +102,7 @@ export function createServer() {
82
102
  });
83
103
  server.registerTool("list_symbols", {
84
104
  title: "List supported commodity symbols",
85
- description: "Returns all commodity symbols supported by CommodityPriceAPI, including category, default currency, and unit. Use this to look up a symbol before calling rate tools.",
105
+ description: "Returns all commodity symbols supported by CommodityPriceAPI, including category, default currency, and unit. Use this to look up a symbol before calling rate tools. Precious metals use ISO 4217 codes (XAU, XAG, XPT, XPD); copper is XCU.",
86
106
  inputSchema: {},
87
107
  }, async () => {
88
108
  try {
@@ -95,17 +115,19 @@ export function createServer() {
95
115
  });
96
116
  server.registerTool("get_latest_rates", {
97
117
  title: "Get latest commodity rates",
98
- description: "Returns the latest rates for one or more commodity symbols (e.g. gold, silver, crude oil). Rates may lag up to 10 minutes depending on plan. Use 'quote' to convert to a specific currency (Premium/Plus plans only).",
118
+ description: "Returns the latest rates for one or more commodity symbols (e.g. gold, silver, crude oil). Rates may lag up to 10 minutes depending on plan. Use 'quote' to convert to a specific currency (Premium/Plus plans only). Common names with a single match (e.g. GOLD) are auto-resolved to the real symbol and flagged in 'unresolved' with 'resolvedTo'. Set 'metadata' to false to omit the per-symbol unit/quote map.",
99
119
  inputSchema: {
100
120
  symbols: symbolsParam,
101
- quote: z
102
- .string()
103
- .optional()
104
- .describe("Target quote currency code (e.g. 'USD', 'EUR'). Premium/Plus plans only; omit to use each symbol's default currency."),
121
+ quote: quoteParam,
122
+ metadata: metadataParam,
105
123
  },
106
- }, async ({ symbols, quote }) => {
124
+ }, async ({ symbols, quote, metadata }) => {
107
125
  try {
108
- const data = await callCommodityApi("/rates/latest", { symbols, quote });
126
+ const data = await callCommodityApi("/rates/latest", {
127
+ symbols,
128
+ quote,
129
+ metadata: metadataFlag(metadata),
130
+ });
109
131
  return textResult(data);
110
132
  }
111
133
  catch (err) {
@@ -114,16 +136,19 @@ export function createServer() {
114
136
  });
115
137
  server.registerTool("get_gold_price", {
116
138
  title: "Get latest gold (XAU) price",
117
- description: "Shortcut for the latest gold (XAU) rate without needing to pass a symbols list.",
139
+ description: "Shortcut for the latest gold (XAU) rate, with bid/ask, without needing to pass a symbols list. Use 'include' to add a per-gram, per-tola, or per-carat breakdown. Set 'metadata' to false to omit the unit/quote map.",
118
140
  inputSchema: {
119
- quote: z
120
- .string()
121
- .optional()
122
- .describe("Target quote currency code. Premium/Plus plans only."),
141
+ quote: quoteParam,
142
+ include: includeParam,
143
+ metadata: metadataParam,
123
144
  },
124
- }, async ({ quote }) => {
145
+ }, async ({ quote, include, metadata }) => {
125
146
  try {
126
- const data = await callCommodityApi("/rates/latest/xau", { quote });
147
+ const data = await callCommodityApi("/rates/latest/xau", {
148
+ quote,
149
+ include,
150
+ metadata: metadataFlag(metadata),
151
+ });
127
152
  return textResult(data);
128
153
  }
129
154
  catch (err) {
@@ -132,16 +157,19 @@ export function createServer() {
132
157
  });
133
158
  server.registerTool("get_silver_price", {
134
159
  title: "Get latest silver (XAG) price",
135
- description: "Shortcut for the latest silver (XAG) rate without needing to pass a symbols list.",
160
+ description: "Shortcut for the latest silver (XAG) rate, with bid/ask, without needing to pass a symbols list. Use 'include' to add a per-gram, per-tola, or per-carat breakdown. Set 'metadata' to false to omit the unit/quote map.",
136
161
  inputSchema: {
137
- quote: z
138
- .string()
139
- .optional()
140
- .describe("Target quote currency code. Premium/Plus plans only."),
162
+ quote: quoteParam,
163
+ include: includeParam,
164
+ metadata: metadataParam,
141
165
  },
142
- }, async ({ quote }) => {
166
+ }, async ({ quote, include, metadata }) => {
143
167
  try {
144
- const data = await callCommodityApi("/rates/latest/xag", { quote });
168
+ const data = await callCommodityApi("/rates/latest/xag", {
169
+ quote,
170
+ include,
171
+ metadata: metadataFlag(metadata),
172
+ });
145
173
  return textResult(data);
146
174
  }
147
175
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commoditypriceapi/mcp",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Official MCP server for CommodityPriceAPI \u2014 real-time and historical commodity rates (gold, silver, oil, and 130+ more) as MCP tools for Claude, Cursor, Windsurf, and any MCP client.",
5
5
  "keywords": [
6
6
  "mcp",