@opennous/mcp 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/server.js +46 -4
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
* get_workspace_status — what's set up in this workspace + a ranked next_steps list (call first)
|
|
25
25
|
* set_workspace_profile— agent-driven onboarding: set the workspace's name, site, type, ICP
|
|
26
26
|
* build_scoring_model — build/rebuild the ICP scoring model from the recorded GTM context
|
|
27
|
+
* record_closed_deals — build the ICP model from real closed-won/lost deals (contrastive lift)
|
|
27
28
|
* connect_integration — connect a key-based integration (Apollo, Prospeo, HubSpot, …)
|
|
28
29
|
* configure_crm_sync — set CRM sync rules (auto-sync, create policy, hygiene cadence)
|
|
29
30
|
* set_trigger — create an outbound event trigger (webhook); list_triggers reads them
|
|
@@ -37,7 +38,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
37
38
|
import { z } from "zod";
|
|
38
39
|
import { get, post } from "./client.js";
|
|
39
40
|
|
|
40
|
-
export const SERVER_VERSION = "0.
|
|
41
|
+
export const SERVER_VERSION = "0.25.0";
|
|
41
42
|
|
|
42
43
|
// ─── helpers ──────────────────────────────────────────────────────────────────
|
|
43
44
|
|
|
@@ -627,9 +628,9 @@ export function createServer() {
|
|
|
627
628
|
"signals so accounts get scored for fit. If a model already exists it is left alone unless you " +
|
|
628
629
|
"pass force:true (use that when the GTM context has changed and the model should be rebuilt). If " +
|
|
629
630
|
"it reports no GTM context yet, record some with update_gtm_profile first, then call this again. " +
|
|
630
|
-
"
|
|
631
|
-
"
|
|
632
|
-
"
|
|
631
|
+
"STRONGER than this tool: if the user can name a few closed-WON and closed-LOST customer domains, " +
|
|
632
|
+
"call record_closed_deals instead (or as well) — it trains the model on real outcomes via " +
|
|
633
|
+
"contrastive lift, which beats a model inferred from a description.",
|
|
633
634
|
{
|
|
634
635
|
force: z.boolean().optional()
|
|
635
636
|
.describe("Rebuild the model even if one already exists — use when the GTM context has changed."),
|
|
@@ -659,6 +660,47 @@ export function createServer() {
|
|
|
659
660
|
}
|
|
660
661
|
);
|
|
661
662
|
|
|
663
|
+
// ===========================================================================
|
|
664
|
+
// TOOL: record_closed_deals — POST /v2/workspace/closed-deals
|
|
665
|
+
// Build the ICP model from REAL outcomes via contrastive lift (won vs lost).
|
|
666
|
+
// ===========================================================================
|
|
667
|
+
server.tool(
|
|
668
|
+
"record_closed_deals",
|
|
669
|
+
"Build (or sharpen) the ICP scoring model from the user's REAL closed deals. Pass closed-WON " +
|
|
670
|
+
"customer domains and closed-LOST domains; Nous enriches each, links the contacts you already " +
|
|
671
|
+
"have there, and runs contrastive lift (what's true of winners but not losers) to discover the " +
|
|
672
|
+
"signals that actually predict revenue — then re-scores open accounts. This is the strongest way " +
|
|
673
|
+
"to build the playbook: a model trained on who actually bought beats one inferred from a " +
|
|
674
|
+
"description. Ask the user for a handful of each (even 3-5 won + 3-5 lost helps). Domains only " +
|
|
675
|
+
"(e.g. 'acme.com'), no scheme.",
|
|
676
|
+
{
|
|
677
|
+
won: z.array(z.string()).optional().describe("Closed-won customer domains, e.g. ['acme.com','globex.com']."),
|
|
678
|
+
lost: z.array(z.string()).optional().describe("Closed-lost domains, e.g. ['tinyco.io']."),
|
|
679
|
+
},
|
|
680
|
+
async ({ won, lost }) => {
|
|
681
|
+
try {
|
|
682
|
+
const r = await post("/v2/workspace/closed-deals", { won: won ?? [], lost: lost ?? [] });
|
|
683
|
+
const disc = r.discovered ?? [];
|
|
684
|
+
const lines = [
|
|
685
|
+
`Learned from ${r.won ?? 0} won + ${r.lost ?? 0} lost deal${(r.won ?? 0) + (r.lost ?? 0) === 1 ? "" : "s"} ` +
|
|
686
|
+
`(${r.enriched ?? 0} enriched, ${r.mode === "winners" ? "winner-signal" : "contrastive-lift"} mode).`,
|
|
687
|
+
];
|
|
688
|
+
if (disc.length) {
|
|
689
|
+
lines.push("", "Signals discovered:");
|
|
690
|
+
for (const d of disc) lines.push(` • ${d.label} (weight ${d.weight})${d.note ? ` — ${d.note}` : ""}`);
|
|
691
|
+
}
|
|
692
|
+
lines.push("", "The model updated and open accounts were re-scored. See the GTM Context page.");
|
|
693
|
+
return { content: [{ type: "text", text: lines.join("\n").trim() }] };
|
|
694
|
+
} catch (e) {
|
|
695
|
+
const msg = String(e?.message ?? e);
|
|
696
|
+
if (msg.includes("need_more_deals")) {
|
|
697
|
+
return { content: [{ type: "text", text: "Give me at least one closed-won or closed-lost domain to learn from." }] };
|
|
698
|
+
}
|
|
699
|
+
throw e;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
);
|
|
703
|
+
|
|
662
704
|
// ===========================================================================
|
|
663
705
|
// TOOL: connect_integration — POST /v2/workspace/integrations
|
|
664
706
|
// The agent connects a KEY-BASED integration for the user (no clicking through
|