@techsnif/mcp-server 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 +105 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +247 -0
- package/dist/index.js.map +1 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# @techsnif/mcp-server
|
|
2
|
+
|
|
3
|
+
MCP server for [TechSnif](https://techsnif.com) — access tech news articles from AI assistants like Claude Desktop, Cursor, and any MCP-compatible client.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
This server gives your AI assistant access to TechSnif's tech news feed. It can:
|
|
8
|
+
|
|
9
|
+
- **Get latest articles** — optionally filtered by category (AI, Startups, Venture, Robotics) or tag (Crypto, Space, EVs, etc.)
|
|
10
|
+
- **Read full articles** — get the complete text of any article
|
|
11
|
+
- **Get trending stories** — see what's hot in the last 48 hours
|
|
12
|
+
- **Search articles** — find articles by keyword
|
|
13
|
+
|
|
14
|
+
## Setup
|
|
15
|
+
|
|
16
|
+
### Claude Desktop
|
|
17
|
+
|
|
18
|
+
Add this to your Claude Desktop config file:
|
|
19
|
+
|
|
20
|
+
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
21
|
+
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"mcpServers": {
|
|
26
|
+
"techsnif": {
|
|
27
|
+
"command": "npx",
|
|
28
|
+
"args": ["-y", "@techsnif/mcp-server"]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Cursor
|
|
35
|
+
|
|
36
|
+
Add this to `.cursor/mcp.json` in your project (or globally):
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"mcpServers": {
|
|
41
|
+
"techsnif": {
|
|
42
|
+
"command": "npx",
|
|
43
|
+
"args": ["-y", "@techsnif/mcp-server"]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Other MCP clients
|
|
50
|
+
|
|
51
|
+
Run the server directly:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx @techsnif/mcp-server
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The server uses stdio transport, compatible with any MCP client.
|
|
58
|
+
|
|
59
|
+
## Available tools
|
|
60
|
+
|
|
61
|
+
| Tool | Description |
|
|
62
|
+
|------|-------------|
|
|
63
|
+
| `get_latest_articles` | Get latest articles with optional category/tag filters |
|
|
64
|
+
| `get_article` | Get full article content by slug |
|
|
65
|
+
| `get_trending_articles` | Get trending articles from the last 48 hours |
|
|
66
|
+
| `search_articles` | Search articles by keyword |
|
|
67
|
+
|
|
68
|
+
## Available resources
|
|
69
|
+
|
|
70
|
+
| Resource | Description |
|
|
71
|
+
|----------|-------------|
|
|
72
|
+
| `techsnif://categories` | List of all categories with descriptions |
|
|
73
|
+
| `techsnif://tags` | List of all tags with descriptions |
|
|
74
|
+
|
|
75
|
+
## Example prompts
|
|
76
|
+
|
|
77
|
+
Once connected, try asking your AI assistant:
|
|
78
|
+
|
|
79
|
+
- "What's the latest AI news on TechSnif?"
|
|
80
|
+
- "Search TechSnif for articles about OpenAI"
|
|
81
|
+
- "What's trending in tech right now?"
|
|
82
|
+
- "Get me the full article about [topic]"
|
|
83
|
+
- "Summarize the latest robotics news from TechSnif"
|
|
84
|
+
|
|
85
|
+
## Configuration
|
|
86
|
+
|
|
87
|
+
Set `TECHSNIF_API_URL` to override the default API base URL (defaults to `https://techsnif.com`):
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"mcpServers": {
|
|
92
|
+
"techsnif": {
|
|
93
|
+
"command": "npx",
|
|
94
|
+
"args": ["-y", "@techsnif/mcp-server"],
|
|
95
|
+
"env": {
|
|
96
|
+
"TECHSNIF_API_URL": "http://localhost:4321"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* TechSnif MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Exposes TechSnif tech news articles to AI assistants via the
|
|
6
|
+
* Model Context Protocol. Connects to the public techsnif.com API.
|
|
7
|
+
*
|
|
8
|
+
* Tools:
|
|
9
|
+
* - get_latest_articles — fetch latest articles, optionally filtered by category or tag
|
|
10
|
+
* - get_article — get full article content by slug
|
|
11
|
+
* - get_trending_articles — get trending articles from the last 48 hours
|
|
12
|
+
* - search_articles — search articles by keyword
|
|
13
|
+
*
|
|
14
|
+
* Resources:
|
|
15
|
+
* - techsnif://categories — list of all article categories
|
|
16
|
+
* - techsnif://tags — list of all article tags
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* TechSnif MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Exposes TechSnif tech news articles to AI assistants via the
|
|
6
|
+
* Model Context Protocol. Connects to the public techsnif.com API.
|
|
7
|
+
*
|
|
8
|
+
* Tools:
|
|
9
|
+
* - get_latest_articles — fetch latest articles, optionally filtered by category or tag
|
|
10
|
+
* - get_article — get full article content by slug
|
|
11
|
+
* - get_trending_articles — get trending articles from the last 48 hours
|
|
12
|
+
* - search_articles — search articles by keyword
|
|
13
|
+
*
|
|
14
|
+
* Resources:
|
|
15
|
+
* - techsnif://categories — list of all article categories
|
|
16
|
+
* - techsnif://tags — list of all article tags
|
|
17
|
+
*/
|
|
18
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
19
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
20
|
+
import { z } from 'zod';
|
|
21
|
+
import { CATEGORIES, CATEGORY_NAMES, TAGS, TAG_NAMES } from '@techsnif/shared';
|
|
22
|
+
const BASE_URL = process.env.TECHSNIF_API_URL || 'https://techsnif.com';
|
|
23
|
+
async function apiFetch(path, params) {
|
|
24
|
+
const url = new URL(`${BASE_URL}${path}`);
|
|
25
|
+
if (params) {
|
|
26
|
+
for (const [key, value] of Object.entries(params)) {
|
|
27
|
+
if (value)
|
|
28
|
+
url.searchParams.set(key, value);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const response = await fetch(url.toString(), {
|
|
32
|
+
headers: { Accept: 'application/json' },
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
const body = await response.text().catch(() => '');
|
|
36
|
+
throw new Error(`API request failed: ${response.status} ${response.statusText} — ${body}`);
|
|
37
|
+
}
|
|
38
|
+
return response.json();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Strip HTML tags for cleaner AI consumption.
|
|
42
|
+
* Preserves paragraph breaks as double newlines.
|
|
43
|
+
*/
|
|
44
|
+
function stripHtml(html) {
|
|
45
|
+
return html
|
|
46
|
+
.replace(/<br\s*\/?>/gi, '\n')
|
|
47
|
+
.replace(/<\/p>/gi, '\n\n')
|
|
48
|
+
.replace(/<[^>]+>/g, '')
|
|
49
|
+
.replace(/&/g, '&')
|
|
50
|
+
.replace(/</g, '<')
|
|
51
|
+
.replace(/>/g, '>')
|
|
52
|
+
.replace(/"/g, '"')
|
|
53
|
+
.replace(/'/g, "'")
|
|
54
|
+
.replace(/ /g, ' ')
|
|
55
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
56
|
+
.trim();
|
|
57
|
+
}
|
|
58
|
+
function formatDate(iso) {
|
|
59
|
+
const d = new Date(iso);
|
|
60
|
+
return d.toLocaleDateString('en-US', {
|
|
61
|
+
weekday: 'short',
|
|
62
|
+
year: 'numeric',
|
|
63
|
+
month: 'short',
|
|
64
|
+
day: 'numeric',
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function articleUrl(article) {
|
|
68
|
+
const d = new Date(article.publishedAt);
|
|
69
|
+
const year = d.getUTCFullYear();
|
|
70
|
+
const month = String(d.getUTCMonth() + 1).padStart(2, '0');
|
|
71
|
+
const day = String(d.getUTCDate()).padStart(2, '0');
|
|
72
|
+
return `${BASE_URL}/${year}/${month}/${day}/${article.slug}`;
|
|
73
|
+
}
|
|
74
|
+
function formatArticleSummary(article) {
|
|
75
|
+
const lines = [
|
|
76
|
+
`## ${article.title}`,
|
|
77
|
+
'',
|
|
78
|
+
article.excerpt,
|
|
79
|
+
'',
|
|
80
|
+
`- **Category:** ${article.category}`,
|
|
81
|
+
];
|
|
82
|
+
if (article.tags?.length) {
|
|
83
|
+
lines.push(`- **Tags:** ${article.tags.join(', ')}`);
|
|
84
|
+
}
|
|
85
|
+
if (article.sources?.length) {
|
|
86
|
+
lines.push(`- **Sources:** ${article.sources.join(', ')}`);
|
|
87
|
+
}
|
|
88
|
+
lines.push(`- **Published:** ${formatDate(article.publishedAt)}`);
|
|
89
|
+
lines.push(`- **URL:** ${articleUrl(article)}`);
|
|
90
|
+
lines.push(`- **Slug:** ${article.slug}`);
|
|
91
|
+
return lines.join('\n');
|
|
92
|
+
}
|
|
93
|
+
function formatArticleFull(article) {
|
|
94
|
+
const lines = [
|
|
95
|
+
`# ${article.title}`,
|
|
96
|
+
'',
|
|
97
|
+
`> ${article.excerpt}`,
|
|
98
|
+
'',
|
|
99
|
+
stripHtml(article.content),
|
|
100
|
+
'',
|
|
101
|
+
'---',
|
|
102
|
+
'',
|
|
103
|
+
`- **Category:** ${article.category}`,
|
|
104
|
+
];
|
|
105
|
+
if (article.tags?.length) {
|
|
106
|
+
lines.push(`- **Tags:** ${article.tags.join(', ')}`);
|
|
107
|
+
}
|
|
108
|
+
if (article.sources?.length) {
|
|
109
|
+
lines.push(`- **Sources:** ${article.sources.join(', ')}`);
|
|
110
|
+
}
|
|
111
|
+
if (article.sourceLinks?.length) {
|
|
112
|
+
const links = article.sourceLinks.map(l => `[${l.name}](${l.url})`).join(', ');
|
|
113
|
+
lines.push(`- **Source links:** ${links}`);
|
|
114
|
+
}
|
|
115
|
+
lines.push(`- **Published:** ${formatDate(article.publishedAt)}`);
|
|
116
|
+
lines.push(`- **URL:** ${article.url}`);
|
|
117
|
+
if (article.isSponsored) {
|
|
118
|
+
lines.push(`- **Sponsored:** Yes`);
|
|
119
|
+
}
|
|
120
|
+
return lines.join('\n');
|
|
121
|
+
}
|
|
122
|
+
// ─── MCP Server ──────────────────────────────────────────────
|
|
123
|
+
const server = new McpServer({
|
|
124
|
+
name: 'techsnif',
|
|
125
|
+
version: '1.0.0',
|
|
126
|
+
});
|
|
127
|
+
// ─── Tools ───────────────────────────────────────────────────
|
|
128
|
+
server.tool('get_latest_articles', 'Get the latest tech news articles from TechSnif. Optionally filter by category (AI, Startups, Venture, Robotics) or tag (Crypto, Space, EVs, Biotech, etc.).', {
|
|
129
|
+
category: z.string().optional().describe('Filter by category: AI, Startups, Venture, or Robotics'),
|
|
130
|
+
tag: z.string().optional().describe('Filter by tag (e.g. Crypto, Space, EVs, Biotech, Cloud Computing)'),
|
|
131
|
+
limit: z.number().min(1).max(50).default(10).describe('Number of articles to return (default 10, max 50)'),
|
|
132
|
+
}, async ({ category, tag, limit }) => {
|
|
133
|
+
const params = { limit: String(limit) };
|
|
134
|
+
if (category)
|
|
135
|
+
params.category = category;
|
|
136
|
+
if (tag)
|
|
137
|
+
params.tag = tag;
|
|
138
|
+
const data = await apiFetch('/api/articles', params);
|
|
139
|
+
if (!data.articles.length) {
|
|
140
|
+
const filter = category ? ` in category "${category}"` : tag ? ` tagged "${tag}"` : '';
|
|
141
|
+
return {
|
|
142
|
+
content: [{ type: 'text', text: `No articles found${filter}.` }],
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const header = `Found ${data.total} article${data.total === 1 ? '' : 's'}${category ? ` in ${category}` : tag ? ` tagged ${tag}` : ''}. Showing ${data.articles.length}:\n\n`;
|
|
146
|
+
const formatted = data.articles.map(formatArticleSummary).join('\n\n---\n\n');
|
|
147
|
+
return {
|
|
148
|
+
content: [{ type: 'text', text: header + formatted }],
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
server.tool('get_article', 'Get the full content of a specific TechSnif article by its slug. Use this to read the complete article text.', {
|
|
152
|
+
slug: z.string().describe('The article slug (e.g. "openai-announces-gpt-5")'),
|
|
153
|
+
}, async ({ slug }) => {
|
|
154
|
+
const data = await apiFetch(`/api/articles/${encodeURIComponent(slug)}`);
|
|
155
|
+
return {
|
|
156
|
+
content: [{ type: 'text', text: formatArticleFull(data.article) }],
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
server.tool('get_trending_articles', 'Get trending tech news articles from the last 48 hours, ranked by how many sources covered the story.', {
|
|
160
|
+
limit: z.number().min(1).max(20).default(5).describe('Number of articles to return (default 5, max 20)'),
|
|
161
|
+
}, async ({ limit }) => {
|
|
162
|
+
const data = await apiFetch('/api/articles/trending', { limit: String(limit) });
|
|
163
|
+
if (!data.articles.length) {
|
|
164
|
+
return {
|
|
165
|
+
content: [{ type: 'text', text: 'No trending articles found in the last 48 hours.' }],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const header = `Top ${data.articles.length} trending article${data.articles.length === 1 ? '' : 's'}:\n\n`;
|
|
169
|
+
const formatted = data.articles.map((a, i) => `### #${i + 1}\n\n${formatArticleSummary(a)}`).join('\n\n---\n\n');
|
|
170
|
+
return {
|
|
171
|
+
content: [{ type: 'text', text: header + formatted }],
|
|
172
|
+
};
|
|
173
|
+
});
|
|
174
|
+
server.tool('search_articles', 'Search TechSnif articles by keyword. Matches against article titles and excerpts.', {
|
|
175
|
+
query: z.string().min(2).describe('Search query (min 2 characters)'),
|
|
176
|
+
limit: z.number().min(1).max(50).default(10).describe('Max results to return (default 10, max 50)'),
|
|
177
|
+
}, async ({ query, limit }) => {
|
|
178
|
+
const data = await apiFetch('/api/articles/search', { q: query, limit: String(limit) });
|
|
179
|
+
if (!data.articles.length) {
|
|
180
|
+
return {
|
|
181
|
+
content: [{ type: 'text', text: `No articles found matching "${query}".` }],
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const header = `Found ${data.total} article${data.total === 1 ? '' : 's'} matching "${query}":\n\n`;
|
|
185
|
+
const formatted = data.articles
|
|
186
|
+
.map(a => {
|
|
187
|
+
const lines = [
|
|
188
|
+
`## ${a.title}`,
|
|
189
|
+
'',
|
|
190
|
+
a.excerpt,
|
|
191
|
+
'',
|
|
192
|
+
`- **Category:** ${a.category}`,
|
|
193
|
+
`- **Published:** ${formatDate(a.publishedAt)}`,
|
|
194
|
+
`- **URL:** ${articleUrl(a)}`,
|
|
195
|
+
`- **Slug:** ${a.slug}`,
|
|
196
|
+
];
|
|
197
|
+
return lines.join('\n');
|
|
198
|
+
})
|
|
199
|
+
.join('\n\n---\n\n');
|
|
200
|
+
return {
|
|
201
|
+
content: [{ type: 'text', text: header + formatted }],
|
|
202
|
+
};
|
|
203
|
+
});
|
|
204
|
+
// ─── Resources ───────────────────────────────────────────────
|
|
205
|
+
server.resource('categories', 'techsnif://categories', { description: 'List of all TechSnif article categories with descriptions' }, async () => {
|
|
206
|
+
const lines = CATEGORY_NAMES.map(key => {
|
|
207
|
+
const cat = CATEGORIES[key];
|
|
208
|
+
return [
|
|
209
|
+
`## ${cat.label}`,
|
|
210
|
+
'',
|
|
211
|
+
cat.description,
|
|
212
|
+
'',
|
|
213
|
+
`- **Slug:** ${cat.slug}`,
|
|
214
|
+
`- **URL:** ${BASE_URL}/category/${cat.slug}`,
|
|
215
|
+
].join('\n');
|
|
216
|
+
});
|
|
217
|
+
return {
|
|
218
|
+
contents: [{
|
|
219
|
+
uri: 'techsnif://categories',
|
|
220
|
+
mimeType: 'text/plain',
|
|
221
|
+
text: `# TechSnif Categories\n\n${lines.join('\n\n---\n\n')}`,
|
|
222
|
+
}],
|
|
223
|
+
};
|
|
224
|
+
});
|
|
225
|
+
server.resource('tags', 'techsnif://tags', { description: 'List of all TechSnif article tags with descriptions' }, async () => {
|
|
226
|
+
const lines = TAG_NAMES.map(key => {
|
|
227
|
+
const tag = TAGS[key];
|
|
228
|
+
return `- **${tag.label}:** ${tag.description}`;
|
|
229
|
+
});
|
|
230
|
+
return {
|
|
231
|
+
contents: [{
|
|
232
|
+
uri: 'techsnif://tags',
|
|
233
|
+
mimeType: 'text/plain',
|
|
234
|
+
text: `# TechSnif Tags\n\n${lines.join('\n')}`,
|
|
235
|
+
}],
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
// ─── Start ───────────────────────────────────────────────────
|
|
239
|
+
async function main() {
|
|
240
|
+
const transport = new StdioServerTransport();
|
|
241
|
+
await server.connect(transport);
|
|
242
|
+
}
|
|
243
|
+
main().catch((error) => {
|
|
244
|
+
console.error('Failed to start TechSnif MCP server:', error);
|
|
245
|
+
process.exit(1);
|
|
246
|
+
});
|
|
247
|
+
//# 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,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@techsnif/mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for TechSnif — access tech news articles from AI assistants like Claude Desktop and Cursor.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"techsnif-mcp": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"dev": "tsc --watch",
|
|
15
|
+
"start": "node dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
19
|
+
"@techsnif/shared": "workspace:*",
|
|
20
|
+
"zod": "^3.23.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"typescript": "^5.7.0"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20"
|
|
27
|
+
},
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"keywords": [
|
|
30
|
+
"mcp",
|
|
31
|
+
"model-context-protocol",
|
|
32
|
+
"techsnif",
|
|
33
|
+
"tech-news",
|
|
34
|
+
"ai",
|
|
35
|
+
"claude",
|
|
36
|
+
"cursor"
|
|
37
|
+
]
|
|
38
|
+
}
|