@pipeworx/mcp-ai-briefing 0.1.2 → 0.1.3
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 +2 -2
- package/package.json +3 -3
- package/server.json +1 -1
- package/src/index.ts +53 -3
- package/src/server.ts +5 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
AI Briefing MCP — Keep AI models current on industry developments
|
|
4
4
|
|
|
5
|
-
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to
|
|
5
|
+
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1786+ live data sources. This is an independent, unofficial integration — not affiliated with, endorsed by, or published by the upstream provider.
|
|
6
6
|
|
|
7
7
|
## Tools
|
|
8
8
|
|
|
@@ -61,7 +61,7 @@ directly, instead of just this one's:
|
|
|
61
61
|
}
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
Both URLs reach the same gateway and the same
|
|
64
|
+
Both URLs reach the same gateway and the same 1786+ data sources. The
|
|
65
65
|
only difference is which pack's tools are listed **directly**; `ask_pipeworx`
|
|
66
66
|
reaches all of them from either one.
|
|
67
67
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipeworx/mcp-ai-briefing",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "AI Briefing MCP — Keep AI models current on industry developments",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@cloudflare/workers-types": "^4.20260405.1"
|
|
27
27
|
},
|
|
28
28
|
"pipeworx": {
|
|
29
|
-
"sourceHash": "v1-
|
|
30
|
-
"sourceCommit": "
|
|
29
|
+
"sourceHash": "v1-53d142ed192e8732003a3dd64e3466c4efc3a6498d947ccc435d84475aa2bbca",
|
|
30
|
+
"sourceCommit": "25e83bad9a91f94df238b7910cd6c46a8143d26d"
|
|
31
31
|
}
|
|
32
32
|
}
|
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.pipeworx-io/ai-briefing",
|
|
4
4
|
"title": "Ai Briefing",
|
|
5
5
|
"description": "AI Briefing MCP — Keep AI models current on industry developments",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.3",
|
|
7
7
|
"websiteUrl": "https://pipeworx.io/packs/ai-briefing",
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/pipeworx-io/mcp-ai-briefing",
|
package/src/index.ts
CHANGED
|
@@ -713,6 +713,37 @@ async function querySupabase(path: string): Promise<unknown> {
|
|
|
713
713
|
return res.json();
|
|
714
714
|
}
|
|
715
715
|
|
|
716
|
+
/**
|
|
717
|
+
* fleet #3041: 4 of 5 AI-lab blog feeds were 404/403 for an unknown period
|
|
718
|
+
* and get_ai_news kept returning a clean 200 with a plausible-looking item
|
|
719
|
+
* count — a dead source read exactly like a quiet news day. The scraper
|
|
720
|
+
* (workers/ai-briefing-scraper) now writes one row per source to
|
|
721
|
+
* `ai_scrape_health` every run; this surfaces it in the response itself so
|
|
722
|
+
* a caller never has to take "no OpenAI/Anthropic/Meta/Mistral items" on
|
|
723
|
+
* faith. Failure here (table missing, query error) returns null rather
|
|
724
|
+
* than throwing — a health-surface outage must never break the main feed.
|
|
725
|
+
*/
|
|
726
|
+
async function getSourceHealth(): Promise<{ partial: boolean; failed_sources: string[]; checked_at: string | null } | null> {
|
|
727
|
+
try {
|
|
728
|
+
const rows = (await querySupabase(
|
|
729
|
+
`ai_scrape_health?select=source,ok,http_status,detail,checked_at&order=checked_at.desc`,
|
|
730
|
+
)) as Array<Record<string, unknown>>;
|
|
731
|
+
if (!Array.isArray(rows) || rows.length === 0) return null;
|
|
732
|
+
const failed = rows.filter((r) => r.ok === false);
|
|
733
|
+
const newest = rows.reduce<string | null>((acc, r) => {
|
|
734
|
+
const c = r.checked_at as string | undefined;
|
|
735
|
+
return c && (!acc || c > acc) ? c : acc;
|
|
736
|
+
}, null);
|
|
737
|
+
return {
|
|
738
|
+
partial: failed.length > 0,
|
|
739
|
+
failed_sources: failed.map((r) => `${r.source}: HTTP ${r.http_status ?? 'n/a'} — ${r.detail}`),
|
|
740
|
+
checked_at: newest,
|
|
741
|
+
};
|
|
742
|
+
} catch {
|
|
743
|
+
return null;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
716
747
|
const tools: McpToolExport['tools'] = [
|
|
717
748
|
{
|
|
718
749
|
name: 'get_briefing',
|
|
@@ -1101,15 +1132,34 @@ async function getAiNews(days: number, limit: number): Promise<unknown> {
|
|
|
1101
1132
|
const newsCategories = ['model_release', 'claude_update', 'funding', 'acquisition', 'policy', 'benchmark', 'news', 'paper'];
|
|
1102
1133
|
const catFilter = newsCategories.map((c) => `category.eq.${c}`).join(',');
|
|
1103
1134
|
|
|
1104
|
-
const devs = await
|
|
1105
|
-
|
|
1106
|
-
|
|
1135
|
+
const [devs, sources] = await Promise.all([
|
|
1136
|
+
querySupabase(
|
|
1137
|
+
`ai_developments?or=(${catFilter})&published_at=gte.${since}&order=published_at.desc&limit=${limit}`
|
|
1138
|
+
) as Promise<Array<Record<string, unknown>>>,
|
|
1139
|
+
getSourceHealth(),
|
|
1140
|
+
]);
|
|
1107
1141
|
|
|
1108
1142
|
return {
|
|
1109
1143
|
feed: 'ai_news',
|
|
1110
1144
|
period: `last ${days} days`,
|
|
1111
1145
|
description: 'AI industry developments — models, funding, policy, research',
|
|
1112
1146
|
total: devs.length,
|
|
1147
|
+
// fleet #3041: a dead lab-blog feed used to read as "no news today" --
|
|
1148
|
+
// this says whether the LAST scrape run actually reached every source.
|
|
1149
|
+
// `sources` is omitted (not faked as healthy) when the health table
|
|
1150
|
+
// could not be read, rather than claiming a status we do not have.
|
|
1151
|
+
...(sources
|
|
1152
|
+
? {
|
|
1153
|
+
sources: {
|
|
1154
|
+
partial: sources.partial,
|
|
1155
|
+
note: sources.partial
|
|
1156
|
+
? `${sources.failed_sources.length} source(s) failed on the last scrape run -- counts above may undercount those sources, not reflect a quiet news day.`
|
|
1157
|
+
: 'all tracked sources reached on the last scrape run.',
|
|
1158
|
+
failed_sources: sources.failed_sources,
|
|
1159
|
+
checked_at: sources.checked_at,
|
|
1160
|
+
},
|
|
1161
|
+
}
|
|
1162
|
+
: {}),
|
|
1113
1163
|
items: devs.map((d) => ({
|
|
1114
1164
|
title: d.title,
|
|
1115
1165
|
summary: d.summary,
|
package/src/server.ts
CHANGED
|
@@ -8,8 +8,9 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
8
8
|
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
9
9
|
import pack from './index.js';
|
|
10
10
|
|
|
11
|
+
|
|
11
12
|
const server = new Server(
|
|
12
|
-
{ name: '@pipeworx/mcp-ai-briefing', version: '0.1.
|
|
13
|
+
{ name: '@pipeworx/mcp-ai-briefing', version: '0.1.3' },
|
|
13
14
|
{ capabilities: { tools: {} } },
|
|
14
15
|
);
|
|
15
16
|
|
|
@@ -24,7 +25,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
24
25
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
25
26
|
const { name, arguments: args } = request.params;
|
|
26
27
|
try {
|
|
27
|
-
const
|
|
28
|
+
const callArgs = { ...((args ?? {}) as Record<string, unknown>) };
|
|
29
|
+
|
|
30
|
+
const result = await pack.callTool(name, callArgs);
|
|
28
31
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
29
32
|
} catch (err) {
|
|
30
33
|
return {
|