skim-mcp 0.2.2 → 0.2.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 +24 -1
- package/dist/index.js +44 -1
- package/package.json +9 -10
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://registry.modelcontextprotocol.io/v0/servers?search=skim402)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
|
|
9
|
-
`skim-mcp` is the official Model Context Protocol server for [Skim](https://skim402.com) — the clean reader API for AI agents. It exposes `read_url`, `read_urls` (batch), `extract_url` (structured / table), `crawl_url`, `read_pdf`, `watch_urls`, and `
|
|
9
|
+
`skim-mcp` is the official Model Context Protocol server for [Skim](https://skim402.com) — the clean reader API for AI agents. It exposes `read_url`, `read_urls` (batch), `extract_url` (structured / table), `crawl_url`, `read_pdf`, `watch_urls`, `check_watch`, and `poll_signal`. The default path is a card-plan API key (`SKIM_API_KEY`); x402 wallet pay stays optional.
|
|
10
10
|
|
|
11
11
|
> **See it before you wire it:** [try Skim free in your browser](https://freeskims.skim402.com) — 10 free skims a day, no signup. Paste a URL, see exactly what your agent gets back.
|
|
12
12
|
|
|
@@ -177,6 +177,27 @@ Register 1–20 URLs, then poll for content diffs. `watch_id` is a secret.
|
|
|
177
177
|
|
|
178
178
|
Card-lane `/api/t/watch*` is live (POST without a key returns `401`). Optional HTTPS `webhookUrl` is supported by the API; this MCP tool still sends `{ urls, note? }`.
|
|
179
179
|
|
|
180
|
+
### `poll_signal`
|
|
181
|
+
|
|
182
|
+
Poll a [Skim Signal](https://skim402.com/signals) and return the latest structured items (title, summary, source, timestamp, link, and entities). **2 credits** per successful poll; failed polls are refunded.
|
|
183
|
+
|
|
184
|
+
**Requires `SKIM_API_KEY`.** Wallet-only configs get a clear error: the live `GET /api/v2/...` wallet twin uses a v2 402 with an empty body, which the current `x402-fetch` wrapper does not handle.
|
|
185
|
+
|
|
186
|
+
**Input:** `{ "slug": "ai-news", "limit": 20 }`
|
|
187
|
+
|
|
188
|
+
Optional documented filters: `forms` (SEC filings and campaign finance), `categories` (deals), `fields` (research), `states` (film incentives), and `committees` (campaign finance).
|
|
189
|
+
|
|
190
|
+
**Routes (API key):** `GET /api/t/signal/{slug}/latest?limit=` · `GET /api/t/feeds/x402/latest?limit=` (x402 is not `/signal/x402`)
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
curl -H 'Authorization: Bearer sk402_your_key_here' \
|
|
194
|
+
'https://skim402.com/api/t/signal/ai-news/latest?limit=20'
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
Poll the ai-news Signal for the latest 20 items.
|
|
199
|
+
```
|
|
200
|
+
|
|
180
201
|
### Example agent prompts
|
|
181
202
|
|
|
182
203
|
```
|
|
@@ -190,6 +211,8 @@ Crawl https://example.com (max 10 pages) and list the page titles.
|
|
|
190
211
|
|
|
191
212
|
Read the PDF at https://example.com/paper.pdf and summarize it.
|
|
192
213
|
|
|
214
|
+
Poll the ai-news Signal for the latest 20 items.
|
|
215
|
+
|
|
193
216
|
Watch https://competitor.com/pricing and https://competitor.com/changelog, then check the watch for changes.
|
|
194
217
|
```
|
|
195
218
|
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4
4
|
import { privateKeyToAccount } from "viem/accounts";
|
|
5
5
|
import { wrapFetchWithPayment } from "x402-fetch";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
const VERSION = "0.2.
|
|
7
|
+
const VERSION = "0.2.4";
|
|
8
8
|
const BASE_URL = (process.env.SKIM_API_URL ?? "https://skim402.com").replace(/\/+$/, "");
|
|
9
9
|
const API_KEY = process.env.SKIM_API_KEY ?? "";
|
|
10
10
|
const PRIVATE_KEY = process.env.SKIM_WALLET_PRIVATE_KEY ?? "";
|
|
@@ -154,6 +154,14 @@ function authMissing() {
|
|
|
154
154
|
function cardLaneOnly(tool, path) {
|
|
155
155
|
return fail(`${tool} is card-lane only (${path}) — there is no x402 /v1 twin. Set SKIM_API_KEY (sk402_..., free tier at skim402.com/pricing). Wallet pay still works for read_url, read_urls, extract_url, and watch.`);
|
|
156
156
|
}
|
|
157
|
+
const SIGNAL_SLUGS = [
|
|
158
|
+
"ai-news", "sec-filings", "crypto-news", "macro", "security", "regulations",
|
|
159
|
+
"courts", "recalls", "deals", "launches", "trending", "research", "energy",
|
|
160
|
+
"entertainment", "studio-jobs", "campaign-finance", "film-incentives", "x402",
|
|
161
|
+
];
|
|
162
|
+
function signalPollPath(slug) {
|
|
163
|
+
return slug === "x402" ? "/api/t/feeds/x402/latest" : `/api/t/signal/${slug}/latest`;
|
|
164
|
+
}
|
|
157
165
|
function buildUrl(path, query) {
|
|
158
166
|
const url = new URL(path, `${BASE_URL}/`);
|
|
159
167
|
if (query) {
|
|
@@ -485,6 +493,41 @@ server.tool("check_watch", "Poll a Skim Watch for content changes (or fetch regi
|
|
|
485
493
|
return fail(requestFailedMessage(err));
|
|
486
494
|
}
|
|
487
495
|
});
|
|
496
|
+
server.tool("poll_signal", "Poll a Skim Signal feed and return the latest structured items (title, summary, source, timestamp, link, entities). 2 credits per successful poll; failed polls are refunded. Card lane: GET /api/t/signal/{slug}/latest?limit= (filters: forms, categories, fields, states, committees). The x402 ecosystem feed is GET /api/t/feeds/x402/latest — never /signal/x402. Requires SKIM_API_KEY. No x402-fetch-compatible wallet twin (GET /api/v2/... returns a v2 402 with an empty body).", {
|
|
497
|
+
slug: z.enum(SIGNAL_SLUGS).describe("Signal slug from skim402.com/signals. Use x402 for the ecosystem feed, not /signal/x402."),
|
|
498
|
+
limit: z.number().int().min(1).max(100).optional().describe("Max items, newest-first. Default 50, capped at 100."),
|
|
499
|
+
forms: z.string().optional().describe("Comma-separated form filter. sec-filings: 8-K, S-1, 10-K, 10-Q, SC 13D, SC 13G, 4. campaign-finance: F1, F2, F3, F3P, F3X, F3L, F24, F5, F6, F9, F13, F99."),
|
|
500
|
+
categories: z.string().optional().describe("deals only. Comma-separated category terms (1–8, each 2–40 chars), e.g. laptop,gpu."),
|
|
501
|
+
fields: z.string().optional().describe("research only. Comma-separated arXiv fields: ai, ml, nlp, vision, robotics, agents, security, quantum."),
|
|
502
|
+
states: z.string().optional().describe("film-incentives only. Comma-separated two-letter states: CA, NY, GA, NM, TX."),
|
|
503
|
+
committees: z.string().optional().describe("campaign-finance only. Comma-separated committee-name substrings (1–8, each 2–60 chars), e.g. turning point,dnc."),
|
|
504
|
+
}, async ({ slug, limit, forms, categories, fields, states, committees }) => {
|
|
505
|
+
if (!hasAuth)
|
|
506
|
+
return authMissing();
|
|
507
|
+
if (!cardLane) {
|
|
508
|
+
return fail("poll_signal is card-lane only (GET /api/t/signal/{slug}/latest or GET /api/t/feeds/x402/latest) — set SKIM_API_KEY (sk402_..., free tier at skim402.com/pricing). The wallet twin returns a v2 402 with an empty body, which the existing x402-fetch wrapper does not handle.");
|
|
509
|
+
}
|
|
510
|
+
try {
|
|
511
|
+
const query = {};
|
|
512
|
+
if (limit !== undefined)
|
|
513
|
+
query.limit = String(limit);
|
|
514
|
+
if (forms)
|
|
515
|
+
query.forms = forms;
|
|
516
|
+
if (categories)
|
|
517
|
+
query.categories = categories;
|
|
518
|
+
if (fields)
|
|
519
|
+
query.fields = fields;
|
|
520
|
+
if (states)
|
|
521
|
+
query.states = states;
|
|
522
|
+
if (committees)
|
|
523
|
+
query.committees = committees;
|
|
524
|
+
const res = await skimFetch("GET", signalPollPath(slug), { query });
|
|
525
|
+
return ok(JSON.stringify(await readJson(res), null, 2));
|
|
526
|
+
}
|
|
527
|
+
catch (err) {
|
|
528
|
+
return fail(requestFailedMessage(err));
|
|
529
|
+
}
|
|
530
|
+
});
|
|
488
531
|
const transport = new StdioServerTransport();
|
|
489
532
|
await server.connect(transport);
|
|
490
533
|
if (cardLane) {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skim-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"mcpName": "io.github.JessieJanie/skim402",
|
|
5
|
-
"description": "MCP server for Skim — clean web reader for AI agents. Card API key or x402 wallet. Batch, extract, crawl, PDF, watch.",
|
|
5
|
+
"description": "MCP server for Skim — clean web reader for AI agents. Card API key or x402 wallet. Batch, extract, crawl, PDF, watch, signals.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
8
|
"skim-mcp": "dist/index.js"
|
|
@@ -13,13 +13,6 @@
|
|
|
13
13
|
"README.md",
|
|
14
14
|
"LICENSE"
|
|
15
15
|
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"build": "tsc -p tsconfig.build.json && node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"",
|
|
18
|
-
"typecheck": "tsc --noEmit",
|
|
19
|
-
"dev": "tsx src/index.ts",
|
|
20
|
-
"prepublishOnly": "pnpm build",
|
|
21
|
-
"postinstall": "npm install -g tsx@4.21.0"
|
|
22
|
-
},
|
|
23
16
|
"dependencies": {
|
|
24
17
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
25
18
|
"viem": "^2.21.0",
|
|
@@ -56,5 +49,11 @@
|
|
|
56
49
|
"license": "MIT",
|
|
57
50
|
"engines": {
|
|
58
51
|
"node": ">=18"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc -p tsconfig.build.json && node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"",
|
|
55
|
+
"typecheck": "tsc --noEmit",
|
|
56
|
+
"dev": "tsx src/index.ts",
|
|
57
|
+
"postinstall": "npm install -g tsx@4.21.0"
|
|
59
58
|
}
|
|
60
|
-
}
|
|
59
|
+
}
|