@signal4/s4 2.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 +92 -0
- package/bin/s4.js +7 -0
- package/bin/signal4-mcp.js +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +737 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +194 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +397 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +37 -0
- package/dist/config.js.map +1 -0
- package/dist/format.d.ts +60 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +682 -0
- package/dist/format.js.map +1 -0
- package/dist/handler_types.d.ts +11 -0
- package/dist/handler_types.d.ts.map +1 -0
- package/dist/handler_types.js +3 -0
- package/dist/handler_types.js.map +1 -0
- package/dist/handlers/ads.d.ts +4 -0
- package/dist/handlers/ads.d.ts.map +1 -0
- package/dist/handlers/ads.js +42 -0
- package/dist/handlers/ads.js.map +1 -0
- package/dist/handlers/analyze.d.ts +8 -0
- package/dist/handlers/analyze.d.ts.map +1 -0
- package/dist/handlers/analyze.js +77 -0
- package/dist/handlers/analyze.js.map +1 -0
- package/dist/handlers/bookmarks.d.ts +4 -0
- package/dist/handlers/bookmarks.d.ts.map +1 -0
- package/dist/handlers/bookmarks.js +42 -0
- package/dist/handlers/bookmarks.js.map +1 -0
- package/dist/handlers/claims.d.ts +4 -0
- package/dist/handlers/claims.d.ts.map +1 -0
- package/dist/handlers/claims.js +47 -0
- package/dist/handlers/claims.js.map +1 -0
- package/dist/handlers/explore.d.ts +9 -0
- package/dist/handlers/explore.d.ts.map +1 -0
- package/dist/handlers/explore.js +120 -0
- package/dist/handlers/explore.js.map +1 -0
- package/dist/handlers/registry.d.ts +4 -0
- package/dist/handlers/registry.d.ts.map +1 -0
- package/dist/handlers/registry.js +33 -0
- package/dist/handlers/registry.js.map +1 -0
- package/dist/handlers/reports.d.ts +9 -0
- package/dist/handlers/reports.d.ts.map +1 -0
- package/dist/handlers/reports.js +160 -0
- package/dist/handlers/reports.js.map +1 -0
- package/dist/handlers/search.d.ts +5 -0
- package/dist/handlers/search.d.ts.map +1 -0
- package/dist/handlers/search.js +128 -0
- package/dist/handlers/search.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +482 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/** Report handlers: stats, top-channels, top-speakers, network, topics, project-stats */
|
|
2
|
+
import * as client from "../client.js";
|
|
3
|
+
import { fmtHours, fmtTime, formatTopics } from "../format.js";
|
|
4
|
+
function extractSpeakers(data) {
|
|
5
|
+
if (Array.isArray(data))
|
|
6
|
+
return data;
|
|
7
|
+
return data.speakers ?? data.results ?? [];
|
|
8
|
+
}
|
|
9
|
+
function extractChannels(data) {
|
|
10
|
+
if (Array.isArray(data))
|
|
11
|
+
return data;
|
|
12
|
+
return data.channels ?? data.results ?? [];
|
|
13
|
+
}
|
|
14
|
+
export async function handleGetPlatformStats(params) {
|
|
15
|
+
const days = params.days ?? 30;
|
|
16
|
+
const data = await client.getReportStats(days);
|
|
17
|
+
const t = data.totals ?? {};
|
|
18
|
+
const lines = [`**Platform stats (last ${days} days)**\n`];
|
|
19
|
+
lines.push(`- Episodes: ${(t.episodes ?? 0).toLocaleString()}`);
|
|
20
|
+
lines.push(`- Channels: ${(t.channels ?? 0).toLocaleString()}`);
|
|
21
|
+
lines.push(`- Speakers: ${(t.speakers ?? 0).toLocaleString()}`);
|
|
22
|
+
if (t.identified_speakers != null)
|
|
23
|
+
lines.push(`- Identified: ${t.identified_speakers.toLocaleString()}`);
|
|
24
|
+
if (t.claims != null)
|
|
25
|
+
lines.push(`- Claims: ${t.claims.toLocaleString()} (${(t.claim_observations ?? 0).toLocaleString()} observations)`);
|
|
26
|
+
if (t.duration_hours)
|
|
27
|
+
lines.push(`- Duration: ${t.duration_hours.toLocaleString(undefined, { maximumFractionDigits: 1 })} hours`);
|
|
28
|
+
const byPlat = data.by_platform ?? {};
|
|
29
|
+
for (const [plat, info] of Object.entries(byPlat)) {
|
|
30
|
+
lines.push(`- ${plat}: ${(info.episodes ?? 0).toLocaleString()} eps, ${info.channels ?? 0} channels, ${(info.duration_hours ?? 0).toLocaleString(undefined, { maximumFractionDigits: 1 })}h`);
|
|
31
|
+
}
|
|
32
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
33
|
+
}
|
|
34
|
+
export async function handleGetProjectStats(_params) {
|
|
35
|
+
const data = await client.getProjectStats();
|
|
36
|
+
function fmtSection(label, rows) {
|
|
37
|
+
const lines = [`\n**${label}**`];
|
|
38
|
+
for (const r of rows) {
|
|
39
|
+
const name = r.project === "_all" ? "ALL PROJECTS" : r.project;
|
|
40
|
+
lines.push(`- ${name}: ${r.episodes.toLocaleString()} eps, ${r.channels.toLocaleString()} channels, ` +
|
|
41
|
+
`${r.speakers.toLocaleString()} speakers, ${r.duration_hours.toLocaleString(undefined, { maximumFractionDigits: 1 })}h ` +
|
|
42
|
+
`(podcast: ${r.podcast_episodes.toLocaleString()}, youtube: ${r.youtube_episodes.toLocaleString()})`);
|
|
43
|
+
}
|
|
44
|
+
return lines;
|
|
45
|
+
}
|
|
46
|
+
const lines = ["**Project Statistics**"];
|
|
47
|
+
lines.push(...fmtSection("Last 30 days", data.last_30d ?? []));
|
|
48
|
+
lines.push(...fmtSection("All time", data.all_time ?? []));
|
|
49
|
+
if (data.refreshed_at)
|
|
50
|
+
lines.push(`\n_Refreshed: ${data.refreshed_at}_`);
|
|
51
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
52
|
+
}
|
|
53
|
+
export async function handleGetTopChannels(params) {
|
|
54
|
+
const days = params.days ?? 30;
|
|
55
|
+
const limit = params.limit ?? 15;
|
|
56
|
+
const language = params.language;
|
|
57
|
+
const includeCharts = params.include_charts ?? false;
|
|
58
|
+
if (includeCharts) {
|
|
59
|
+
const data = await client.getChannelOverview({ days, limit });
|
|
60
|
+
const summary = data.summary ?? {};
|
|
61
|
+
const lines = [`**Channel overview (last ${days} days)**\n`];
|
|
62
|
+
lines.push(`Total channels: ${summary.total_channels ?? "?"}`);
|
|
63
|
+
lines.push(`Total hours: ${(summary.total_hours ?? 0).toLocaleString(undefined, { maximumFractionDigits: 1 })}`);
|
|
64
|
+
const charting = data.charting_channels ?? [];
|
|
65
|
+
if (charting.length) {
|
|
66
|
+
lines.push("\n**Charting:**");
|
|
67
|
+
for (let i = 0; i < Math.min(charting.length, limit); i++) {
|
|
68
|
+
const ch = charting[i];
|
|
69
|
+
lines.push(`${i + 1}. ${ch.name ?? "?"} (rank #${ch.best_rank ?? "?"}, ${ch.episode_count ?? 0} eps)`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
73
|
+
}
|
|
74
|
+
const data = await client.getTopChannels({ days, limit, language });
|
|
75
|
+
const channels = extractChannels(data);
|
|
76
|
+
const langLabel = language ? `, language=${language}` : "";
|
|
77
|
+
const lines = [`**Top channels (last ${days} days${langLabel})**\n`];
|
|
78
|
+
for (let i = 0; i < channels.length; i++) {
|
|
79
|
+
const ch = channels[i];
|
|
80
|
+
const name = ch.display_name ?? ch.name ?? "?";
|
|
81
|
+
const count = ch.episode_count ?? ch.episodes ?? "?";
|
|
82
|
+
lines.push(`${String(i + 1).padStart(2)}. ${name} (${count} episodes)`);
|
|
83
|
+
}
|
|
84
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
85
|
+
}
|
|
86
|
+
export async function handleGetTopSpeakers(params) {
|
|
87
|
+
const days = params.days ?? 30;
|
|
88
|
+
const limit = params.limit ?? 15;
|
|
89
|
+
const ranking = params.ranking ?? "appearances";
|
|
90
|
+
const data = await client.getTopSpeakers({ days, limit, ranking });
|
|
91
|
+
const speakers = extractSpeakers(data);
|
|
92
|
+
if (ranking === "talkative") {
|
|
93
|
+
const lines = [`**Most talkative speakers (last ${days} days)**\n`];
|
|
94
|
+
for (let i = 0; i < speakers.length; i++) {
|
|
95
|
+
const s = speakers[i];
|
|
96
|
+
const dur = fmtHours(s.total_duration_seconds ?? 0);
|
|
97
|
+
const eps = s.episode_count ?? 0;
|
|
98
|
+
lines.push(`${String(i + 1).padStart(2)}. ${s.name ?? s.primary_name ?? "?"} — ${dur} across ${eps} episodes`);
|
|
99
|
+
}
|
|
100
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
101
|
+
}
|
|
102
|
+
if (ranking === "clipped") {
|
|
103
|
+
const lines = [`**Most clipped speakers (last ${days} days)**\n`];
|
|
104
|
+
for (let i = 0; i < speakers.length; i++) {
|
|
105
|
+
const s = speakers[i];
|
|
106
|
+
const clips = s.recent_appearances ?? s.appearance_count ?? s.appearances ?? "?";
|
|
107
|
+
lines.push(`${String(i + 1).padStart(2)}. ${s.name ?? s.primary_name ?? "?"} (${clips} clips)`);
|
|
108
|
+
}
|
|
109
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
110
|
+
}
|
|
111
|
+
// Default: appearances
|
|
112
|
+
const lines = [`**Top speakers (last ${days} days)**\n`];
|
|
113
|
+
for (let i = 0; i < speakers.length; i++) {
|
|
114
|
+
const s = speakers[i];
|
|
115
|
+
const count = s.recent_appearances ?? s.appearance_count ?? s.appearances ?? "?";
|
|
116
|
+
const dur = s.total_duration;
|
|
117
|
+
const extra = dur ? `, ${fmtTime(dur)}` : "";
|
|
118
|
+
lines.push(`${String(i + 1).padStart(2)}. ${s.name ?? s.primary_name ?? "?"} (${count} appearances${extra})`);
|
|
119
|
+
}
|
|
120
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
121
|
+
}
|
|
122
|
+
export async function handleGetSpeakerNetwork(params) {
|
|
123
|
+
const days = params.days ?? 30;
|
|
124
|
+
const limit = params.limit ?? 20;
|
|
125
|
+
const language = params.language ?? "en";
|
|
126
|
+
const data = await client.getSpeakerNetwork({ days, limit, language });
|
|
127
|
+
const names = new Map();
|
|
128
|
+
for (const n of data.nodes)
|
|
129
|
+
names.set(n.id ?? n.speaker_id ?? 0, n.name ?? "?");
|
|
130
|
+
const connCount = new Map();
|
|
131
|
+
for (const e of data.edges) {
|
|
132
|
+
for (const nid of [e.source, e.target]) {
|
|
133
|
+
if (nid != null)
|
|
134
|
+
connCount.set(nid, (connCount.get(nid) ?? 0) + 1);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const lines = [`**Speaker network: ${data.nodes.length} speakers, ${data.edges.length} connections**\n`];
|
|
138
|
+
const topConnected = [...connCount.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10);
|
|
139
|
+
lines.push("**Most connected:**");
|
|
140
|
+
for (const [nid, count] of topConnected) {
|
|
141
|
+
lines.push(`- ${names.get(nid) ?? "?"} (${count} connections)`);
|
|
142
|
+
}
|
|
143
|
+
const sorted = [...data.edges].sort((a, b) => (b.weight ?? 0) - (a.weight ?? 0));
|
|
144
|
+
lines.push("\n**Strongest connections:**");
|
|
145
|
+
for (const e of sorted.slice(0, 20)) {
|
|
146
|
+
const src = names.get(e.source ?? 0) ?? "?";
|
|
147
|
+
const tgt = names.get(e.target ?? 0) ?? "?";
|
|
148
|
+
lines.push(`- ${src} ↔ ${tgt} (${e.weight ?? 0} co-appearances)`);
|
|
149
|
+
}
|
|
150
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
151
|
+
}
|
|
152
|
+
export async function handleGetTopics(params) {
|
|
153
|
+
const language = params.language ?? "en";
|
|
154
|
+
const limit = params.limit ?? 20;
|
|
155
|
+
const minSegments = params.min_segments ?? 50;
|
|
156
|
+
const category = params.category;
|
|
157
|
+
const data = await client.getTopics({ language, limit, min_segments: minSegments, category });
|
|
158
|
+
return { content: [{ type: "text", text: formatTopics(data.topics, data.total_clusters, data.partition) }] };
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=reports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/handlers/reports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Search handlers: search_quotes, detect_trend */
|
|
2
|
+
import type { CallToolResult } from "../handler_types.js";
|
|
3
|
+
export declare function handleSearchQuotes(params: Record<string, unknown>): Promise<CallToolResult>;
|
|
4
|
+
export declare function handleDetectTrend(params: Record<string, unknown>): Promise<CallToolResult>;
|
|
5
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/handlers/search.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAInD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAiGjG;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAgChG"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/** Search handlers: search_quotes, detect_trend */
|
|
2
|
+
import * as client from "../client.js";
|
|
3
|
+
import { formatQuotes, emptyStateSuggestions, fmtDate } from "../format.js";
|
|
4
|
+
export async function handleSearchQuotes(params) {
|
|
5
|
+
const topic = params.topic;
|
|
6
|
+
const speakerName = params.speaker_name;
|
|
7
|
+
const speakerId = params.speaker_id;
|
|
8
|
+
const channelName = params.channel_name;
|
|
9
|
+
const days = params.days ?? 30;
|
|
10
|
+
const startDate = params.start_date ?? new Date(Date.now() - days * 86400000).toISOString().slice(0, 10);
|
|
11
|
+
const endDate = params.end_date ?? new Date().toISOString().slice(0, 10);
|
|
12
|
+
const minSimilarity = params.min_similarity;
|
|
13
|
+
const limit = params.limit ?? 20;
|
|
14
|
+
const offset = params.offset ?? 0;
|
|
15
|
+
const countOnly = params.count_only ?? false;
|
|
16
|
+
const sort = params.sort ?? "relevance";
|
|
17
|
+
const mode = params.mode ?? "semantic";
|
|
18
|
+
if (!topic && !speakerName && !speakerId) {
|
|
19
|
+
return { content: [{ type: "text", text: "Error: provide at least one of `topic`, `speaker_name`, or `speaker_id`." }] };
|
|
20
|
+
}
|
|
21
|
+
// Chronological speaker timeline
|
|
22
|
+
if (sort === "chronological" && (speakerId || speakerName) && !topic) {
|
|
23
|
+
let sid = speakerId;
|
|
24
|
+
if (!sid && speakerName) {
|
|
25
|
+
const byName = await client.getSpeakerByName(speakerName);
|
|
26
|
+
sid = byName.speaker_id ?? byName.id;
|
|
27
|
+
if (!sid)
|
|
28
|
+
return { content: [{ type: "text", text: `Speaker "${speakerName}" not found.` }] };
|
|
29
|
+
}
|
|
30
|
+
const data = await client.getSpeakerSegments({
|
|
31
|
+
identity_id: sid,
|
|
32
|
+
days,
|
|
33
|
+
limit: Math.min(limit, 50),
|
|
34
|
+
offset,
|
|
35
|
+
});
|
|
36
|
+
const segs = data.segments ?? [];
|
|
37
|
+
if (!segs.length)
|
|
38
|
+
return { content: [{ type: "text", text: "No segments found for this speaker in the given time window." }] };
|
|
39
|
+
const name = data.speaker_name ?? `Speaker ${sid}`;
|
|
40
|
+
const more = data.has_more ? " (more available — increase offset)" : "";
|
|
41
|
+
const lines = [`**${segs.length} segments from ${name}**${more}\n`];
|
|
42
|
+
for (let i = 0; i < segs.length; i++) {
|
|
43
|
+
const seg = segs[i];
|
|
44
|
+
const date = fmtDate(seg.publish_date);
|
|
45
|
+
const ch = seg.channel_name ?? "?";
|
|
46
|
+
const text = (seg.text ?? "").slice(0, 200);
|
|
47
|
+
lines.push(`${i + 1}. [${date}] ${ch}`);
|
|
48
|
+
lines.push(` ${text}\n`);
|
|
49
|
+
}
|
|
50
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
51
|
+
}
|
|
52
|
+
// Semantic search within a speaker
|
|
53
|
+
if (sort === "relevance" && speakerId && topic) {
|
|
54
|
+
const data = await client.searchSpeakerSegments({
|
|
55
|
+
identity_id: speakerId,
|
|
56
|
+
query: topic,
|
|
57
|
+
days,
|
|
58
|
+
limit: Math.min(limit, 50),
|
|
59
|
+
});
|
|
60
|
+
const segs = data.segments ?? [];
|
|
61
|
+
if (!segs.length)
|
|
62
|
+
return { content: [{ type: "text", text: "No segments found for this speaker matching the query." }] };
|
|
63
|
+
const name = data.speaker_name ?? `Speaker ${speakerId}`;
|
|
64
|
+
const lines = [`**${segs.length} segments from ${name}**\n`];
|
|
65
|
+
for (let i = 0; i < segs.length; i++) {
|
|
66
|
+
const seg = segs[i];
|
|
67
|
+
const sim = seg.similarity ?? 0;
|
|
68
|
+
const date = fmtDate(seg.publish_date);
|
|
69
|
+
const ch = seg.channel_name ?? "?";
|
|
70
|
+
const text = (seg.text ?? "").slice(0, 250);
|
|
71
|
+
lines.push(`${i + 1}. [${date}] ${ch} (sim:${sim.toFixed(2)})`);
|
|
72
|
+
lines.push(` ${text}\n`);
|
|
73
|
+
}
|
|
74
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
75
|
+
}
|
|
76
|
+
// Standard quote search
|
|
77
|
+
const data = await client.searchQuotes({
|
|
78
|
+
topic,
|
|
79
|
+
speaker_name: speakerName,
|
|
80
|
+
speaker_identity_id: speakerId,
|
|
81
|
+
channel_name: channelName,
|
|
82
|
+
start_date: startDate,
|
|
83
|
+
end_date: endDate,
|
|
84
|
+
min_similarity: minSimilarity,
|
|
85
|
+
limit: countOnly ? 1 : Math.min(limit, 50),
|
|
86
|
+
offset,
|
|
87
|
+
mode: mode !== "semantic" ? mode : undefined,
|
|
88
|
+
});
|
|
89
|
+
if (countOnly) {
|
|
90
|
+
const total = data.total_results ?? 0;
|
|
91
|
+
const label = topic ?? speakerName ?? "query";
|
|
92
|
+
return { content: [{ type: "text", text: `${total} segments matching "${label}"` }] };
|
|
93
|
+
}
|
|
94
|
+
const text = data.quotes?.length
|
|
95
|
+
? formatQuotes(data)
|
|
96
|
+
: emptyStateSuggestions({ topic, speaker_name: speakerName, mode, days });
|
|
97
|
+
return { content: [{ type: "text", text }] };
|
|
98
|
+
}
|
|
99
|
+
export async function handleDetectTrend(params) {
|
|
100
|
+
const topic = params.topic;
|
|
101
|
+
let recentDays = params.recent_days ?? 7;
|
|
102
|
+
const baselineDays = params.baseline_days ?? 30;
|
|
103
|
+
const minSimilarity = params.min_similarity;
|
|
104
|
+
if (recentDays > baselineDays)
|
|
105
|
+
recentDays = Math.max(1, Math.floor(baselineDays / 2));
|
|
106
|
+
const data = await client.detectTrend({
|
|
107
|
+
topic,
|
|
108
|
+
recent_days: recentDays,
|
|
109
|
+
baseline_days: baselineDays,
|
|
110
|
+
min_similarity: minSimilarity,
|
|
111
|
+
});
|
|
112
|
+
const arrows = {
|
|
113
|
+
surging: "▲▲", rising: "▲", steady: "─",
|
|
114
|
+
declining: "▼", fading: "▼▼", new: "★",
|
|
115
|
+
};
|
|
116
|
+
const arrow = arrows[data.direction] ?? "?";
|
|
117
|
+
const changePct = data.change_pct;
|
|
118
|
+
const changeStr = typeof changePct === "number" ? `${changePct > 0 ? "+" : ""}${changePct.toFixed(0)}%` : "NEW";
|
|
119
|
+
const recent = data.recent ?? {};
|
|
120
|
+
const baseline = data.baseline ?? {};
|
|
121
|
+
const text = [
|
|
122
|
+
`${arrow} **"${topic}"** — ${data.direction} (${changeStr})`,
|
|
123
|
+
`Recent (${recent.days ?? "?"}d): ${recent.segments ?? 0} segments (${(recent.per_day ?? 0).toFixed(1)}/day)`,
|
|
124
|
+
`Baseline (${baseline.days ?? "?"}d): ${baseline.segments ?? 0} segments (${(baseline.per_day ?? 0).toFixed(1)}/day)`,
|
|
125
|
+
].join("\n");
|
|
126
|
+
return { content: [{ type: "text", text }] };
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/handlers/search.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Signal4 MCP server — media intelligence tools for AI agents.
|
|
2
|
+
*
|
|
3
|
+
* Connects to the Signal4 REST API at api.signal4.ca.
|
|
4
|
+
* Tool definitions (names, descriptions, schemas) are fetched from the API
|
|
5
|
+
* at startup — the npm package contains only handler logic, not metadata.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/** Signal4 MCP server — media intelligence tools for AI agents.
|
|
2
|
+
*
|
|
3
|
+
* Connects to the Signal4 REST API at api.signal4.ca.
|
|
4
|
+
* Tool definitions (names, descriptions, schemas) are fetched from the API
|
|
5
|
+
* at startup — the npm package contains only handler logic, not metadata.
|
|
6
|
+
*/
|
|
7
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
9
|
+
import { ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
+
import * as client from "./client.js";
|
|
11
|
+
import { HANDLERS } from "./handlers/registry.js";
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Manifest cache — fetched once per session from the API
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
let _manifest = null;
|
|
16
|
+
async function fetchManifest() {
|
|
17
|
+
if (_manifest)
|
|
18
|
+
return _manifest;
|
|
19
|
+
if (!process.env.SIGNAL4_API_KEY) {
|
|
20
|
+
throw new Error("SIGNAL4_API_KEY environment variable is not set. " +
|
|
21
|
+
"Get your API key from Signal4 and set it in your MCP server config.");
|
|
22
|
+
}
|
|
23
|
+
_manifest = await client.getManifest();
|
|
24
|
+
return _manifest;
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Server setup
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
const FALLBACK_INSTRUCTIONS = "Signal4 media intelligence platform. Authenticating...";
|
|
30
|
+
const server = new McpServer({ name: "Signal4", version: "1.0.0" }, { instructions: FALLBACK_INSTRUCTIONS });
|
|
31
|
+
// Register tool capabilities and custom handlers on the underlying Server
|
|
32
|
+
// BEFORE any .tool() call — we own the tool protocol directly so we can
|
|
33
|
+
// serve raw JSON Schema from the manifest without zod conversion.
|
|
34
|
+
server.server.registerCapabilities({ tools: { listChanged: true } });
|
|
35
|
+
server.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
36
|
+
const m = await fetchManifest();
|
|
37
|
+
return {
|
|
38
|
+
tools: m.tools.map((t) => ({
|
|
39
|
+
name: t.name,
|
|
40
|
+
description: t.description,
|
|
41
|
+
inputSchema: t.inputSchema,
|
|
42
|
+
})),
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
server.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
46
|
+
try {
|
|
47
|
+
const { name, arguments: args } = request.params;
|
|
48
|
+
// Verify the tool is in the manifest (scope enforcement)
|
|
49
|
+
const m = await fetchManifest();
|
|
50
|
+
const authorized = m.tools.some((t) => t.name === name);
|
|
51
|
+
if (!authorized) {
|
|
52
|
+
return {
|
|
53
|
+
content: [{ type: "text", text: `Tool "${name}" is not available.` }],
|
|
54
|
+
isError: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const handler = HANDLERS[name];
|
|
58
|
+
if (!handler) {
|
|
59
|
+
return {
|
|
60
|
+
content: [{ type: "text", text: `Tool "${name}" is not implemented.` }],
|
|
61
|
+
isError: true,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return await handler(args ?? {});
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
return {
|
|
68
|
+
content: [{
|
|
69
|
+
type: "text",
|
|
70
|
+
text: `Error: ${err instanceof Error ? err.message : String(err)}`,
|
|
71
|
+
}],
|
|
72
|
+
isError: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Start
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
async function main() {
|
|
80
|
+
const transport = new StdioServerTransport();
|
|
81
|
+
await server.connect(transport);
|
|
82
|
+
// Eagerly fetch manifest so tools/list is populated on first call.
|
|
83
|
+
// If this fails (bad key, network), the ListTools handler will retry
|
|
84
|
+
// on the next tools/list request.
|
|
85
|
+
try {
|
|
86
|
+
await fetchManifest();
|
|
87
|
+
server.server.sendToolListChanged();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Will retry on first tools/list call
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
main().catch((err) => {
|
|
94
|
+
console.error("Signal4 MCP server failed to start:", err);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|