@seldonframe/mcp 1.50.0 → 1.52.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/tools.js +18 -54
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seldonframe/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.52.0",
|
|
4
4
|
"mcpName": "io.github.seldonframe/seldonframe-mcp",
|
|
5
5
|
"description": "Open-source GoHighLevel alternative for agencies. 146+ MCP tools that let Claude Code spin up white-labeled client workspaces — CRM, booking, intake forms, landing pages, AI chatbot, and pre-wired agent archetypes (speed-to-lead, missed-call-text-back, review-requester) — in minutes. AGPL-3.0.",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
package/src/tools.js
CHANGED
|
@@ -60,11 +60,9 @@ export const TOOLS = [
|
|
|
60
60
|
{
|
|
61
61
|
name: "create_full_workspace",
|
|
62
62
|
description:
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"MANDATORY FOLLOW-UP: After this returns `status: 'ready'`, ask the operator verbatim 'What email should I use for your account? This is where you'll get your login link and notifications.' Then call `finalize_workspace({ workspace_id, email })`. The admin dashboard URL is ONLY created by finalize_workspace — it does not exist in this response (so there's nothing for you to display prematurely). " +
|
|
67
|
-
"Example: create_full_workspace({ business_name: 'Summit Air Comfort', city: 'Phoenix', state: 'AZ', phone: '(480) 555-2100', services: ['AC repair', 'heating installation', 'duct cleaning'], business_description: 'Residential and commercial HVAC in Phoenix', review_count: 950, review_rating: 4.7, trust_signals: ['licensed', 'bonded', 'insured'], emergency_service: true, same_day: true, service_area: ['Scottsdale', 'Tempe', 'Mesa'] })",
|
|
63
|
+
"Atomic workspace creation from pre-extracted business facts. Equivalent to create_workspace_v2 but single-call (no block-by-block iteration). Used as the follow-up after `create_workspace_from_url` for cases where the operator wants the workspace produced in one shot rather than block-iterated. " +
|
|
64
|
+
"Example: create_full_workspace({ business_name: 'Summit Air Comfort', city: 'Phoenix', state: 'AZ', phone: '(480) 555-2100', services: ['AC repair', 'heating installation', 'duct cleaning'], business_description: 'Residential and commercial HVAC in Phoenix', review_count: 950, review_rating: 4.7, trust_signals: ['licensed', 'bonded', 'insured'], emergency_service: true, same_day: true, service_area: ['Scottsdale', 'Tempe', 'Mesa'] }). " +
|
|
65
|
+
"MANDATORY FOLLOW-UP: same as create_workspace_v2 — after this returns `status: 'ready'`, ask 'What email should I use for your account?' and call finalize_workspace({ workspace_id, email }).",
|
|
68
66
|
inputSchema: obj(
|
|
69
67
|
{
|
|
70
68
|
business_name: str("Business display name (e.g. 'Summit Air Comfort')."),
|
|
@@ -101,19 +99,8 @@ export const TOOLS = [
|
|
|
101
99
|
},
|
|
102
100
|
email: str("Optional contact email surfaced in the landing footer (NOT the operator's account email — that comes via finalize_workspace)."),
|
|
103
101
|
address: str("Optional business address."),
|
|
104
|
-
// v1.48 — schema-level routing guard. The model MUST pass `true`
|
|
105
|
-
// to confirm no URL was available. When the operator's input
|
|
106
|
-
// contains a URL, this assertion is false (don't lie); use
|
|
107
|
-
// `create_workspace_from_url` instead. This makes the routing
|
|
108
|
-
// a hard schema constraint, not just description prose.
|
|
109
|
-
confirmed_no_url_available: {
|
|
110
|
-
type: "boolean",
|
|
111
|
-
enum: [true],
|
|
112
|
-
description:
|
|
113
|
-
"MUST be `true`. Set to true ONLY if the operator did NOT provide a website URL (e.g. they pasted Google Maps text or typed structured fields). If a URL IS available, use `create_workspace_from_url` instead — do NOT lie here. The schema rejects calls without this confirmation.",
|
|
114
|
-
},
|
|
115
102
|
},
|
|
116
|
-
["business_name", "city", "state", "phone", "services", "business_description"
|
|
103
|
+
["business_name", "city", "state", "phone", "services", "business_description"]
|
|
117
104
|
),
|
|
118
105
|
handler: async (args) => {
|
|
119
106
|
const firstEver = isFirstEverCall();
|
|
@@ -489,33 +476,22 @@ export const TOOLS = [
|
|
|
489
476
|
{
|
|
490
477
|
name: "create_workspace_from_url",
|
|
491
478
|
description:
|
|
492
|
-
"
|
|
493
|
-
"
|
|
494
|
-
"
|
|
495
|
-
"
|
|
496
|
-
"DOES NOT GENERATE A LANDING PAGE BY DEFAULT — agency clients typically already have their own website (the URL the operator passed). The chatbot ships as an embed snippet (`chatbot_embed_snippet` in the response) which the agency pastes onto the client's existing site. " +
|
|
497
|
-
"If you ALSO need a SeldonFrame-hosted landing page (only when the client has no site of their own), call `generate_landing_page({ workspace_id })` AFTER this returns — it's a separate ~30-60s opt-in step. " +
|
|
498
|
-
"DO NOT use create_workspace_v2 or create_full_workspace when a URL is available. Those tools require PRE-EXTRACTED structured fields (business_name, services[], phone) and will produce INFERIOR results for URL input because they skip the URL crawler, the FAQ extractor, and the auto-chatbot build. " +
|
|
499
|
-
"DO NOT manually WebFetch the URL first — the SeldonFrame backend's soul-compiler is already wired to scrape + extract. Forwarding pre-fetched HTML wastes a round-trip and bypasses the FAQ-from-URL pipeline. " +
|
|
500
|
-
"Eval gate: chatbot must pass ≥10 of 11 safety + behavior scenarios to ship 'live'. White-label-ready under partner-agency attachment. " +
|
|
501
|
-
"Returns: workspace + agent + chatbot_embed_snippet + faq_summary. MANDATORY FOLLOW-UP: ask the operator verbatim 'What email should I use for your account?' then call finalize_workspace({ workspace_id, email }) — the admin dashboard URL is ONLY created by finalize_workspace. " +
|
|
502
|
-
"⭐ WHEN RENDERING THE RESPONSE BACK TO THE OPERATOR: lead with `primary_deliverable.embed_snippet` + `primary_deliverable.paste_instruction`. The chatbot embed snippet is the agency's HEADLINE deliverable — the agency pastes it onto their CLIENT'S existing website (e.g. dallasplumbing.com), not onto a SeldonFrame-hosted page. DO NOT lead the response summary with 'Public URLs' or a `*.app.seldonframe.com` subdomain. When `include_landing_page: false` (the default for URL flow), there is NO SeldonFrame-hosted landing page — the subdomain is for previewing the chatbot only; don't promote it as a deliverable.",
|
|
479
|
+
"Entry point for URL-based workspace creation. Returns instructions Claude follows: WebFetch the URL, optionally WebFetch up to 2 priority sub-pages (e.g. /about, /services, /contact, /pricing), extract structured business facts, ask the operator for any required field that can't be determined, then call `create_workspace_v2` with the result. " +
|
|
480
|
+
"THIS TOOL DOES NOT CREATE A WORKSPACE — it returns the playbook. The workspace is created by the follow-up `create_workspace_v2` call (then per-block: get_block_skill + persist_block + complete_workspace_v2 + finalize_workspace). " +
|
|
481
|
+
"When operator provides ANY of: 'http://', 'https://', a domain (.com/.io/.net/.co/.app/.dev/.us etc), or 'create workspace for <URL>' — call this tool. Do NOT manually WebFetch first; the instructions returned by this tool tell you exactly what to fetch and in what order. " +
|
|
482
|
+
"MANDATORY FOLLOW-UP: After create_workspace_v2 returns 'ready' and all blocks land via persist_block + complete_workspace_v2, ask the operator 'What email should I use for your account?' and call finalize_workspace({ workspace_id, email }).",
|
|
503
483
|
inputSchema: obj(
|
|
504
484
|
{
|
|
505
|
-
url: str("Business website URL, e.g. https://
|
|
485
|
+
url: str("Business website URL the operator provided, e.g. https://quigleyac.com"),
|
|
506
486
|
},
|
|
507
487
|
["url"]
|
|
508
488
|
),
|
|
509
489
|
handler: async (args) =>
|
|
510
|
-
api(
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
include_landing_page: false,
|
|
516
|
-
},
|
|
517
|
-
allow_anonymous: true,
|
|
518
|
-
}),
|
|
490
|
+
api(
|
|
491
|
+
"GET",
|
|
492
|
+
`/workspace/extract-instructions?url=${encodeURIComponent(args.url)}`,
|
|
493
|
+
{ allow_anonymous: true }
|
|
494
|
+
),
|
|
519
495
|
},
|
|
520
496
|
// v1.47 — explicit opt-in landing-page generator. create_workspace_from_url
|
|
521
497
|
// defaults to NO landing page (the client already has their own site);
|
|
@@ -3018,11 +2994,9 @@ export const TOOLS = [
|
|
|
3018
2994
|
{
|
|
3019
2995
|
name: "create_workspace_v2",
|
|
3020
2996
|
description:
|
|
3021
|
-
"
|
|
3022
|
-
"
|
|
3023
|
-
"
|
|
3024
|
-
"MANDATORY FOLLOW-UP: After this returns `status: 'ready'` AND after all blocks land via persist_block + complete_workspace_v2, ask the operator verbatim 'What email should I use for your account?' Then call finalize_workspace({ workspace_id, email }). The admin dashboard URL is created by finalize_workspace, not here. " +
|
|
3025
|
-
"Why v2: v1 generated all copy server-side from a hardcoded personality system, which produced layer-mismatch bugs every time a new niche was tested. v2 puts the LLM in your context (the IDE agent), reads from one SKILL.md per block, and the generated copy is naturally niche-aware. The operator can later say 'change the hero' and you customize it via persist_block with a customization payload.",
|
|
2997
|
+
"Create a workspace from pre-extracted business facts. Used as the follow-up call after `create_workspace_from_url` returns extraction instructions, OR directly when the operator provides structured info (no URL). " +
|
|
2998
|
+
"Flow: 1) call this tool with the business facts; 2) for each block in `v2.recommended_blocks`, call get_block_skill(name) and use your LLM to generate props matching the SKILL.md prompt + schema; 3) call persist_block({ workspace_id, block_name, generation_prompt, props }) for each; 4) call complete_workspace_v2({ workspace_id }). " +
|
|
2999
|
+
"MANDATORY FOLLOW-UP: After this returns `status: 'ready'` AND after all blocks land via persist_block + complete_workspace_v2, ask the operator verbatim 'What email should I use for your account?' Then call finalize_workspace({ workspace_id, email }). The admin dashboard URL is created by finalize_workspace, not here.",
|
|
3026
3000
|
inputSchema: obj(
|
|
3027
3001
|
{
|
|
3028
3002
|
business_name: str("Business display name."),
|
|
@@ -3046,18 +3020,8 @@ export const TOOLS = [
|
|
|
3046
3020
|
service_area: { type: "array", items: { type: "string" } },
|
|
3047
3021
|
email: str("Optional contact email surfaced in the landing footer (NOT the operator's account email)."),
|
|
3048
3022
|
address: str("Optional business address."),
|
|
3049
|
-
// v1.48 — schema-level routing guard (same as create_full_workspace).
|
|
3050
|
-
// Forces the model to acknowledge no URL was available, preventing
|
|
3051
|
-
// accidental routing to v2 when create_workspace_from_url is the
|
|
3052
|
-
// correct path.
|
|
3053
|
-
confirmed_no_url_available: {
|
|
3054
|
-
type: "boolean",
|
|
3055
|
-
enum: [true],
|
|
3056
|
-
description:
|
|
3057
|
-
"MUST be `true`. Set to true ONLY if the operator did NOT provide a website URL. If a URL IS available, use `create_workspace_from_url` instead — do NOT lie here.",
|
|
3058
|
-
},
|
|
3059
3023
|
},
|
|
3060
|
-
["business_name", "city", "state", "phone", "services", "business_description"
|
|
3024
|
+
["business_name", "city", "state", "phone", "services", "business_description"],
|
|
3061
3025
|
),
|
|
3062
3026
|
handler: async (args) => {
|
|
3063
3027
|
const firstEver = isFirstEverCall();
|