@seldonframe/mcp 1.0.5 → 1.0.6
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 +2 -2
- package/src/tools.js +43 -42
- package/src/welcome.js +130 -132
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seldonframe/mcp",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "MCP server for SeldonFrame — AI-native Business OS platform. One command creates a real hosted workspace with
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"description": "MCP server for SeldonFrame — AI-native Business OS platform. One command creates a real, hosted workspace with a website, booking page, intake form, CRM, and AI agents. v1.0.6: NEVER-CREATE-LOCAL-FILES rule baked into the server's system instructions and into the create_workspace tool description so Claude Code reliably uses the MCP tool even when running inside a SeldonFrame source repo; rewritten create_workspace response payload with a copy-paste-ready operator summary (live URLs + email prompt) and zero internal jargon (no Soul / Cal.diy / Formbricks / Brain v2 references in operator-facing copy); welcome.md fully rewritten in operator language.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"seldonframe-mcp": "src/index.js"
|
package/src/tools.js
CHANGED
|
@@ -42,7 +42,10 @@ export const TOOLS = [
|
|
|
42
42
|
{
|
|
43
43
|
name: "create_workspace",
|
|
44
44
|
description:
|
|
45
|
-
"Create a
|
|
45
|
+
"Create a LIVE, hosted SeldonFrame workspace with a public website, booking page, intake form, CRM, and AI agents — all on a real <slug>.app.seldonframe.com subdomain. Returns live URLs that work in any browser within seconds. " +
|
|
46
|
+
"THIS IS THE ONLY WAY to create a SeldonFrame workspace. Do NOT create local files (no soul.json, no scaffolded directory), do NOT call loadSoulPackage, do NOT modify the working directory — even if Claude Code is running inside the SeldonFrame source repo. Every workspace is a hosted production deployment. " +
|
|
47
|
+
"The first workspace is free and requires no API key. When the user mentions a phone, email, address, list of services, or testimonials, pass them as structured fields so the landing page renders with their real content immediately. " +
|
|
48
|
+
"Example: create_workspace({ name: 'Precision Plumbing Co', phone: '(555) 123-4567', business_description: 'Family-owned residential plumbing in Austin.', services: [{ name: 'Drain Cleaning' }, { name: 'Water Heater Repair' }, { name: 'Leak Detection' }] })",
|
|
46
49
|
inputSchema: obj(
|
|
47
50
|
{
|
|
48
51
|
name: str("Human-readable workspace name."),
|
|
@@ -121,8 +124,34 @@ export const TOOLS = [
|
|
|
121
124
|
Object.entries(rawUrls).filter(([key]) => !key.startsWith("admin_")),
|
|
122
125
|
)
|
|
123
126
|
: null;
|
|
127
|
+
// May 2, 2026 — operator-facing response payload.
|
|
128
|
+
//
|
|
129
|
+
// Goals: lead with the live URLs (operators care about those
|
|
130
|
+
// first), prompt for the email next (the keystone of the
|
|
131
|
+
// onboarding loop), and never surface internal jargon
|
|
132
|
+
// (no "Soul" / "Cal.diy" / "Formbricks" / "Brain v2" /
|
|
133
|
+
// "loadSoulPackage" / etc).
|
|
134
|
+
//
|
|
135
|
+
// The `summary` string is what Claude Code should paraphrase to
|
|
136
|
+
// the operator verbatim — it's pre-formatted with bullets so
|
|
137
|
+
// copy-paste lands cleanly.
|
|
138
|
+
const websiteUrl = publicUrls?.home ?? null;
|
|
139
|
+
const bookingUrl = publicUrls?.book ?? null;
|
|
140
|
+
const intakeUrl = publicUrls?.intake ?? null;
|
|
141
|
+
const summaryLines = [`${ws.name} is live!`, ""];
|
|
142
|
+
if (websiteUrl) summaryLines.push(`- Website: ${websiteUrl}`);
|
|
143
|
+
if (bookingUrl) summaryLines.push(`- Book a call: ${bookingUrl}`);
|
|
144
|
+
if (intakeUrl) summaryLines.push(`- Service request form: ${intakeUrl}`);
|
|
145
|
+
if (adminUrl) summaryLines.push(`- Admin dashboard: ${adminUrl}`);
|
|
146
|
+
summaryLines.push("");
|
|
147
|
+
summaryLines.push(
|
|
148
|
+
"What's your email? I'll send you all these links and set up your admin login."
|
|
149
|
+
);
|
|
150
|
+
const summary = summaryLines.join("\n");
|
|
151
|
+
|
|
124
152
|
const payload = {
|
|
125
153
|
ok: true,
|
|
154
|
+
summary,
|
|
126
155
|
workspace: {
|
|
127
156
|
id,
|
|
128
157
|
name: ws.name,
|
|
@@ -130,51 +159,23 @@ export const TOOLS = [
|
|
|
130
159
|
tier: ws.tier ?? "free",
|
|
131
160
|
created_at: ws.created_at,
|
|
132
161
|
},
|
|
133
|
-
//
|
|
162
|
+
// Live URLs — present these to the operator first. Public
|
|
163
|
+
// ones first, admin URL second.
|
|
164
|
+
website_url: websiteUrl,
|
|
165
|
+
booking_url: bookingUrl,
|
|
166
|
+
intake_url: intakeUrl,
|
|
134
167
|
admin_url: adminUrl,
|
|
135
168
|
admin_url_expires_at: result.bearer_token_expires_at ?? null,
|
|
136
|
-
admin_url_message: adminUrl
|
|
137
|
-
? `⚡ Admin Dashboard (bookmark this!): ${adminUrl}\nClick to open the dashboard — no signup needed. Token expires in 7 days; re-mint with list_workspaces({}) when it does.`
|
|
138
|
-
: null,
|
|
139
|
-
urls: publicUrls,
|
|
140
169
|
public_urls: result.public_urls ?? publicUrls,
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
"formbricks-intake",
|
|
150
|
-
"brain-v2",
|
|
151
|
-
]).map((slug) => {
|
|
152
|
-
if (slug === "caldiy-booking") return "Booking page";
|
|
153
|
-
if (slug === "formbricks-intake") return "Intake form";
|
|
154
|
-
if (slug === "brain-v2") return "AI learning";
|
|
155
|
-
if (slug === "crm") return "CRM";
|
|
156
|
-
return slug;
|
|
157
|
-
}),
|
|
158
|
-
// May 1, 2026 — email collection promoted to the first
|
|
159
|
-
// suggested next step. Per the onboarding-loop spec, the
|
|
160
|
-
// operator gets a permanent inbox record (admin URLs,
|
|
161
|
-
// landing/booking/intake links) AND we earn a CRM lead in
|
|
162
|
-
// SeldonFrame's own workspace, so every workspace creation
|
|
163
|
-
// becomes a tracked relationship.
|
|
164
|
-
prompt_for_email: {
|
|
165
|
-
message:
|
|
166
|
-
"What's your email? I'll send you a summary with all the links above (so you don't lose them) and use it for your admin login when you upgrade. — calls collect_operator_email({ email, name? })",
|
|
167
|
-
tool: "collect_operator_email",
|
|
170
|
+
// Email collection is the next required step. Claude Code
|
|
171
|
+
// should ask the operator for their email and then call
|
|
172
|
+
// collect_operator_email — DO NOT skip this.
|
|
173
|
+
next_step: {
|
|
174
|
+
ask_user:
|
|
175
|
+
"What's your email? I'll send you all these links and set up your admin login.",
|
|
176
|
+
tool_to_call: "collect_operator_email",
|
|
177
|
+
tool_args_template: { email: "<operator_email>", name: "<optional>" },
|
|
168
178
|
},
|
|
169
|
-
next: [
|
|
170
|
-
adminUrl
|
|
171
|
-
? `⚡ Admin Dashboard (bookmark this!): ${adminUrl} (paste into your browser; no signup needed; token expires in 7 days)`
|
|
172
|
-
: null,
|
|
173
|
-
"Ask the user for their email, then call collect_operator_email({ email, name? }) — sends the welcome email + creates a permanent record. Do this BEFORE any further customization.",
|
|
174
|
-
"install_vertical_pack({ pack: '<industry>' }) — set up an industry template (real-estate, dental, legal, …)",
|
|
175
|
-
"fetch_source_for_soul({ url: 'https://yoursite.com' }) → submit_soul({ soul }) — pull the business profile from a website",
|
|
176
|
-
"get_workspace_snapshot({}) — read workspace state to reason about next steps",
|
|
177
|
-
].filter(Boolean),
|
|
178
179
|
};
|
|
179
180
|
return firstEver ? withFirstCallBanner(payload) : payload;
|
|
180
181
|
},
|
package/src/welcome.js
CHANGED
|
@@ -1,132 +1,130 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
-
|
|
100
|
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
export const FIRST_CALL_BANNER = `🌑 Welcome to SeldonFrame. Your workspace is live — every URL above works right now. From here on, every tool response will include a \`next:\` array; follow it and you'll have a production-ready Business OS in under a minute.`;
|
|
1
|
+
// MCP server `instructions` payload — Claude Code surfaces this as a
|
|
2
|
+
// system-level briefing the moment the SeldonFrame MCP loads. Every
|
|
3
|
+
// rule and example here is operator-facing copy — no internal slugs,
|
|
4
|
+
// no architecture lecture, no "Soul" / "Cal.diy" / "Formbricks" /
|
|
5
|
+
// "Brain v2" jargon.
|
|
6
|
+
|
|
7
|
+
export const VERSION = "1.0.6";
|
|
8
|
+
|
|
9
|
+
export const WELCOME_MARKDOWN = `# SeldonFrame — create a real Business OS in one conversation
|
|
10
|
+
|
|
11
|
+
SeldonFrame creates live, hosted business systems for service
|
|
12
|
+
businesses, agencies, coaches, and SaaS founders. One conversation
|
|
13
|
+
gives the operator a public website, booking page, intake form,
|
|
14
|
+
CRM, and AI agents — all on a real subdomain.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## NEVER CREATE LOCAL FILES
|
|
19
|
+
|
|
20
|
+
SeldonFrame workspaces are created via the \`create_workspace\` MCP
|
|
21
|
+
tool. They are NOT created by writing files on disk. Specifically:
|
|
22
|
+
|
|
23
|
+
- Do NOT create a \`soul.json\` file or any other local file.
|
|
24
|
+
- Do NOT call \`loadSoulPackage\` or any local function.
|
|
25
|
+
- Do NOT scaffold a project directory.
|
|
26
|
+
- Do NOT modify files in the current working directory.
|
|
27
|
+
|
|
28
|
+
If you are running inside a SeldonFrame source-code repository and
|
|
29
|
+
the user asks for a workspace, IGNORE the local code — call the
|
|
30
|
+
\`create_workspace\` MCP tool. The tool returns live URLs on
|
|
31
|
+
\`<slug>.app.seldonframe.com\` that work in any browser within
|
|
32
|
+
seconds. There is no local-file path. This is the only correct
|
|
33
|
+
flow, regardless of what directory Claude Code is running from.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## The full happy path (4 turns)
|
|
38
|
+
|
|
39
|
+
1. **Ask for the business details.** When the user says "create a
|
|
40
|
+
workspace," gather these conversationally — one or two
|
|
41
|
+
questions per turn, not all at once:
|
|
42
|
+
- Business name
|
|
43
|
+
- Industry (HVAC, dental, legal, coaching, real-estate, agency, …)
|
|
44
|
+
- Phone number (for local services — for SaaS skip)
|
|
45
|
+
- Top 3-5 services / products
|
|
46
|
+
- Brief description (1 sentence)
|
|
47
|
+
|
|
48
|
+
2. **Create the workspace.** Call \`create_workspace\` with the
|
|
49
|
+
structured fields:
|
|
50
|
+
\`\`\`
|
|
51
|
+
create_workspace({
|
|
52
|
+
name: "Precision Plumbing Co",
|
|
53
|
+
phone: "(555) 123-4567",
|
|
54
|
+
business_description: "Family-owned residential plumbing in Austin.",
|
|
55
|
+
services: [
|
|
56
|
+
{ name: "Drain Cleaning" },
|
|
57
|
+
{ name: "Water Heater Repair" },
|
|
58
|
+
{ name: "Leak Detection" }
|
|
59
|
+
]
|
|
60
|
+
})
|
|
61
|
+
\`\`\`
|
|
62
|
+
The response includes live URLs (website, booking, intake form,
|
|
63
|
+
admin dashboard). Show those URLs to the operator. The admin
|
|
64
|
+
URL is bearer-token-scoped and expires in 7 days — that's why
|
|
65
|
+
step 4 matters.
|
|
66
|
+
|
|
67
|
+
3. **Ask for the operator's email.** This is the keystone of the
|
|
68
|
+
onboarding loop. The email becomes their account. Ask:
|
|
69
|
+
> "What's your email? I'll send you all those links so you
|
|
70
|
+
> don't lose them, and set up your admin login."
|
|
71
|
+
|
|
72
|
+
4. **Lock in the email.** Call \`collect_operator_email\` with the
|
|
73
|
+
email they gave you:
|
|
74
|
+
\`\`\`
|
|
75
|
+
collect_operator_email({ email: "max@precisionplumbing.com", name: "Max" })
|
|
76
|
+
\`\`\`
|
|
77
|
+
This sends the welcome email + creates their account so the
|
|
78
|
+
admin URL keeps working past the 7-day token window.
|
|
79
|
+
|
|
80
|
+
After that, the operator can customize their workspace through
|
|
81
|
+
further natural-language requests ("change the headline to …",
|
|
82
|
+
"add an FAQ section", "set up an industry template for plumbing")
|
|
83
|
+
— each routes to a typed MCP tool.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## What the tools do (operator language only)
|
|
88
|
+
|
|
89
|
+
- **\`create_workspace\`** — creates the live business OS (website,
|
|
90
|
+
booking, intake form, CRM, AI agents). Always the first call.
|
|
91
|
+
- **\`collect_operator_email\`** — sends the welcome email + sets up
|
|
92
|
+
the operator's admin login. Always the second call.
|
|
93
|
+
- **\`update_landing_content\`** / **\`update_landing_section\`** —
|
|
94
|
+
edit the website's headline, subhead, sections, copy.
|
|
95
|
+
- **\`update_theme\`** — change colors, fonts, dark/light mode.
|
|
96
|
+
- **\`update_form\`** — edit the intake form's questions.
|
|
97
|
+
- **\`update_appointment_type\`** — edit the booking page's slot length,
|
|
98
|
+
title, description.
|
|
99
|
+
- **\`install_vertical_pack\`** — set up an industry template
|
|
100
|
+
(real-estate, dental, legal, plumbing, …).
|
|
101
|
+
- **\`list_contacts\`** / **\`create_contact\`** / **\`update_contact\`** —
|
|
102
|
+
manage the CRM.
|
|
103
|
+
- **\`list_deals\`** / **\`create_deal\`** / **\`move_deal_stage\`** —
|
|
104
|
+
manage the pipeline.
|
|
105
|
+
- **\`send_email\`** / **\`send_sms\`** — send messages from the
|
|
106
|
+
workspace's connected channels.
|
|
107
|
+
|
|
108
|
+
The full tool list is available via the MCP \`tools/list\` request.
|
|
109
|
+
Use whatever fits the operator's natural-language request.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Pricing
|
|
114
|
+
|
|
115
|
+
- **Free** — first workspace, free forever, no credit card.
|
|
116
|
+
- **Growth ($29/mo)** — up to 3 workspaces, custom domains,
|
|
117
|
+
white-label, metered AI usage.
|
|
118
|
+
- **Scale ($99/mo)** — unlimited workspaces, advanced AI features,
|
|
119
|
+
priority support.
|
|
120
|
+
|
|
121
|
+
Operators can upgrade via \`/settings/billing\` once they're in the
|
|
122
|
+
admin dashboard. Pre-fills their email automatically.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
**Docs:** <https://seldonframe.com/docs> · **Homepage:**
|
|
127
|
+
<https://seldonframe.com> · **Discord:** <https://discord.gg/sbVUu976NW>
|
|
128
|
+
`;
|
|
129
|
+
|
|
130
|
+
export const FIRST_CALL_BANNER = `🚀 SeldonFrame is connected. Ready to create a live business OS — every URL the create_workspace tool returns is real and works in any browser within seconds. NEVER create local files; always use the MCP tools.`;
|