@cyanheads/secedgar-mcp-server 0.4.4 → 0.5.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 +28 -9
- package/dist/config/server-config.d.ts +2 -0
- package/dist/config/server-config.d.ts.map +1 -1
- package/dist/config/server-config.js +13 -0
- package/dist/config/server-config.js.map +1 -1
- package/dist/index.js +22 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/dataframe-describe.tool.d.ts +33 -0
- package/dist/mcp-server/tools/definitions/dataframe-describe.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/dataframe-describe.tool.js +114 -0
- package/dist/mcp-server/tools/definitions/dataframe-describe.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/dataframe-drop.tool.d.ts +20 -0
- package/dist/mcp-server/tools/definitions/dataframe-drop.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/dataframe-drop.tool.js +48 -0
- package/dist/mcp-server/tools/definitions/dataframe-drop.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.d.ts +29 -0
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.js +124 -0
- package/dist/mcp-server/tools/definitions/dataframe-query.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/{compare-metric.tool.d.ts → fetch-frames.tool.d.ts} +25 -4
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.js +235 -0
- package/dist/mcp-server/tools/definitions/fetch-frames.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-financials.tool.d.ts +5 -0
- package/dist/mcp-server/tools/definitions/get-financials.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-financials.tool.js +49 -0
- package/dist/mcp-server/tools/definitions/get-financials.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-filings.tool.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/search-filings.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-filings.tool.js +97 -4
- package/dist/mcp-server/tools/definitions/search-filings.tool.js.map +1 -1
- package/dist/services/canvas-bridge/canvas-bridge.d.ts +146 -0
- package/dist/services/canvas-bridge/canvas-bridge.d.ts.map +1 -0
- package/dist/services/canvas-bridge/canvas-bridge.js +270 -0
- package/dist/services/canvas-bridge/canvas-bridge.js.map +1 -0
- package/dist/services/canvas-bridge/sql-gate-extras.d.ts +15 -0
- package/dist/services/canvas-bridge/sql-gate-extras.d.ts.map +1 -0
- package/dist/services/canvas-bridge/sql-gate-extras.js +49 -0
- package/dist/services/canvas-bridge/sql-gate-extras.js.map +1 -0
- package/dist/services/edgar/edgar-api-service.d.ts +2 -0
- package/dist/services/edgar/edgar-api-service.d.ts.map +1 -1
- package/dist/services/edgar/edgar-api-service.js +11 -1
- package/dist/services/edgar/edgar-api-service.js.map +1 -1
- package/dist/services/edgar/types.d.ts +2 -0
- package/dist/services/edgar/types.d.ts.map +1 -1
- package/package.json +6 -5
- package/server.json +3 -3
- package/dist/mcp-server/tools/definitions/compare-metric.tool.d.ts.map +0 -1
- package/dist/mcp-server/tools/definitions/compare-metric.tool.js +0 -149
- package/dist/mcp-server/tools/definitions/compare-metric.tool.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<h1>@cyanheads/secedgar-mcp-server</h1>
|
|
3
3
|
<p><b>Query SEC EDGAR filings, XBRL financials, and company data through MCP. STDIO & Streamable HTTP.</b>
|
|
4
|
-
<div>
|
|
4
|
+
<div>8 Tools (+1 opt-in) • 2 Resources • 1 Prompt</div>
|
|
5
5
|
</p>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
## Tools
|
|
25
25
|
|
|
26
|
-
Six tools for querying SEC EDGAR data:
|
|
26
|
+
Six tools for querying SEC EDGAR data, plus three for SQL analytics over the DuckDB-backed canvas dataframes those tools materialize:
|
|
27
27
|
|
|
28
28
|
| Tool | Description |
|
|
29
29
|
|:---|:---|
|
|
@@ -31,8 +31,11 @@ Six tools for querying SEC EDGAR data:
|
|
|
31
31
|
| `secedgar_search_filings` | Full-text search across all EDGAR filing documents since 1993 |
|
|
32
32
|
| `secedgar_get_filing` | Fetch a specific filing's metadata and document content |
|
|
33
33
|
| `secedgar_get_financials` | Get historical XBRL financial data for a company |
|
|
34
|
-
| `
|
|
34
|
+
| `secedgar_fetch_frames` | Fetch SEC XBRL frames for one concept × one period across all reporting companies |
|
|
35
35
|
| `secedgar_search_concepts` | Discover supported XBRL concept names or reverse-lookup a raw tag |
|
|
36
|
+
| `secedgar_dataframe_describe` | List canvas dataframes with provenance, TTL, and schema |
|
|
37
|
+
| `secedgar_dataframe_query` | Run a single-statement SELECT across dataframes |
|
|
38
|
+
| `secedgar_dataframe_drop` | Drop a canvas dataframe by name. Opt-in via `EDGAR_DATAFRAME_DROP_ENABLED=true` — off by default since TTL already handles cleanup |
|
|
36
39
|
|
|
37
40
|
### `secedgar_company_search`
|
|
38
41
|
|
|
@@ -52,6 +55,7 @@ Full-text search across all EDGAR filing documents since 1993.
|
|
|
52
55
|
- Entity targeting within query string (`cik:320193` or `ticker:AAPL`)
|
|
53
56
|
- Date range filtering, form type filtering, pagination up to 10,000 results
|
|
54
57
|
- Returns form distribution for narrowing follow-up searches
|
|
58
|
+
- When post-filter hits exceed the inline limit, the already-fetched EFTS window (entity-filtered when `ticker:`/`cik:` is used) is materialized as a `df_<id>` dataframe — query it with `secedgar_dataframe_query`
|
|
55
59
|
|
|
56
60
|
---
|
|
57
61
|
|
|
@@ -78,14 +82,14 @@ Get historical XBRL financial data for a company with friendly concept name reso
|
|
|
78
82
|
|
|
79
83
|
---
|
|
80
84
|
|
|
81
|
-
### `
|
|
85
|
+
### `secedgar_fetch_frames`
|
|
82
86
|
|
|
83
|
-
|
|
87
|
+
Fetch SEC XBRL frames for one concept × one period across all reporting companies.
|
|
84
88
|
|
|
85
89
|
- Same friendly concept names as `secedgar_get_financials`
|
|
86
90
|
- Supports annual (`CY2023`), quarterly (`CY2024Q2`), and instant (`CY2023Q4I`) periods
|
|
87
|
-
-
|
|
88
|
-
-
|
|
91
|
+
- Inline response returns the top N ranked companies (sort + limit), with ticker enrichment
|
|
92
|
+
- The full frames response (all reporters, typically 2k–10k rows) is materialized as a `df_<id>` dataframe — query it with `secedgar_dataframe_query`
|
|
89
93
|
|
|
90
94
|
---
|
|
91
95
|
|
|
@@ -96,7 +100,17 @@ Discover supported XBRL concept names before querying financials or cross-compan
|
|
|
96
100
|
- Search by friendly name, label, or raw XBRL tag
|
|
97
101
|
- Filter by statement group (`income_statement`, `balance_sheet`, `cash_flow`, `per_share`, `entity_info`) or taxonomy
|
|
98
102
|
- Reverse-lookup raw tags like `NetIncomeLoss` to the supported friendly names
|
|
99
|
-
- Returns the same catalog used by `secedgar_get_financials`, `
|
|
103
|
+
- Returns the same catalog used by `secedgar_get_financials`, `secedgar_fetch_frames`, and `secedgar://concepts`
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### `secedgar_dataframe_describe` / `secedgar_dataframe_query` / `secedgar_dataframe_drop`
|
|
108
|
+
|
|
109
|
+
In-conversation SQL analytics over the dataframes that `secedgar_fetch_frames`, `secedgar_search_filings`, and `secedgar_get_financials` materialize on a shared DuckDB-backed canvas. Each data-returning call adds a `dataset` field with a `df_XXXXX_XXXXX` handle; pass that handle to `secedgar_dataframe_query` for joins, aggregates, window functions, percentiles — standard DuckDB SQL.
|
|
110
|
+
|
|
111
|
+
- **Read-only by default.** Writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected by the framework SQL gate. System catalogs (`information_schema`, `pg_catalog`, `sqlite_master`, `duckdb_*`) are denied at the bridge layer so callers can't enumerate dataframes they don't already hold a handle for. `secedgar_dataframe_drop` is the only destructive tool and is opt-in (`EDGAR_DATAFRAME_DROP_ENABLED=true`); TTL handles cleanup otherwise.
|
|
112
|
+
- **Per-table TTL.** Each dataframe ages on its own clock (default 24h, override with `EDGAR_DATASET_TTL_SECONDS`). The canvas itself uses the framework's sliding TTL.
|
|
113
|
+
- **`register_as` chaining.** `secedgar_dataframe_query` can persist its result as a new dataframe (`df_XXXXX_XXXXX`) with a fresh TTL — pipe analyses without re-running the source query.
|
|
100
114
|
|
|
101
115
|
## Resources
|
|
102
116
|
|
|
@@ -129,6 +143,7 @@ SEC EDGAR–specific:
|
|
|
129
143
|
- Friendly XBRL concept name mapping with historical tag change handling
|
|
130
144
|
- Searchable concept catalog with statement-group metadata and reverse XBRL tag lookup
|
|
131
145
|
- HTML-to-text conversion for filing documents via `html-to-text`
|
|
146
|
+
- In-conversation SQL analytics: `secedgar_fetch_frames`, `secedgar_search_filings`, and `secedgar_get_financials` materialize their full upstream response as a DuckDB-backed canvas dataframe queryable via `secedgar_dataframe_query`
|
|
132
147
|
- No API keys required — SEC EDGAR is a free, public API
|
|
133
148
|
|
|
134
149
|
## Getting started
|
|
@@ -232,6 +247,9 @@ All configuration is validated at startup via Zod schemas in `src/config/server-
|
|
|
232
247
|
| `EDGAR_USER_AGENT` | **Required.** User-Agent header for SEC compliance. Format: `"AppName contact@email.com"`. SEC blocks IPs without a valid User-Agent. | — |
|
|
233
248
|
| `EDGAR_RATE_LIMIT_RPS` | Max requests/second to SEC APIs. Do not exceed 10. | `10` |
|
|
234
249
|
| `EDGAR_TICKER_CACHE_TTL` | Seconds to cache the company tickers lookup file. | `3600` |
|
|
250
|
+
| `EDGAR_DATASET_TTL_SECONDS` | Per-table TTL for canvas-registered dataframes. Sliding window touched on every dataframe op. | `86400` |
|
|
251
|
+
| `EDGAR_DATAFRAME_DROP_ENABLED` | Set to `true` to expose `secedgar_dataframe_drop` — the only destructive tool on this server. Off by default; TTL handles cleanup. | `false` |
|
|
252
|
+
| `CANVAS_PROVIDER_TYPE` | Canvas engine. Defaults to `duckdb`; set to `none` to disable the canvas (e.g. when running on Cloudflare Workers, where DuckDB has no V8-isolate build). | `duckdb` |
|
|
235
253
|
| `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http` | `stdio` |
|
|
236
254
|
| `MCP_HTTP_PORT` | HTTP server port | `3010` |
|
|
237
255
|
| `MCP_AUTH_MODE` | Authentication: `none`, `jwt`, or `oauth` | `none` |
|
|
@@ -266,10 +284,11 @@ docker run -e EDGAR_USER_AGENT="MyApp my@email.com" -p 3010:3010 secedgar-mcp-se
|
|
|
266
284
|
|
|
267
285
|
| Directory | Purpose |
|
|
268
286
|
|:---|:---|
|
|
269
|
-
| `src/mcp-server/tools/definitions/` | Tool definitions (`*.tool.ts`). Six SEC EDGAR tools. |
|
|
287
|
+
| `src/mcp-server/tools/definitions/` | Tool definitions (`*.tool.ts`). Six SEC EDGAR tools plus three `dataframe_*` tools for SQL analytics. |
|
|
270
288
|
| `src/mcp-server/resources/definitions/` | Resource definitions. XBRL concepts and filing types. |
|
|
271
289
|
| `src/mcp-server/prompts/definitions/` | Prompt definitions. Company analysis prompt. |
|
|
272
290
|
| `src/services/edgar/` | SEC EDGAR API client, XBRL concept mapping, HTML-to-text conversion. |
|
|
291
|
+
| `src/services/canvas-bridge/` | Adapter over the framework `DataCanvas`: `df_<id>` minting, all-nullable schema derivation, per-table TTL bookkeeping, bridge-layer system-catalog SQL deny. |
|
|
273
292
|
| `src/config/` | Server-specific environment variable parsing and validation with Zod. |
|
|
274
293
|
| `tests/` | Unit and integration tests, mirroring the `src/` structure. |
|
|
275
294
|
|
|
@@ -7,6 +7,8 @@ declare const ServerConfigSchema: z.ZodObject<{
|
|
|
7
7
|
userAgent: z.ZodString;
|
|
8
8
|
rateLimitRps: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
9
9
|
tickerCacheTtl: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
10
|
+
datasetTtlSeconds: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
11
|
+
dataframeDropEnabled: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<boolean, string | undefined>>;
|
|
10
12
|
}, z.core.$strip>;
|
|
11
13
|
export type ServerConfig = z.infer<typeof ServerConfigSchema>;
|
|
12
14
|
export declare function getServerConfig(): ServerConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE3C,QAAA,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE3C,QAAA,MAAM,kBAAkB;;;;;;iBAgCtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,wBAAgB,eAAe,IAAI,YAAY,CAS9C"}
|
|
@@ -20,6 +20,17 @@ const ServerConfigSchema = z.object({
|
|
|
20
20
|
.min(60)
|
|
21
21
|
.default(3600)
|
|
22
22
|
.describe('Seconds to cache company_tickers.json'),
|
|
23
|
+
datasetTtlSeconds: z.coerce
|
|
24
|
+
.number()
|
|
25
|
+
.int()
|
|
26
|
+
.min(60)
|
|
27
|
+
.default(86400)
|
|
28
|
+
.describe('Per-table TTL for canvas-registered dataframes, in seconds. Bridge-side bookkeeping in ctx.state (backstop for cyanheads/mcp-ts-core#140 until the framework exposes RegisterTableOptions.ttlMs).'),
|
|
29
|
+
dataframeDropEnabled: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.transform((v) => v === 'true' || v === '1')
|
|
33
|
+
.describe('Set to "true" to expose secedgar_dataframe_drop. Off by default — the canvas already drops tables on the per-table TTL, and a write surface against the shared canvas is the only destructive tool on this server.'),
|
|
23
34
|
});
|
|
24
35
|
let _config;
|
|
25
36
|
export function getServerConfig() {
|
|
@@ -27,6 +38,8 @@ export function getServerConfig() {
|
|
|
27
38
|
userAgent: process.env.EDGAR_USER_AGENT,
|
|
28
39
|
rateLimitRps: process.env.EDGAR_RATE_LIMIT_RPS,
|
|
29
40
|
tickerCacheTtl: process.env.EDGAR_TICKER_CACHE_TTL,
|
|
41
|
+
datasetTtlSeconds: process.env.EDGAR_DATASET_TTL_SECONDS,
|
|
42
|
+
dataframeDropEnabled: process.env.EDGAR_DATAFRAME_DROP_ENABLED,
|
|
30
43
|
});
|
|
31
44
|
return _config;
|
|
32
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE3C,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,QAAQ,CAAC,2EAA2E,CAAC;IACxF,YAAY,EAAE,CAAC,CAAC,MAAM;SACnB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;SACP,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CAAC,iCAAiC,CAAC;IAC9C,cAAc,EAAE,CAAC,CAAC,MAAM;SACrB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,EAAE,CAAC;SACP,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE3C,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,QAAQ,CAAC,2EAA2E,CAAC;IACxF,YAAY,EAAE,CAAC,CAAC,MAAM;SACnB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;SACP,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CAAC,iCAAiC,CAAC;IAC9C,cAAc,EAAE,CAAC,CAAC,MAAM;SACrB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,EAAE,CAAC;SACP,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,uCAAuC,CAAC;IACpD,iBAAiB,EAAE,CAAC,CAAC,MAAM;SACxB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,EAAE,CAAC;SACP,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CACP,mMAAmM,CACpM;IACH,oBAAoB,EAAE,CAAC;SACpB,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,GAAG,CAAC;SAC3C,QAAQ,CACP,oNAAoN,CACrN;CACJ,CAAC,CAAC;AAIH,IAAI,OAAiC,CAAC;AAEtC,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,kBAAkB,CAAC,KAAK,CAAC;QACnC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB;QACvC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAC9C,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB;QAClD,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;QACxD,oBAAoB,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B;KAC/D,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,29 +4,48 @@
|
|
|
4
4
|
* @module index
|
|
5
5
|
*/
|
|
6
6
|
import { createApp } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import { getServerConfig } from './config/server-config.js';
|
|
7
8
|
import { companyAnalysisPrompt } from './mcp-server/prompts/definitions/company-analysis.prompt.js';
|
|
8
9
|
import { conceptsResource } from './mcp-server/resources/definitions/concepts.resource.js';
|
|
9
10
|
import { filingTypesResource } from './mcp-server/resources/definitions/filing-types.resource.js';
|
|
10
11
|
import { companySearchTool } from './mcp-server/tools/definitions/company-search.tool.js';
|
|
11
|
-
import {
|
|
12
|
+
import { dataframeDescribeTool } from './mcp-server/tools/definitions/dataframe-describe.tool.js';
|
|
13
|
+
import { dataframeDropTool } from './mcp-server/tools/definitions/dataframe-drop.tool.js';
|
|
14
|
+
import { dataframeQueryTool } from './mcp-server/tools/definitions/dataframe-query.tool.js';
|
|
15
|
+
import { fetchFramesTool } from './mcp-server/tools/definitions/fetch-frames.tool.js';
|
|
12
16
|
import { getFilingTool } from './mcp-server/tools/definitions/get-filing.tool.js';
|
|
13
17
|
import { getFinancialsTool } from './mcp-server/tools/definitions/get-financials.tool.js';
|
|
14
18
|
import { searchConceptsTool } from './mcp-server/tools/definitions/search-concepts.tool.js';
|
|
15
19
|
import { searchFilingsTool } from './mcp-server/tools/definitions/search-filings.tool.js';
|
|
20
|
+
import { initCanvasBridge } from './services/canvas-bridge/canvas-bridge.js';
|
|
16
21
|
import { initEdgarApiService } from './services/edgar/edgar-api-service.js';
|
|
22
|
+
// DuckDB is the only canvas engine we support and ships as a direct dep, so
|
|
23
|
+
// enable the canvas by default. Set CANVAS_PROVIDER_TYPE=none explicitly to
|
|
24
|
+
// turn it off (e.g. on Cloudflare Workers, where DuckDB has no V8-isolate
|
|
25
|
+
// build and the framework would fail to construct a canvas anyway).
|
|
26
|
+
process.env.CANVAS_PROVIDER_TYPE ??= 'duckdb';
|
|
27
|
+
// secedgar_dataframe_drop is the only destructive tool on this server and is
|
|
28
|
+
// off by default — TTL handles cleanup. Set EDGAR_DATAFRAME_DROP_ENABLED=true
|
|
29
|
+
// to expose it.
|
|
30
|
+
const dropEnabled = getServerConfig().dataframeDropEnabled;
|
|
17
31
|
await createApp({
|
|
18
32
|
tools: [
|
|
19
33
|
companySearchTool,
|
|
20
34
|
searchFilingsTool,
|
|
21
35
|
getFilingTool,
|
|
22
36
|
getFinancialsTool,
|
|
23
|
-
|
|
37
|
+
fetchFramesTool,
|
|
24
38
|
searchConceptsTool,
|
|
39
|
+
dataframeDescribeTool,
|
|
40
|
+
dataframeQueryTool,
|
|
41
|
+
...(dropEnabled ? [dataframeDropTool] : []),
|
|
25
42
|
],
|
|
26
43
|
resources: [conceptsResource, filingTypesResource],
|
|
27
44
|
prompts: [companyAnalysisPrompt],
|
|
28
|
-
|
|
45
|
+
instructions: 'Use the secedgar_* tools to query SEC EDGAR — US public-company filings since 1993 plus historical XBRL financials. Resolve companies with secedgar_company_search (accepts ticker, name, or CIK), fetch document text with secedgar_get_filing by accession number, and run full-text search across all filings with secedgar_search_filings (supports boolean operators and inline ticker:AAPL / cik:320193 targeting). For financials, secedgar_get_financials and secedgar_fetch_frames accept friendly names like "revenue" or "eps_diluted" (discover them with secedgar_search_concepts) or raw XBRL tags. Data-returning tools also materialize their full upstream response as a df_<id> handle for downstream SQL via secedgar_dataframe_query — list dataframes with secedgar_dataframe_describe.',
|
|
46
|
+
setup(core) {
|
|
29
47
|
initEdgarApiService();
|
|
48
|
+
initCanvasBridge(core.canvas);
|
|
30
49
|
},
|
|
31
50
|
});
|
|
32
51
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,MAAM,yDAAyD,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E,MAAM,SAAS,CAAC;IACd,KAAK,EAAE;QACL,iBAAiB;QACjB,iBAAiB;QACjB,aAAa;QACb,iBAAiB;QACjB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,MAAM,yDAAyD,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,qDAAqD,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E,4EAA4E;AAC5E,4EAA4E;AAC5E,0EAA0E;AAC1E,oEAAoE;AACpE,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,QAAQ,CAAC;AAE9C,6EAA6E;AAC7E,8EAA8E;AAC9E,gBAAgB;AAChB,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC,oBAAoB,CAAC;AAE3D,MAAM,SAAS,CAAC;IACd,KAAK,EAAE;QACL,iBAAiB;QACjB,iBAAiB;QACjB,aAAa;QACb,iBAAiB;QACjB,eAAe;QACf,kBAAkB;QAClB,qBAAqB;QACrB,kBAAkB;QAClB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5C;IACD,SAAS,EAAE,CAAC,gBAAgB,EAAE,mBAAmB,CAAC;IAClD,OAAO,EAAE,CAAC,qBAAqB,CAAC;IAChC,YAAY,EACV,8wBAA8wB;IAChxB,KAAK,CAAC,IAAI;QACR,mBAAmB,EAAE,CAAC;QACtB,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview List the dataframes materialized by SEC EDGAR data-returning
|
|
3
|
+
* tools, with provenance, TTL, and column schema. Reads from the canvas
|
|
4
|
+
* bridge (which lazy-sweeps expired tables before responding).
|
|
5
|
+
* @module mcp-server/tools/definitions/dataframe-describe
|
|
6
|
+
*/
|
|
7
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
8
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
9
|
+
export declare const dataframeDescribeTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
10
|
+
name: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
12
|
+
dataframes: z.ZodArray<z.ZodObject<{
|
|
13
|
+
name: z.ZodString;
|
|
14
|
+
source_tool: z.ZodString;
|
|
15
|
+
query_params: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
16
|
+
created_at: z.ZodString;
|
|
17
|
+
expires_at: z.ZodString;
|
|
18
|
+
row_count: z.ZodNumber;
|
|
19
|
+
truncated: z.ZodBoolean;
|
|
20
|
+
max_rows: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
column_schema: z.ZodArray<z.ZodObject<{
|
|
22
|
+
name: z.ZodString;
|
|
23
|
+
type: z.ZodString;
|
|
24
|
+
nullable: z.ZodBoolean;
|
|
25
|
+
}, z.core.$strip>>;
|
|
26
|
+
}, z.core.$strip>>;
|
|
27
|
+
}, z.core.$strip>, readonly [{
|
|
28
|
+
readonly reason: "canvas_unavailable";
|
|
29
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
30
|
+
readonly when: "The DataCanvas service is not configured for this deployment";
|
|
31
|
+
readonly recovery: "Set CANVAS_PROVIDER_TYPE=duckdb in the server environment to enable dataframes.";
|
|
32
|
+
}]>;
|
|
33
|
+
//# sourceMappingURL=dataframe-describe.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataframe-describe.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/dataframe-describe.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;GAmHhC,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview List the dataframes materialized by SEC EDGAR data-returning
|
|
3
|
+
* tools, with provenance, TTL, and column schema. Reads from the canvas
|
|
4
|
+
* bridge (which lazy-sweeps expired tables before responding).
|
|
5
|
+
* @module mcp-server/tools/definitions/dataframe-describe
|
|
6
|
+
*/
|
|
7
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
8
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
9
|
+
import { getCanvasBridge } from '../../../services/canvas-bridge/canvas-bridge.js';
|
|
10
|
+
export const dataframeDescribeTool = tool('secedgar_dataframe_describe', {
|
|
11
|
+
description: 'List dataframes (df_XXXXX_XXXXX) materialized by secedgar_fetch_frames, secedgar_search_filings, and secedgar_get_financials. Each entry surfaces source tool, query parameters, creation/expiry timestamps, row count, column schema, and whether the dataframe is truncated relative to the upstream source.',
|
|
12
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
|
|
13
|
+
errors: [
|
|
14
|
+
{
|
|
15
|
+
reason: 'canvas_unavailable',
|
|
16
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
17
|
+
when: 'The DataCanvas service is not configured for this deployment',
|
|
18
|
+
recovery: 'Set CANVAS_PROVIDER_TYPE=duckdb in the server environment to enable dataframes.',
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
input: z.object({
|
|
22
|
+
name: z
|
|
23
|
+
.string()
|
|
24
|
+
.optional()
|
|
25
|
+
.describe('Optional table name (df_XXXXX_XXXXX) to describe a single dataframe. Omit to list all dataframes.'),
|
|
26
|
+
}),
|
|
27
|
+
output: z.object({
|
|
28
|
+
dataframes: z
|
|
29
|
+
.array(z
|
|
30
|
+
.object({
|
|
31
|
+
name: z.string().describe('Canvas table name (df_XXXXX_XXXXX).'),
|
|
32
|
+
source_tool: z.string().describe('Tool that produced this dataframe.'),
|
|
33
|
+
query_params: z
|
|
34
|
+
.record(z.string(), z.unknown())
|
|
35
|
+
.describe('Input parameters the source tool was called with.'),
|
|
36
|
+
created_at: z.string().describe('ISO 8601 creation timestamp.'),
|
|
37
|
+
expires_at: z
|
|
38
|
+
.string()
|
|
39
|
+
.describe('ISO 8601 expiry timestamp. Sliding TTL touched on every dataframe op.'),
|
|
40
|
+
row_count: z.number().describe('Rows materialized in the dataframe.'),
|
|
41
|
+
truncated: z
|
|
42
|
+
.boolean()
|
|
43
|
+
.describe('True when the upstream source had more rows than were materialized.'),
|
|
44
|
+
max_rows: z
|
|
45
|
+
.number()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe('Materialization cap that produced `truncated`, when applicable.'),
|
|
48
|
+
column_schema: z
|
|
49
|
+
.array(z
|
|
50
|
+
.object({
|
|
51
|
+
name: z.string().describe('Column name.'),
|
|
52
|
+
type: z.string().describe('Canvas column type (VARCHAR, BIGINT, DOUBLE, ...).'),
|
|
53
|
+
nullable: z.boolean().describe('Whether the column permits NULL.'),
|
|
54
|
+
})
|
|
55
|
+
.describe('One column declaration in the dataframe schema.'))
|
|
56
|
+
.describe('Resolved column schema (all SEC dataframe columns are nullable).'),
|
|
57
|
+
})
|
|
58
|
+
.describe('Provenance and schema for one dataframe.'))
|
|
59
|
+
.describe('Active dataframes for this tenant, newest first. Empty when none are registered.'),
|
|
60
|
+
}),
|
|
61
|
+
async handler(input, ctx) {
|
|
62
|
+
const bridge = getCanvasBridge();
|
|
63
|
+
if (!bridge) {
|
|
64
|
+
throw ctx.fail('canvas_unavailable', 'DataCanvas is not configured on this server.', {
|
|
65
|
+
...ctx.recoveryFor('canvas_unavailable'),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const entries = await bridge.describe(ctx, input.name);
|
|
69
|
+
return {
|
|
70
|
+
dataframes: entries.map((meta) => ({
|
|
71
|
+
name: meta.tableName,
|
|
72
|
+
source_tool: meta.sourceTool,
|
|
73
|
+
query_params: meta.queryParams,
|
|
74
|
+
created_at: meta.createdAt,
|
|
75
|
+
expires_at: meta.expiresAt,
|
|
76
|
+
row_count: meta.rowCount,
|
|
77
|
+
truncated: meta.truncated,
|
|
78
|
+
max_rows: meta.maxRows,
|
|
79
|
+
column_schema: meta.columnSchema.map((c) => ({
|
|
80
|
+
name: c.name,
|
|
81
|
+
type: c.type,
|
|
82
|
+
nullable: c.nullable ?? true,
|
|
83
|
+
})),
|
|
84
|
+
})),
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
format: (result) => {
|
|
88
|
+
if (result.dataframes.length === 0) {
|
|
89
|
+
return [{ type: 'text', text: 'No active dataframes.' }];
|
|
90
|
+
}
|
|
91
|
+
const lines = [`**${result.dataframes.length} active dataframe(s):**\n`];
|
|
92
|
+
for (const df of result.dataframes) {
|
|
93
|
+
const truncated = df.truncated
|
|
94
|
+
? ` (truncated${df.max_rows ? ` at ${df.max_rows}` : ''})`
|
|
95
|
+
: '';
|
|
96
|
+
lines.push(`### ${df.name}`);
|
|
97
|
+
lines.push(`- Source: ${df.source_tool}`);
|
|
98
|
+
lines.push(`- Rows: ${df.row_count}${truncated}`);
|
|
99
|
+
lines.push(`- Created: ${df.created_at} — Expires: ${df.expires_at}`);
|
|
100
|
+
const params = Object.entries(df.query_params)
|
|
101
|
+
.map(([k, v]) => `${k}=${JSON.stringify(v)}`)
|
|
102
|
+
.join(', ');
|
|
103
|
+
if (params)
|
|
104
|
+
lines.push(`- Params: ${params}`);
|
|
105
|
+
const cols = df.column_schema
|
|
106
|
+
.map((c) => `${c.name}:${c.type} (nullable=${c.nullable})`)
|
|
107
|
+
.join(', ');
|
|
108
|
+
lines.push(`- Columns: ${cols}`);
|
|
109
|
+
lines.push('');
|
|
110
|
+
}
|
|
111
|
+
return [{ type: 'text', text: lines.join('\n').trimEnd() }];
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
//# sourceMappingURL=dataframe-describe.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataframe-describe.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/dataframe-describe.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Drop a canvas dataframe by name. Idempotent — removes the
|
|
3
|
+
* canvas table and the bridge-side provenance entry; returns whether anything
|
|
4
|
+
* was found and removed.
|
|
5
|
+
* @module mcp-server/tools/definitions/dataframe-drop
|
|
6
|
+
*/
|
|
7
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
8
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
9
|
+
export declare const dataframeDropTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
10
|
+
name: z.ZodString;
|
|
11
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
12
|
+
name: z.ZodString;
|
|
13
|
+
dropped: z.ZodBoolean;
|
|
14
|
+
}, z.core.$strip>, readonly [{
|
|
15
|
+
readonly reason: "canvas_unavailable";
|
|
16
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
17
|
+
readonly when: "The DataCanvas service is not configured for this deployment";
|
|
18
|
+
readonly recovery: "Set CANVAS_PROVIDER_TYPE=duckdb in the server environment to enable dataframes.";
|
|
19
|
+
}]>;
|
|
20
|
+
//# sourceMappingURL=dataframe-drop.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataframe-drop.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/dataframe-drop.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,iBAAiB;;;;;;;;;;GA2C5B,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Drop a canvas dataframe by name. Idempotent — removes the
|
|
3
|
+
* canvas table and the bridge-side provenance entry; returns whether anything
|
|
4
|
+
* was found and removed.
|
|
5
|
+
* @module mcp-server/tools/definitions/dataframe-drop
|
|
6
|
+
*/
|
|
7
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
8
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
9
|
+
import { getCanvasBridge } from '../../../services/canvas-bridge/canvas-bridge.js';
|
|
10
|
+
export const dataframeDropTool = tool('secedgar_dataframe_drop', {
|
|
11
|
+
description: 'Drop a canvas dataframe by name. Idempotent — returns dropped=false when nothing matched. Use to free canvas resources ahead of the per-table TTL when an analysis is complete.',
|
|
12
|
+
annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false },
|
|
13
|
+
errors: [
|
|
14
|
+
{
|
|
15
|
+
reason: 'canvas_unavailable',
|
|
16
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
17
|
+
when: 'The DataCanvas service is not configured for this deployment',
|
|
18
|
+
recovery: 'Set CANVAS_PROVIDER_TYPE=duckdb in the server environment to enable dataframes.',
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
input: z.object({
|
|
22
|
+
name: z.string().min(1).describe('Canvas table name (df_XXXXX_XXXXX) to drop.'),
|
|
23
|
+
}),
|
|
24
|
+
output: z.object({
|
|
25
|
+
name: z.string().describe('Name that was requested for drop.'),
|
|
26
|
+
dropped: z
|
|
27
|
+
.boolean()
|
|
28
|
+
.describe('True when the dataframe existed and was removed; false when nothing matched.'),
|
|
29
|
+
}),
|
|
30
|
+
async handler(input, ctx) {
|
|
31
|
+
const bridge = getCanvasBridge();
|
|
32
|
+
if (!bridge) {
|
|
33
|
+
throw ctx.fail('canvas_unavailable', 'DataCanvas is not configured on this server.', {
|
|
34
|
+
...ctx.recoveryFor('canvas_unavailable'),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const dropped = await bridge.drop(ctx, input.name);
|
|
38
|
+
ctx.log.info('Dataframe drop requested', { name: input.name, dropped });
|
|
39
|
+
return { name: input.name, dropped };
|
|
40
|
+
},
|
|
41
|
+
format: (result) => [
|
|
42
|
+
{
|
|
43
|
+
type: 'text',
|
|
44
|
+
text: result.dropped ? `Dropped ${result.name}.` : `${result.name} not found.`,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=dataframe-drop.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataframe-drop.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/dataframe-drop.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAE5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC,yBAAyB,EAAE;IAC/D,WAAW,EACT,iLAAiL;IACnL,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;IAEhF,MAAM,EAAE;QACN;YACE,MAAM,EAAE,oBAAoB;YAC5B,IAAI,EAAE,gBAAgB,CAAC,kBAAkB;YACzC,IAAI,EAAE,8DAA8D;YACpE,QAAQ,EAAE,iFAAiF;SAC5F;KACF;IAED,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;KAChF,CAAC;IAEF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QAC9D,OAAO,EAAE,CAAC;aACP,OAAO,EAAE;aACT,QAAQ,CAAC,8EAA8E,CAAC;KAC5F,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACtB,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE,8CAA8C,EAAE;gBACnF,GAAG,GAAG,CAAC,WAAW,CAAC,oBAAoB,CAAC;aACzC,CAAC,CAAC;QACL,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACnD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACxE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;IACvC,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;QAClB;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,aAAa;SAC/E;KACF;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Run a single-statement SELECT against the canvas dataframes
|
|
3
|
+
* registered by SEC EDGAR data-returning tools. Layered SQL gate: framework
|
|
4
|
+
* (single-statement → SELECT only → plan-walk allowlist + denied table
|
|
5
|
+
* functions) plus a bridge-layer deny on DuckDB system catalogs
|
|
6
|
+
* (information_schema, pg_catalog, sqlite_master, duckdb_*) so callers cannot
|
|
7
|
+
* enumerate every df_<id> on the shared canvas.
|
|
8
|
+
* @module mcp-server/tools/definitions/dataframe-query
|
|
9
|
+
*/
|
|
10
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
11
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
12
|
+
export declare const dataframeQueryTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
13
|
+
sql: z.ZodString;
|
|
14
|
+
register_as: z.ZodOptional<z.ZodString>;
|
|
15
|
+
preview: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
row_limit: z.ZodDefault<z.ZodNumber>;
|
|
17
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
18
|
+
columns: z.ZodArray<z.ZodString>;
|
|
19
|
+
row_count: z.ZodNumber;
|
|
20
|
+
rows: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
21
|
+
registered_as: z.ZodOptional<z.ZodString>;
|
|
22
|
+
expires_at: z.ZodOptional<z.ZodString>;
|
|
23
|
+
}, z.core.$strip>, readonly [{
|
|
24
|
+
readonly reason: "canvas_unavailable";
|
|
25
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
26
|
+
readonly when: "The DataCanvas service is not configured for this deployment";
|
|
27
|
+
readonly recovery: "Set CANVAS_PROVIDER_TYPE=duckdb in the server environment to enable dataframes.";
|
|
28
|
+
}]>;
|
|
29
|
+
//# sourceMappingURL=dataframe-query.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataframe-query.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/dataframe-query.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;GAiI7B,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Run a single-statement SELECT against the canvas dataframes
|
|
3
|
+
* registered by SEC EDGAR data-returning tools. Layered SQL gate: framework
|
|
4
|
+
* (single-statement → SELECT only → plan-walk allowlist + denied table
|
|
5
|
+
* functions) plus a bridge-layer deny on DuckDB system catalogs
|
|
6
|
+
* (information_schema, pg_catalog, sqlite_master, duckdb_*) so callers cannot
|
|
7
|
+
* enumerate every df_<id> on the shared canvas.
|
|
8
|
+
* @module mcp-server/tools/definitions/dataframe-query
|
|
9
|
+
*/
|
|
10
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
11
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
12
|
+
import { getCanvasBridge } from '../../../services/canvas-bridge/canvas-bridge.js';
|
|
13
|
+
export const dataframeQueryTool = tool('secedgar_dataframe_query', {
|
|
14
|
+
description: 'Run a single-statement SELECT against the canvas dataframes registered by secedgar_fetch_frames, secedgar_search_filings, and secedgar_get_financials. Read-only: writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected. System catalogs (information_schema, pg_catalog, sqlite_master, duckdb_*) are denied at the bridge layer — list dataframes via secedgar_dataframe_describe. Optional register_as chains the result as a new dataframe with a fresh TTL.',
|
|
15
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
|
|
16
|
+
errors: [
|
|
17
|
+
{
|
|
18
|
+
reason: 'canvas_unavailable',
|
|
19
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
20
|
+
when: 'The DataCanvas service is not configured for this deployment',
|
|
21
|
+
recovery: 'Set CANVAS_PROVIDER_TYPE=duckdb in the server environment to enable dataframes.',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
input: z.object({
|
|
25
|
+
sql: z
|
|
26
|
+
.string()
|
|
27
|
+
.min(1)
|
|
28
|
+
.describe('Single-statement SELECT against df_<id> tables on the shared canvas. Standard DuckDB SQL — joins, aggregates, window functions, CTEs all supported. Reference dataframes by the names returned in fetch/search responses or listed by secedgar_dataframe_describe. BIGINT columns (e.g., XBRL `value`, COUNT/SUM results) serialize as JSON strings to preserve precision past 2^53 — CAST(col AS DOUBLE) in projections for inline arithmetic.'),
|
|
29
|
+
register_as: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.describe('When set, persist the result as a new dataframe under this name (must match df_XXXXX_XXXXX shape, or pass a fresh df_<id> generated by the agent). Fresh TTL window — not inherited from the parents in the SELECT. Use to chain analyses without re-running the source SQL.'),
|
|
33
|
+
preview: z
|
|
34
|
+
.number()
|
|
35
|
+
.int()
|
|
36
|
+
.min(0)
|
|
37
|
+
.max(10000)
|
|
38
|
+
.optional()
|
|
39
|
+
.describe('Rows to include in the immediate response. Defaults to the row limit. Set lower (e.g., 50) when chaining via register_as and only a sample is needed inline.'),
|
|
40
|
+
row_limit: z
|
|
41
|
+
.number()
|
|
42
|
+
.int()
|
|
43
|
+
.min(1)
|
|
44
|
+
.max(10000)
|
|
45
|
+
.default(1000)
|
|
46
|
+
.describe('Hard cap on rows materialized in the response. Default 1000, max 10000. The full result lives on-canvas under register_as when provided — do not raise this to keep large results.'),
|
|
47
|
+
}),
|
|
48
|
+
output: z.object({
|
|
49
|
+
columns: z.array(z.string()).describe('Column names in projection order.'),
|
|
50
|
+
row_count: z
|
|
51
|
+
.number()
|
|
52
|
+
.describe('Total rows the query produced (may exceed `rows.length` when capped).'),
|
|
53
|
+
rows: z
|
|
54
|
+
.array(z.record(z.string(), z.unknown()))
|
|
55
|
+
.describe('Materialized rows, bounded by `preview` / `row_limit`.'),
|
|
56
|
+
registered_as: z
|
|
57
|
+
.string()
|
|
58
|
+
.optional()
|
|
59
|
+
.describe('Set when `register_as` was supplied and the new dataframe was materialized.'),
|
|
60
|
+
expires_at: z
|
|
61
|
+
.string()
|
|
62
|
+
.optional()
|
|
63
|
+
.describe('ISO 8601 expiry timestamp for the newly registered dataframe, when applicable.'),
|
|
64
|
+
}),
|
|
65
|
+
async handler(input, ctx) {
|
|
66
|
+
const bridge = getCanvasBridge();
|
|
67
|
+
if (!bridge) {
|
|
68
|
+
throw ctx.fail('canvas_unavailable', 'DataCanvas is not configured on this server.', {
|
|
69
|
+
...ctx.recoveryFor('canvas_unavailable'),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const { result, meta } = await bridge.query(ctx, input.sql, {
|
|
73
|
+
...(input.register_as !== undefined && { registerAs: input.register_as }),
|
|
74
|
+
...(input.preview !== undefined && { preview: input.preview }),
|
|
75
|
+
rowLimit: input.row_limit,
|
|
76
|
+
sourceTool: 'secedgar_dataframe_query',
|
|
77
|
+
queryParams: { sql: input.sql },
|
|
78
|
+
});
|
|
79
|
+
ctx.log.info('Dataframe query executed', {
|
|
80
|
+
rowCount: result.rowCount,
|
|
81
|
+
returned: result.rows.length,
|
|
82
|
+
registeredAs: meta?.tableName,
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
columns: result.columns,
|
|
86
|
+
row_count: result.rowCount,
|
|
87
|
+
rows: result.rows,
|
|
88
|
+
registered_as: meta?.tableName,
|
|
89
|
+
expires_at: meta?.expiresAt,
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
format: (result) => {
|
|
93
|
+
const lines = [];
|
|
94
|
+
if (result.registered_as) {
|
|
95
|
+
lines.push(`Registered as ${result.registered_as} (expires ${result.expires_at ?? 'unknown'}).`);
|
|
96
|
+
}
|
|
97
|
+
const cappedNote = result.row_count > result.rows.length
|
|
98
|
+
? ` (showing ${result.rows.length} of ${result.row_count})`
|
|
99
|
+
: '';
|
|
100
|
+
lines.push(`**${result.row_count} rows**${cappedNote}\n`);
|
|
101
|
+
if (result.rows.length === 0) {
|
|
102
|
+
lines.push('_No rows._');
|
|
103
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
104
|
+
}
|
|
105
|
+
const header = `| ${result.columns.join(' | ')} |`;
|
|
106
|
+
const sep = `| ${result.columns.map(() => '---').join(' | ')} |`;
|
|
107
|
+
lines.push(header, sep);
|
|
108
|
+
for (const row of result.rows) {
|
|
109
|
+
const cells = result.columns.map((c) => {
|
|
110
|
+
const v = row[c];
|
|
111
|
+
if (v === null || v === undefined)
|
|
112
|
+
return '';
|
|
113
|
+
if (typeof v === 'string')
|
|
114
|
+
return v.replace(/\|/g, '\\|');
|
|
115
|
+
if (typeof v === 'object')
|
|
116
|
+
return JSON.stringify(v).replace(/\|/g, '\\|');
|
|
117
|
+
return String(v);
|
|
118
|
+
});
|
|
119
|
+
lines.push(`| ${cells.join(' | ')} |`);
|
|
120
|
+
}
|
|
121
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=dataframe-query.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataframe-query.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/dataframe-query.tool.ts"],"names":[],"mappings":"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"}
|