@insightsentry/mcp 1.4.2 → 1.4.4

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
@@ -1,8 +1,6 @@
1
1
  # @insightsentry/mcp
2
2
 
3
- MCP server and CLI for the [InsightSentry](https://insightsentry.com) financial data API.
4
-
5
- Gives AI assistants direct access to real-time and historical market data for equities, futures, options, crypto, forex, and more — plus comprehensive documentation resources for building applications with the InsightSentry API and WebSocket feeds. Also usable as a standalone CLI for scripting and terminal workflows.
3
+ MCP server and CLI for the InsightSentry financial data API.
6
4
 
7
5
  ## Install
8
6
 
@@ -10,44 +8,35 @@ Gives AI assistants direct access to real-time and historical market data for eq
10
8
  npm install -g @insightsentry/mcp
11
9
  ```
12
10
 
13
- This gives you two commands:
11
+ Commands:
14
12
 
15
13
  | Command | Purpose |
16
14
  |---------|---------|
17
- | `insight` | CLI for terminal / scripting |
18
- | `insight-mcp` | MCP server for AI assistants |
15
+ | `insight` | CLI for terminal use and scripts |
16
+ | `insight-mcp` | MCP server for AI clients |
17
+ | `mcp` | Alias for `insight-mcp` |
18
+
19
+ ## Authentication
19
20
 
20
- Get your API key from the [InsightSentry Dashboard](https://insightsentry.com/dashboard).
21
+ Set an API key for the current shell:
21
22
 
22
23
  ```bash
23
24
  export INSIGHTSENTRY_API_KEY="your-api-key"
24
25
  ```
25
26
 
26
- ## MCP Server Setup
27
-
28
- No global install needed — use npx in your MCP config.
29
-
30
- ### Claude Desktop
31
-
32
- Add to your `claude_desktop_config.json`:
27
+ Or save one locally for the CLI:
33
28
 
34
- ```json
35
- {
36
- "mcpServers": {
37
- "insightsentry": {
38
- "command": "npx",
39
- "args": ["-y", "@insightsentry/mcp"],
40
- "env": {
41
- "INSIGHTSENTRY_API_KEY": "your-api-key"
42
- }
43
- }
44
- }
45
- }
29
+ ```bash
30
+ insight login --key "your-api-key"
31
+ insight whoami
32
+ insight logout
46
33
  ```
47
34
 
48
- ### Claude Code
35
+ `whoami` parses the configured JWT locally and prints `uuid`, falling back to `email` then `sub`.
49
36
 
50
- Add to `.mcp.json` in your project root:
37
+ ## MCP Setup
38
+
39
+ Use `npx` in your MCP config:
51
40
 
52
41
  ```json
53
42
  {
@@ -63,140 +52,78 @@ Add to `.mcp.json` in your project root:
63
52
  }
64
53
  ```
65
54
 
66
- ### Other MCP Clients
67
-
68
- Any MCP client that supports stdio transport can use the server:
69
-
70
- ```bash
71
- insight-mcp
72
- ```
55
+ The MCP server also falls back to the key saved by `insight login` when `INSIGHTSENTRY_API_KEY` is not set.
73
56
 
74
57
  ## CLI Usage
75
58
 
76
59
  ```bash
77
- insight --help # List all tools
78
- insight <tool> --help # Tool-specific parameters
79
- insight <tool> [--param value] # Call a tool
60
+ insight --help
61
+ insight <tool> --help
62
+ insight <tool> [--param value]
80
63
  ```
81
64
 
82
- ### Examples
65
+ Examples:
83
66
 
84
67
  ```bash
85
- # Search for a symbol
68
+ insight whoami
86
69
  insight search_symbols --query "tesla"
87
-
88
- # Get real-time quotes
89
70
  insight get_quotes --codes "NASDAQ:AAPL,NASDAQ:MSFT"
71
+ insight get_symbol_series --symbol "NASDAQ:AAPL" --bar_type day --dp 30
72
+ insight screen_stocks --fields "close,volume,market_cap" --exchanges "NYSE,NASDAQ" --sortBy market_cap --sortOrder desc
73
+ insight download_history --symbol "NASDAQ:AAPL" --bar_type day --from 2024-01-01 --to 2024-06-30 --output_dir ./history
74
+ ```
90
75
 
91
- # Daily OHLCV with JSONata filter
92
- insight get_symbol_series --symbol "NASDAQ:AAPL" --bar_type day --dp 30 \
93
- --filter "{ \"last_close\": series[-1].close, \"avg_vol\": \$average(series.volume) }"
94
-
95
- # Screen for high-cap stocks
96
- insight screen_stocks --fields "close,volume,market_cap" \
97
- --exchanges "NYSE,NASDAQ" --sortBy market_cap --sortOrder desc
76
+ Symbol codes must use `EXCHANGE:SYMBOL` format. Use `search_symbols` before calling symbol tools.
98
77
 
99
- # Upcoming earnings
100
- insight get_earnings --c US
78
+ All API tools support:
101
79
 
102
- # Options chain
103
- insight list_options --code "NASDAQ:AAPL" --type call --range 10
80
+ ```bash
81
+ --filter '<jsonata-expression>'
82
+ --store json --output_file ./response.json
83
+ --store json --output_dir ./responses
104
84
  ```
105
85
 
106
- All tools support `--filter <jsonata>` to transform/reduce the JSON response before output. See [JSONata docs](https://jsonata.org) for expression syntax.
107
-
108
- ## Available Tools (28)
109
-
110
- ### Market Data
111
- | Tool | Description |
112
- |------|-------------|
113
- | `get_symbol_series` | Recent OHLCV data (up to 30k bars) with real-time option |
114
- | `get_symbol_history` | Deep historical data (20+ years) |
115
- | `get_quotes` | Real-time quotes for up to 10 symbols |
116
- | `get_symbol_info` | Symbol metadata (type, sector, market cap, etc.) |
117
- | `get_symbol_session` | Trading session details and hours |
118
- | `get_symbol_contracts` | Futures contract list with settlement dates |
119
-
120
- ### Search
121
- | Tool | Description |
122
- |------|-------------|
123
- | `search_symbols` | Search for symbols across all asset classes |
124
-
125
- ### Fundamentals
126
- | Tool | Description |
127
- |------|-------------|
128
- | `get_symbol_fundamentals` | Company fundamentals (valuation, profitability, balance sheet) |
129
- | `get_fundamentals_series` | Historical fundamental indicators |
130
- | `get_fundamentals_meta` | Available fundamental/technical indicator IDs |
131
-
132
- ### Options
133
- | Tool | Description |
134
- |------|-------------|
135
- | `list_options` | List available option contracts |
136
- | `get_options_expiration` | Option chain by expiration date |
137
- | `get_options_strike` | Option chain by strike price |
138
-
139
- ### Screeners
140
- | Tool | Description |
141
- |------|-------------|
142
- | `screen_stocks` | Filter stocks with custom criteria |
143
- | `screen_etfs` | Filter ETFs with custom criteria |
144
- | `screen_bonds` | Filter bonds with custom criteria |
145
- | `screen_crypto` | Filter crypto with custom criteria |
146
- | `get_stock_screener_params` | Available stock screener fields |
147
- | `get_etf_screener_params` | Available ETF screener fields |
148
- | `get_bond_screener_params` | Available bond screener fields |
149
- | `get_crypto_screener_params` | Available crypto screener fields |
150
-
151
- ### Calendar
152
- | Tool | Description |
153
- |------|-------------|
154
- | `get_dividends` | Dividend calendar |
155
- | `get_earnings` | Earnings calendar |
156
- | `get_ipos` | IPO calendar |
157
- | `get_events` | Economic events calendar |
158
-
159
- ### News & Documents
160
- | Tool | Description |
161
- |------|-------------|
162
- | `get_newsfeed` | Financial news with keyword filtering |
163
- | `get_documents` | List SEC filings and transcripts |
164
- | `get_document` | Get specific document content |
165
-
166
- ## Documentation Resources
167
-
168
- The MCP server also provides documentation resources that AI assistants can read to help you build applications:
169
-
170
- | Resource | Content |
171
- |----------|---------|
172
- | `insightsentry://docs/rest-api` | Complete REST API reference |
173
- | `insightsentry://docs/websocket` | WebSocket API: connection, subscriptions, data formats, code examples |
174
- | `insightsentry://docs/screener` | Screener API: field discovery and filtering |
175
- | `insightsentry://docs/options` | Options API: chains, Greeks, option codes |
176
- | `insightsentry://docs/futures-history` | Futures historical data and contract month logic |
177
-
178
- ## Online Documentation
179
-
180
- - API Docs: https://insightsentry.com/docs
181
- - WebSocket Live Demo: https://insightsentry.com/test/realtime
182
- - News Feed Demo: https://insightsentry.com/test/newsfeed
183
- - OpenAPI Spec: https://insightsentry.com/openapi.json
184
-
185
- ## Development
86
+ `get_symbol_series` also supports CSV storage:
186
87
 
187
88
  ```bash
188
- npm install
189
- npm run generate # Generate tool definitions from OpenAPI spec
190
- npm run build # Generate + compile TypeScript
191
- npm run dev # Run MCP server with tsx (no build needed)
89
+ insight get_symbol_series --symbol "NASDAQ:AAPL" --bar_type day --store csv --output_file ./aapl.csv
192
90
  ```
193
91
 
194
- ### Testing
92
+ ## Tools
195
93
 
196
- ```bash
197
- npx tsx --test test/cli.test.ts # CLI unit tests
198
- ```
94
+ Auth and files:
95
+
96
+ | Tool | Purpose |
97
+ |------|---------|
98
+ | `whoami` | Print the configured user's `uuid`/email from the API key JWT |
99
+ | `download_history` | Download date ranges to JSON/CSV files |
100
+ | `render_chart` | Render Chart.js configs as PNG images |
199
101
 
200
- ## License
102
+ Market data:
103
+
104
+ | Tool | Purpose |
105
+ |------|---------|
106
+ | `search_symbols` | Find valid `EXCHANGE:SYMBOL` codes |
107
+ | `get_quotes` | Real-time quotes |
108
+ | `get_symbol_series` | Recent OHLCV series |
109
+ | `get_symbol_history` | Deep intraday history |
110
+ | `get_symbol_info` | Symbol metadata |
111
+ | `get_symbol_session` | Trading hours and session details |
112
+ | `get_symbol_contracts` | Futures contract list |
113
+
114
+ Fundamentals, options, screeners, calendars, documents:
115
+
116
+ | Tool | Purpose |
117
+ |------|---------|
118
+ | `get_symbol_fundamentals` | Company fundamentals |
119
+ | `get_fundamentals_series` | Historical fundamental indicators |
120
+ | `get_fundamentals_meta` | Available fundamental/technical IDs |
121
+ | `list_options` | Available option contracts |
122
+ | `get_options_expiration` | Option chain by expiration |
123
+ | `get_options_strike` | Option chain by strike |
124
+ | `screen_stocks`, `screen_etfs`, `screen_bonds`, `screen_crypto` | Screen assets |
125
+ | `get_stock_screener_params`, `get_etf_screener_params`, `get_bond_screener_params`, `get_crypto_screener_params` | Screener fields |
126
+ | `get_dividends`, `get_earnings`, `get_ipos`, `get_events` | Calendars |
127
+ | `get_newsfeed` | Financial news |
128
+ | `get_documents`, `get_document` | Filings and transcripts |
201
129
 
202
- MIT
package/bin/insight.js CHANGED
@@ -1,3 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
  import { main } from "../dist/cli.js";
3
+
3
4
  main();
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AA+BA,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAIpB,OAAO,CACX,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B,OAAO,CAAC,GAAG,CAAC;CAoEhB"}
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AA0BA,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAIpB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;CA+D/F"}
@@ -7,9 +7,7 @@ function validateSymbolParams(params) {
7
7
  for (const [key, value] of Object.entries(params)) {
8
8
  if (!SYMBOL_PARAM_NAMES.has(key) || !value)
9
9
  continue;
10
- const codes = key === "codes"
11
- ? String(value).split(",")
12
- : [String(value)];
10
+ const codes = key === "codes" ? String(value).split(",") : [String(value)];
13
11
  for (const code of codes) {
14
12
  const trimmed = code.trim();
15
13
  if (!SYMBOL_CODE_PATTERN.test(trimmed)) {
@@ -33,9 +31,7 @@ export class ApiClient {
33
31
  throw new Error(symbolError);
34
32
  }
35
33
  // Separate path params from query/body params
36
- const pathParamNames = [
37
- ...pathTemplate.matchAll(/\{(\w+)\}/g),
38
- ].map((m) => m[1]);
34
+ const pathParamNames = [...pathTemplate.matchAll(/\{(\w+)\}/g)].map((m) => m[1]);
39
35
  let path = pathTemplate;
40
36
  const remaining = {};
41
37
  for (const [key, value] of Object.entries(params)) {
@@ -74,8 +70,7 @@ export class ApiClient {
74
70
  let errorMessage;
75
71
  try {
76
72
  const errorJson = JSON.parse(text);
77
- errorMessage =
78
- errorJson.message || errorJson.error || JSON.stringify(errorJson);
73
+ errorMessage = errorJson.message || errorJson.error || JSON.stringify(errorJson);
79
74
  }
80
75
  catch {
81
76
  errorMessage = text || `HTTP ${response.status} ${response.statusText}`;
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export type AuthKeySource = "environment" | "config" | "none";
2
+ export interface AuthStatus {
3
+ authenticated: boolean;
4
+ source: AuthKeySource;
5
+ config_path: string;
6
+ key_present: boolean;
7
+ key_format_valid: boolean;
8
+ subject?: string;
9
+ expires_at?: string;
10
+ expired?: boolean;
11
+ message: string;
12
+ }
13
+ export interface WhoamiResult {
14
+ ok: boolean;
15
+ identity?: string;
16
+ error?: string;
17
+ }
18
+ export declare function getAuthStatus(): AuthStatus;
19
+ export declare function getWhoami(): WhoamiResult;
20
+ export declare function getWhoamiForKey(apiKey: string | undefined, _source: AuthKeySource): WhoamiResult;
21
+ export declare function getAuthStatusForKey(apiKey: string | undefined, source: AuthKeySource, configPath: string, now?: Date): AuthStatus;
22
+ export declare function isJwt(token: string): boolean;
23
+ //# sourceMappingURL=auth-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-status.d.ts","sourceRoot":"","sources":["../src/auth-status.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AASD,wBAAgB,aAAa,IAAI,UAAU,CAG1C;AAED,wBAAgB,SAAS,IAAI,YAAY,CAGxC;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,aAAa,GAAG,YAAY,CAqBhG;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,MAAM,EAClB,GAAG,OAAa,GACf,UAAU,CA4CZ;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5C"}
@@ -0,0 +1,86 @@
1
+ import { getConfigLocation, resolveApiKeyWithSource } from "./config.js";
2
+ export function getAuthStatus() {
3
+ const { apiKey, source } = resolveApiKeyWithSource();
4
+ return getAuthStatusForKey(apiKey, source, getConfigLocation());
5
+ }
6
+ export function getWhoami() {
7
+ const { apiKey, source } = resolveApiKeyWithSource();
8
+ return getWhoamiForKey(apiKey, source);
9
+ }
10
+ export function getWhoamiForKey(apiKey, _source) {
11
+ const token = apiKey?.trim();
12
+ if (!token)
13
+ return { ok: false, error: "No API key found." };
14
+ const payload = decodeJwtPayload(token);
15
+ if (!payload) {
16
+ return {
17
+ ok: false,
18
+ error: "API key is not a valid InsightSentry JWT.",
19
+ };
20
+ }
21
+ const identity = payload.uuid ?? payload.email ?? payload.sub;
22
+ if (!identity) {
23
+ return {
24
+ ok: false,
25
+ error: "API key JWT does not include uuid, email, or sub.",
26
+ };
27
+ }
28
+ return { ok: true, identity };
29
+ }
30
+ export function getAuthStatusForKey(apiKey, source, configPath, now = new Date()) {
31
+ const token = apiKey?.trim();
32
+ if (!token) {
33
+ return {
34
+ authenticated: false,
35
+ source: "none",
36
+ config_path: configPath,
37
+ key_present: false,
38
+ key_format_valid: false,
39
+ message: "Logged out. No API key found.",
40
+ };
41
+ }
42
+ const payload = decodeJwtPayload(token);
43
+ if (!payload) {
44
+ return {
45
+ authenticated: false,
46
+ source,
47
+ config_path: configPath,
48
+ key_present: true,
49
+ key_format_valid: false,
50
+ message: "Logged out. INSIGHTSENTRY_API_KEY is not a valid API key. InsightSentry API keys are JWT tokens.",
51
+ };
52
+ }
53
+ const expiresAt = payload.exp ? new Date(payload.exp * 1000) : undefined;
54
+ const expired = expiresAt ? expiresAt.getTime() <= now.getTime() : undefined;
55
+ const sourceLabel = source === "environment" ? "INSIGHTSENTRY_API_KEY" : "saved config";
56
+ return {
57
+ authenticated: expired !== true,
58
+ source,
59
+ config_path: configPath,
60
+ key_present: true,
61
+ key_format_valid: true,
62
+ subject: payload.uuid ?? payload.email ?? payload.sub,
63
+ expires_at: expiresAt?.toISOString(),
64
+ expired,
65
+ message: expired === true
66
+ ? `Logged out. API key from ${sourceLabel} is expired.`
67
+ : `Logged in using ${sourceLabel}.`,
68
+ };
69
+ }
70
+ export function isJwt(token) {
71
+ return decodeJwtPayload(token) !== null;
72
+ }
73
+ function decodeJwtPayload(token) {
74
+ const parts = token.split(".");
75
+ if (parts.length !== 3)
76
+ return null;
77
+ try {
78
+ JSON.parse(Buffer.from(parts[0], "base64url").toString("utf8"));
79
+ const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
80
+ return payload && typeof payload === "object" ? payload : null;
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
86
+ //# sourceMappingURL=auth-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-status.js","sourceRoot":"","sources":["../src/auth-status.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../src/chart.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAyBnD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,kBAAkB,EAC1B,KAAK,GAAE,MAAsB,EAC7B,MAAM,GAAE,MAAuB,GAC9B,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAW/C"}
1
+ {"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../src/chart.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAuBnD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,kBAAkB,EAC1B,KAAK,GAAE,MAAsB,EAC7B,MAAM,GAAE,MAAuB,GAC9B,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAW/C"}
package/dist/chart.js CHANGED
@@ -1,7 +1,7 @@
1
+ import { writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
1
4
  import { ChartJSNodeCanvas } from "chartjs-node-canvas";
2
- import { writeFileSync } from "fs";
3
- import { tmpdir } from "os";
4
- import { join } from "path";
5
5
  const DEFAULT_WIDTH = 800;
6
6
  const DEFAULT_HEIGHT = 400;
7
7
  // Cache canvases by dimension to avoid re-creating them
package/dist/chart.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"chart.js","sourceRoot":"","sources":["../src/chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,wDAAwD;AACxD,MAAM,WAAW,GAAG,IAAI,GAAG,EAA6B,CAAC;AAEzD,SAAS,SAAS,CAAC,KAAa,EAAE,MAAc;IAC9C,MAAM,GAAG,GAAG,GAAG,KAAK,IAAI,MAAM,EAAE,CAAC;IACjC,IAAI,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,IAAI,iBAAiB,CAAC;YAC7B,KAAK;YACL,MAAM;YACN,gBAAgB,EAAE,OAAO;SAC1B,CAAC,CAAC;QACH,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAA0B,EAC1B,QAAgB,aAAa,EAC7B,SAAiB,cAAc;IAE/B,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEzC,wEAAwE;IACxE,MAAM,QAAQ,GAAG,uBAAuB,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC1C,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEhC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"chart.js","sourceRoot":"","sources":["../src/chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,wDAAwD;AACxD,MAAM,WAAW,GAAG,IAAI,GAAG,EAA6B,CAAC;AAEzD,SAAS,SAAS,CAAC,KAAa,EAAE,MAAc;IAC9C,MAAM,GAAG,GAAG,GAAG,KAAK,IAAI,MAAM,EAAE,CAAC;IACjC,IAAI,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,IAAI,iBAAiB,CAAC;YAC7B,KAAK;YACL,MAAM;YACN,gBAAgB,EAAE,OAAO;SAC1B,CAAC,CAAC;QACH,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAA0B,EAC1B,QAAgB,aAAa,EAC7B,SAAiB,cAAc;IAE/B,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEzC,wEAAwE;IACxE,MAAM,QAAQ,GAAG,uBAAuB,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC1C,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEhC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC"}
package/dist/cli.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type AuthStatus } from "./auth-status.js";
1
2
  import { type ToolDefinition } from "./tool-definitions.js";
2
3
  export { coerceArgs } from "./arg-coercion.js";
3
4
  interface ParsedArgs {
@@ -17,6 +18,7 @@ interface CliIO {
17
18
  progress?: (s: string) => void;
18
19
  prompt?: (question: string) => Promise<string>;
19
20
  isInteractive?: boolean;
21
+ getAuthStatus?: () => AuthStatus;
20
22
  }
21
23
  export declare function runCli(argv: string[], io: CliIO): Promise<void>;
22
24
  export declare function main(): void;
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAU7E,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI/C,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAoCpD;AAED,wBAAgB,SAAS,IAAI,MAAM,CAoClC;AAED,wBAAgB,wBAAwB,IAAI,MAAM,CA6BjD;AA8GD,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAgC1D;AAkBD,KAAK,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAErG,UAAU,KAAK;IACb,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAKD,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAsHrE;AA+HD,wBAAgB,IAAI,SASnB"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAGlE,OAAO,EAAE,KAAK,cAAc,EAAmB,MAAM,uBAAuB,CAAC;AAG7E,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI/C,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAoCpD;AAED,wBAAgB,SAAS,IAAI,MAAM,CA6ClC;AAED,wBAAgB,wBAAwB,IAAI,MAAM,CA6BjD;AAyFD,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAsC1D;AAkBD,KAAK,SAAS,GAAG,CACf,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KACxB,OAAO,CAAC,GAAG,CAAC,CAAC;AAElB,UAAU,KAAK;IACb,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,UAAU,CAAC;CAClC;AAKD,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAwIrE;AAuID,wBAAgB,IAAI,SASnB"}
package/dist/cli.js CHANGED
@@ -1,11 +1,12 @@
1
- import { createInterface } from "node:readline/promises";
2
1
  import { stdin as input, stdout as output } from "node:process";
2
+ import { createInterface } from "node:readline/promises";
3
3
  import { ApiClient } from "./api-client.js";
4
- import { toolDefinitions } from "./tool-definitions.js";
5
- import { saveConfig, deleteConfig, resolveApiKey, getConfigLocation } from "./config.js";
4
+ import { coerceArgs, getZodEnumValues, getZodTypeName, isOptionalZodType } from "./arg-coercion.js";
5
+ import { getAuthStatus } from "./auth-status.js";
6
+ import { deleteConfig, getConfigLocation, resolveApiKey, saveConfig } from "./config.js";
6
7
  import { downloadHistory } from "./history.js";
8
+ import { toolDefinitions } from "./tool-definitions.js";
7
9
  import { runApiTool } from "./tool-runner.js";
8
- import { coerceArgs, getZodEnumValues, getZodTypeName, isOptionalZodType, } from "./arg-coercion.js";
9
10
  export { coerceArgs } from "./arg-coercion.js";
10
11
  const DOWNLOAD_HISTORY_COMMAND = "download_history";
11
12
  export function parseArgs(argv) {
@@ -63,7 +64,7 @@ export function buildHelp() {
63
64
  lines.push(' insight get_symbol_series --symbol "NASDAQ:AAPL" --bar_type day --dp 30');
64
65
  lines.push(' insight download_history --symbol "NASDAQ:AAPL" --bar_type minute --from 2024-01 --to 2024-03 --output_dir ./data --format csv');
65
66
  lines.push(' insight screen_stocks --fields "close,volume,market_cap" --exchanges "NYSE,NASDAQ" --sortBy market_cap --sortOrder desc');
66
- lines.push(' insight get_earnings --c US');
67
+ lines.push(" insight get_earnings --c US");
67
68
  lines.push(' insight list_options --code "NASDAQ:AAPL" --type call --range 10');
68
69
  lines.push("");
69
70
  lines.push("All tools support --filter <jsonata> to transform the response.");
@@ -71,6 +72,7 @@ export function buildHelp() {
71
72
  lines.push("");
72
73
  lines.push("Authentication:");
73
74
  lines.push(" insight login --key <your-api-key> Save API key (persisted across sessions)");
75
+ lines.push(" insight whoami Print the logged-in user's email");
74
76
  lines.push(" insight logout Remove saved API key");
75
77
  lines.push("");
76
78
  lines.push(" Or set INSIGHTSENTRY_API_KEY environment variable (takes priority over saved key).");
@@ -127,18 +129,14 @@ const toolExamples = {
127
129
  'insight get_symbol_history --symbol "NASDAQ:AAPL" --bar_type minute --start_date "2025-01"',
128
130
  'insight get_symbol_history --symbol "NASDAQ:AAPL" --bar_type hour --start_date "2025-06" --bar_interval 4',
129
131
  ],
130
- get_symbol_contracts: [
131
- 'insight get_symbol_contracts --symbol "CME_MINI:NQ1!"',
132
- ],
132
+ get_symbol_contracts: ['insight get_symbol_contracts --symbol "CME_MINI:NQ1!"'],
133
133
  get_symbol_info: [
134
134
  'insight get_symbol_info --symbol "NASDAQ:AAPL"',
135
135
  `insight get_symbol_info --symbol "NASDAQ:AAPL" --filter '{ "sector": sector, "market_cap": market_cap, "pe": price_earnings_ttm }'`,
136
136
  ],
137
- get_symbol_session: [
138
- 'insight get_symbol_session --symbol "NASDAQ:AAPL"',
139
- ],
137
+ get_symbol_session: ['insight get_symbol_session --symbol "NASDAQ:AAPL"'],
140
138
  get_symbol_fundamentals: [
141
- 'insight get_symbol_fundamentals --symbol "NASDAQ:AAPL" --filter \'$distinct(data.category)\'',
139
+ "insight get_symbol_fundamentals --symbol \"NASDAQ:AAPL\" --filter '$distinct(data.category)'",
142
140
  `insight get_symbol_fundamentals --symbol "NASDAQ:AAPL" --filter 'data[category="Valuation"].{ "id": id, "name": name, "value": value }'`,
143
141
  ],
144
142
  get_fundamentals_series: [
@@ -161,21 +159,12 @@ const toolExamples = {
161
159
  'insight get_options_strike --code "NASDAQ:AAPL" --range 5 --sortBy delta --sort desc',
162
160
  ],
163
161
  get_dividends: [
164
- 'insight get_dividends --c US',
162
+ "insight get_dividends --c US",
165
163
  'insight get_dividends --code "NASDAQ:AAPL" --w 4',
166
164
  ],
167
- get_earnings: [
168
- 'insight get_earnings --c US',
169
- 'insight get_earnings --code "NASDAQ:AAPL"',
170
- ],
171
- get_ipos: [
172
- 'insight get_ipos --c US',
173
- 'insight get_ipos --w 4',
174
- ],
175
- get_events: [
176
- 'insight get_events --c US',
177
- 'insight get_events --w 2',
178
- ],
165
+ get_earnings: ["insight get_earnings --c US", 'insight get_earnings --code "NASDAQ:AAPL"'],
166
+ get_ipos: ["insight get_ipos --c US", "insight get_ipos --w 4"],
167
+ get_events: ["insight get_events --c US", "insight get_events --w 2"],
179
168
  get_newsfeed: [
180
169
  'insight get_newsfeed --keywords "tesla,apple" --limit 10',
181
170
  `insight get_newsfeed --keywords "bitcoin" --filter 'data[[0..4]].{ "title": title, "published_at": published_at }'`,
@@ -194,25 +183,17 @@ const toolExamples = {
194
183
  'insight screen_crypto --fields "close,volume,market_cap" --sortBy market_cap --sortOrder desc',
195
184
  ],
196
185
  get_stock_screener_params: [
197
- 'insight get_stock_screener_params',
186
+ "insight get_stock_screener_params",
198
187
  `insight get_stock_screener_params --filter 'available_fields[$contains($, "volume")]'`,
199
188
  ],
200
- get_etf_screener_params: [
201
- 'insight get_etf_screener_params',
202
- ],
203
- get_bond_screener_params: [
204
- 'insight get_bond_screener_params',
205
- ],
206
- get_crypto_screener_params: [
207
- 'insight get_crypto_screener_params',
208
- ],
189
+ get_etf_screener_params: ["insight get_etf_screener_params"],
190
+ get_bond_screener_params: ["insight get_bond_screener_params"],
191
+ get_crypto_screener_params: ["insight get_crypto_screener_params"],
209
192
  get_documents: [
210
193
  'insight get_documents --code "NASDAQ:AAPL"',
211
194
  `insight get_documents --code "NASDAQ:AAPL" --filter '$[form="10-K" or form="10-Q"].{ "id": id, "title": title, "form": form }'`,
212
195
  ],
213
- get_document: [
214
- 'insight get_document --id "transcripts:2133670" --code "NASDAQ:AAPL" --text',
215
- ],
196
+ get_document: ['insight get_document --id "transcripts:2133670" --code "NASDAQ:AAPL" --text'],
216
197
  };
217
198
  export function buildToolHelp(tool) {
218
199
  const lines = [
@@ -286,6 +267,18 @@ export async function runCli(argv, io) {
286
267
  io.exit(0);
287
268
  return;
288
269
  }
270
+ if (toolName === "whoami") {
271
+ const status = (io.getAuthStatus ?? getAuthStatus)();
272
+ if (status.subject) {
273
+ io.write(status.subject);
274
+ io.exit(0);
275
+ }
276
+ else {
277
+ io.write(`Error: ${status.message}`);
278
+ io.exit(1);
279
+ }
280
+ return;
281
+ }
289
282
  if (toolName === DOWNLOAD_HISTORY_COMMAND) {
290
283
  if (help) {
291
284
  io.write(buildDownloadHistoryHelp());
@@ -464,7 +457,15 @@ function parseDownloadHistoryArgs(args) {
464
457
  if (args[key] !== undefined)
465
458
  options[key] = Number(args[key]);
466
459
  }
467
- for (const key of ["overwrite", "merge", "keep_chunks", "extended", "dadj", "badj", "settlement"]) {
460
+ for (const key of [
461
+ "overwrite",
462
+ "merge",
463
+ "keep_chunks",
464
+ "extended",
465
+ "dadj",
466
+ "badj",
467
+ "settlement",
468
+ ]) {
468
469
  if (args[key] !== undefined)
469
470
  options[key] = args[key] === "true";
470
471
  }
@@ -476,8 +477,8 @@ function parseDownloadHistoryArgs(args) {
476
477
  export function main() {
477
478
  const rl = createInterface({ input, output });
478
479
  runCli(process.argv.slice(2), {
479
- write: (s) => process.stdout.write(s + "\n"),
480
- progress: (s) => process.stderr.write(s + "\n"),
480
+ write: (s) => process.stdout.write(`${s}\n`),
481
+ progress: (s) => process.stderr.write(`${s}\n`),
481
482
  prompt: (question) => rl.question(question),
482
483
  isInteractive: process.stdin.isTTY && process.stdout.isTTY && process.env.CI !== "true",
483
484
  exit: (code) => process.exit(code),