@socialneuron/mcp-server 1.7.14 → 1.7.15
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/CHANGELOG.md +15 -0
- package/README.md +5 -3
- package/dist/http.js +112 -52
- package/dist/index.js +111 -50
- package/dist/sn.js +34 -24
- package/package.json +4 -2
- package/tools.lock.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@socialneuron/mcp-server` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.7.15] - 2026-07-06
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **Public tool surface tightened.** Internal service tools used by Social Neuron's own automation are still registered and scope-gated at runtime, but are no longer advertised on the hosted server card, HTTP discovery, `search_tools`, knowledge documents, or the CLI tool listing. The hosted endpoint now advertises 85 tools; the npm stdio server exposes 87 discoverable tools (including 2 local screen-capture tools).
|
|
10
|
+
- **Tool descriptions cleaned up.** Internal project references and implementation jargon removed from tool descriptions across the catalog.
|
|
11
|
+
- **`run_content_pipeline` scheduling guard restored.** Scheduling again requires `schedule_confirmed=true` after explicit user approval, cannot run with the quality stage skipped, caps generated posts to the requested plan size, drops posts targeting unrequested platforms, and counts scheduled posts against the credit budget. (This hardening was unintentionally dropped in the 1.7.14 source sync.)
|
|
12
|
+
- **Metadata contract unified + CI-guarded.** `server.json` version/pricing/tool-count now match `package.json` and the canonical pricing (MCP requires Pro $49/mo or higher; free tier is 50 credits/mo with no MCP access). Added `mcpName` for MCP Registry ownership verification. New `npm run verify:metadata` gate (wired into CI and release) blocks stale counts, stale pricing, internal codenames, and dead endpoint links from re-entering the public surface.
|
|
13
|
+
- **Docs corrected.** REST API docs (tool count, response `version` example, plan limits), troubleshooting boot log line (95/95), integration methods (stdio vs hosted tool split), and auth docs (plan-scope matrix; removed internal implementation notes). Removed links to the not-yet-deployed `/v1/openapi.json` endpoint.
|
|
14
|
+
- **SDK release path hardened.** `packages/sdk` now ships a `package-lock.json`, the SDK release workflow uses `npm ci --ignore-scripts`, and Dependabot watches `/packages/sdk` and `/apps/content-calendar`.
|
|
15
|
+
|
|
16
|
+
## [1.7.12–1.7.14] - 2026-06/07
|
|
17
|
+
|
|
18
|
+
Released without changelog entries (see git history): OAuth connector flow + DCR, MCP Apps content calendar, trial-key scopes and post-trial degrade, funnel instrumentation, 96-tool catalog sync, dependency cooldown pins.
|
|
19
|
+
|
|
5
20
|
## [1.7.11] - 2026-05-15
|
|
6
21
|
|
|
7
22
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @socialneuron/mcp-server
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> 85+ MCP tools for AI-powered social media management. Create content, schedule posts, track analytics, and optimize performance — all from Claude Code or any MCP client.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@socialneuron/mcp-server)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -92,7 +92,9 @@ Ask Claude things like:
|
|
|
92
92
|
- "Check my analytics and suggest improvements"
|
|
93
93
|
- "Set up autopilot to post 3 times per week"
|
|
94
94
|
|
|
95
|
-
## Tool Categories
|
|
95
|
+
## Tool Categories
|
|
96
|
+
|
|
97
|
+
The hosted endpoint advertises **85 tools** (live count: [server card](https://mcp.socialneuron.com/.well-known/mcp/server-card.json)); the npm stdio server adds 2 local screen-capture tools (87 discoverable). A small set of internal service tools used by Social Neuron's own automation are registered but not part of the public surface.
|
|
96
98
|
|
|
97
99
|
These tools are available to AI agents (Claude, Cursor, etc.) via the MCP protocol.
|
|
98
100
|
|
|
@@ -217,7 +219,7 @@ socialneuron-mcp sn loop
|
|
|
217
219
|
socialneuron-mcp sn credits
|
|
218
220
|
|
|
219
221
|
# Agent-native CLI v2
|
|
220
|
-
socialneuron-mcp sn tools [--module ideation] [--scope mcp:write] # List/filter
|
|
222
|
+
socialneuron-mcp sn tools [--module ideation] [--scope mcp:write] # List/filter available tools
|
|
221
223
|
socialneuron-mcp sn info # Version, auth, credits, tool count
|
|
222
224
|
socialneuron-mcp sn plan list|view|approve # Content plan management
|
|
223
225
|
socialneuron-mcp sn preset list|show|save|delete # Platform presets (6 built-in)
|
package/dist/http.js
CHANGED
|
@@ -707,10 +707,10 @@ var TOOL_SCOPES = {
|
|
|
707
707
|
record_campaign_spend: "mcp:write",
|
|
708
708
|
// mcp:read
|
|
709
709
|
get_active_campaigns: "mcp:read",
|
|
710
|
-
// mcp:read / mcp:write (Skills
|
|
710
|
+
// mcp:read / mcp:write (Skills)
|
|
711
711
|
list_skills: "mcp:read",
|
|
712
712
|
run_skill: "mcp:write",
|
|
713
|
-
// mcp:read (Loop observability — growth-loop KPIs +
|
|
713
|
+
// mcp:read (Loop observability — growth-loop KPIs + content learning state)
|
|
714
714
|
get_loop_pulse: "mcp:read",
|
|
715
715
|
get_bandit_state: "mcp:read"
|
|
716
716
|
};
|
|
@@ -1213,7 +1213,7 @@ function checkRateLimit(category, key) {
|
|
|
1213
1213
|
init_supabase();
|
|
1214
1214
|
|
|
1215
1215
|
// src/lib/version.ts
|
|
1216
|
-
var MCP_VERSION = "1.7.
|
|
1216
|
+
var MCP_VERSION = "1.7.15";
|
|
1217
1217
|
|
|
1218
1218
|
// src/tools/ideation.ts
|
|
1219
1219
|
function asEnvelope(data) {
|
|
@@ -9555,7 +9555,7 @@ var TOOL_CATALOG = [
|
|
|
9555
9555
|
// niche research
|
|
9556
9556
|
{
|
|
9557
9557
|
name: "find_winning_content",
|
|
9558
|
-
description: "Find QA-gated high-performing short-form videos in the project's niche. Returns extracted hook patterns, content structures, and pre-compiled replication prompts
|
|
9558
|
+
description: "Find QA-gated high-performing short-form videos in the project's niche. Returns extracted hook patterns, content structures, and pre-compiled replication prompts.",
|
|
9559
9559
|
module: "research",
|
|
9560
9560
|
scope: "mcp:read"
|
|
9561
9561
|
},
|
|
@@ -9706,59 +9706,68 @@ var TOOL_CATALOG = [
|
|
|
9706
9706
|
// agentic-harness — learning loop write-back
|
|
9707
9707
|
{
|
|
9708
9708
|
name: "write_agent_reflection",
|
|
9709
|
-
description: "Persist a verbal reflection for an agent loop. Provenance keys are restricted
|
|
9709
|
+
description: "Persist a verbal reflection for an agent loop. Provenance keys are restricted to an allowlist: only content_history_id, outcome_event_id, prm_score_ids, and handoff_ids are accepted.",
|
|
9710
9710
|
module: "harness",
|
|
9711
|
-
scope: "mcp:write"
|
|
9711
|
+
scope: "mcp:write",
|
|
9712
|
+
internal: true
|
|
9712
9713
|
},
|
|
9713
9714
|
{
|
|
9714
9715
|
name: "record_outcome",
|
|
9715
|
-
description: "Record an outcome for a published decision event. Idempotent on (decision_event_id, horizon). Only horizon=24h triggers a
|
|
9716
|
+
description: "Record an outcome for a published decision event. Idempotent on (decision_event_id, horizon). Only horizon=24h triggers a learning-loop update.",
|
|
9716
9717
|
module: "harness",
|
|
9717
|
-
scope: "mcp:write"
|
|
9718
|
+
scope: "mcp:write",
|
|
9719
|
+
internal: true
|
|
9718
9720
|
},
|
|
9719
9721
|
// agentic-harness — learning loop read-back
|
|
9720
9722
|
{
|
|
9721
9723
|
name: "read_agent_reflection",
|
|
9722
9724
|
description: "Read past agent reflections for a brand. Ordered by created_at DESC, id ASC (deterministic tiebreak). Only active reflections returned (superseded_by IS NULL). Optional generated_by_agent filter.",
|
|
9723
9725
|
module: "harness",
|
|
9724
|
-
scope: "mcp:read"
|
|
9726
|
+
scope: "mcp:read",
|
|
9727
|
+
internal: true
|
|
9725
9728
|
},
|
|
9726
9729
|
// hermes — autonomous agent integration (closed-loop content)
|
|
9727
9730
|
{
|
|
9728
9731
|
name: "save_draft_to_library",
|
|
9729
|
-
description: "Save a draft post to the SN content library
|
|
9732
|
+
description: "Save a draft post to the SN content library for review before publishing. Drafts land in the content library pending approval.",
|
|
9730
9733
|
module: "hermes",
|
|
9731
|
-
scope: "mcp:write"
|
|
9734
|
+
scope: "mcp:write",
|
|
9735
|
+
internal: true
|
|
9732
9736
|
},
|
|
9733
9737
|
{
|
|
9734
9738
|
name: "record_voice_lesson",
|
|
9735
|
-
description: "Persist a learned voice lesson to
|
|
9739
|
+
description: "Persist a learned voice lesson to the brand voice profile.",
|
|
9736
9740
|
module: "hermes",
|
|
9737
|
-
scope: "mcp:write"
|
|
9741
|
+
scope: "mcp:write",
|
|
9742
|
+
internal: true
|
|
9738
9743
|
},
|
|
9739
9744
|
{
|
|
9740
9745
|
name: "record_observation",
|
|
9741
|
-
description: 'Record an agent observation (e.g. "topic X engagement up 23%") for the
|
|
9746
|
+
description: 'Record an agent observation (e.g. "topic X engagement up 23%") for the analytics playbook.',
|
|
9742
9747
|
module: "hermes",
|
|
9743
|
-
scope: "mcp:write"
|
|
9748
|
+
scope: "mcp:write",
|
|
9749
|
+
internal: true
|
|
9744
9750
|
},
|
|
9745
9751
|
{
|
|
9746
9752
|
name: "record_intel_signal",
|
|
9747
|
-
description: "Record a research/trend signal
|
|
9753
|
+
description: "Record a research/trend signal (news, competitor, community sources) for niche intelligence. Dedupes by URL.",
|
|
9748
9754
|
module: "hermes",
|
|
9749
|
-
scope: "mcp:write"
|
|
9755
|
+
scope: "mcp:write",
|
|
9756
|
+
internal: true
|
|
9750
9757
|
},
|
|
9751
9758
|
{
|
|
9752
9759
|
name: "record_campaign_spend",
|
|
9753
|
-
description: "Log a campaign cost line
|
|
9760
|
+
description: "Log a campaign cost line item. Ownership-checked.",
|
|
9754
9761
|
module: "hermes",
|
|
9755
|
-
scope: "mcp:write"
|
|
9762
|
+
scope: "mcp:write",
|
|
9763
|
+
internal: true
|
|
9756
9764
|
},
|
|
9757
9765
|
{
|
|
9758
9766
|
name: "get_active_campaigns",
|
|
9759
|
-
description: "List currently-running campaigns with thesis, budget, hero format, and current spend.
|
|
9767
|
+
description: "List currently-running campaigns with thesis, budget, hero format, and current spend.",
|
|
9760
9768
|
module: "hermes",
|
|
9761
|
-
scope: "mcp:read"
|
|
9769
|
+
scope: "mcp:read",
|
|
9770
|
+
internal: true
|
|
9762
9771
|
},
|
|
9763
9772
|
// skills (workflow skills — multi-step brand-locked content pipelines)
|
|
9764
9773
|
{
|
|
@@ -9769,20 +9778,20 @@ var TOOL_CATALOG = [
|
|
|
9769
9778
|
},
|
|
9770
9779
|
{
|
|
9771
9780
|
name: "run_skill",
|
|
9772
|
-
description: "Run a Social Neuron workflow skill end-to-end (brand-locked content production).
|
|
9781
|
+
description: "Run a Social Neuron workflow skill end-to-end (brand-locked content production). Returns a structured run preview with the step plan, credit cost, and a deep-link to launch in the SN dashboard.",
|
|
9773
9782
|
module: "skills",
|
|
9774
9783
|
scope: "mcp:write"
|
|
9775
9784
|
},
|
|
9776
|
-
// loop observability (growth-loop KPIs +
|
|
9785
|
+
// loop observability (growth-loop KPIs + content learning state)
|
|
9777
9786
|
{
|
|
9778
9787
|
name: "get_loop_pulse",
|
|
9779
|
-
description: "Read dynamic loop-health KPIs for the growth loop over the last 7 days (reflection/decision coverage, visual gate pass rate,
|
|
9788
|
+
description: "Read dynamic loop-health KPIs for the growth loop over the last 7 days (reflection/decision coverage, visual gate pass rate, learning-update application rate, per-platform uptake, autopilot lag) \u2014 each with an ok/warn/bad status. Use to decide whether the loop is closing or where it is stuck.",
|
|
9780
9789
|
module: "loop",
|
|
9781
9790
|
scope: "mcp:read"
|
|
9782
9791
|
},
|
|
9783
9792
|
{
|
|
9784
9793
|
name: "get_bandit_state",
|
|
9785
|
-
description: "Read the current
|
|
9794
|
+
description: "Read the current content learning state for a project \u2014 top-K arms per (arm_type, platform) with expected performance and uncertainty. Use to reason about which hook family / format / timing slot currently performs best per platform.",
|
|
9786
9795
|
module: "loop",
|
|
9787
9796
|
scope: "mcp:read"
|
|
9788
9797
|
}
|
|
@@ -9892,7 +9901,10 @@ function toolKnowledgeDocument(tool) {
|
|
|
9892
9901
|
};
|
|
9893
9902
|
}
|
|
9894
9903
|
function getKnowledgeDocuments() {
|
|
9895
|
-
return [
|
|
9904
|
+
return [
|
|
9905
|
+
...STATIC_KNOWLEDGE_DOCUMENTS,
|
|
9906
|
+
...TOOL_CATALOG.filter((t) => !t.internal).map(toolKnowledgeDocument)
|
|
9907
|
+
];
|
|
9896
9908
|
}
|
|
9897
9909
|
function tokenize(input) {
|
|
9898
9910
|
return input.toLowerCase().split(/[^a-z0-9:_-]+/).map((token) => token.trim()).filter(Boolean);
|
|
@@ -10008,6 +10020,7 @@ function registerDiscoveryTools(server) {
|
|
|
10008
10020
|
if (query) {
|
|
10009
10021
|
results = searchTools(query);
|
|
10010
10022
|
}
|
|
10023
|
+
results = results.filter((t) => !t.internal);
|
|
10011
10024
|
if (module) {
|
|
10012
10025
|
const moduleTools = getToolsByModule(module);
|
|
10013
10026
|
results = results.filter((t) => moduleTools.some((mt) => mt.name === t.name));
|
|
@@ -10084,6 +10097,7 @@ var PLATFORM_ENUM2 = z24.enum([
|
|
|
10084
10097
|
]);
|
|
10085
10098
|
var BASE_PLAN_CREDITS = 15;
|
|
10086
10099
|
var SOURCE_EXTRACTION_CREDITS = 5;
|
|
10100
|
+
var SCHEDULE_POST_CREDITS = 1;
|
|
10087
10101
|
function registerPipelineTools(server) {
|
|
10088
10102
|
server.tool(
|
|
10089
10103
|
"check_pipeline_readiness",
|
|
@@ -10200,7 +10214,7 @@ function registerPipelineTools(server) {
|
|
|
10200
10214
|
);
|
|
10201
10215
|
server.tool(
|
|
10202
10216
|
"run_content_pipeline",
|
|
10203
|
-
"Run the full content pipeline: research trends \u2192 generate plan \u2192 quality check \u2192 auto-approve \u2192 schedule posts. Chains all stages in one call for maximum efficiency. Set dry_run=true to preview the plan without publishing. Check check_pipeline_readiness first to verify credits, OAuth, and brand profile are ready.",
|
|
10217
|
+
"Run the full content pipeline: research trends \u2192 generate plan \u2192 quality check \u2192 auto-approve \u2192 schedule posts. Chains all stages in one call for maximum efficiency. Set dry_run=true to preview the plan without publishing. To schedule posts, set schedule_confirmed=true after the user explicitly approves publishing. Check check_pipeline_readiness first to verify credits, OAuth, and brand profile are ready.",
|
|
10204
10218
|
{
|
|
10205
10219
|
project_id: z24.string().uuid().optional().describe("Project ID (auto-detected if omitted)"),
|
|
10206
10220
|
topic: z24.string().optional().describe("Content topic (required if no source_url)"),
|
|
@@ -10216,6 +10230,9 @@ function registerPipelineTools(server) {
|
|
|
10216
10230
|
),
|
|
10217
10231
|
max_credits: z24.number().optional().describe("Credit budget cap"),
|
|
10218
10232
|
dry_run: z24.boolean().default(false).describe("If true, skip scheduling and return plan only"),
|
|
10233
|
+
schedule_confirmed: z24.boolean().default(false).describe(
|
|
10234
|
+
"Required to schedule posts. Set true only after explicit user confirmation to publish/schedule."
|
|
10235
|
+
),
|
|
10219
10236
|
skip_stages: z24.array(z24.enum(["research", "quality", "schedule"])).optional().describe("Stages to skip"),
|
|
10220
10237
|
response_format: z24.enum(["text", "json"]).default("json")
|
|
10221
10238
|
},
|
|
@@ -10230,6 +10247,7 @@ function registerPipelineTools(server) {
|
|
|
10230
10247
|
auto_approve_threshold,
|
|
10231
10248
|
max_credits,
|
|
10232
10249
|
dry_run,
|
|
10250
|
+
schedule_confirmed,
|
|
10233
10251
|
skip_stages,
|
|
10234
10252
|
response_format
|
|
10235
10253
|
}) => {
|
|
@@ -10245,6 +10263,29 @@ function registerPipelineTools(server) {
|
|
|
10245
10263
|
};
|
|
10246
10264
|
}
|
|
10247
10265
|
const skipSet = new Set(skip_stages ?? []);
|
|
10266
|
+
const schedulingRequested = !dry_run && !skipSet.has("schedule");
|
|
10267
|
+
if (schedulingRequested && !schedule_confirmed) {
|
|
10268
|
+
return {
|
|
10269
|
+
content: [
|
|
10270
|
+
{
|
|
10271
|
+
type: "text",
|
|
10272
|
+
text: 'Scheduling requires explicit confirmation. Re-run with schedule_confirmed=true after the user approves publishing, or set dry_run=true / skip_stages=["schedule"].'
|
|
10273
|
+
}
|
|
10274
|
+
],
|
|
10275
|
+
isError: true
|
|
10276
|
+
};
|
|
10277
|
+
}
|
|
10278
|
+
if (schedulingRequested && skipSet.has("quality")) {
|
|
10279
|
+
return {
|
|
10280
|
+
content: [
|
|
10281
|
+
{
|
|
10282
|
+
type: "text",
|
|
10283
|
+
text: "Scheduling cannot run when the quality stage is skipped."
|
|
10284
|
+
}
|
|
10285
|
+
],
|
|
10286
|
+
isError: true
|
|
10287
|
+
};
|
|
10288
|
+
}
|
|
10248
10289
|
try {
|
|
10249
10290
|
const resolvedProjectId = project_id ?? await getDefaultProjectId() ?? void 0;
|
|
10250
10291
|
const estimatedCost = BASE_PLAN_CREDITS + (source_url ? SOURCE_EXTRACTION_CREDITS : 0);
|
|
@@ -10287,6 +10328,7 @@ function registerPipelineTools(server) {
|
|
|
10287
10328
|
approval_mode,
|
|
10288
10329
|
auto_approve_threshold,
|
|
10289
10330
|
dry_run,
|
|
10331
|
+
schedule_confirmed,
|
|
10290
10332
|
skip_stages: skip_stages ?? []
|
|
10291
10333
|
},
|
|
10292
10334
|
current_stage: "planning",
|
|
@@ -10352,7 +10394,9 @@ function registerPipelineTools(server) {
|
|
|
10352
10394
|
stagesCompleted.push("planning");
|
|
10353
10395
|
const rawText = String(planData.text ?? planData.content ?? "");
|
|
10354
10396
|
const postsArray = extractJsonArray(rawText);
|
|
10355
|
-
const
|
|
10397
|
+
const requestedPlatformSet = new Set(platforms);
|
|
10398
|
+
const maxPosts = platforms.length * days * posts_per_day;
|
|
10399
|
+
const parsedPosts = (postsArray ?? []).map((p) => ({
|
|
10356
10400
|
id: String(p.id ?? randomUUID3().slice(0, 8)),
|
|
10357
10401
|
day: Number(p.day ?? 1),
|
|
10358
10402
|
date: String(p.date ?? ""),
|
|
@@ -10366,6 +10410,23 @@ function registerPipelineTools(server) {
|
|
|
10366
10410
|
visual_direction: p.visual_direction ? String(p.visual_direction) : void 0,
|
|
10367
10411
|
media_type: p.media_type ? String(p.media_type) : void 0
|
|
10368
10412
|
}));
|
|
10413
|
+
const platformFilteredPosts = parsedPosts.filter(
|
|
10414
|
+
(post) => requestedPlatformSet.has(post.platform)
|
|
10415
|
+
);
|
|
10416
|
+
const posts = platformFilteredPosts.slice(0, maxPosts);
|
|
10417
|
+
if (parsedPosts.length > maxPosts) {
|
|
10418
|
+
errors.push({
|
|
10419
|
+
stage: "planning",
|
|
10420
|
+
message: `AI returned ${parsedPosts.length} posts; truncated to ${maxPosts}.`
|
|
10421
|
+
});
|
|
10422
|
+
}
|
|
10423
|
+
const invalidPlatformCount = parsedPosts.length - platformFilteredPosts.length;
|
|
10424
|
+
if (invalidPlatformCount > 0) {
|
|
10425
|
+
errors.push({
|
|
10426
|
+
stage: "planning",
|
|
10427
|
+
message: `Dropped ${invalidPlatformCount} post(s) with unrequested or invalid platform.`
|
|
10428
|
+
});
|
|
10429
|
+
}
|
|
10369
10430
|
let postsApproved = 0;
|
|
10370
10431
|
let postsFlagged = 0;
|
|
10371
10432
|
if (!skipSet.has("quality")) {
|
|
@@ -10518,6 +10579,7 @@ function registerPipelineTools(server) {
|
|
|
10518
10579
|
});
|
|
10519
10580
|
} else {
|
|
10520
10581
|
postsScheduled++;
|
|
10582
|
+
creditsUsed += SCHEDULE_POST_CREDITS;
|
|
10521
10583
|
}
|
|
10522
10584
|
} catch (schedErr) {
|
|
10523
10585
|
errors.push({
|
|
@@ -12577,13 +12639,13 @@ function asEnvelope24(data) {
|
|
|
12577
12639
|
function registerNicheResearchTools(server) {
|
|
12578
12640
|
server.tool(
|
|
12579
12641
|
"find_winning_content",
|
|
12580
|
-
"Find QA-gated high-performing short-form videos in the project's niche. Returns extracted hook patterns, content structures, and pre-compiled replication prompts you can use to generate new content on a different topic.
|
|
12642
|
+
"Find QA-gated high-performing short-form videos in the project's niche. Returns extracted hook patterns, content structures, and pre-compiled replication prompts you can use to generate new content on a different topic. Only QA-gated winners with a populated replication prompt are returned.",
|
|
12581
12643
|
{
|
|
12582
12644
|
project_id: z29.string().uuid().optional().describe("Project ID (auto-detected if omitted)"),
|
|
12583
12645
|
platform: z29.enum(["tiktok", "instagram", "youtube", "reddit", "twitter"]).optional().describe("Filter to one platform. Omit for all platforms."),
|
|
12584
12646
|
days: z29.number().int().min(1).max(365).default(30).describe("Window: only return winners scanned within this many days."),
|
|
12585
12647
|
limit: z29.number().int().min(1).max(50).default(10).describe("Number of winners to return (1-50)."),
|
|
12586
|
-
min_qa_score: z29.number().min(0).max(1).default(0.5).describe("Minimum QA score (0..1). Default 0.5
|
|
12648
|
+
min_qa_score: z29.number().min(0).max(1).default(0.5).describe("Minimum QA score (0..1). Default 0.5."),
|
|
12587
12649
|
response_format: z29.enum(["text", "json"]).optional()
|
|
12588
12650
|
},
|
|
12589
12651
|
async ({ project_id, platform: platform2, days, limit, min_qa_score, response_format }) => {
|
|
@@ -13241,7 +13303,7 @@ var writeReflectionSchema = {
|
|
|
13241
13303
|
prm_score_ids: z33.array(z33.string()).optional().describe("PRM score IDs that informed this reflection."),
|
|
13242
13304
|
handoff_ids: z33.array(z33.string()).optional().describe("Handoff event IDs that triggered this reflection.")
|
|
13243
13305
|
}).strict().describe(
|
|
13244
|
-
"Source evidence for this reflection. Only these four keys are accepted
|
|
13306
|
+
"Source evidence for this reflection. Only these four keys are accepted \u2014 unknown keys are rejected to prevent spurious provenance claims."
|
|
13245
13307
|
),
|
|
13246
13308
|
brand_id: z33.string().describe("Brand profile UUID this reflection belongs to."),
|
|
13247
13309
|
pipeline_id: z33.string().optional().describe("Optional: pipeline run UUID."),
|
|
@@ -13259,7 +13321,7 @@ var readReflectionSchema = {
|
|
|
13259
13321
|
var recordOutcomeSchema = {
|
|
13260
13322
|
decision_event_id: z33.string().describe("UUID of the decision_events row to record an outcome for."),
|
|
13261
13323
|
horizon: z33.enum(["1h", "6h", "24h"]).describe(
|
|
13262
|
-
"Observation horizon. Only horizon=24h with a non-null reward triggers a
|
|
13324
|
+
"Observation horizon. Only horizon=24h with a non-null reward triggers a learning-loop update; 1h/6h are stored but inert for learning."
|
|
13263
13325
|
),
|
|
13264
13326
|
reward: z33.number().min(0).max(1).describe("Normalised reward signal in [0, 1]. Higher = better outcome."),
|
|
13265
13327
|
outcome_metrics: z33.record(z33.string(), z33.number()).optional().describe(
|
|
@@ -13269,7 +13331,7 @@ var recordOutcomeSchema = {
|
|
|
13269
13331
|
function registerHarnessTools(server, _ctx) {
|
|
13270
13332
|
server.tool(
|
|
13271
13333
|
"write_agent_reflection",
|
|
13272
|
-
"Persist a verbal reflection for an agent loop. Provenance keys are restricted
|
|
13334
|
+
"Persist a verbal reflection for an agent loop. Provenance keys are restricted to an allowlist: only content_history_id, outcome_event_id, prm_score_ids, and handoff_ids are accepted \u2014 unknown keys are rejected at the input layer. Requires mcp:write scope. Returns the created reflection UUID on success.",
|
|
13273
13335
|
writeReflectionSchema,
|
|
13274
13336
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13275
13337
|
async (args) => {
|
|
@@ -13297,7 +13359,7 @@ function registerHarnessTools(server, _ctx) {
|
|
|
13297
13359
|
);
|
|
13298
13360
|
server.tool(
|
|
13299
13361
|
"record_outcome",
|
|
13300
|
-
"Record an outcome for a published decision event. Idempotent on (decision_event_id, horizon) \u2014 safe to call multiple times. Returns idempotent:true when the row already existed (UPDATE), idempotent:false on fresh INSERT. Note: only horizon=24h with reward != null triggers a
|
|
13362
|
+
"Record an outcome for a published decision event. Idempotent on (decision_event_id, horizon) \u2014 safe to call multiple times. Returns idempotent:true when the row already existed (UPDATE), idempotent:false on fresh INSERT. Note: only horizon=24h with reward != null triggers a learning-loop update; 1h/6h outcomes are stored but are inert for the learning loop. Requires mcp:write scope.",
|
|
13301
13363
|
recordOutcomeSchema,
|
|
13302
13364
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13303
13365
|
async (args) => {
|
|
@@ -13381,13 +13443,13 @@ var PLATFORM = z34.enum([
|
|
|
13381
13443
|
function registerHermesTools(server) {
|
|
13382
13444
|
server.tool(
|
|
13383
13445
|
"save_draft_to_library",
|
|
13384
|
-
"Save a draft post to the SN content library. Use when an autonomous agent
|
|
13446
|
+
"Save a draft post to the SN content library. Use when an autonomous agent wants to persist a draft for review before publishing. Lands in the content library with status='draft'. The draft can then be approved/edited in the SN UI.",
|
|
13385
13447
|
{
|
|
13386
13448
|
platform: PLATFORM.describe("Target platform for the draft."),
|
|
13387
13449
|
copy: z34.string().min(1).max(8e3).describe("The draft post body."),
|
|
13388
13450
|
project_id: z34.string().optional().describe("SN project UUID. Optional but recommended."),
|
|
13389
13451
|
media_url: z34.string().url().optional().describe("Optional cover/media URL (R2 signed URL)."),
|
|
13390
|
-
hermes_run_id: z34.string().optional().describe("
|
|
13452
|
+
hermes_run_id: z34.string().optional().describe("Agent run id, for traceability."),
|
|
13391
13453
|
source_intel_ids: z34.array(z34.string()).optional().describe("Optional list of intel_signals.id rows that informed this draft."),
|
|
13392
13454
|
response_format: z34.enum(["text", "json"]).optional()
|
|
13393
13455
|
},
|
|
@@ -13469,11 +13531,11 @@ function registerHermesTools(server) {
|
|
|
13469
13531
|
);
|
|
13470
13532
|
server.tool(
|
|
13471
13533
|
"record_observation",
|
|
13472
|
-
'Record an agent observation ("
|
|
13534
|
+
'Record an agent observation (e.g. "topic X engagement up 23% this week"). Surfaces in the analytics Playbook. Use for weekly reflection digests and mid-campaign pulse summaries.',
|
|
13473
13535
|
{
|
|
13474
|
-
summary: z34.string().min(1).max(2e3).describe("One-paragraph summary,
|
|
13536
|
+
summary: z34.string().min(1).max(2e3).describe("One-paragraph summary, shown to the account owner."),
|
|
13475
13537
|
deltas: z34.record(z34.string(), z34.union([z34.number(), z34.string(), z34.boolean()])).optional().describe("Optional structured key/value payload (e.g. {topic_x_er_pct: 23})."),
|
|
13476
|
-
run_id: z34.string().optional().describe("
|
|
13538
|
+
run_id: z34.string().optional().describe("Agent run id for traceability."),
|
|
13477
13539
|
response_format: z34.enum(["text", "json"]).optional()
|
|
13478
13540
|
},
|
|
13479
13541
|
async ({ summary, deltas, run_id, response_format }) => {
|
|
@@ -13543,7 +13605,7 @@ function registerHermesTools(server) {
|
|
|
13543
13605
|
);
|
|
13544
13606
|
server.tool(
|
|
13545
13607
|
"record_campaign_spend",
|
|
13546
|
-
"Log a campaign cost line. Use when
|
|
13608
|
+
"Log a campaign cost line. Use when an autonomous agent incurs spend that should be attributed to a campaign \u2014 drafts, renders, paid amp. Read aggregate via get_active_campaigns.",
|
|
13547
13609
|
{
|
|
13548
13610
|
campaign_id: z34.string().min(1).max(200).describe("Campaign identifier (slug)."),
|
|
13549
13611
|
category: z34.enum([
|
|
@@ -13587,7 +13649,7 @@ function registerHermesTools(server) {
|
|
|
13587
13649
|
);
|
|
13588
13650
|
server.tool(
|
|
13589
13651
|
"get_active_campaigns",
|
|
13590
|
-
"List currently-running campaigns with thesis, budget, hero format, and current spend.
|
|
13652
|
+
"List currently-running campaigns with thesis, budget, hero format, and current spend. Use to bias drafts toward active campaign themes.",
|
|
13591
13653
|
{
|
|
13592
13654
|
response_format: z34.enum(["text", "json"]).optional()
|
|
13593
13655
|
},
|
|
@@ -13730,7 +13792,7 @@ ${blocks}` }]
|
|
|
13730
13792
|
);
|
|
13731
13793
|
server.tool(
|
|
13732
13794
|
"run_skill",
|
|
13733
|
-
"Run a Social Neuron workflow skill end-to-end (brand-locked content production).
|
|
13795
|
+
"Run a Social Neuron workflow skill end-to-end (brand-locked content production). Returns a structured run preview with the exact step plan, credit cost, and a deep-link to launch the run in the SN dashboard. A future release executes in-process so you can stream step-by-step progress back to the user. Call list_skills first to discover available skill ids.",
|
|
13734
13796
|
{
|
|
13735
13797
|
skill_id: z35.string().describe(
|
|
13736
13798
|
'The id of the skill to run (e.g. "skill-brand-locked-viral-hook-reel"). Use list_skills to discover available ids.'
|
|
@@ -13775,7 +13837,7 @@ ${blocks}` }]
|
|
|
13775
13837
|
inputs,
|
|
13776
13838
|
runUrl,
|
|
13777
13839
|
previewedAt,
|
|
13778
|
-
note: "
|
|
13840
|
+
note: "This release returns a preview. A future release will execute in-process."
|
|
13779
13841
|
}),
|
|
13780
13842
|
null,
|
|
13781
13843
|
2
|
|
@@ -13804,7 +13866,7 @@ ${blocks}` }]
|
|
|
13804
13866
|
"",
|
|
13805
13867
|
`Launch in dashboard: ${runUrl}`,
|
|
13806
13868
|
"",
|
|
13807
|
-
"\u26A0\uFE0F
|
|
13869
|
+
"\u26A0\uFE0F Preview only. End-to-end MCP execution arrives in a future release."
|
|
13808
13870
|
];
|
|
13809
13871
|
return {
|
|
13810
13872
|
content: [{ type: "text", text: lines.join("\n") }]
|
|
@@ -13824,7 +13886,7 @@ function asEnvelope27(data) {
|
|
|
13824
13886
|
function registerLoopPulseTools(server) {
|
|
13825
13887
|
server.tool(
|
|
13826
13888
|
"get_loop_pulse",
|
|
13827
|
-
'Read the dynamic loop-health KPIs for the Social Neuron growth loop over the last 7 days. Returns reflection coverage, decision coverage, visual gate pass rate,
|
|
13889
|
+
'Read the dynamic loop-health KPIs for the Social Neuron growth loop over the last 7 days. Returns reflection coverage, decision coverage, visual gate pass rate, learning-update application rate, per-platform learning uptake, autopilot lag, and pattern aggregation counts \u2014 each with a status ("ok" / "warn" / "bad") and a why-line explaining what the metric measures. Use this to decide whether the loop is closing or where it is stuck before recommending next moves.',
|
|
13828
13890
|
{
|
|
13829
13891
|
response_format: z36.enum(["text", "json"]).optional().describe("Output format. Defaults to text.")
|
|
13830
13892
|
},
|
|
@@ -13880,7 +13942,7 @@ function asEnvelope28(data) {
|
|
|
13880
13942
|
function registerBanditStateTools(server) {
|
|
13881
13943
|
server.tool(
|
|
13882
13944
|
"get_bandit_state",
|
|
13883
|
-
"Read the current
|
|
13945
|
+
"Read the current content learning state for a project. Returns top-K arms per (arm_type, platform) with expected performance and uncertainty. Use this to reason about which hook family / format / timing slot currently performs best on each platform before recommending next moves. Arm types: hook_family, length_bucket (xs/s/m/l/xl by platform), posting_time_bucket (morning/midday/evening/late), content_format (video/carousel/image/caption/text/avatar/storyboard).",
|
|
13884
13946
|
{
|
|
13885
13947
|
project_id: z37.string().uuid().optional().describe("Project UUID. Defaults to the authenticated user default project."),
|
|
13886
13948
|
platform: z37.enum([
|
|
@@ -13931,9 +13993,7 @@ function registerBanditStateTools(server) {
|
|
|
13931
13993
|
});
|
|
13932
13994
|
if (error || !data) {
|
|
13933
13995
|
return {
|
|
13934
|
-
content: [
|
|
13935
|
-
{ type: "text", text: `Failed to read bandit state: ${error || "no data"}` }
|
|
13936
|
-
],
|
|
13996
|
+
content: [{ type: "text", text: `Failed to read bandit state: ${error || "no data"}` }],
|
|
13937
13997
|
isError: true
|
|
13938
13998
|
};
|
|
13939
13999
|
}
|
|
@@ -15280,7 +15340,7 @@ async function computeDiscoveryCatalog() {
|
|
|
15280
15340
|
err?.message
|
|
15281
15341
|
);
|
|
15282
15342
|
}
|
|
15283
|
-
return TOOL_CATALOG.filter((t) => !t.localOnly).map((t) => ({
|
|
15343
|
+
return TOOL_CATALOG.filter((t) => !t.localOnly && !t.internal).map((t) => ({
|
|
15284
15344
|
name: t.name,
|
|
15285
15345
|
description: t.description,
|
|
15286
15346
|
inputSchema: schemaByName.get(t.name) ?? { type: "object", properties: {} }
|
|
@@ -15633,8 +15693,8 @@ app.get("/.well-known/mcp/server-card.json", (_req, res) => {
|
|
|
15633
15693
|
required: true,
|
|
15634
15694
|
schemes: ["oauth2"]
|
|
15635
15695
|
},
|
|
15636
|
-
toolCount: TOOL_CATALOG.filter((t) => !t.localOnly).length,
|
|
15637
|
-
tools: TOOL_CATALOG.filter((t) => !t.localOnly).map((t) => ({
|
|
15696
|
+
toolCount: TOOL_CATALOG.filter((t) => !t.localOnly && !t.internal).length,
|
|
15697
|
+
tools: TOOL_CATALOG.filter((t) => !t.localOnly && !t.internal).map((t) => ({
|
|
15638
15698
|
name: t.name,
|
|
15639
15699
|
description: t.description,
|
|
15640
15700
|
module: t.module,
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var MCP_VERSION;
|
|
|
19
19
|
var init_version = __esm({
|
|
20
20
|
"src/lib/version.ts"() {
|
|
21
21
|
"use strict";
|
|
22
|
-
MCP_VERSION = "1.7.
|
|
22
|
+
MCP_VERSION = "1.7.15";
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -1235,7 +1235,7 @@ var init_tool_catalog = __esm({
|
|
|
1235
1235
|
// niche research
|
|
1236
1236
|
{
|
|
1237
1237
|
name: "find_winning_content",
|
|
1238
|
-
description: "Find QA-gated high-performing short-form videos in the project's niche. Returns extracted hook patterns, content structures, and pre-compiled replication prompts
|
|
1238
|
+
description: "Find QA-gated high-performing short-form videos in the project's niche. Returns extracted hook patterns, content structures, and pre-compiled replication prompts.",
|
|
1239
1239
|
module: "research",
|
|
1240
1240
|
scope: "mcp:read"
|
|
1241
1241
|
},
|
|
@@ -1386,59 +1386,68 @@ var init_tool_catalog = __esm({
|
|
|
1386
1386
|
// agentic-harness — learning loop write-back
|
|
1387
1387
|
{
|
|
1388
1388
|
name: "write_agent_reflection",
|
|
1389
|
-
description: "Persist a verbal reflection for an agent loop. Provenance keys are restricted
|
|
1389
|
+
description: "Persist a verbal reflection for an agent loop. Provenance keys are restricted to an allowlist: only content_history_id, outcome_event_id, prm_score_ids, and handoff_ids are accepted.",
|
|
1390
1390
|
module: "harness",
|
|
1391
|
-
scope: "mcp:write"
|
|
1391
|
+
scope: "mcp:write",
|
|
1392
|
+
internal: true
|
|
1392
1393
|
},
|
|
1393
1394
|
{
|
|
1394
1395
|
name: "record_outcome",
|
|
1395
|
-
description: "Record an outcome for a published decision event. Idempotent on (decision_event_id, horizon). Only horizon=24h triggers a
|
|
1396
|
+
description: "Record an outcome for a published decision event. Idempotent on (decision_event_id, horizon). Only horizon=24h triggers a learning-loop update.",
|
|
1396
1397
|
module: "harness",
|
|
1397
|
-
scope: "mcp:write"
|
|
1398
|
+
scope: "mcp:write",
|
|
1399
|
+
internal: true
|
|
1398
1400
|
},
|
|
1399
1401
|
// agentic-harness — learning loop read-back
|
|
1400
1402
|
{
|
|
1401
1403
|
name: "read_agent_reflection",
|
|
1402
1404
|
description: "Read past agent reflections for a brand. Ordered by created_at DESC, id ASC (deterministic tiebreak). Only active reflections returned (superseded_by IS NULL). Optional generated_by_agent filter.",
|
|
1403
1405
|
module: "harness",
|
|
1404
|
-
scope: "mcp:read"
|
|
1406
|
+
scope: "mcp:read",
|
|
1407
|
+
internal: true
|
|
1405
1408
|
},
|
|
1406
1409
|
// hermes — autonomous agent integration (closed-loop content)
|
|
1407
1410
|
{
|
|
1408
1411
|
name: "save_draft_to_library",
|
|
1409
|
-
description: "Save a draft post to the SN content library
|
|
1412
|
+
description: "Save a draft post to the SN content library for review before publishing. Drafts land in the content library pending approval.",
|
|
1410
1413
|
module: "hermes",
|
|
1411
|
-
scope: "mcp:write"
|
|
1414
|
+
scope: "mcp:write",
|
|
1415
|
+
internal: true
|
|
1412
1416
|
},
|
|
1413
1417
|
{
|
|
1414
1418
|
name: "record_voice_lesson",
|
|
1415
|
-
description: "Persist a learned voice lesson to
|
|
1419
|
+
description: "Persist a learned voice lesson to the brand voice profile.",
|
|
1416
1420
|
module: "hermes",
|
|
1417
|
-
scope: "mcp:write"
|
|
1421
|
+
scope: "mcp:write",
|
|
1422
|
+
internal: true
|
|
1418
1423
|
},
|
|
1419
1424
|
{
|
|
1420
1425
|
name: "record_observation",
|
|
1421
|
-
description: 'Record an agent observation (e.g. "topic X engagement up 23%") for the
|
|
1426
|
+
description: 'Record an agent observation (e.g. "topic X engagement up 23%") for the analytics playbook.',
|
|
1422
1427
|
module: "hermes",
|
|
1423
|
-
scope: "mcp:write"
|
|
1428
|
+
scope: "mcp:write",
|
|
1429
|
+
internal: true
|
|
1424
1430
|
},
|
|
1425
1431
|
{
|
|
1426
1432
|
name: "record_intel_signal",
|
|
1427
|
-
description: "Record a research/trend signal
|
|
1433
|
+
description: "Record a research/trend signal (news, competitor, community sources) for niche intelligence. Dedupes by URL.",
|
|
1428
1434
|
module: "hermes",
|
|
1429
|
-
scope: "mcp:write"
|
|
1435
|
+
scope: "mcp:write",
|
|
1436
|
+
internal: true
|
|
1430
1437
|
},
|
|
1431
1438
|
{
|
|
1432
1439
|
name: "record_campaign_spend",
|
|
1433
|
-
description: "Log a campaign cost line
|
|
1440
|
+
description: "Log a campaign cost line item. Ownership-checked.",
|
|
1434
1441
|
module: "hermes",
|
|
1435
|
-
scope: "mcp:write"
|
|
1442
|
+
scope: "mcp:write",
|
|
1443
|
+
internal: true
|
|
1436
1444
|
},
|
|
1437
1445
|
{
|
|
1438
1446
|
name: "get_active_campaigns",
|
|
1439
|
-
description: "List currently-running campaigns with thesis, budget, hero format, and current spend.
|
|
1447
|
+
description: "List currently-running campaigns with thesis, budget, hero format, and current spend.",
|
|
1440
1448
|
module: "hermes",
|
|
1441
|
-
scope: "mcp:read"
|
|
1449
|
+
scope: "mcp:read",
|
|
1450
|
+
internal: true
|
|
1442
1451
|
},
|
|
1443
1452
|
// skills (workflow skills — multi-step brand-locked content pipelines)
|
|
1444
1453
|
{
|
|
@@ -1449,20 +1458,20 @@ var init_tool_catalog = __esm({
|
|
|
1449
1458
|
},
|
|
1450
1459
|
{
|
|
1451
1460
|
name: "run_skill",
|
|
1452
|
-
description: "Run a Social Neuron workflow skill end-to-end (brand-locked content production).
|
|
1461
|
+
description: "Run a Social Neuron workflow skill end-to-end (brand-locked content production). Returns a structured run preview with the step plan, credit cost, and a deep-link to launch in the SN dashboard.",
|
|
1453
1462
|
module: "skills",
|
|
1454
1463
|
scope: "mcp:write"
|
|
1455
1464
|
},
|
|
1456
|
-
// loop observability (growth-loop KPIs +
|
|
1465
|
+
// loop observability (growth-loop KPIs + content learning state)
|
|
1457
1466
|
{
|
|
1458
1467
|
name: "get_loop_pulse",
|
|
1459
|
-
description: "Read dynamic loop-health KPIs for the growth loop over the last 7 days (reflection/decision coverage, visual gate pass rate,
|
|
1468
|
+
description: "Read dynamic loop-health KPIs for the growth loop over the last 7 days (reflection/decision coverage, visual gate pass rate, learning-update application rate, per-platform uptake, autopilot lag) \u2014 each with an ok/warn/bad status. Use to decide whether the loop is closing or where it is stuck.",
|
|
1460
1469
|
module: "loop",
|
|
1461
1470
|
scope: "mcp:read"
|
|
1462
1471
|
},
|
|
1463
1472
|
{
|
|
1464
1473
|
name: "get_bandit_state",
|
|
1465
|
-
description: "Read the current
|
|
1474
|
+
description: "Read the current content learning state for a project \u2014 top-K arms per (arm_type, platform) with expected performance and uncertainty. Use to reason about which hook family / format / timing slot currently performs best per platform.",
|
|
1466
1475
|
module: "loop",
|
|
1467
1476
|
scope: "mcp:read"
|
|
1468
1477
|
}
|
|
@@ -2637,6 +2646,7 @@ async function handleTools(args, asJson) {
|
|
|
2637
2646
|
if (typeof module === "string") {
|
|
2638
2647
|
tools = getToolsByModule(module);
|
|
2639
2648
|
}
|
|
2649
|
+
tools = tools.filter((t) => !t.internal);
|
|
2640
2650
|
if (asJson) {
|
|
2641
2651
|
emitSnResult({ ok: true, command: "tools", toolCount: tools.length, tools }, true);
|
|
2642
2652
|
return;
|
|
@@ -2667,7 +2677,7 @@ Module: ${moduleName} (${moduleTools.length} tools)`);
|
|
|
2667
2677
|
async function handleInfo(args, asJson) {
|
|
2668
2678
|
const info = {
|
|
2669
2679
|
version: MCP_VERSION,
|
|
2670
|
-
toolCount: TOOL_CATALOG.length,
|
|
2680
|
+
toolCount: TOOL_CATALOG.filter((t) => !t.internal).length,
|
|
2671
2681
|
modules: getModules()
|
|
2672
2682
|
};
|
|
2673
2683
|
try {
|
|
@@ -4270,10 +4280,10 @@ var TOOL_SCOPES = {
|
|
|
4270
4280
|
record_campaign_spend: "mcp:write",
|
|
4271
4281
|
// mcp:read
|
|
4272
4282
|
get_active_campaigns: "mcp:read",
|
|
4273
|
-
// mcp:read / mcp:write (Skills
|
|
4283
|
+
// mcp:read / mcp:write (Skills)
|
|
4274
4284
|
list_skills: "mcp:read",
|
|
4275
4285
|
run_skill: "mcp:write",
|
|
4276
|
-
// mcp:read (Loop observability — growth-loop KPIs +
|
|
4286
|
+
// mcp:read (Loop observability — growth-loop KPIs + content learning state)
|
|
4277
4287
|
get_loop_pulse: "mcp:read",
|
|
4278
4288
|
get_bandit_state: "mcp:read"
|
|
4279
4289
|
};
|
|
@@ -12615,7 +12625,10 @@ function toolKnowledgeDocument(tool) {
|
|
|
12615
12625
|
};
|
|
12616
12626
|
}
|
|
12617
12627
|
function getKnowledgeDocuments() {
|
|
12618
|
-
return [
|
|
12628
|
+
return [
|
|
12629
|
+
...STATIC_KNOWLEDGE_DOCUMENTS,
|
|
12630
|
+
...TOOL_CATALOG.filter((t) => !t.internal).map(toolKnowledgeDocument)
|
|
12631
|
+
];
|
|
12619
12632
|
}
|
|
12620
12633
|
function tokenize(input) {
|
|
12621
12634
|
return input.toLowerCase().split(/[^a-z0-9:_-]+/).map((token) => token.trim()).filter(Boolean);
|
|
@@ -12731,6 +12744,7 @@ function registerDiscoveryTools(server2) {
|
|
|
12731
12744
|
if (query) {
|
|
12732
12745
|
results = searchTools(query);
|
|
12733
12746
|
}
|
|
12747
|
+
results = results.filter((t) => !t.internal);
|
|
12734
12748
|
if (module) {
|
|
12735
12749
|
const moduleTools = getToolsByModule(module);
|
|
12736
12750
|
results = results.filter((t) => moduleTools.some((mt) => mt.name === t.name));
|
|
@@ -12810,6 +12824,7 @@ var PLATFORM_ENUM2 = z24.enum([
|
|
|
12810
12824
|
]);
|
|
12811
12825
|
var BASE_PLAN_CREDITS = 15;
|
|
12812
12826
|
var SOURCE_EXTRACTION_CREDITS = 5;
|
|
12827
|
+
var SCHEDULE_POST_CREDITS = 1;
|
|
12813
12828
|
function registerPipelineTools(server2) {
|
|
12814
12829
|
server2.tool(
|
|
12815
12830
|
"check_pipeline_readiness",
|
|
@@ -12926,7 +12941,7 @@ function registerPipelineTools(server2) {
|
|
|
12926
12941
|
);
|
|
12927
12942
|
server2.tool(
|
|
12928
12943
|
"run_content_pipeline",
|
|
12929
|
-
"Run the full content pipeline: research trends \u2192 generate plan \u2192 quality check \u2192 auto-approve \u2192 schedule posts. Chains all stages in one call for maximum efficiency. Set dry_run=true to preview the plan without publishing. Check check_pipeline_readiness first to verify credits, OAuth, and brand profile are ready.",
|
|
12944
|
+
"Run the full content pipeline: research trends \u2192 generate plan \u2192 quality check \u2192 auto-approve \u2192 schedule posts. Chains all stages in one call for maximum efficiency. Set dry_run=true to preview the plan without publishing. To schedule posts, set schedule_confirmed=true after the user explicitly approves publishing. Check check_pipeline_readiness first to verify credits, OAuth, and brand profile are ready.",
|
|
12930
12945
|
{
|
|
12931
12946
|
project_id: z24.string().uuid().optional().describe("Project ID (auto-detected if omitted)"),
|
|
12932
12947
|
topic: z24.string().optional().describe("Content topic (required if no source_url)"),
|
|
@@ -12942,6 +12957,9 @@ function registerPipelineTools(server2) {
|
|
|
12942
12957
|
),
|
|
12943
12958
|
max_credits: z24.number().optional().describe("Credit budget cap"),
|
|
12944
12959
|
dry_run: z24.boolean().default(false).describe("If true, skip scheduling and return plan only"),
|
|
12960
|
+
schedule_confirmed: z24.boolean().default(false).describe(
|
|
12961
|
+
"Required to schedule posts. Set true only after explicit user confirmation to publish/schedule."
|
|
12962
|
+
),
|
|
12945
12963
|
skip_stages: z24.array(z24.enum(["research", "quality", "schedule"])).optional().describe("Stages to skip"),
|
|
12946
12964
|
response_format: z24.enum(["text", "json"]).default("json")
|
|
12947
12965
|
},
|
|
@@ -12956,6 +12974,7 @@ function registerPipelineTools(server2) {
|
|
|
12956
12974
|
auto_approve_threshold,
|
|
12957
12975
|
max_credits,
|
|
12958
12976
|
dry_run,
|
|
12977
|
+
schedule_confirmed,
|
|
12959
12978
|
skip_stages,
|
|
12960
12979
|
response_format
|
|
12961
12980
|
}) => {
|
|
@@ -12971,6 +12990,29 @@ function registerPipelineTools(server2) {
|
|
|
12971
12990
|
};
|
|
12972
12991
|
}
|
|
12973
12992
|
const skipSet = new Set(skip_stages ?? []);
|
|
12993
|
+
const schedulingRequested = !dry_run && !skipSet.has("schedule");
|
|
12994
|
+
if (schedulingRequested && !schedule_confirmed) {
|
|
12995
|
+
return {
|
|
12996
|
+
content: [
|
|
12997
|
+
{
|
|
12998
|
+
type: "text",
|
|
12999
|
+
text: 'Scheduling requires explicit confirmation. Re-run with schedule_confirmed=true after the user approves publishing, or set dry_run=true / skip_stages=["schedule"].'
|
|
13000
|
+
}
|
|
13001
|
+
],
|
|
13002
|
+
isError: true
|
|
13003
|
+
};
|
|
13004
|
+
}
|
|
13005
|
+
if (schedulingRequested && skipSet.has("quality")) {
|
|
13006
|
+
return {
|
|
13007
|
+
content: [
|
|
13008
|
+
{
|
|
13009
|
+
type: "text",
|
|
13010
|
+
text: "Scheduling cannot run when the quality stage is skipped."
|
|
13011
|
+
}
|
|
13012
|
+
],
|
|
13013
|
+
isError: true
|
|
13014
|
+
};
|
|
13015
|
+
}
|
|
12974
13016
|
try {
|
|
12975
13017
|
const resolvedProjectId = project_id ?? await getDefaultProjectId() ?? void 0;
|
|
12976
13018
|
const estimatedCost = BASE_PLAN_CREDITS + (source_url ? SOURCE_EXTRACTION_CREDITS : 0);
|
|
@@ -13013,6 +13055,7 @@ function registerPipelineTools(server2) {
|
|
|
13013
13055
|
approval_mode,
|
|
13014
13056
|
auto_approve_threshold,
|
|
13015
13057
|
dry_run,
|
|
13058
|
+
schedule_confirmed,
|
|
13016
13059
|
skip_stages: skip_stages ?? []
|
|
13017
13060
|
},
|
|
13018
13061
|
current_stage: "planning",
|
|
@@ -13078,7 +13121,9 @@ function registerPipelineTools(server2) {
|
|
|
13078
13121
|
stagesCompleted.push("planning");
|
|
13079
13122
|
const rawText = String(planData.text ?? planData.content ?? "");
|
|
13080
13123
|
const postsArray = extractJsonArray(rawText);
|
|
13081
|
-
const
|
|
13124
|
+
const requestedPlatformSet = new Set(platforms);
|
|
13125
|
+
const maxPosts = platforms.length * days * posts_per_day;
|
|
13126
|
+
const parsedPosts = (postsArray ?? []).map((p) => ({
|
|
13082
13127
|
id: String(p.id ?? randomUUID3().slice(0, 8)),
|
|
13083
13128
|
day: Number(p.day ?? 1),
|
|
13084
13129
|
date: String(p.date ?? ""),
|
|
@@ -13092,6 +13137,23 @@ function registerPipelineTools(server2) {
|
|
|
13092
13137
|
visual_direction: p.visual_direction ? String(p.visual_direction) : void 0,
|
|
13093
13138
|
media_type: p.media_type ? String(p.media_type) : void 0
|
|
13094
13139
|
}));
|
|
13140
|
+
const platformFilteredPosts = parsedPosts.filter(
|
|
13141
|
+
(post) => requestedPlatformSet.has(post.platform)
|
|
13142
|
+
);
|
|
13143
|
+
const posts = platformFilteredPosts.slice(0, maxPosts);
|
|
13144
|
+
if (parsedPosts.length > maxPosts) {
|
|
13145
|
+
errors.push({
|
|
13146
|
+
stage: "planning",
|
|
13147
|
+
message: `AI returned ${parsedPosts.length} posts; truncated to ${maxPosts}.`
|
|
13148
|
+
});
|
|
13149
|
+
}
|
|
13150
|
+
const invalidPlatformCount = parsedPosts.length - platformFilteredPosts.length;
|
|
13151
|
+
if (invalidPlatformCount > 0) {
|
|
13152
|
+
errors.push({
|
|
13153
|
+
stage: "planning",
|
|
13154
|
+
message: `Dropped ${invalidPlatformCount} post(s) with unrequested or invalid platform.`
|
|
13155
|
+
});
|
|
13156
|
+
}
|
|
13095
13157
|
let postsApproved = 0;
|
|
13096
13158
|
let postsFlagged = 0;
|
|
13097
13159
|
if (!skipSet.has("quality")) {
|
|
@@ -13244,6 +13306,7 @@ function registerPipelineTools(server2) {
|
|
|
13244
13306
|
});
|
|
13245
13307
|
} else {
|
|
13246
13308
|
postsScheduled++;
|
|
13309
|
+
creditsUsed += SCHEDULE_POST_CREDITS;
|
|
13247
13310
|
}
|
|
13248
13311
|
} catch (schedErr) {
|
|
13249
13312
|
errors.push({
|
|
@@ -15313,13 +15376,13 @@ function asEnvelope24(data) {
|
|
|
15313
15376
|
function registerNicheResearchTools(server2) {
|
|
15314
15377
|
server2.tool(
|
|
15315
15378
|
"find_winning_content",
|
|
15316
|
-
"Find QA-gated high-performing short-form videos in the project's niche. Returns extracted hook patterns, content structures, and pre-compiled replication prompts you can use to generate new content on a different topic.
|
|
15379
|
+
"Find QA-gated high-performing short-form videos in the project's niche. Returns extracted hook patterns, content structures, and pre-compiled replication prompts you can use to generate new content on a different topic. Only QA-gated winners with a populated replication prompt are returned.",
|
|
15317
15380
|
{
|
|
15318
15381
|
project_id: z29.string().uuid().optional().describe("Project ID (auto-detected if omitted)"),
|
|
15319
15382
|
platform: z29.enum(["tiktok", "instagram", "youtube", "reddit", "twitter"]).optional().describe("Filter to one platform. Omit for all platforms."),
|
|
15320
15383
|
days: z29.number().int().min(1).max(365).default(30).describe("Window: only return winners scanned within this many days."),
|
|
15321
15384
|
limit: z29.number().int().min(1).max(50).default(10).describe("Number of winners to return (1-50)."),
|
|
15322
|
-
min_qa_score: z29.number().min(0).max(1).default(0.5).describe("Minimum QA score (0..1). Default 0.5
|
|
15385
|
+
min_qa_score: z29.number().min(0).max(1).default(0.5).describe("Minimum QA score (0..1). Default 0.5."),
|
|
15323
15386
|
response_format: z29.enum(["text", "json"]).optional()
|
|
15324
15387
|
},
|
|
15325
15388
|
async ({ project_id, platform: platform3, days, limit, min_qa_score, response_format }) => {
|
|
@@ -15981,7 +16044,7 @@ var writeReflectionSchema = {
|
|
|
15981
16044
|
prm_score_ids: z33.array(z33.string()).optional().describe("PRM score IDs that informed this reflection."),
|
|
15982
16045
|
handoff_ids: z33.array(z33.string()).optional().describe("Handoff event IDs that triggered this reflection.")
|
|
15983
16046
|
}).strict().describe(
|
|
15984
|
-
"Source evidence for this reflection. Only these four keys are accepted
|
|
16047
|
+
"Source evidence for this reflection. Only these four keys are accepted \u2014 unknown keys are rejected to prevent spurious provenance claims."
|
|
15985
16048
|
),
|
|
15986
16049
|
brand_id: z33.string().describe("Brand profile UUID this reflection belongs to."),
|
|
15987
16050
|
pipeline_id: z33.string().optional().describe("Optional: pipeline run UUID."),
|
|
@@ -15999,7 +16062,7 @@ var readReflectionSchema = {
|
|
|
15999
16062
|
var recordOutcomeSchema = {
|
|
16000
16063
|
decision_event_id: z33.string().describe("UUID of the decision_events row to record an outcome for."),
|
|
16001
16064
|
horizon: z33.enum(["1h", "6h", "24h"]).describe(
|
|
16002
|
-
"Observation horizon. Only horizon=24h with a non-null reward triggers a
|
|
16065
|
+
"Observation horizon. Only horizon=24h with a non-null reward triggers a learning-loop update; 1h/6h are stored but inert for learning."
|
|
16003
16066
|
),
|
|
16004
16067
|
reward: z33.number().min(0).max(1).describe("Normalised reward signal in [0, 1]. Higher = better outcome."),
|
|
16005
16068
|
outcome_metrics: z33.record(z33.string(), z33.number()).optional().describe(
|
|
@@ -16009,7 +16072,7 @@ var recordOutcomeSchema = {
|
|
|
16009
16072
|
function registerHarnessTools(server2, _ctx) {
|
|
16010
16073
|
server2.tool(
|
|
16011
16074
|
"write_agent_reflection",
|
|
16012
|
-
"Persist a verbal reflection for an agent loop. Provenance keys are restricted
|
|
16075
|
+
"Persist a verbal reflection for an agent loop. Provenance keys are restricted to an allowlist: only content_history_id, outcome_event_id, prm_score_ids, and handoff_ids are accepted \u2014 unknown keys are rejected at the input layer. Requires mcp:write scope. Returns the created reflection UUID on success.",
|
|
16013
16076
|
writeReflectionSchema,
|
|
16014
16077
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16015
16078
|
async (args) => {
|
|
@@ -16037,7 +16100,7 @@ function registerHarnessTools(server2, _ctx) {
|
|
|
16037
16100
|
);
|
|
16038
16101
|
server2.tool(
|
|
16039
16102
|
"record_outcome",
|
|
16040
|
-
"Record an outcome for a published decision event. Idempotent on (decision_event_id, horizon) \u2014 safe to call multiple times. Returns idempotent:true when the row already existed (UPDATE), idempotent:false on fresh INSERT. Note: only horizon=24h with reward != null triggers a
|
|
16103
|
+
"Record an outcome for a published decision event. Idempotent on (decision_event_id, horizon) \u2014 safe to call multiple times. Returns idempotent:true when the row already existed (UPDATE), idempotent:false on fresh INSERT. Note: only horizon=24h with reward != null triggers a learning-loop update; 1h/6h outcomes are stored but are inert for the learning loop. Requires mcp:write scope.",
|
|
16041
16104
|
recordOutcomeSchema,
|
|
16042
16105
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16043
16106
|
async (args) => {
|
|
@@ -16123,13 +16186,13 @@ var PLATFORM = z34.enum([
|
|
|
16123
16186
|
function registerHermesTools(server2) {
|
|
16124
16187
|
server2.tool(
|
|
16125
16188
|
"save_draft_to_library",
|
|
16126
|
-
"Save a draft post to the SN content library. Use when an autonomous agent
|
|
16189
|
+
"Save a draft post to the SN content library. Use when an autonomous agent wants to persist a draft for review before publishing. Lands in the content library with status='draft'. The draft can then be approved/edited in the SN UI.",
|
|
16127
16190
|
{
|
|
16128
16191
|
platform: PLATFORM.describe("Target platform for the draft."),
|
|
16129
16192
|
copy: z34.string().min(1).max(8e3).describe("The draft post body."),
|
|
16130
16193
|
project_id: z34.string().optional().describe("SN project UUID. Optional but recommended."),
|
|
16131
16194
|
media_url: z34.string().url().optional().describe("Optional cover/media URL (R2 signed URL)."),
|
|
16132
|
-
hermes_run_id: z34.string().optional().describe("
|
|
16195
|
+
hermes_run_id: z34.string().optional().describe("Agent run id, for traceability."),
|
|
16133
16196
|
source_intel_ids: z34.array(z34.string()).optional().describe("Optional list of intel_signals.id rows that informed this draft."),
|
|
16134
16197
|
response_format: z34.enum(["text", "json"]).optional()
|
|
16135
16198
|
},
|
|
@@ -16211,11 +16274,11 @@ function registerHermesTools(server2) {
|
|
|
16211
16274
|
);
|
|
16212
16275
|
server2.tool(
|
|
16213
16276
|
"record_observation",
|
|
16214
|
-
'Record an agent observation ("
|
|
16277
|
+
'Record an agent observation (e.g. "topic X engagement up 23% this week"). Surfaces in the analytics Playbook. Use for weekly reflection digests and mid-campaign pulse summaries.',
|
|
16215
16278
|
{
|
|
16216
|
-
summary: z34.string().min(1).max(2e3).describe("One-paragraph summary,
|
|
16279
|
+
summary: z34.string().min(1).max(2e3).describe("One-paragraph summary, shown to the account owner."),
|
|
16217
16280
|
deltas: z34.record(z34.string(), z34.union([z34.number(), z34.string(), z34.boolean()])).optional().describe("Optional structured key/value payload (e.g. {topic_x_er_pct: 23})."),
|
|
16218
|
-
run_id: z34.string().optional().describe("
|
|
16281
|
+
run_id: z34.string().optional().describe("Agent run id for traceability."),
|
|
16219
16282
|
response_format: z34.enum(["text", "json"]).optional()
|
|
16220
16283
|
},
|
|
16221
16284
|
async ({ summary, deltas, run_id, response_format }) => {
|
|
@@ -16285,7 +16348,7 @@ function registerHermesTools(server2) {
|
|
|
16285
16348
|
);
|
|
16286
16349
|
server2.tool(
|
|
16287
16350
|
"record_campaign_spend",
|
|
16288
|
-
"Log a campaign cost line. Use when
|
|
16351
|
+
"Log a campaign cost line. Use when an autonomous agent incurs spend that should be attributed to a campaign \u2014 drafts, renders, paid amp. Read aggregate via get_active_campaigns.",
|
|
16289
16352
|
{
|
|
16290
16353
|
campaign_id: z34.string().min(1).max(200).describe("Campaign identifier (slug)."),
|
|
16291
16354
|
category: z34.enum([
|
|
@@ -16329,7 +16392,7 @@ function registerHermesTools(server2) {
|
|
|
16329
16392
|
);
|
|
16330
16393
|
server2.tool(
|
|
16331
16394
|
"get_active_campaigns",
|
|
16332
|
-
"List currently-running campaigns with thesis, budget, hero format, and current spend.
|
|
16395
|
+
"List currently-running campaigns with thesis, budget, hero format, and current spend. Use to bias drafts toward active campaign themes.",
|
|
16333
16396
|
{
|
|
16334
16397
|
response_format: z34.enum(["text", "json"]).optional()
|
|
16335
16398
|
},
|
|
@@ -16473,7 +16536,7 @@ ${blocks}` }]
|
|
|
16473
16536
|
);
|
|
16474
16537
|
server2.tool(
|
|
16475
16538
|
"run_skill",
|
|
16476
|
-
"Run a Social Neuron workflow skill end-to-end (brand-locked content production).
|
|
16539
|
+
"Run a Social Neuron workflow skill end-to-end (brand-locked content production). Returns a structured run preview with the exact step plan, credit cost, and a deep-link to launch the run in the SN dashboard. A future release executes in-process so you can stream step-by-step progress back to the user. Call list_skills first to discover available skill ids.",
|
|
16477
16540
|
{
|
|
16478
16541
|
skill_id: z35.string().describe(
|
|
16479
16542
|
'The id of the skill to run (e.g. "skill-brand-locked-viral-hook-reel"). Use list_skills to discover available ids.'
|
|
@@ -16518,7 +16581,7 @@ ${blocks}` }]
|
|
|
16518
16581
|
inputs,
|
|
16519
16582
|
runUrl,
|
|
16520
16583
|
previewedAt,
|
|
16521
|
-
note: "
|
|
16584
|
+
note: "This release returns a preview. A future release will execute in-process."
|
|
16522
16585
|
}),
|
|
16523
16586
|
null,
|
|
16524
16587
|
2
|
|
@@ -16547,7 +16610,7 @@ ${blocks}` }]
|
|
|
16547
16610
|
"",
|
|
16548
16611
|
`Launch in dashboard: ${runUrl}`,
|
|
16549
16612
|
"",
|
|
16550
|
-
"\u26A0\uFE0F
|
|
16613
|
+
"\u26A0\uFE0F Preview only. End-to-end MCP execution arrives in a future release."
|
|
16551
16614
|
];
|
|
16552
16615
|
return {
|
|
16553
16616
|
content: [{ type: "text", text: lines.join("\n") }]
|
|
@@ -16569,7 +16632,7 @@ function asEnvelope27(data) {
|
|
|
16569
16632
|
function registerLoopPulseTools(server2) {
|
|
16570
16633
|
server2.tool(
|
|
16571
16634
|
"get_loop_pulse",
|
|
16572
|
-
'Read the dynamic loop-health KPIs for the Social Neuron growth loop over the last 7 days. Returns reflection coverage, decision coverage, visual gate pass rate,
|
|
16635
|
+
'Read the dynamic loop-health KPIs for the Social Neuron growth loop over the last 7 days. Returns reflection coverage, decision coverage, visual gate pass rate, learning-update application rate, per-platform learning uptake, autopilot lag, and pattern aggregation counts \u2014 each with a status ("ok" / "warn" / "bad") and a why-line explaining what the metric measures. Use this to decide whether the loop is closing or where it is stuck before recommending next moves.',
|
|
16573
16636
|
{
|
|
16574
16637
|
response_format: z36.enum(["text", "json"]).optional().describe("Output format. Defaults to text.")
|
|
16575
16638
|
},
|
|
@@ -16627,7 +16690,7 @@ function asEnvelope28(data) {
|
|
|
16627
16690
|
function registerBanditStateTools(server2) {
|
|
16628
16691
|
server2.tool(
|
|
16629
16692
|
"get_bandit_state",
|
|
16630
|
-
"Read the current
|
|
16693
|
+
"Read the current content learning state for a project. Returns top-K arms per (arm_type, platform) with expected performance and uncertainty. Use this to reason about which hook family / format / timing slot currently performs best on each platform before recommending next moves. Arm types: hook_family, length_bucket (xs/s/m/l/xl by platform), posting_time_bucket (morning/midday/evening/late), content_format (video/carousel/image/caption/text/avatar/storyboard).",
|
|
16631
16694
|
{
|
|
16632
16695
|
project_id: z37.string().uuid().optional().describe("Project UUID. Defaults to the authenticated user default project."),
|
|
16633
16696
|
platform: z37.enum([
|
|
@@ -16678,9 +16741,7 @@ function registerBanditStateTools(server2) {
|
|
|
16678
16741
|
});
|
|
16679
16742
|
if (error || !data) {
|
|
16680
16743
|
return {
|
|
16681
|
-
content: [
|
|
16682
|
-
{ type: "text", text: `Failed to read bandit state: ${error || "no data"}` }
|
|
16683
|
-
],
|
|
16744
|
+
content: [{ type: "text", text: `Failed to read bandit state: ${error || "no data"}` }],
|
|
16684
16745
|
isError: true
|
|
16685
16746
|
};
|
|
16686
16747
|
}
|
package/dist/sn.js
CHANGED
|
@@ -19,7 +19,7 @@ var MCP_VERSION;
|
|
|
19
19
|
var init_version = __esm({
|
|
20
20
|
"src/lib/version.ts"() {
|
|
21
21
|
"use strict";
|
|
22
|
-
MCP_VERSION = "1.7.
|
|
22
|
+
MCP_VERSION = "1.7.15";
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -2377,7 +2377,7 @@ var init_tool_catalog = __esm({
|
|
|
2377
2377
|
// niche research
|
|
2378
2378
|
{
|
|
2379
2379
|
name: "find_winning_content",
|
|
2380
|
-
description: "Find QA-gated high-performing short-form videos in the project's niche. Returns extracted hook patterns, content structures, and pre-compiled replication prompts
|
|
2380
|
+
description: "Find QA-gated high-performing short-form videos in the project's niche. Returns extracted hook patterns, content structures, and pre-compiled replication prompts.",
|
|
2381
2381
|
module: "research",
|
|
2382
2382
|
scope: "mcp:read"
|
|
2383
2383
|
},
|
|
@@ -2528,59 +2528,68 @@ var init_tool_catalog = __esm({
|
|
|
2528
2528
|
// agentic-harness — learning loop write-back
|
|
2529
2529
|
{
|
|
2530
2530
|
name: "write_agent_reflection",
|
|
2531
|
-
description: "Persist a verbal reflection for an agent loop. Provenance keys are restricted
|
|
2531
|
+
description: "Persist a verbal reflection for an agent loop. Provenance keys are restricted to an allowlist: only content_history_id, outcome_event_id, prm_score_ids, and handoff_ids are accepted.",
|
|
2532
2532
|
module: "harness",
|
|
2533
|
-
scope: "mcp:write"
|
|
2533
|
+
scope: "mcp:write",
|
|
2534
|
+
internal: true
|
|
2534
2535
|
},
|
|
2535
2536
|
{
|
|
2536
2537
|
name: "record_outcome",
|
|
2537
|
-
description: "Record an outcome for a published decision event. Idempotent on (decision_event_id, horizon). Only horizon=24h triggers a
|
|
2538
|
+
description: "Record an outcome for a published decision event. Idempotent on (decision_event_id, horizon). Only horizon=24h triggers a learning-loop update.",
|
|
2538
2539
|
module: "harness",
|
|
2539
|
-
scope: "mcp:write"
|
|
2540
|
+
scope: "mcp:write",
|
|
2541
|
+
internal: true
|
|
2540
2542
|
},
|
|
2541
2543
|
// agentic-harness — learning loop read-back
|
|
2542
2544
|
{
|
|
2543
2545
|
name: "read_agent_reflection",
|
|
2544
2546
|
description: "Read past agent reflections for a brand. Ordered by created_at DESC, id ASC (deterministic tiebreak). Only active reflections returned (superseded_by IS NULL). Optional generated_by_agent filter.",
|
|
2545
2547
|
module: "harness",
|
|
2546
|
-
scope: "mcp:read"
|
|
2548
|
+
scope: "mcp:read",
|
|
2549
|
+
internal: true
|
|
2547
2550
|
},
|
|
2548
2551
|
// hermes — autonomous agent integration (closed-loop content)
|
|
2549
2552
|
{
|
|
2550
2553
|
name: "save_draft_to_library",
|
|
2551
|
-
description: "Save a draft post to the SN content library
|
|
2554
|
+
description: "Save a draft post to the SN content library for review before publishing. Drafts land in the content library pending approval.",
|
|
2552
2555
|
module: "hermes",
|
|
2553
|
-
scope: "mcp:write"
|
|
2556
|
+
scope: "mcp:write",
|
|
2557
|
+
internal: true
|
|
2554
2558
|
},
|
|
2555
2559
|
{
|
|
2556
2560
|
name: "record_voice_lesson",
|
|
2557
|
-
description: "Persist a learned voice lesson to
|
|
2561
|
+
description: "Persist a learned voice lesson to the brand voice profile.",
|
|
2558
2562
|
module: "hermes",
|
|
2559
|
-
scope: "mcp:write"
|
|
2563
|
+
scope: "mcp:write",
|
|
2564
|
+
internal: true
|
|
2560
2565
|
},
|
|
2561
2566
|
{
|
|
2562
2567
|
name: "record_observation",
|
|
2563
|
-
description: 'Record an agent observation (e.g. "topic X engagement up 23%") for the
|
|
2568
|
+
description: 'Record an agent observation (e.g. "topic X engagement up 23%") for the analytics playbook.',
|
|
2564
2569
|
module: "hermes",
|
|
2565
|
-
scope: "mcp:write"
|
|
2570
|
+
scope: "mcp:write",
|
|
2571
|
+
internal: true
|
|
2566
2572
|
},
|
|
2567
2573
|
{
|
|
2568
2574
|
name: "record_intel_signal",
|
|
2569
|
-
description: "Record a research/trend signal
|
|
2575
|
+
description: "Record a research/trend signal (news, competitor, community sources) for niche intelligence. Dedupes by URL.",
|
|
2570
2576
|
module: "hermes",
|
|
2571
|
-
scope: "mcp:write"
|
|
2577
|
+
scope: "mcp:write",
|
|
2578
|
+
internal: true
|
|
2572
2579
|
},
|
|
2573
2580
|
{
|
|
2574
2581
|
name: "record_campaign_spend",
|
|
2575
|
-
description: "Log a campaign cost line
|
|
2582
|
+
description: "Log a campaign cost line item. Ownership-checked.",
|
|
2576
2583
|
module: "hermes",
|
|
2577
|
-
scope: "mcp:write"
|
|
2584
|
+
scope: "mcp:write",
|
|
2585
|
+
internal: true
|
|
2578
2586
|
},
|
|
2579
2587
|
{
|
|
2580
2588
|
name: "get_active_campaigns",
|
|
2581
|
-
description: "List currently-running campaigns with thesis, budget, hero format, and current spend.
|
|
2589
|
+
description: "List currently-running campaigns with thesis, budget, hero format, and current spend.",
|
|
2582
2590
|
module: "hermes",
|
|
2583
|
-
scope: "mcp:read"
|
|
2591
|
+
scope: "mcp:read",
|
|
2592
|
+
internal: true
|
|
2584
2593
|
},
|
|
2585
2594
|
// skills (workflow skills — multi-step brand-locked content pipelines)
|
|
2586
2595
|
{
|
|
@@ -2591,20 +2600,20 @@ var init_tool_catalog = __esm({
|
|
|
2591
2600
|
},
|
|
2592
2601
|
{
|
|
2593
2602
|
name: "run_skill",
|
|
2594
|
-
description: "Run a Social Neuron workflow skill end-to-end (brand-locked content production).
|
|
2603
|
+
description: "Run a Social Neuron workflow skill end-to-end (brand-locked content production). Returns a structured run preview with the step plan, credit cost, and a deep-link to launch in the SN dashboard.",
|
|
2595
2604
|
module: "skills",
|
|
2596
2605
|
scope: "mcp:write"
|
|
2597
2606
|
},
|
|
2598
|
-
// loop observability (growth-loop KPIs +
|
|
2607
|
+
// loop observability (growth-loop KPIs + content learning state)
|
|
2599
2608
|
{
|
|
2600
2609
|
name: "get_loop_pulse",
|
|
2601
|
-
description: "Read dynamic loop-health KPIs for the growth loop over the last 7 days (reflection/decision coverage, visual gate pass rate,
|
|
2610
|
+
description: "Read dynamic loop-health KPIs for the growth loop over the last 7 days (reflection/decision coverage, visual gate pass rate, learning-update application rate, per-platform uptake, autopilot lag) \u2014 each with an ok/warn/bad status. Use to decide whether the loop is closing or where it is stuck.",
|
|
2602
2611
|
module: "loop",
|
|
2603
2612
|
scope: "mcp:read"
|
|
2604
2613
|
},
|
|
2605
2614
|
{
|
|
2606
2615
|
name: "get_bandit_state",
|
|
2607
|
-
description: "Read the current
|
|
2616
|
+
description: "Read the current content learning state for a project \u2014 top-K arms per (arm_type, platform) with expected performance and uncertainty. Use to reason about which hook family / format / timing slot currently performs best per platform.",
|
|
2608
2617
|
module: "loop",
|
|
2609
2618
|
scope: "mcp:read"
|
|
2610
2619
|
}
|
|
@@ -2628,6 +2637,7 @@ async function handleTools(args, asJson) {
|
|
|
2628
2637
|
if (typeof module === "string") {
|
|
2629
2638
|
tools = getToolsByModule(module);
|
|
2630
2639
|
}
|
|
2640
|
+
tools = tools.filter((t) => !t.internal);
|
|
2631
2641
|
if (asJson) {
|
|
2632
2642
|
emitSnResult({ ok: true, command: "tools", toolCount: tools.length, tools }, true);
|
|
2633
2643
|
return;
|
|
@@ -2658,7 +2668,7 @@ Module: ${moduleName} (${moduleTools.length} tools)`);
|
|
|
2658
2668
|
async function handleInfo(args, asJson) {
|
|
2659
2669
|
const info = {
|
|
2660
2670
|
version: MCP_VERSION,
|
|
2661
|
-
toolCount: TOOL_CATALOG.length,
|
|
2671
|
+
toolCount: TOOL_CATALOG.filter((t) => !t.internal).length,
|
|
2662
2672
|
modules: getModules()
|
|
2663
2673
|
};
|
|
2664
2674
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@socialneuron/mcp-server",
|
|
3
|
-
"
|
|
3
|
+
"mcpName": "com.socialneuron/mcp-server",
|
|
4
|
+
"version": "1.7.15",
|
|
4
5
|
"description": "Official MCP server, REST API & CLI for Social Neuron \u2014 create, schedule, and optimize social content with 35+ AI models across YouTube, TikTok, and more.",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"main": "dist/index.js",
|
|
@@ -78,7 +79,8 @@
|
|
|
78
79
|
"test:watch": "vitest",
|
|
79
80
|
"clean": "rm -rf dist/",
|
|
80
81
|
"prepublishOnly": "npm run clean && npm run build:all && npm test",
|
|
81
|
-
"build:docs": "node scripts/build-tools-reference.mjs"
|
|
82
|
+
"build:docs": "node scripts/build-tools-reference.mjs",
|
|
83
|
+
"verify:metadata": "node scripts/verify-metadata.mjs"
|
|
82
84
|
},
|
|
83
85
|
"dependencies": {
|
|
84
86
|
"@modelcontextprotocol/ext-apps": "1.7.4",
|
package/tools.lock.json
CHANGED
|
@@ -43,16 +43,16 @@
|
|
|
43
43
|
"fetch_trends": "9efd2a24c9f9d9a3a6fa707f2355c8ef0d12dbc25f416e9237c0b9b73d15007b",
|
|
44
44
|
"fetch_youtube_analytics": "c1d6cf67a5d0ad1696b4320ee91de7ddf58af6cf4a3be537636be746a4822af7",
|
|
45
45
|
"find_next_slots": "fccf3bc7a8ac54b7ee243c59272252dbfeb307ca8d2987b1527b3b904408c909",
|
|
46
|
-
"find_winning_content": "
|
|
46
|
+
"find_winning_content": "f124ae937ea5c3bda8ff9eae82c0ad5b6b095c9a8b1b1812931e10a5b6b35766",
|
|
47
47
|
"generate_carousel": "e6420e3ccc766f5f0fa2e783ecada527dc4ca23b2bb34954963c912eacba84a9",
|
|
48
48
|
"generate_content": "1425c9bc1a8ce800448344a5dea61dd1359eb30872a563b7014d461a696fc6bb",
|
|
49
49
|
"generate_image": "0aa3f14e2b4475ec5909f3b5cc141556b3315989af886a817d9fa7efa1be40e0",
|
|
50
50
|
"generate_performance_digest": "8bbb53edc46698927a10372444239ba9973c5c84e2d0a8160f74192495dae74b",
|
|
51
51
|
"generate_video": "371eda383af033b4f99a1f4447e8a555d16d10688995f6fd55b9c6eb0a619313",
|
|
52
52
|
"generate_voiceover": "ced5ecaf3d936bb7ba0f17d2efe3c15594a061226fbcec1fb572ec87555eff20",
|
|
53
|
-
"get_active_campaigns": "
|
|
53
|
+
"get_active_campaigns": "2e593f72a0a4e1a7744049556444c64eda760a40f5c08d603c32b3b34b1d760a",
|
|
54
54
|
"get_autopilot_status": "c6e689867a32a491a7afbbae46326d223bba412f0c66113ddf4be831c73fd769",
|
|
55
|
-
"get_bandit_state": "
|
|
55
|
+
"get_bandit_state": "1e58ef7836e24d6c9d474bea52916c15397611200e779ded692cc34fe882352f",
|
|
56
56
|
"get_best_posting_times": "78932988a8a2238d81c7b2c065e95349fda3e226702998fb08262b74baff6a53",
|
|
57
57
|
"get_brand_profile": "a0ebd63ebd7032de497751d2b35c0ec78c847869d64e54f7019baa5e532fed0e",
|
|
58
58
|
"get_brand_runtime": "5ac3149d38eac100aca5d769ddb0f5d900832fb29eef78c18dc97678902e3a41",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"get_content_plan": "24a3845da81533d8c22affd76ce28dc179d79f2556c50317eafafbff6b1c520a",
|
|
61
61
|
"get_credit_balance": "e5a086ab75278640ec589893a7575aa561fe0cbc30bbbd67a328fb4032d3164d",
|
|
62
62
|
"get_ideation_context": "fa07379c69b5045de910d8f70445b4bab0bded9f04a1cb41b157cab5a5385f9d",
|
|
63
|
-
"get_loop_pulse": "
|
|
63
|
+
"get_loop_pulse": "cf3c386feaaf6c07d0d1c831451da8f7043ab43ef1e685ae7f90c824f58dd4cd",
|
|
64
64
|
"get_loop_summary": "e37bbc18048c039876dd4f4ba640dbb5e1efaf968fb887cb5479683e2840c1cc",
|
|
65
65
|
"get_mcp_usage": "3e75743113a8e232c831f915edec38143528e92c504219ac3921d524f738df10",
|
|
66
66
|
"get_media_url": "2132e420dc3df1a3c6b8d421b3530be23a7282b8f03af53d26707b337de73370",
|
|
@@ -84,22 +84,22 @@
|
|
|
84
84
|
"quality_check": "a627658f804100276c6335cda8c2359edea163c155fa48aba6adb8749a80416a",
|
|
85
85
|
"quality_check_plan": "9ce43929418427b4b256afc621283c7e887b97e208da849f4ae02418c2103954",
|
|
86
86
|
"read_agent_reflection": "bdf834b25577eb7d8b992b7e7b2462949b2ffd6da664a38eba8b53d1ec8fa5a6",
|
|
87
|
-
"record_campaign_spend": "
|
|
88
|
-
"record_intel_signal": "
|
|
89
|
-
"record_observation": "
|
|
90
|
-
"record_outcome": "
|
|
91
|
-
"record_voice_lesson": "
|
|
87
|
+
"record_campaign_spend": "a7d94f00b4f8875b21f851d5f608a590c958e0acf75cfc45f16c1688f8cd2d2e",
|
|
88
|
+
"record_intel_signal": "35e0841dd77b8d388692fdc15de13f745b8629a57444ca41fc431a4bb2bff3fd",
|
|
89
|
+
"record_observation": "6b560716f8e594016e7a00cca06c1c7988cf72e9890132c680510713e03f1e70",
|
|
90
|
+
"record_outcome": "4b89861c57ea54cbefe48e372c4f0e7a1dbedd1aa3588729c359e5dcf8029f6a",
|
|
91
|
+
"record_voice_lesson": "c296119b1985179f9196e5c220847f0e696dc6b1eaa0017f21f817948bb15914",
|
|
92
92
|
"refresh_platform_analytics": "2cb4e3c060aa26c6616c09fd5c8831f324fb232a2cdb17c69413db26ee732503",
|
|
93
93
|
"render_demo_video": "cd7c3e1c0aef1f4c785f3dda46134cf37717911cfccb8c0513cd1768213005f2",
|
|
94
94
|
"render_hyperframes": "517ccab72014c626074c6da94867b0e81cda51b20b6609287dec9b8dd22f8386",
|
|
95
95
|
"render_template_video": "e696bc84a44e797807f247d5ceb85c66e65657edb82d8ed3e23ef82760fadace",
|
|
96
96
|
"reply_to_comment": "25756f7c2a8c2cd133d7b9623b395c76a452be11f1e9e795a7b03111fd2c1858",
|
|
97
97
|
"respond_plan_approval": "60ef3827a8e199b140a1008746947d6753e766505b2dc69291dccddb276216e2",
|
|
98
|
-
"run_content_pipeline": "
|
|
99
|
-
"run_skill": "
|
|
98
|
+
"run_content_pipeline": "f34d8e01125aa430bde4b3ac06d8d2bdcee64d45e7227ba8e08100e300ad2a69",
|
|
99
|
+
"run_skill": "c9180db96375a64952e292d06f4e39e33241906ba855e77443a528d20cbf474d",
|
|
100
100
|
"save_brand_profile": "70c40bbd3f80b0fb7251050cbd75e5dab79e03b7b6cacc4fa702301e6c7cda67",
|
|
101
101
|
"save_content_plan": "e876db2b255acd39bdced9d5ff9ea0f1b6472343cb6833f9b9d402c7edb27e67",
|
|
102
|
-
"save_draft_to_library": "
|
|
102
|
+
"save_draft_to_library": "cb7c13b408e959ce7b78ed4f9c87872558366a9b9bd7cec8a32f0d9c59541f75",
|
|
103
103
|
"schedule_content_plan": "c61002f034b198e8f405cf9a3a05032d9639ddee75ea6649f08a432fca46542d",
|
|
104
104
|
"schedule_post": "4bd2efdcf9584c579e8adacdfca8d75bdb2c4783013432b047bf3cc521bdd5c1",
|
|
105
105
|
"search": "a985b8fb8cdfc6260bab53bd7aa0c2f02b1f0107c2d3cc4e6c845f7b5f5b0018",
|
|
@@ -114,6 +114,6 @@
|
|
|
114
114
|
"visual_gate_constraints": "77d8c1eeba11d9aa4d3af08609c4c1f1ee365c2d14410efd16a2b9911dd76a8e",
|
|
115
115
|
"visual_quality_check": "63a52d8f38864162b901bdb38cc69032e9f530a8a53f11db617f87b62d70f36c",
|
|
116
116
|
"wait_for_connection": "3f3a587e9a6d3a32e6dd23600665eee1a428721ea352daf6eefafd746bfff8e7",
|
|
117
|
-
"write_agent_reflection": "
|
|
117
|
+
"write_agent_reflection": "eb8faeb1dc7e1e6484a475a82b801108e9c7bbcca20918f73a07f7f4eae724b0"
|
|
118
118
|
}
|
|
119
119
|
}
|