thumbgate 1.4.3 → 1.4.5
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.well-known/llms.txt +12 -8
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +18 -8
- package/adapters/README.md +1 -1
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/codex/config.toml +2 -2
- package/adapters/mcp/server-stdio.js +1 -1
- package/adapters/opencode/opencode.json +1 -1
- package/config/github-about.json +2 -2
- package/package.json +158 -10
- package/scripts/billing.js +5 -2
- package/scripts/statusline.sh +1 -0
- package/src/api/server.js +113 -16
- package/src/index.js +3 -0
- package/.claude-plugin/bundle/icon.png +0 -0
- package/.claude-plugin/bundle/icon.svg +0 -18
- package/.claude-plugin/bundle/server/index.js +0 -24
- package/adapters/chatgpt/INSTALL.md +0 -158
- package/adapters/perplexity/.mcp.json +0 -36
- package/adapters/perplexity/config.toml +0 -16
- package/adapters/perplexity/opencode.json +0 -29
- package/bin/memory.sh +0 -64
- package/bin/obsidian-sync.sh +0 -20
- package/plugins/amp-skill/INSTALL.md +0 -52
- package/plugins/amp-skill/SKILL.md +0 -64
- package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +0 -22
- package/plugins/claude-codex-bridge/.mcp.json +0 -14
- package/plugins/claude-codex-bridge/INSTALL.md +0 -43
- package/plugins/claude-codex-bridge/README.md +0 -46
- package/plugins/claude-codex-bridge/scripts/codex-bridge.js +0 -286
- package/plugins/claude-codex-bridge/skills/adversarial-review/SKILL.md +0 -24
- package/plugins/claude-codex-bridge/skills/result/SKILL.md +0 -22
- package/plugins/claude-codex-bridge/skills/review/SKILL.md +0 -28
- package/plugins/claude-codex-bridge/skills/second-pass/SKILL.md +0 -27
- package/plugins/claude-codex-bridge/skills/setup/SKILL.md +0 -21
- package/plugins/claude-codex-bridge/skills/status/SKILL.md +0 -19
- package/plugins/claude-skill/INSTALL.md +0 -55
- package/plugins/claude-skill/SKILL.md +0 -46
- package/plugins/codex-profile/.codex-plugin/plugin.json +0 -43
- package/plugins/codex-profile/.mcp.json +0 -14
- package/plugins/codex-profile/AGENTS.md +0 -20
- package/plugins/codex-profile/INSTALL.md +0 -89
- package/plugins/codex-profile/README.md +0 -61
- package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +0 -23
- package/plugins/cursor-marketplace/CHANGELOG.md +0 -30
- package/plugins/cursor-marketplace/LICENSE +0 -21
- package/plugins/cursor-marketplace/README.md +0 -124
- package/plugins/cursor-marketplace/agents/reliability-reviewer.md +0 -31
- package/plugins/cursor-marketplace/assets/logo-400x400.png +0 -0
- package/plugins/cursor-marketplace/commands/capture-feedback.md +0 -33
- package/plugins/cursor-marketplace/commands/check-gates.md +0 -25
- package/plugins/cursor-marketplace/commands/show-lessons.md +0 -27
- package/plugins/cursor-marketplace/hooks/hooks.json +0 -10
- package/plugins/cursor-marketplace/mcp.json +0 -14
- package/plugins/cursor-marketplace/rules/feedback-capture.mdc +0 -34
- package/plugins/cursor-marketplace/rules/pre-action-gates.mdc +0 -30
- package/plugins/cursor-marketplace/rules/session-continuity.mdc +0 -28
- package/plugins/cursor-marketplace/scripts/gate-check.sh +0 -21
- package/plugins/cursor-marketplace/skills/capture-feedback/SKILL.md +0 -48
- package/plugins/cursor-marketplace/skills/prevention-rules/SKILL.md +0 -31
- package/plugins/cursor-marketplace/skills/recall-context/SKILL.md +0 -30
- package/plugins/cursor-marketplace/skills/search-lessons/SKILL.md +0 -33
- package/plugins/gemini-extension/INSTALL.md +0 -92
- package/plugins/gemini-extension/gemini_prompt.txt +0 -14
- package/plugins/gemini-extension/tool_contract.json +0 -45
- package/plugins/opencode-profile/INSTALL.md +0 -57
- package/public/assets/instagram-card.png +0 -0
- package/public/assets/tiktok-agent-memory.mp4 +0 -0
- package/public/blog.html +0 -474
- package/public/compare/mem0.html +0 -189
- package/public/compare/speclock.html +0 -180
- package/public/compare.html +0 -310
- package/public/dashboard.html +0 -1100
- package/public/guide.html +0 -317
- package/public/guides/claude-code-prevent-repeated-mistakes.html +0 -161
- package/public/guides/codex-cli-guardrails.html +0 -158
- package/public/guides/cursor-prevent-repeated-mistakes.html +0 -161
- package/public/guides/pre-action-gates.html +0 -162
- package/public/guides/stop-repeated-ai-agent-mistakes.html +0 -159
- package/public/index.html +0 -1225
- package/public/js/buyer-intent.js +0 -252
- package/public/learn/agent-harness-pattern.html +0 -180
- package/public/learn/ai-agent-persistent-memory.html +0 -203
- package/public/learn/learn.css +0 -45
- package/public/learn/mcp-pre-action-gates-explained.html +0 -172
- package/public/learn/stop-ai-agent-force-push.html +0 -134
- package/public/learn/vibe-coding-safety-net.html +0 -142
- package/public/learn.html +0 -274
- package/public/lessons.html +0 -967
- package/public/llm-context.md +0 -156
- package/public/pro.html +0 -1087
- package/public/vercel.json +0 -8
- package/scripts/a2ui-engine.js +0 -73
- package/scripts/adk-consolidator.js +0 -274
- package/scripts/agent-security-hardening.js +0 -225
- package/scripts/ai-search-visibility.js +0 -116
- package/scripts/autonomous-sales-agent.js +0 -39
- package/scripts/autoresearch-runner.js +0 -216
- package/scripts/background-agent-governance.js +0 -229
- package/scripts/behavioral-extraction.js +0 -93
- package/scripts/budget-enforcer.js +0 -173
- package/scripts/budget-guard.js +0 -173
- package/scripts/build-claude-mcpb.js +0 -255
- package/scripts/build-codex-plugin.js +0 -152
- package/scripts/capture-railway-diagnostics.sh +0 -97
- package/scripts/changeset-check.js +0 -372
- package/scripts/check-congruence.js +0 -443
- package/scripts/computer-use-firewall.js +0 -280
- package/scripts/content-engine/linkedin-content-generator.js +0 -154
- package/scripts/content-engine/output/linkedin-memento-validation.md +0 -17
- package/scripts/content-engine/output/linkedin-posts-2026-04-09.md +0 -175
- package/scripts/content-engine/reddit-thread-finder.js +0 -154
- package/scripts/context-engine.js +0 -710
- package/scripts/daily-digest.js +0 -11
- package/scripts/data-governance.js +0 -173
- package/scripts/deploy-gcp.sh +0 -44
- package/scripts/deploy-policy.js +0 -249
- package/scripts/disagreement-mining.js +0 -315
- package/scripts/dpo-optimizer.js +0 -206
- package/scripts/ensure-repo-bootstrap.js +0 -130
- package/scripts/ephemeral-agent-store.js +0 -212
- package/scripts/eval-harness.js +0 -56
- package/scripts/export-kto-pairs.js +0 -309
- package/scripts/export-training.js +0 -446
- package/scripts/feedback-fallback.js +0 -111
- package/scripts/feedback-inbox-read.js +0 -162
- package/scripts/feedback-root-consolidator.js +0 -233
- package/scripts/feedback-to-memory.js +0 -185
- package/scripts/gate-satisfy.js +0 -42
- package/scripts/generate-paperbanana-diagrams.sh +0 -99
- package/scripts/generate-pretool-hook.sh +0 -40
- package/scripts/github-about.js +0 -430
- package/scripts/github-outreach.js +0 -65
- package/scripts/gtm-revenue-loop.js +0 -535
- package/scripts/hallucination-detector.js +0 -226
- package/scripts/hf-papers.js +0 -317
- package/scripts/hook-auto-capture.sh +0 -100
- package/scripts/hook-stop-pr-thread-check.sh +0 -68
- package/scripts/hook-stop-self-score.sh +0 -51
- package/scripts/hook-stop-verify-deploy.sh +0 -31
- package/scripts/hook-verify-before-done.sh +0 -20
- package/scripts/managed-dpo-export.js +0 -91
- package/scripts/markdown-escape.js +0 -12
- package/scripts/marketing-experiment.js +0 -657
- package/scripts/memalign-recall.js +0 -111
- package/scripts/memory-migration.js +0 -296
- package/scripts/meta-policy.js +0 -190
- package/scripts/metered-billing.js +0 -16
- package/scripts/model-tier-router.js +0 -310
- package/scripts/money-watcher.js +0 -218
- package/scripts/multi-hop-recall.js +0 -240
- package/scripts/per-step-scoring.js +0 -163
- package/scripts/perplexity-command-center.js +0 -644
- package/scripts/perplexity-marketing.js +0 -454
- package/scripts/pii-scanner.js +0 -153
- package/scripts/plan-gate.js +0 -154
- package/scripts/post-everywhere.js +0 -341
- package/scripts/post-to-x-retry.sh +0 -22
- package/scripts/post-to-x.js +0 -369
- package/scripts/pr-manager.js +0 -421
- package/scripts/principle-extractor.js +0 -162
- package/scripts/pro-features.js +0 -41
- package/scripts/prompt-dlp.js +0 -222
- package/scripts/prove-adapters.js +0 -860
- package/scripts/prove-attribution.js +0 -361
- package/scripts/prove-automation.js +0 -651
- package/scripts/prove-autoresearch.js +0 -304
- package/scripts/prove-claim-verification.js +0 -277
- package/scripts/prove-cloudflare-sandbox.js +0 -161
- package/scripts/prove-data-pipeline.js +0 -408
- package/scripts/prove-data-quality.js +0 -227
- package/scripts/prove-evolution.js +0 -352
- package/scripts/prove-harnesses.js +0 -287
- package/scripts/prove-intelligence.js +0 -257
- package/scripts/prove-lancedb.js +0 -425
- package/scripts/prove-local-intelligence.js +0 -340
- package/scripts/prove-loop-closure.js +0 -263
- package/scripts/prove-packaged-runtime.js +0 -327
- package/scripts/prove-predictive-insights.js +0 -355
- package/scripts/prove-runtime.js +0 -363
- package/scripts/prove-seo-gsd.js +0 -234
- package/scripts/prove-settings.js +0 -279
- package/scripts/prove-subway-upgrades.js +0 -277
- package/scripts/prove-tessl.js +0 -229
- package/scripts/prove-training-export.js +0 -325
- package/scripts/prove-workflow-contract.js +0 -112
- package/scripts/prove-xmemory.js +0 -332
- package/scripts/publish-decision.js +0 -159
- package/scripts/ralph-loop.js +0 -376
- package/scripts/ralph-mode-ci.js +0 -434
- package/scripts/reddit-dm-outreach.js +0 -192
- package/scripts/reddit-monitor-cron.sh +0 -26
- package/scripts/reminder-engine.js +0 -132
- package/scripts/revenue-status.js +0 -472
- package/scripts/rotate-stripe-webhook-secret.js +0 -314
- package/scripts/schedule-manager.js +0 -249
- package/scripts/self-healing-check.js +0 -193
- package/scripts/session-analyzer.js +0 -533
- package/scripts/shieldcortex-memory-firewall-runner.mjs +0 -53
- package/scripts/skill-exporter.js +0 -260
- package/scripts/skill-materializer.js +0 -134
- package/scripts/skill-packs.js +0 -136
- package/scripts/skill-proposer.js +0 -99
- package/scripts/skill-quality-tracker.js +0 -282
- package/scripts/slow-loop.js +0 -72
- package/scripts/social-analytics/db/marketing-db.js +0 -179
- package/scripts/social-analytics/db/schema.sql +0 -55
- package/scripts/social-analytics/digest.js +0 -256
- package/scripts/social-analytics/engagement-audit.js +0 -185
- package/scripts/social-analytics/generate-instagram-card.js +0 -123
- package/scripts/social-analytics/generate-slides.js +0 -268
- package/scripts/social-analytics/instagram-thumbgate-post.js +0 -111
- package/scripts/social-analytics/install-growth-automation.js +0 -114
- package/scripts/social-analytics/load-env.js +0 -77
- package/scripts/social-analytics/mcp-server.js +0 -289
- package/scripts/social-analytics/normalizer.js +0 -580
- package/scripts/social-analytics/notify.js +0 -162
- package/scripts/social-analytics/poll-all.js +0 -107
- package/scripts/social-analytics/pollers/github.js +0 -195
- package/scripts/social-analytics/pollers/instagram.js +0 -253
- package/scripts/social-analytics/pollers/linkedin.js +0 -340
- package/scripts/social-analytics/pollers/plausible.js +0 -245
- package/scripts/social-analytics/pollers/reddit.js +0 -306
- package/scripts/social-analytics/pollers/threads.js +0 -233
- package/scripts/social-analytics/pollers/tiktok.js +0 -203
- package/scripts/social-analytics/pollers/x.js +0 -227
- package/scripts/social-analytics/pollers/youtube.js +0 -304
- package/scripts/social-analytics/pollers/zernio.js +0 -183
- package/scripts/social-analytics/post-video.js +0 -316
- package/scripts/social-analytics/publish-instagram-thumbgate.js +0 -104
- package/scripts/social-analytics/publish-thumbgate-launch.js +0 -322
- package/scripts/social-analytics/publishers/devto.js +0 -122
- package/scripts/social-analytics/publishers/instagram.js +0 -317
- package/scripts/social-analytics/publishers/linkedin.js +0 -294
- package/scripts/social-analytics/publishers/reddit.js +0 -385
- package/scripts/social-analytics/publishers/threads.js +0 -275
- package/scripts/social-analytics/publishers/tiktok.js +0 -217
- package/scripts/social-analytics/publishers/x.js +0 -259
- package/scripts/social-analytics/publishers/youtube.js +0 -223
- package/scripts/social-analytics/publishers/zernio.js +0 -568
- package/scripts/social-analytics/reconcile-thumbgate-campaign.js +0 -165
- package/scripts/social-analytics/run-digest.js +0 -34
- package/scripts/social-analytics/schedule-thumbgate-campaign.js +0 -275
- package/scripts/social-analytics/store.js +0 -455
- package/scripts/social-analytics/sync-launch-assets.js +0 -185
- package/scripts/social-analytics/utm.js +0 -143
- package/scripts/social-pipeline.js +0 -2626
- package/scripts/social-post-hourly.js +0 -228
- package/scripts/social-quality-gate.js +0 -134
- package/scripts/social-reply-monitor.js +0 -592
- package/scripts/status-dashboard.js +0 -155
- package/scripts/stripe-live-status.js +0 -115
- package/scripts/subagent-profiles.js +0 -79
- package/scripts/sync-branch-protection.js +0 -340
- package/scripts/sync-gh-secrets-from-env.sh +0 -70
- package/scripts/sync-github-about.js +0 -55
- package/scripts/sync-version.js +0 -479
- package/scripts/synthetic-dpo.js +0 -234
- package/scripts/tessl-export.js +0 -369
- package/scripts/test-coverage.js +0 -128
- package/scripts/thumbgate-bench.js +0 -494
- package/scripts/thumbgate_session_start.sh +0 -32
- package/scripts/train_from_feedback.py +0 -929
- package/scripts/validate-feedback.js +0 -581
- package/scripts/verify-obsidian-setup.sh +0 -269
- package/scripts/verify-run.js +0 -269
- package/scripts/weekly-auto-post.js +0 -124
- package/scripts/x-autonomous-marketing.js +0 -139
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* MCP stdio server for social analytics.
|
|
5
|
-
*
|
|
6
|
-
* Exposes social metrics from SQLite as queryable tools for Claude.
|
|
7
|
-
* Uses a simple JSON-RPC 2.0 over stdio pattern — no external MCP SDK required.
|
|
8
|
-
*
|
|
9
|
-
* Protocol:
|
|
10
|
-
* - Reads newline-delimited JSON-RPC 2.0 requests from stdin.
|
|
11
|
-
* - Writes newline-delimited JSON-RPC 2.0 responses to stdout.
|
|
12
|
-
* - Supported methods: tools/list, tools/call
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const readline = require('readline');
|
|
16
|
-
|
|
17
|
-
const { initDb, queryMetrics, topContent, getFollowerHistory } = require('./store');
|
|
18
|
-
const { generateDigest } = require('./digest');
|
|
19
|
-
|
|
20
|
-
const VALID_PLATFORMS = ['instagram', 'tiktok', 'github', 'all'];
|
|
21
|
-
|
|
22
|
-
// Tool definitions exposed to Claude.
|
|
23
|
-
const TOOLS = [
|
|
24
|
-
{
|
|
25
|
-
name: 'query_social_metrics',
|
|
26
|
-
description:
|
|
27
|
-
'Returns aggregated engagement metrics from the social analytics database for the given platform and time window.',
|
|
28
|
-
inputSchema: {
|
|
29
|
-
type: 'object',
|
|
30
|
-
properties: {
|
|
31
|
-
platform: {
|
|
32
|
-
type: 'string',
|
|
33
|
-
enum: VALID_PLATFORMS,
|
|
34
|
-
description: 'Platform to query. Use "all" for all platforms combined.',
|
|
35
|
-
},
|
|
36
|
-
days: {
|
|
37
|
-
type: 'number',
|
|
38
|
-
description: 'Number of past days to include in the query.',
|
|
39
|
-
default: 7,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
required: ['platform'],
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
name: 'top_social_content',
|
|
47
|
-
description:
|
|
48
|
-
'Returns top content items ranked by total engagement (likes + comments + shares + saves) over the past N days.',
|
|
49
|
-
inputSchema: {
|
|
50
|
-
type: 'object',
|
|
51
|
-
properties: {
|
|
52
|
-
days: {
|
|
53
|
-
type: 'number',
|
|
54
|
-
description: 'Number of past days to consider.',
|
|
55
|
-
default: 7,
|
|
56
|
-
},
|
|
57
|
-
limit: {
|
|
58
|
-
type: 'number',
|
|
59
|
-
description: 'Maximum number of results to return.',
|
|
60
|
-
default: 10,
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
required: [],
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
name: 'follower_growth',
|
|
68
|
-
description: 'Returns follower count snapshots for a platform over the past N days.',
|
|
69
|
-
inputSchema: {
|
|
70
|
-
type: 'object',
|
|
71
|
-
properties: {
|
|
72
|
-
platform: {
|
|
73
|
-
type: 'string',
|
|
74
|
-
enum: ['instagram', 'tiktok', 'github'],
|
|
75
|
-
description: 'Platform to query follower history for.',
|
|
76
|
-
},
|
|
77
|
-
days: {
|
|
78
|
-
type: 'number',
|
|
79
|
-
description: 'Number of past days to include.',
|
|
80
|
-
default: 7,
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
required: ['platform'],
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
name: 'social_digest',
|
|
88
|
-
description:
|
|
89
|
-
'Returns a full digest object summarising all social metrics, follower deltas, and top content for the past N days.',
|
|
90
|
-
inputSchema: {
|
|
91
|
-
type: 'object',
|
|
92
|
-
properties: {
|
|
93
|
-
days: {
|
|
94
|
-
type: 'number',
|
|
95
|
-
description: 'Number of past days to summarise.',
|
|
96
|
-
default: 7,
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
required: [],
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
];
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Validates that a value is a positive integer (or coerces a numeric string).
|
|
106
|
-
*
|
|
107
|
-
* @param {*} value
|
|
108
|
-
* @param {number} defaultVal
|
|
109
|
-
* @returns {number}
|
|
110
|
-
*/
|
|
111
|
-
function asPositiveInt(value, defaultVal) {
|
|
112
|
-
const n = value == null ? defaultVal : Number(value);
|
|
113
|
-
if (!Number.isFinite(n) || n <= 0) {
|
|
114
|
-
throw new Error(`Expected a positive number, got: ${value}`);
|
|
115
|
-
}
|
|
116
|
-
return Math.floor(n);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Dispatches a tools/call request and returns the result payload.
|
|
121
|
-
*
|
|
122
|
-
* @param {import('better-sqlite3').Database} db
|
|
123
|
-
* @param {string} toolName
|
|
124
|
-
* @param {object} toolArgs
|
|
125
|
-
* @returns {object}
|
|
126
|
-
*/
|
|
127
|
-
function callTool(db, toolName, toolArgs) {
|
|
128
|
-
const args = toolArgs || {};
|
|
129
|
-
|
|
130
|
-
switch (toolName) {
|
|
131
|
-
case 'query_social_metrics': {
|
|
132
|
-
const platform = args.platform;
|
|
133
|
-
if (!VALID_PLATFORMS.includes(platform)) {
|
|
134
|
-
throw new Error(`Invalid platform "${platform}". Must be one of: ${VALID_PLATFORMS.join(', ')}`);
|
|
135
|
-
}
|
|
136
|
-
const days = asPositiveInt(args.days, 7);
|
|
137
|
-
const opts = platform === 'all' ? { days } : { platform, days };
|
|
138
|
-
const rows = queryMetrics(db, opts);
|
|
139
|
-
return { rows };
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
case 'top_social_content': {
|
|
143
|
-
const days = asPositiveInt(args.days, 7);
|
|
144
|
-
const limit = asPositiveInt(args.limit, 10);
|
|
145
|
-
const rows = topContent(db, { days, limit });
|
|
146
|
-
return { rows };
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
case 'follower_growth': {
|
|
150
|
-
const platform = args.platform;
|
|
151
|
-
if (!platform || !['instagram', 'tiktok', 'github'].includes(platform)) {
|
|
152
|
-
throw new Error(`Invalid platform "${platform}". Must be one of: instagram, tiktok, github`);
|
|
153
|
-
}
|
|
154
|
-
const days = asPositiveInt(args.days, 7);
|
|
155
|
-
const rows = getFollowerHistory(db, { platform, days });
|
|
156
|
-
return { rows };
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
case 'social_digest': {
|
|
160
|
-
const days = asPositiveInt(args.days, 7);
|
|
161
|
-
const digest = generateDigest(db, { days });
|
|
162
|
-
return digest;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
default:
|
|
166
|
-
throw new Error(`Unknown tool: ${toolName}`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Builds a JSON-RPC 2.0 success response.
|
|
172
|
-
*
|
|
173
|
-
* @param {string|number|null} id
|
|
174
|
-
* @param {*} result
|
|
175
|
-
* @returns {object}
|
|
176
|
-
*/
|
|
177
|
-
function successResponse(id, result) {
|
|
178
|
-
return { jsonrpc: '2.0', id, result };
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Builds a JSON-RPC 2.0 error response.
|
|
183
|
-
*
|
|
184
|
-
* @param {string|number|null} id
|
|
185
|
-
* @param {number} code
|
|
186
|
-
* @param {string} message
|
|
187
|
-
* @returns {object}
|
|
188
|
-
*/
|
|
189
|
-
function errorResponse(id, code, message) {
|
|
190
|
-
return { jsonrpc: '2.0', id, error: { code, message } };
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Handles a single parsed JSON-RPC request object and returns a response object.
|
|
195
|
-
*
|
|
196
|
-
* @param {import('better-sqlite3').Database} db
|
|
197
|
-
* @param {object} request
|
|
198
|
-
* @returns {object}
|
|
199
|
-
*/
|
|
200
|
-
function handleRequest(db, request) {
|
|
201
|
-
const { id = null, method, params } = request;
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
if (method === 'tools/list') {
|
|
205
|
-
return successResponse(id, { tools: TOOLS });
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (method === 'tools/call') {
|
|
209
|
-
const { name: toolName, arguments: toolArgs } = params || {};
|
|
210
|
-
if (!toolName) {
|
|
211
|
-
return errorResponse(id, -32602, 'Missing required param: name');
|
|
212
|
-
}
|
|
213
|
-
const result = callTool(db, toolName, toolArgs);
|
|
214
|
-
return successResponse(id, {
|
|
215
|
-
content: [
|
|
216
|
-
{
|
|
217
|
-
type: 'text',
|
|
218
|
-
text: JSON.stringify(result, null, 2),
|
|
219
|
-
},
|
|
220
|
-
],
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Method not found.
|
|
225
|
-
return errorResponse(id, -32601, `Method not found: ${method}`);
|
|
226
|
-
} catch (err) {
|
|
227
|
-
return errorResponse(id, -32603, err.message);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Starts the MCP stdio server. Reads newline-delimited JSON from stdin,
|
|
233
|
-
* writes newline-delimited JSON to stdout.
|
|
234
|
-
*/
|
|
235
|
-
function startServer() {
|
|
236
|
-
const db = initDb();
|
|
237
|
-
|
|
238
|
-
const rl = readline.createInterface({
|
|
239
|
-
input: process.stdin,
|
|
240
|
-
output: null,
|
|
241
|
-
terminal: false,
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
process.stderr.write('[social-analytics mcp-server] Listening on stdin...\n');
|
|
245
|
-
|
|
246
|
-
rl.on('line', (line) => {
|
|
247
|
-
const trimmed = line.trim();
|
|
248
|
-
if (!trimmed) return;
|
|
249
|
-
|
|
250
|
-
let request;
|
|
251
|
-
try {
|
|
252
|
-
request = JSON.parse(trimmed);
|
|
253
|
-
} catch (_) {
|
|
254
|
-
const resp = errorResponse(null, -32700, 'Parse error: invalid JSON');
|
|
255
|
-
process.stdout.write(JSON.stringify(resp) + '\n');
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
const response = handleRequest(db, request);
|
|
260
|
-
process.stdout.write(JSON.stringify(response) + '\n');
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
rl.on('close', () => {
|
|
264
|
-
db.close();
|
|
265
|
-
process.stderr.write('[social-analytics mcp-server] stdin closed, shutting down.\n');
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
process.on('SIGINT', () => {
|
|
269
|
-
db.close();
|
|
270
|
-
process.exit(0);
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
process.on('SIGTERM', () => {
|
|
274
|
-
db.close();
|
|
275
|
-
process.exit(0);
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
module.exports = {
|
|
280
|
-
TOOLS,
|
|
281
|
-
callTool,
|
|
282
|
-
handleRequest,
|
|
283
|
-
startServer,
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
// Run as main: start the stdio server.
|
|
287
|
-
if (require.main === module) {
|
|
288
|
-
startServer();
|
|
289
|
-
}
|