rnkflow-mcp 1.0.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 ADDED
@@ -0,0 +1,115 @@
1
+ # rnkflow-mcp
2
+
3
+ MCP server for [RNKFLOW](https://rnkflow.com) — real-time ranked tech intelligence feed.
4
+
5
+ Get live-ranked stories from Hacker News, arXiv, Dev.to, Ars Technica, Product Hunt, and more, directly inside Claude, Cursor, Windsurf, or any MCP-compatible agent.
6
+
7
+ ## Requirements
8
+
9
+ - Node.js 18+
10
+ - An active [RNKFLOW Pro](https://rnkflow.com) subscription
11
+ - An RNKFLOW API key (Settings > API Keys after subscribing)
12
+
13
+ ## Setup
14
+
15
+ ### Claude Desktop
16
+
17
+ Add to your `claude_desktop_config.json`:
18
+
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "rnkflow": {
23
+ "command": "npx",
24
+ "args": ["-y", "rnkflow-mcp"],
25
+ "env": {
26
+ "RNKFLOW_API_KEY": "rnk_your_key_here"
27
+ }
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ Config file location:
34
+ - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
35
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
36
+
37
+ ### Cursor
38
+
39
+ Add to your `~/.cursor/mcp.json`:
40
+
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "rnkflow": {
45
+ "command": "npx",
46
+ "args": ["-y", "rnkflow-mcp"],
47
+ "env": {
48
+ "RNKFLOW_API_KEY": "rnk_your_key_here"
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ ### Other MCP clients
56
+
57
+ Run directly:
58
+
59
+ ```bash
60
+ RNKFLOW_API_KEY=rnk_your_key_here npx rnkflow-mcp
61
+ ```
62
+
63
+ ## Tools
64
+
65
+ ### `get_feed`
66
+
67
+ Get the current ranked tech feed.
68
+
69
+ | Parameter | Type | Default | Description |
70
+ |------------|--------|---------|-------------|
71
+ | `category` | string | `all` | `all`, `ai`, `tech`, `code`, `science`, `space`, `robotics`, `security`, `showhn` |
72
+ | `limit` | number | `20` | Stories to return (1-50) |
73
+ | `offset` | number | `0` | Pagination offset |
74
+
75
+ ### `list_sources`
76
+
77
+ List all available feed categories with descriptions.
78
+
79
+ ### `search_feed`
80
+
81
+ Search the current feed by keyword.
82
+
83
+ | Parameter | Type | Default | Description |
84
+ |------------|--------|---------|-------------|
85
+ | `query` | string | — | Keyword or phrase to search for |
86
+ | `category` | string | `all` | Limit search to a specific category |
87
+ | `limit` | number | `10` | Maximum results to return |
88
+
89
+ ## Example prompts
90
+
91
+ - "What are the top tech stories right now?"
92
+ - "Show me the latest AI research papers from RNKFLOW"
93
+ - "Search the feed for anything about Rust"
94
+ - "What are people on Hacker News talking about today?"
95
+ - "Show me the top 5 Show HN projects this hour"
96
+
97
+ ## Data sources
98
+
99
+ RNKFLOW aggregates and ranks stories from:
100
+ - Hacker News
101
+ - arXiv (cs.AI, cs.LG, cs.CL, cs.RO, and more)
102
+ - Dev.to
103
+ - Ars Technica
104
+ - Product Hunt
105
+ - New Atlas
106
+ - IEEE Spectrum
107
+ - SpaceNews
108
+ - CISA security alerts
109
+ - and more
110
+
111
+ Rankings update every 5-30 seconds.
112
+
113
+ ## License
114
+
115
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
+ const API_KEY = process.env["RNKFLOW_API_KEY"];
6
+ const API_BASE = process.env["RNKFLOW_API_BASE"] ?? "https://api.rnkflow.com/api";
7
+ if (!API_KEY) {
8
+ process.stderr.write("Error: RNKFLOW_API_KEY environment variable is required.\n" +
9
+ "Get your API key at https://rnkflow.com (Settings > API Keys, Pro subscription required).\n");
10
+ process.exit(1);
11
+ }
12
+ const CATEGORIES = ["all", "ai", "tech", "code", "science", "space", "robotics", "security", "showhn"];
13
+ async function apiFetch(path, init) {
14
+ const res = await fetch(`${API_BASE}${path}`, {
15
+ ...init,
16
+ headers: {
17
+ Authorization: `Bearer ${API_KEY}`,
18
+ "Content-Type": "application/json",
19
+ ...init?.headers,
20
+ },
21
+ });
22
+ if (res.status === 401)
23
+ throw new Error("Invalid API key. Generate one at https://rnkflow.com (Settings > API Keys).");
24
+ if (res.status === 403)
25
+ throw new Error("Active Pro subscription required. Subscribe at https://rnkflow.com.");
26
+ if (res.status === 429)
27
+ throw new Error("Rate limited. Slow down requests or wait a moment.");
28
+ if (!res.ok) {
29
+ const body = await res.json().catch(() => ({}));
30
+ throw new Error(`API error ${res.status}: ${body.error ?? res.statusText}`);
31
+ }
32
+ return res.json();
33
+ }
34
+ function formatStory(s, i) {
35
+ const lines = [`${i}. **${s.title}**`];
36
+ if (s.url)
37
+ lines.push(` ${s.url}`);
38
+ lines.push(` Score: ${s.score} | Comments: ${s.comments} | By: ${s.author} | Source: ${s.source}`);
39
+ if (s.snippet)
40
+ lines.push(` > ${s.snippet.slice(0, 200)}${s.snippet.length > 200 ? "…" : ""}`);
41
+ return lines.join("\n");
42
+ }
43
+ const TOOLS = [
44
+ {
45
+ name: "get_feed",
46
+ description: "Get the current real-time ranked tech feed from RNKFLOW. Returns top stories aggregated from Hacker News, arXiv, Dev.to, Ars Technica, Product Hunt, and more — ranked live by score and recency. Use this to find out what the tech community is reading right now.",
47
+ inputSchema: {
48
+ type: "object",
49
+ properties: {
50
+ category: {
51
+ type: "string",
52
+ enum: CATEGORIES,
53
+ description: "Feed category. 'all' returns the blended hot-takes view. Other options filter by topic.",
54
+ default: "all",
55
+ },
56
+ limit: {
57
+ type: "number",
58
+ minimum: 1,
59
+ maximum: 50,
60
+ description: "Number of stories to return (1-50). Defaults to 20.",
61
+ default: 20,
62
+ },
63
+ offset: {
64
+ type: "number",
65
+ minimum: 0,
66
+ description: "Offset for pagination. Defaults to 0.",
67
+ default: 0,
68
+ },
69
+ },
70
+ },
71
+ },
72
+ {
73
+ name: "list_sources",
74
+ description: "List all available feed categories in RNKFLOW with descriptions of what each covers.",
75
+ inputSchema: {
76
+ type: "object",
77
+ properties: {},
78
+ },
79
+ },
80
+ {
81
+ name: "search_feed",
82
+ description: "Search the current RNKFLOW feed for stories matching a keyword or phrase. Searches across title, domain, and author fields. Returns matching stories ranked by score.",
83
+ inputSchema: {
84
+ type: "object",
85
+ properties: {
86
+ query: {
87
+ type: "string",
88
+ description: "Keyword or phrase to search for.",
89
+ },
90
+ category: {
91
+ type: "string",
92
+ enum: CATEGORIES,
93
+ description: "Limit search to a specific category. Defaults to 'all'.",
94
+ default: "all",
95
+ },
96
+ limit: {
97
+ type: "number",
98
+ minimum: 1,
99
+ maximum: 50,
100
+ description: "Maximum number of matching stories to return. Defaults to 10.",
101
+ default: 10,
102
+ },
103
+ },
104
+ required: ["query"],
105
+ },
106
+ },
107
+ ];
108
+ const server = new Server({ name: "rnkflow", version: "1.0.0" }, { capabilities: { tools: {} } });
109
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
110
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
111
+ const { name, arguments: args = {} } = request.params;
112
+ try {
113
+ if (name === "get_feed") {
114
+ const category = (CATEGORIES.includes(args["category"]) ? args["category"] : "all");
115
+ const limit = Math.min(Math.max(Number(args["limit"] ?? 20), 1), 50);
116
+ const offset = Math.max(Number(args["offset"] ?? 0), 0);
117
+ const data = await apiFetch(`/v1/feed?category=${category}&limit=${limit}&offset=${offset}`);
118
+ const header = `**RNKFLOW — ${data.category === "all" ? "Hot Takes" : data.category.toUpperCase()} feed**\n` +
119
+ `Showing ${data.stories.length} of ${data.meta.total} stories · updated ${data.meta.fetched_at}\n\n`;
120
+ const body = data.stories.map((s, i) => formatStory(s, offset + i + 1)).join("\n\n");
121
+ return { content: [{ type: "text", text: header + body }] };
122
+ }
123
+ if (name === "list_sources") {
124
+ const data = await apiFetch("/v1/sources");
125
+ const text = "**Available RNKFLOW feed categories:**\n\n" +
126
+ data.sources
127
+ .map((s) => `- **${s.label}** (\`${s.id}\`): ${s.description}`)
128
+ .join("\n");
129
+ return { content: [{ type: "text", text }] };
130
+ }
131
+ if (name === "search_feed") {
132
+ const query = String(args["query"] ?? "").trim().toLowerCase();
133
+ if (!query) {
134
+ return { content: [{ type: "text", text: "Please provide a search query." }] };
135
+ }
136
+ const category = (CATEGORIES.includes(args["category"]) ? args["category"] : "all");
137
+ const limit = Math.min(Math.max(Number(args["limit"] ?? 10), 1), 50);
138
+ const data = await apiFetch(`/v1/feed?category=${category}&limit=500`);
139
+ const matches = data.stories.filter((s) => {
140
+ const haystack = `${s.title} ${s.domain ?? ""} ${s.author} ${s.snippet ?? ""}`.toLowerCase();
141
+ return haystack.includes(query);
142
+ }).slice(0, limit);
143
+ if (matches.length === 0) {
144
+ return {
145
+ content: [{ type: "text", text: `No stories found matching "${args["query"]}" in the ${category} feed.` }],
146
+ };
147
+ }
148
+ const text = `**Search results for "${args["query"]}" in ${category} feed** (${matches.length} matches)\n\n` +
149
+ matches.map((s, i) => formatStory(s, i + 1)).join("\n\n");
150
+ return { content: [{ type: "text", text }] };
151
+ }
152
+ return {
153
+ content: [{ type: "text", text: `Unknown tool: ${name}` }],
154
+ isError: true,
155
+ };
156
+ }
157
+ catch (err) {
158
+ return {
159
+ content: [{ type: "text", text: `Error: ${err.message}` }],
160
+ isError: true,
161
+ };
162
+ }
163
+ });
164
+ async function main() {
165
+ const transport = new StdioServerTransport();
166
+ await server.connect(transport);
167
+ process.stderr.write("RNKFLOW MCP server running (stdio)\n");
168
+ }
169
+ main().catch((err) => {
170
+ process.stderr.write(`Fatal: ${err.message}\n`);
171
+ process.exit(1);
172
+ });
173
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "rnkflow-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for RNKFLOW: real-time ranked tech intelligence feed from HN, arXiv, Dev.to, Ars Technica, Product Hunt, and more.",
5
+ "keywords": ["mcp", "rnkflow", "hacker-news", "tech-feed", "ai", "arxiv", "modelcontextprotocol"],
6
+ "homepage": "https://rnkflow.com",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/rnkflow/rnkflow"
10
+ },
11
+ "license": "MIT",
12
+ "type": "module",
13
+ "bin": {
14
+ "rnkflow-mcp": "./dist/index.js"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc && chmod +x dist/index.js",
22
+ "dev": "tsx src/index.ts",
23
+ "prepare": "tsc && chmod +x dist/index.js"
24
+ },
25
+ "dependencies": {
26
+ "@modelcontextprotocol/sdk": "^1.29.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^22.0.0",
30
+ "tsx": "^4.21.0",
31
+ "typescript": "^5.8.0"
32
+ },
33
+ "engines": {
34
+ "node": ">=18"
35
+ }
36
+ }