nod-shout 0.1.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 +82 -0
- package/TASK-AGENT-POSTS.md +112 -0
- package/assets/shout-default.svg +5 -0
- package/bin/shout +68 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/ai.d.ts +13 -0
- package/dist/lib/ai.d.ts.map +1 -0
- package/dist/lib/ai.js +135 -0
- package/dist/lib/ai.js.map +1 -0
- package/dist/lib/content-filter.d.ts +74 -0
- package/dist/lib/content-filter.d.ts.map +1 -0
- package/dist/lib/content-filter.js +188 -0
- package/dist/lib/content-filter.js.map +1 -0
- package/dist/lib/context-extractor.d.ts +39 -0
- package/dist/lib/context-extractor.d.ts.map +1 -0
- package/dist/lib/context-extractor.js +170 -0
- package/dist/lib/context-extractor.js.map +1 -0
- package/dist/lib/match-engine.d.ts +31 -0
- package/dist/lib/match-engine.d.ts.map +1 -0
- package/dist/lib/match-engine.js +322 -0
- package/dist/lib/match-engine.js.map +1 -0
- package/dist/lib/metadata.d.ts +7 -0
- package/dist/lib/metadata.d.ts.map +1 -0
- package/dist/lib/metadata.js +311 -0
- package/dist/lib/metadata.js.map +1 -0
- package/dist/lib/skills.d.ts +3 -0
- package/dist/lib/skills.d.ts.map +1 -0
- package/dist/lib/skills.js +20 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/lib/supabase.d.ts +2 -0
- package/dist/lib/supabase.d.ts.map +1 -0
- package/dist/lib/supabase.js +8 -0
- package/dist/lib/supabase.js.map +1 -0
- package/dist/tools/collections.d.ts +3 -0
- package/dist/tools/collections.d.ts.map +1 -0
- package/dist/tools/collections.js +142 -0
- package/dist/tools/collections.js.map +1 -0
- package/dist/tools/intros.d.ts +3 -0
- package/dist/tools/intros.d.ts.map +1 -0
- package/dist/tools/intros.js +483 -0
- package/dist/tools/intros.js.map +1 -0
- package/dist/tools/links.d.ts +3 -0
- package/dist/tools/links.d.ts.map +1 -0
- package/dist/tools/links.js +424 -0
- package/dist/tools/links.js.map +1 -0
- package/dist/tools/posts.d.ts +3 -0
- package/dist/tools/posts.d.ts.map +1 -0
- package/dist/tools/posts.js +212 -0
- package/dist/tools/posts.js.map +1 -0
- package/dist/tools/settings.d.ts +3 -0
- package/dist/tools/settings.d.ts.map +1 -0
- package/dist/tools/settings.js +45 -0
- package/dist/tools/settings.js.map +1 -0
- package/dist/tools/shout_agent_curate.d.ts +28 -0
- package/dist/tools/shout_agent_curate.d.ts.map +1 -0
- package/dist/tools/shout_agent_curate.js +80 -0
- package/dist/tools/shout_agent_curate.js.map +1 -0
- package/dist/tools/social.d.ts +3 -0
- package/dist/tools/social.d.ts.map +1 -0
- package/dist/tools/social.js +169 -0
- package/dist/tools/social.js.map +1 -0
- package/dist/types.d.ts +60 -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 +24 -0
- package/quick-test.ts +22 -0
- package/regenerate-summaries.ts +111 -0
- package/save-jeffries-shout.ts +38 -0
- package/save-openai-shout.ts +35 -0
- package/save-prcarly.ts +46 -0
- package/save-shout.ts +35 -0
- package/save-techcrunch-shout.ts +59 -0
- package/save-zdnet-shout.ts +36 -0
- package/skills/collection-routing/SKILL.md +34 -0
- package/skills/link-summary/SKILL.md +53 -0
- package/skills/tagging-and-routing/SKILL.md +54 -0
- package/src/index.ts +32 -0
- package/src/lib/ai.ts +166 -0
- package/src/lib/content-filter.ts +258 -0
- package/src/lib/metadata.ts +353 -0
- package/src/lib/skills.ts +21 -0
- package/src/lib/supabase.ts +12 -0
- package/src/tools/collections.ts +182 -0
- package/src/tools/links.ts +524 -0
- package/src/tools/posts.ts +264 -0
- package/src/tools/settings.ts +55 -0
- package/src/tools/shout_agent_curate.ts +95 -0
- package/src/tools/social.ts +206 -0
- package/src/types.ts +66 -0
- package/supabase/.temp/cli-latest +1 -0
- package/supabase/.temp/gotrue-version +1 -0
- package/supabase/.temp/pooler-url +1 -0
- package/supabase/.temp/postgres-version +1 -0
- package/supabase/.temp/project-ref +1 -0
- package/supabase/.temp/rest-version +1 -0
- package/supabase/.temp/storage-migration +1 -0
- package/supabase/.temp/storage-version +1 -0
- package/supabase/migrations/001_initial_schema.sql +147 -0
- package/supabase/migrations/20260317010000_decouple_profiles_from_auth.sql +9 -0
- package/supabase/migrations/20260317020000_agent_curation.sql +10 -0
- package/supabase/migrations/20260320000000_agent_posts.sql +41 -0
- package/supabase/migrations/20260320120000_fix_draft_fk.sql +2 -0
- package/supabase/migrations/20260320130000_fix_identity.sql +17 -0
- package/supabase/migrations/20260320170000_intros.sql +118 -0
- package/test-model-comparison.ts +89 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"posts.js","sourceRoot":"","sources":["../../src/tools/posts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/tools/settings.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,QA+CtD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// in-memory settings store for v1
|
|
3
|
+
// TODO: persist to supabase user_settings table
|
|
4
|
+
const userSettings = new Map();
|
|
5
|
+
export function registerSettingsTools(server) {
|
|
6
|
+
// shout_settings - configure behavior
|
|
7
|
+
server.tool("shout_settings", "configure your shout behavior preferences.", {
|
|
8
|
+
user_id: z.string().uuid().describe("the user's id"),
|
|
9
|
+
auto_detect: z
|
|
10
|
+
.boolean()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("auto-detect links in conversation"),
|
|
13
|
+
default_visibility: z
|
|
14
|
+
.enum(["public", "private", "unlisted"])
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("default visibility for new shouts"),
|
|
17
|
+
digest_frequency: z
|
|
18
|
+
.enum(["daily", "weekly", "monthly", "never"])
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("how often to generate digests"),
|
|
21
|
+
}, async ({ user_id, auto_detect, default_visibility, digest_frequency }) => {
|
|
22
|
+
const current = userSettings.get(user_id) || {
|
|
23
|
+
auto_detect: true,
|
|
24
|
+
default_visibility: "public",
|
|
25
|
+
digest_frequency: "weekly",
|
|
26
|
+
};
|
|
27
|
+
if (auto_detect !== undefined)
|
|
28
|
+
current.auto_detect = auto_detect;
|
|
29
|
+
if (default_visibility !== undefined)
|
|
30
|
+
current.default_visibility = default_visibility;
|
|
31
|
+
if (digest_frequency !== undefined)
|
|
32
|
+
current.digest_frequency = digest_frequency;
|
|
33
|
+
userSettings.set(user_id, current);
|
|
34
|
+
return {
|
|
35
|
+
content: [
|
|
36
|
+
{
|
|
37
|
+
type: "text",
|
|
38
|
+
text: `settings updated:\n- auto_detect: ${current.auto_detect}\n- default_visibility: ${current.default_visibility}\n- digest_frequency: ${current.digest_frequency}`,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
// shout_generate_digest is registered in links.ts
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/tools/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,kCAAkC;AAClC,gDAAgD;AAChD,MAAM,YAAY,GAAyC,IAAI,GAAG,EAAE,CAAC;AAErE,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,sCAAsC;IACtC,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,4CAA4C,EAC5C;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;QACpD,WAAW,EAAE,CAAC;aACX,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,mCAAmC,CAAC;QAChD,kBAAkB,EAAE,CAAC;aAClB,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;aACvC,QAAQ,EAAE;aACV,QAAQ,CAAC,mCAAmC,CAAC;QAChD,gBAAgB,EAAE,CAAC;aAChB,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;aAC7C,QAAQ,EAAE;aACV,QAAQ,CAAC,+BAA+B,CAAC;KAC7C,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,EAAE,EAAE;QACvE,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI;YAC3C,WAAW,EAAE,IAAI;YACjB,kBAAkB,EAAE,QAAQ;YAC5B,gBAAgB,EAAE,QAAQ;SAC3B,CAAC;QAEF,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;QACjE,IAAI,kBAAkB,KAAK,SAAS;YAClC,OAAO,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;QAClD,IAAI,gBAAgB,KAAK,SAAS;YAChC,OAAO,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QAE9C,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAEnC,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,qCAAqC,OAAO,CAAC,WAAW,2BAA2B,OAAO,CAAC,kBAAkB,yBAAyB,OAAO,CAAC,gBAAgB,EAAE;iBACvK;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,kDAAkD;AACpD,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
export declare const shoutAgentCurateSchema: z.ZodObject<{
|
|
4
|
+
url: z.ZodString;
|
|
5
|
+
agent_take: z.ZodOptional<z.ZodString>;
|
|
6
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
7
|
+
collection_id: z.ZodOptional<z.ZodString>;
|
|
8
|
+
user_id: z.ZodString;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
url: string;
|
|
11
|
+
user_id: string;
|
|
12
|
+
agent_take?: string | undefined;
|
|
13
|
+
tags?: string[] | undefined;
|
|
14
|
+
collection_id?: string | undefined;
|
|
15
|
+
}, {
|
|
16
|
+
url: string;
|
|
17
|
+
user_id: string;
|
|
18
|
+
agent_take?: string | undefined;
|
|
19
|
+
tags?: string[] | undefined;
|
|
20
|
+
collection_id?: string | undefined;
|
|
21
|
+
}>;
|
|
22
|
+
export type ShoutAgentCurateInput = z.infer<typeof shoutAgentCurateSchema>;
|
|
23
|
+
export declare function shoutAgentCurate(input: ShoutAgentCurateInput): Promise<{
|
|
24
|
+
message: string;
|
|
25
|
+
shout: any;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function registerAgentCurateTools(server: McpServer): void;
|
|
28
|
+
//# sourceMappingURL=shout_agent_curate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shout_agent_curate.d.ts","sourceRoot":"","sources":["../../src/tools/shout_agent_curate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;EAgBjC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE3E,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB;;;GAwDlE;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,QAUzD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { supabase } from "../lib/supabase.js";
|
|
3
|
+
import { extractMetadata } from "../lib/metadata.js";
|
|
4
|
+
import { generateSummary } from "../lib/ai.js";
|
|
5
|
+
export const shoutAgentCurateSchema = z.object({
|
|
6
|
+
url: z.string().url().describe("The URL to save"),
|
|
7
|
+
agent_take: z
|
|
8
|
+
.string()
|
|
9
|
+
.optional()
|
|
10
|
+
.describe("The agent's own commentary or opinion on why this link is interesting"),
|
|
11
|
+
tags: z
|
|
12
|
+
.array(z.string())
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("Override auto-generated tags with these tags"),
|
|
15
|
+
collection_id: z
|
|
16
|
+
.string()
|
|
17
|
+
.uuid()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("Put the shout in a specific collection by ID"),
|
|
20
|
+
user_id: z.string().uuid().describe("The user's profile ID (fubz)"),
|
|
21
|
+
});
|
|
22
|
+
export async function shoutAgentCurate(input) {
|
|
23
|
+
// 1. Fetch metadata
|
|
24
|
+
const meta = await extractMetadata(input.url);
|
|
25
|
+
// 2. AI summary + tags + category (all returned from generateSummary)
|
|
26
|
+
const aiResult = await generateSummary({
|
|
27
|
+
url: input.url,
|
|
28
|
+
title: meta.title,
|
|
29
|
+
description: meta.description,
|
|
30
|
+
bodyText: meta.bodyText,
|
|
31
|
+
userContext: input.agent_take ?? null,
|
|
32
|
+
});
|
|
33
|
+
const tags = input.tags ?? aiResult.tags;
|
|
34
|
+
const category = aiResult.category;
|
|
35
|
+
const summary = aiResult.summary;
|
|
36
|
+
// 3. PII filter before saving
|
|
37
|
+
const { filterShoutContent } = await import("../lib/content-filter.js");
|
|
38
|
+
const filtered = filterShoutContent({
|
|
39
|
+
take: input.agent_take ?? null,
|
|
40
|
+
summary,
|
|
41
|
+
title: meta.title,
|
|
42
|
+
description: meta.description,
|
|
43
|
+
});
|
|
44
|
+
if (filtered.filterReport) {
|
|
45
|
+
console.log(`[nod-shout] agent curate filter: ${filtered.filterReport}`);
|
|
46
|
+
}
|
|
47
|
+
// 4. Insert shout with source "agent_curated"
|
|
48
|
+
const { data, error } = await supabase
|
|
49
|
+
.from("shouts")
|
|
50
|
+
.insert({
|
|
51
|
+
user_id: input.user_id,
|
|
52
|
+
url: input.url,
|
|
53
|
+
title: filtered.title,
|
|
54
|
+
description: filtered.description,
|
|
55
|
+
summary: filtered.summary,
|
|
56
|
+
user_take: filtered.take,
|
|
57
|
+
image_url: meta.image_url,
|
|
58
|
+
tags,
|
|
59
|
+
category,
|
|
60
|
+
collection_id: input.collection_id ?? null,
|
|
61
|
+
source: "agent_curated",
|
|
62
|
+
agent_context: input.agent_take ? `Agent curated: ${input.agent_take}` : "Agent curated link",
|
|
63
|
+
visibility: "public",
|
|
64
|
+
})
|
|
65
|
+
.select()
|
|
66
|
+
.single();
|
|
67
|
+
if (error)
|
|
68
|
+
throw new Error(`Failed to save agent-curated shout: ${error.message}`);
|
|
69
|
+
return {
|
|
70
|
+
message: `Agent curated! "${meta.title}" saved.`,
|
|
71
|
+
shout: data,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export function registerAgentCurateTools(server) {
|
|
75
|
+
server.tool("shout_agent_curate", "Save a link to the agent's shout page. Use this when you find an interesting link worth sharing — from conversations, research, or browsing. The agent curates its own page.", shoutAgentCurateSchema.shape, async (params) => {
|
|
76
|
+
const result = await shoutAgentCurate(params);
|
|
77
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=shout_agent_curate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shout_agent_curate.js","sourceRoot":"","sources":["../../src/tools/shout_agent_curate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social.d.ts","sourceRoot":"","sources":["../../src/tools/social.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,QAyMpD"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { supabase } from "../lib/supabase.js";
|
|
3
|
+
export function registerSocialTools(server) {
|
|
4
|
+
// shout_follow - subscribe to a user's shouts
|
|
5
|
+
server.tool("shout_follow", "follow another user's shouts. optionally follow a specific collection.", {
|
|
6
|
+
user_id: z.string().uuid().describe("your user id"),
|
|
7
|
+
username: z.string().describe("username to follow"),
|
|
8
|
+
collection: z
|
|
9
|
+
.string()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("specific collection slug to follow"),
|
|
12
|
+
}, async ({ user_id, username, collection }) => {
|
|
13
|
+
// resolve username to user id
|
|
14
|
+
const { data: profile } = await supabase
|
|
15
|
+
.from("profiles")
|
|
16
|
+
.select("id")
|
|
17
|
+
.eq("username", username)
|
|
18
|
+
.single();
|
|
19
|
+
if (!profile) {
|
|
20
|
+
return {
|
|
21
|
+
content: [
|
|
22
|
+
{ type: "text", text: `user "${username}" not found.` },
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// resolve collection if provided
|
|
27
|
+
let collection_id = null;
|
|
28
|
+
if (collection) {
|
|
29
|
+
const { data: col } = await supabase
|
|
30
|
+
.from("collections")
|
|
31
|
+
.select("id")
|
|
32
|
+
.eq("user_id", profile.id)
|
|
33
|
+
.eq("slug", collection)
|
|
34
|
+
.single();
|
|
35
|
+
collection_id = col?.id || null;
|
|
36
|
+
}
|
|
37
|
+
// check if already following
|
|
38
|
+
let existingQuery = supabase
|
|
39
|
+
.from("subscriptions")
|
|
40
|
+
.select("id")
|
|
41
|
+
.eq("follower_id", user_id)
|
|
42
|
+
.eq("following_id", profile.id);
|
|
43
|
+
if (collection_id) {
|
|
44
|
+
existingQuery = existingQuery.eq("collection_id", collection_id);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
existingQuery = existingQuery.is("collection_id", null);
|
|
48
|
+
}
|
|
49
|
+
const { data: existing } = await existingQuery.single();
|
|
50
|
+
if (existing) {
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{ type: "text", text: `you're already following ${username}${collection ? ` (${collection})` : ""}.` },
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const { error } = await supabase.from("subscriptions").insert({
|
|
58
|
+
follower_id: user_id,
|
|
59
|
+
following_id: profile.id,
|
|
60
|
+
collection_id,
|
|
61
|
+
});
|
|
62
|
+
if (error) {
|
|
63
|
+
return {
|
|
64
|
+
content: [
|
|
65
|
+
{ type: "text", text: `error following: ${error.message}` },
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
content: [
|
|
71
|
+
{
|
|
72
|
+
type: "text",
|
|
73
|
+
text: `now following ${username}${collection ? ` (${collection})` : ""}!`,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
// shout_unfollow
|
|
79
|
+
server.tool("shout_unfollow", "unfollow a user's shouts.", {
|
|
80
|
+
user_id: z.string().uuid().describe("your user id"),
|
|
81
|
+
username: z.string().describe("username to unfollow"),
|
|
82
|
+
}, async ({ user_id, username }) => {
|
|
83
|
+
const { data: profile } = await supabase
|
|
84
|
+
.from("profiles")
|
|
85
|
+
.select("id")
|
|
86
|
+
.eq("username", username)
|
|
87
|
+
.single();
|
|
88
|
+
if (!profile) {
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
{ type: "text", text: `user "${username}" not found.` },
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const { error } = await supabase
|
|
96
|
+
.from("subscriptions")
|
|
97
|
+
.delete()
|
|
98
|
+
.eq("follower_id", user_id)
|
|
99
|
+
.eq("following_id", profile.id);
|
|
100
|
+
if (error) {
|
|
101
|
+
return {
|
|
102
|
+
content: [
|
|
103
|
+
{ type: "text", text: `error unfollowing: ${error.message}` },
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
content: [
|
|
109
|
+
{ type: "text", text: `unfollowed ${username}.` },
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
// shout_feed - aggregated feed from followed users
|
|
114
|
+
server.tool("shout_feed", "get an aggregated feed of shouts from users you follow.", {
|
|
115
|
+
user_id: z.string().uuid().describe("your user id"),
|
|
116
|
+
limit: z.number().optional().default(20).describe("max results"),
|
|
117
|
+
}, async ({ user_id, limit }) => {
|
|
118
|
+
// get list of followed user ids
|
|
119
|
+
const { data: subs } = await supabase
|
|
120
|
+
.from("subscriptions")
|
|
121
|
+
.select("following_id, collection_id")
|
|
122
|
+
.eq("follower_id", user_id);
|
|
123
|
+
if (!subs || subs.length === 0) {
|
|
124
|
+
return {
|
|
125
|
+
content: [
|
|
126
|
+
{
|
|
127
|
+
type: "text",
|
|
128
|
+
text: "you're not following anyone yet. use shout_follow to subscribe to someone's shouts.",
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
const followingIds = subs.map((s) => s.following_id);
|
|
134
|
+
const { data, error } = await supabase
|
|
135
|
+
.from("shouts")
|
|
136
|
+
.select("*, profiles!inner(username, display_name)")
|
|
137
|
+
.in("user_id", followingIds)
|
|
138
|
+
.eq("visibility", "public")
|
|
139
|
+
.order("created_at", { ascending: false })
|
|
140
|
+
.limit(limit || 20);
|
|
141
|
+
if (error) {
|
|
142
|
+
return {
|
|
143
|
+
content: [
|
|
144
|
+
{ type: "text", text: `error fetching feed: ${error.message}` },
|
|
145
|
+
],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
if (!data || data.length === 0) {
|
|
149
|
+
return {
|
|
150
|
+
content: [
|
|
151
|
+
{ type: "text", text: "no shouts in your feed yet." },
|
|
152
|
+
],
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
const lines = data.map((s, i) => {
|
|
156
|
+
const who = s.profiles?.username || "unknown";
|
|
157
|
+
return `${i + 1}. @${who}: ${s.title || s.url}\n ${s.summary || ""}\n tags: ${(s.tags || []).join(", ")} | ${s.created_at}`;
|
|
158
|
+
});
|
|
159
|
+
return {
|
|
160
|
+
content: [
|
|
161
|
+
{
|
|
162
|
+
type: "text",
|
|
163
|
+
text: `feed (${data.length} shouts):\n\n${lines.join("\n\n")}`,
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=social.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social.js","sourceRoot":"","sources":["../../src/tools/social.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface Profile {
|
|
2
|
+
id: string;
|
|
3
|
+
username: string;
|
|
4
|
+
display_name: string | null;
|
|
5
|
+
bio: string | null;
|
|
6
|
+
avatar_url: string | null;
|
|
7
|
+
created_at: string;
|
|
8
|
+
updated_at: string;
|
|
9
|
+
}
|
|
10
|
+
export interface Shout {
|
|
11
|
+
id: string;
|
|
12
|
+
user_id: string;
|
|
13
|
+
url: string;
|
|
14
|
+
title: string | null;
|
|
15
|
+
description: string | null;
|
|
16
|
+
summary: string | null;
|
|
17
|
+
user_take: string | null;
|
|
18
|
+
image_url: string | null;
|
|
19
|
+
tags: string[] | null;
|
|
20
|
+
category: string | null;
|
|
21
|
+
collection_id: string | null;
|
|
22
|
+
source: string;
|
|
23
|
+
agent_context: string | null;
|
|
24
|
+
visibility: "public" | "private" | "unlisted";
|
|
25
|
+
created_at: string;
|
|
26
|
+
updated_at: string;
|
|
27
|
+
}
|
|
28
|
+
export interface Collection {
|
|
29
|
+
id: string;
|
|
30
|
+
user_id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
description: string | null;
|
|
33
|
+
slug: string;
|
|
34
|
+
visibility: "public" | "private" | "unlisted";
|
|
35
|
+
auto_rules: Record<string, unknown> | null;
|
|
36
|
+
created_at: string;
|
|
37
|
+
updated_at: string;
|
|
38
|
+
}
|
|
39
|
+
export interface Subscription {
|
|
40
|
+
id: string;
|
|
41
|
+
follower_id: string;
|
|
42
|
+
following_id: string;
|
|
43
|
+
collection_id: string | null;
|
|
44
|
+
notify: boolean;
|
|
45
|
+
created_at: string;
|
|
46
|
+
}
|
|
47
|
+
export interface PageMetadata {
|
|
48
|
+
title: string | null;
|
|
49
|
+
description: string | null;
|
|
50
|
+
image_url: string | null;
|
|
51
|
+
author: string | null;
|
|
52
|
+
date: string | null;
|
|
53
|
+
bodyText: string | null;
|
|
54
|
+
}
|
|
55
|
+
export interface AISummaryResult {
|
|
56
|
+
summary: string;
|
|
57
|
+
tags: string[];
|
|
58
|
+
category: string;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;IAC9C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,wCAAwC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nod-shout",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "mcp server for nod social - turn links into curated public pages",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"start": "node dist/index.js",
|
|
10
|
+
"dev": "tsx src/index.ts",
|
|
11
|
+
"lint": "tsc --noEmit"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
15
|
+
"@supabase/supabase-js": "^2.49.1",
|
|
16
|
+
"cheerio": "^1.0.0",
|
|
17
|
+
"zod": "^3.24.2"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/node": "^22.13.10",
|
|
21
|
+
"tsx": "^4.19.3",
|
|
22
|
+
"typescript": "^5.8.2"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/quick-test.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
const env = Object.fromEntries(
|
|
3
|
+
readFileSync('.env', 'utf8').split('\n').filter(l => l.includes('=')).map(l => {
|
|
4
|
+
const [k, ...v] = l.split('=');
|
|
5
|
+
return [k.trim(), v.join('=').trim()];
|
|
6
|
+
})
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
async function main() {
|
|
10
|
+
const res = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
11
|
+
method: "POST",
|
|
12
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${env.OPENAI_API_KEY}` },
|
|
13
|
+
body: JSON.stringify({
|
|
14
|
+
model: "gpt-5-mini",
|
|
15
|
+
messages: [{ role: "user", content: 'Summarize in 1 sentence: Apple skipped AI data center spending. Respond in JSON: {"summary": "..."}' }],
|
|
16
|
+
max_completion_tokens: 200,
|
|
17
|
+
}),
|
|
18
|
+
});
|
|
19
|
+
const data = await res.json();
|
|
20
|
+
console.log(JSON.stringify(data, null, 2));
|
|
21
|
+
}
|
|
22
|
+
main();
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { createClient } from "@supabase/supabase-js";
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
|
|
4
|
+
const env = Object.fromEntries(
|
|
5
|
+
readFileSync(".env", "utf8").split("\n").filter(l => l.includes("=")).map(l => {
|
|
6
|
+
const [k, ...v] = l.split("=");
|
|
7
|
+
return [k.trim(), v.join("=").trim()];
|
|
8
|
+
})
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
const supabase = createClient(env.SUPABASE_URL, env.SUPABASE_SERVICE_ROLE_KEY);
|
|
12
|
+
const OPENAI_API_KEY = env.OPENAI_API_KEY;
|
|
13
|
+
|
|
14
|
+
async function regenerate() {
|
|
15
|
+
// get fubz's profile
|
|
16
|
+
const { data: profile } = await supabase
|
|
17
|
+
.from("profiles")
|
|
18
|
+
.select("id")
|
|
19
|
+
.eq("username", "fubz")
|
|
20
|
+
.single();
|
|
21
|
+
|
|
22
|
+
if (!profile) { console.log("no profile found"); return; }
|
|
23
|
+
|
|
24
|
+
const { data: shouts } = await supabase
|
|
25
|
+
.from("shouts")
|
|
26
|
+
.select("id, url, title, summary")
|
|
27
|
+
.eq("user_id", profile.id)
|
|
28
|
+
.order("created_at", { ascending: false });
|
|
29
|
+
|
|
30
|
+
if (!shouts || shouts.length === 0) { console.log("no shouts"); return; }
|
|
31
|
+
|
|
32
|
+
console.log(`regenerating ${shouts.length} summaries...\n`);
|
|
33
|
+
|
|
34
|
+
for (const shout of shouts) {
|
|
35
|
+
// fetch page content
|
|
36
|
+
let bodyText = "";
|
|
37
|
+
try {
|
|
38
|
+
const pageRes = await fetch(shout.url, {
|
|
39
|
+
headers: { "User-Agent": "Mozilla/5.0 (compatible; NodShout/0.1)" },
|
|
40
|
+
signal: AbortSignal.timeout(10000),
|
|
41
|
+
});
|
|
42
|
+
if (pageRes.ok) {
|
|
43
|
+
const html = await pageRes.text();
|
|
44
|
+
// rough text extraction - strip tags
|
|
45
|
+
bodyText = html
|
|
46
|
+
.replace(/<script[\s\S]*?<\/script>/gi, "")
|
|
47
|
+
.replace(/<style[\s\S]*?<\/style>/gi, "")
|
|
48
|
+
.replace(/<[^>]+>/g, " ")
|
|
49
|
+
.replace(/\s+/g, " ")
|
|
50
|
+
.trim()
|
|
51
|
+
.slice(0, 1500);
|
|
52
|
+
}
|
|
53
|
+
} catch { /* ignore fetch errors */ }
|
|
54
|
+
|
|
55
|
+
const prompt = `Write a nod shout card summary.
|
|
56
|
+
|
|
57
|
+
Rules:
|
|
58
|
+
- 2 short sentences max
|
|
59
|
+
- sentence 1: what the thing is or what happened
|
|
60
|
+
- sentence 2: a reason to click or a key detail
|
|
61
|
+
- include concrete specifics when available (names, numbers, claims)
|
|
62
|
+
- write like you're texting a friend, not writing a blurb
|
|
63
|
+
- never start with: "this article discusses", "this post is about", "the page explains", "X tweeted that", "post by", "page", "clicking gives", "clicking provides", "clicking reveals"
|
|
64
|
+
- never use: "not just X but Y", "isn't just X"
|
|
65
|
+
- no filler like "thought-provoking", "must-read", "fascinating", "insightful"
|
|
66
|
+
|
|
67
|
+
url: ${shout.url}
|
|
68
|
+
title: ${shout.title || "unknown"}
|
|
69
|
+
${bodyText ? `page content: ${bodyText}` : ""}
|
|
70
|
+
|
|
71
|
+
respond in json only, no markdown:
|
|
72
|
+
{"summary": "..."}`;
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
const res = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
76
|
+
method: "POST",
|
|
77
|
+
headers: {
|
|
78
|
+
"Content-Type": "application/json",
|
|
79
|
+
Authorization: `Bearer ${OPENAI_API_KEY}`,
|
|
80
|
+
},
|
|
81
|
+
body: JSON.stringify({
|
|
82
|
+
model: "gpt-4.1-mini",
|
|
83
|
+
messages: [{ role: "user", content: prompt }],
|
|
84
|
+
temperature: 0.7,
|
|
85
|
+
max_tokens: 250,
|
|
86
|
+
response_format: { type: "json_object" },
|
|
87
|
+
}),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const data = await res.json();
|
|
91
|
+
const content = data.choices?.[0]?.message?.content;
|
|
92
|
+
const parsed = JSON.parse(content);
|
|
93
|
+
const newSummary = parsed.summary;
|
|
94
|
+
|
|
95
|
+
await supabase
|
|
96
|
+
.from("shouts")
|
|
97
|
+
.update({ summary: newSummary })
|
|
98
|
+
.eq("id", shout.id);
|
|
99
|
+
|
|
100
|
+
console.log(`✓ ${shout.title?.slice(0, 60) || shout.url}`);
|
|
101
|
+
console.log(` OLD: ${shout.summary?.slice(0, 100)}`);
|
|
102
|
+
console.log(` NEW: ${newSummary?.slice(0, 100)}`);
|
|
103
|
+
console.log();
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.log(`✗ ${shout.title?.slice(0, 60)} — ${err}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
console.log("done!");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
regenerate();
|