@defipipe/mcp 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,8 +28,8 @@ Or in any MCP client config:
28
28
  }
29
29
  ```
30
30
 
31
- `DEFIPIPE_API_KEY` is optional: without it you run on the free tier (aligned queries at 5m
32
- resolution and coarser, trailing 90 days, no raw rows). Keys come from the
31
+ `DEFIPIPE_API_KEY` is optional: without it you run on the free tier (5m resolution and
32
+ coarser, trailing 90 days). Keys come from the
33
33
  [dashboard](https://defipipe.io/dashboard); tiers are on the
34
34
  [pricing page](https://defipipe.io/pricing).
35
35
 
@@ -38,9 +38,8 @@ resolution and coarser, trailing 90 days, no raw rows). Keys come from the
38
38
  | Tool | What it does |
39
39
  |---|---|
40
40
  | `search_datasets` | Search the catalog (protocol, metric, category). Returns datasets with their canonical series IDs. |
41
- | `get_aligned` | Up to 10 series resampled onto one shared UTC time axis. Last value at or before each boundary: no interpolation, no lookahead, safe for backtests. |
42
- | `get_series_raw` | Raw per-block rows for one series: `[block_number, block_timestamp, value_raw, value_decimal]` with the exact uint256 value as a string. Requires an API key. |
43
- | `get_limits` | Machine-readable entitlements for the current credential: rate limits, allowed frequencies, history window. |
41
+ | `get_data` | Up to 10 series on one shared UTC time grid at any granularity (block to 1d). Every point is a real on-chain observation and returns both the exact raw integer (uint256-safe string) and the unit-scaled float, plus the scaling metadata (unit, decimals) so the arithmetic is auditable. Pages via a `next` cursor. |
42
+ | `get_limits` | Machine-readable entitlements for the current credential: rate limits, allowed frequencies, history window, page size. |
44
43
 
45
44
  Plus a `defipipe://docs` resource with the full API reference as markdown.
46
45
 
package/dist/server.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /** MCP server for defipipe (stdio). Thin wrapper over the public HTTPS API:
2
- * search the dataset catalog, query aligned time series, raw per-block rows,
2
+ * search the dataset catalog, query observations for one or more series on a
3
+ * shared time grid (raw integers + curated floats, self-describing units),
3
4
  * and tier entitlements. Set DEFIPIPE_API_KEY for keyed tiers; the free tier
4
5
  * works without one. */
5
6
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
package/dist/server.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /** MCP server for defipipe (stdio). Thin wrapper over the public HTTPS API:
2
- * search the dataset catalog, query aligned time series, raw per-block rows,
2
+ * search the dataset catalog, query observations for one or more series on a
3
+ * shared time grid (raw integers + curated floats, self-describing units),
3
4
  * and tier entitlements. Set DEFIPIPE_API_KEY for keyed tiers; the free tier
4
5
  * works without one. */
5
6
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -7,7 +8,7 @@ import { z } from "zod";
7
8
  const API = process.env.DEFIPIPE_API_URL ?? "https://api.defipipe.io";
8
9
  const SITE = process.env.DEFIPIPE_SITE_URL ?? "https://defipipe.io";
9
10
  const KEY = process.env.DEFIPIPE_API_KEY;
10
- const VERSION = "0.2.0";
11
+ const VERSION = "0.3.0";
11
12
  function headers() {
12
13
  return KEY ? { authorization: `Bearer ${KEY}` } : {};
13
14
  }
@@ -58,14 +59,15 @@ export function buildServer() {
58
59
  server.registerTool("search_datasets", {
59
60
  title: "Search defipipe datasets",
60
61
  description: "Search the defipipe catalog of historical per-block DeFi datasets. Returns matching " +
61
- "datasets with their canonical series IDs, which are the inputs to get_aligned and " +
62
- "get_series_raw. Omit the query to list every dataset.",
62
+ "datasets with their canonical series IDs, which are the inputs to get_data. " +
63
+ "Omit the query to list every dataset.",
63
64
  inputSchema: {
64
65
  query: z
65
66
  .string()
66
67
  .optional()
67
68
  .describe("Case-insensitive match against protocol, label, category, and metrics (e.g. 'aave', 'borrow rate', 'lending')"),
68
69
  },
70
+ annotations: { readOnlyHint: true },
69
71
  }, async ({ query }) => {
70
72
  let datasets;
71
73
  try {
@@ -91,20 +93,31 @@ export function buildServer() {
91
93
  content: [{ type: "text", text: JSON.stringify({ count: out.length, datasets: out }, null, 2) }],
92
94
  };
93
95
  });
94
- server.registerTool("get_aligned", {
95
- title: "Query aligned time series",
96
- description: "Resample up to 10 series onto one shared UTC time axis (GET /v1/aligned). Timeframe " +
97
- "and granularity are explicit: pick from/to and a freq from the ladder; freq=block " +
98
- "returns one row per sampled block (max ~16h per request, API key required). Each " +
99
- "value is the last observation at or before the boundary: no interpolation, no " +
100
- "lookahead, safe for backtests. Free tier: 5m and coarser, trailing 90 days.",
96
+ server.registerTool("get_data", {
97
+ title: "Query historical DeFi data",
98
+ description: "Observations for up to 10 series on one shared UTC time grid (GET /v1/data). " +
99
+ "Timeframe and granularity are explicit: pick from/to and a freq from the ladder; " +
100
+ "freq=block returns one row per sampled block. Every point at every freq is a real " +
101
+ "on-chain observation (last observation at or before each boundary; never an " +
102
+ "average): no interpolation, no lookahead, safe for backtests. Each series returns " +
103
+ "values (unit-scaled floats), raw (the exact on-chain integers as strings — " +
104
+ "uint256-safe), blocks (per-point source block), and its scaling metadata " +
105
+ "(unit, decimals, note), so the arithmetic behind every float is auditable. " +
106
+ "Derived series (kind=derived) are computed at query time and expose their formula " +
107
+ "instead of raw. Windows larger than one page return a `next` cursor: pass it back " +
108
+ "as `cursor` and keep the other params identical until next is null. " +
109
+ "Free tier: 5m and coarser, trailing 90 days; block/1m need an API key; full " +
110
+ "history needs quant.",
101
111
  inputSchema: {
102
112
  series: z.array(z.string()).min(1).max(10).describe("Canonical series IDs (from search_datasets)"),
103
113
  freq: z.enum(["block", "1m", "5m", "15m", "1h", "4h", "1d", "7d"]).describe("Granularity. block and 1m require an API key."),
104
- from: z.string().describe("ISO 8601 start of the timeframe, e.g. 2026-07-07"),
114
+ from: z.string().describe("ISO 8601 start of the timeframe, e.g. 2026-07-09"),
105
115
  to: z.string().describe("ISO 8601 end of the timeframe, e.g. 2026-07-12"),
116
+ cursor: z.string().optional().describe("The `next` value from the previous page, verbatim"),
117
+ limit: z.number().int().min(1).optional().describe("Points per page (capped by tier page size)"),
106
118
  },
107
- }, async ({ series, freq, from, to }) => {
119
+ annotations: { readOnlyHint: true },
120
+ }, async ({ series, freq, from, to, cursor, limit }) => {
108
121
  const p = new URLSearchParams({ series: series.join(",") });
109
122
  if (freq)
110
123
  p.set("freq", freq);
@@ -112,40 +125,19 @@ export function buildServer() {
112
125
  p.set("from", from);
113
126
  if (to)
114
127
  p.set("to", to);
115
- return toolResult(await apiGet(`${API}/v1/aligned?${p}`));
116
- });
117
- server.registerTool("get_series_raw", {
118
- title: "Query raw per-block rows",
119
- description: "Raw per-block rows for one series (GET /v1/series/:id). Each row is " +
120
- "[block_number, block_timestamp, value_raw, value_decimal]; value_raw is the exact " +
121
- "uint256-safe on-chain value as a string. Requires an API key (DEFIPIPE_API_KEY). " +
122
- "Paginate by passing the response's next_after_block as after_block.",
123
- inputSchema: {
124
- id: z.string().describe("Canonical series ID"),
125
- from: z.string().describe("ISO 8601 start of the timeframe, e.g. 2026-07-11"),
126
- to: z.string().describe("ISO 8601 end of the timeframe, e.g. 2026-07-12"),
127
- after_block: z.number().int().optional().describe("Pagination cursor: only rows with a strictly greater block number"),
128
- limit: z.number().int().min(1).max(10000).optional().describe("Rows per page, default 1,000"),
129
- },
130
- }, async ({ id, from, to, after_block, limit }) => {
131
- const p = new URLSearchParams();
132
- if (from)
133
- p.set("from", from);
134
- if (to)
135
- p.set("to", to);
136
- if (after_block !== undefined)
137
- p.set("after_block", String(after_block));
128
+ if (cursor)
129
+ p.set("cursor", cursor);
138
130
  if (limit !== undefined)
139
131
  p.set("limit", String(limit));
140
- const qs = p.size ? `?${p}` : "";
141
- return toolResult(await apiGet(`${API}/v1/series/${encodeURIComponent(id)}${qs}`));
132
+ return toolResult(await apiGet(`${API}/v1/data?${p}`));
142
133
  });
143
134
  server.registerTool("get_limits", {
144
135
  title: "Check tier entitlements",
145
136
  description: "Machine-readable entitlements for the current credential (GET /v1/limits): rate " +
146
- "limits, allowed frequencies, raw-row access, and history window. Call this before " +
137
+ "limits, allowed frequencies, history window, and page size. Call this before " +
147
138
  "large pulls instead of discovering limits through 429s.",
148
139
  inputSchema: {},
140
+ annotations: { readOnlyHint: true },
149
141
  }, async () => toolResult(await apiGet(`${API}/v1/limits`)));
150
142
  server.registerResource("docs", "defipipe://docs", {
151
143
  title: "defipipe API reference",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defipipe/mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "MCP server for defipipe: historical, point-in-time DeFi contract state per block. Search datasets, query aligned time series and raw per-block rows.",
5
5
  "license": "MIT",
6
6
  "type": "module",