@seldonframe/mcp 1.18.0 → 1.18.1
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 -1
- package/src/welcome.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seldonframe/mcp",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.1",
|
|
4
|
+
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.18.1: HOTFIX — register_partner_agency_sender_domain is now idempotent. Smoke surfaced 2026-05-06: agency tried to register a domain that was already registered in our Resend account (from a prior smoke), got Resend 403 'The <name> domain has been registered already'. Pre-1.18.1 the operator dead-ended with no recovery. v1.18.1: when create returns 403/already-registered, we list all domains in our Resend account, find the existing record by name, fetch its DNS records, and use that domain_id + records as if create had succeeded. If the existing record happens to be already verified by Resend (DNS resolved at some prior point), we mirror that into our agency row's verified_sender_at and skip the DNS-add prompt entirely. Edge case: if Resend says the domain is already registered but it's NOT in our account list, we surface a structured error pointing the operator at a different domain or support — that's the 'registered under a different Resend account' case which is unrecoverable without contacting Resend. NO migrations, NO env vars, NO new deps. The MCP package itself is unchanged in v1.18.1 — version bump coupled with backend so they redeploy together.",
|
|
4
5
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.18.0: WHITE-LABEL CRM PHASE 2 — Resend per-agency sender + agency-branded transactional emails. v1.17 shipped the partner-agency hierarchy. v1.18 closes the loop on email branding: agencies' clients now receive transactional emails (portal-access-code in v1.18.0; welcome + admin-link queued for v1.18.1) FROM the agency's verified domain WITH the agency's brand name in the template, instead of welcome@seldonframe.com / 'on SeldonFrame'. WHAT SHIPS: (1) Resend Domains API integration (lib/integrations/resend-domains.ts) — createResendSenderDomain (POST /domains), getResendSenderDomain (GET /domains/:id), triggerResendDomainVerification (POST /domains/:id/verify), removeResendSenderDomain. Uses the existing RESEND_API_KEY (no new env var). Each agency's sender domain registered UNDER our Resend account (no separate Resend account per agency). (2) Sender-domain orchestration (lib/partner-agencies/sender-domain.ts) — registerAgencySenderDomain creates the Resend domain + persists resend_domain_id + sender_email_address on the agency row (verified_sender_at left NULL until verification confirms); verifyAgencySenderDomain triggers Resend's verify endpoint, persists verified_sender_at on first success. (3) Two new MCP tools: register_partner_agency_sender_domain (returns DNS records the agency must add at their registrar), verify_partner_agency_sender_domain (idempotent — safe to call while DNS propagates). (4) Portal-access-code email wired to agency branding: when workspace has active agency with verified_sender_at, the email goes FROM the agency's domain + 'on <Agency Name>' in the footer + (optionally) the agency's logo in template. Falls back to SF defaults when no agency / not verified — defense-in-depth via deriveEffectiveBranding (only exposes sender_email_address when verified_sender_at is populated). (5) Email template extended: PortalAccessCodeEmailRequest gains brandName / logoUrl / supportUrl optional fields; HTML + text bodies branch on brandName for footer text. SECURITY: agencies only operate on their OWN agency rows (caller_owns_agency check at every mutation). Resend's standard SPF/DKIM/DMARC enforcement covers email-spoofing risk. Test count: 2539 (unchanged from v1.17 — v1.18 is wiring + integration; the security-critical pure helpers were already covered by v1.17's tests). Typecheck clean. Backward compatible. NO migrations (v1.17's 0040 is sufficient). v1.18.1 candidate (this session if time permits, else fresh): wire welcome + device-auth + admin-link emails to also use agency branding + admin dashboard chrome substitution. v1.19 — agency self-serve management tools + nightly plan-gate sweep. v1.20 — agency custom domain + per-client wildcard subdomains via Vercel.",
|
|
5
6
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.17.0: WHITE-LABEL CRM PHASE 1 — partner-agency hierarchy + foundational primitives. SeldonFrame's Scale-tier customers (agencies / solopreneurs reselling AI-native Business OS to SMBs like HVAC contractors / dentists / lawyers / realtors) can now register as a partner agency, attach client workspaces to that agency, and have those workspaces' chrome (logo, colors, sender, support pointers, 'Powered by' badge) substitute the agency's branding for SeldonFrame's. WHAT SHIPS: (1) Migration 0040 — new partner_agencies table (id, name, slug, logo_url, colors, support pointers, sender_email_address + verified_sender_at for v1.18, agency_domain + agency_domain_verified_at for v1.20, owner_user_id, status: pending|active|suspended|archived, hide_powered_by_badge). organizations.parent_agency_id FK column. Applied to prod via Neon MCP. (2) Drizzle schema modules: partner-agencies.ts + organizations.ts extended with parentAgencyId. (3) Pure helper deriveEffectiveBranding(agency, workspaceName) — decides chrome (SF default vs agency-substituted). Defense-in-depth: doesn't expose sender_email_address until verified_sender_at is populated; doesn't expose agency_domain until agency_domain_verified_at is populated. Plan-gate semantics: only 'active' agencies substitute chrome; pending/suspended/archived fall back to SF defaults (data preserved). (4) DB-loading wrapper getEffectiveBrandingForWorkspace(workspaceId) for chrome consumers. (5) State management: registerPartnerAgency (Scale-tier check + slug uniqueness), attachWorkspaceToAgency (caller-owns-both check), detachWorkspaceFromAgency (caller is workspace owner OR agency owner). (6) Three new MCP tools: register_partner_agency, attach_workspace_to_agency, detach_workspace_from_agency. (7) shouldShowPoweredByBadgeForOrg now respects agency.hide_powered_by_badge for active agencies — first chrome surface wired up. (8) 14 new unit tests covering branding-derivation in all status states, color/sender/domain echo, defense-in-depth on unverified sender + domain. Test count: 2539 (was 2525). NO new env vars (Resend + Vercel come into play in v1.18 + v1.20). Plan gate: agency creation requires Scale-tier ownership; non-Scale callers get the agency in 'pending' status (chrome substitution only activates on active). v1.18 (next ship) — wire the dashboard chrome substitution + welcome/admin/portal-access-code emails to use the agency's verified Resend sender. v1.19 — agency self-serve management tools (list_my_agencies, update_partner_agency, list_my_workspaces). v1.20 — agency custom domain (crm.acmeai.com) with per-client wildcard subdomains via Vercel.",
|
|
6
7
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.16.2: HOTFIX — public booking + intake POST handlers correctly resolve workspace on custom domains. The C4 booking client and C5 intake client both fall back to hostname.split('.')[0] when the path-based orgSlug is missing — fine for <slug>.app.seldonframe.com (the segment IS the slug), broken for custom domains (hvac.tirionforge.com → 'hvac' is just the operator's chosen subdomain, not the workspace slug 'cypress-pine-hvac'). Reproduced 2026-05-06: visitor on hvac.tirionforge.com/book got 'Couldn't book that time'; logs showed booking_context_not_found with org_slug='hvac' (no template booking row exists for that — the workspace's slug is 'cypress-pine-hvac'). Fix: new resolveWorkspaceSlugFromRequestWithCustomDomains async helper that tries the existing subdomain extraction first, then falls back to a workspace_domains lookup by full hostname → returns the canonical workspace slug. Both /api/v1/public/bookings and /api/v1/public/intake routes now PREFER the host-derived slug (when a verified custom domain matches) over body's orgSlug, since on custom domains the body value is whatever the client guessed from the URL — unreliable. Slug-source diagnostic now reports custom_domain | body | subdomain_fallback for funnel observability. NO migrations, NO env vars, NO new deps. The MCP package itself didn't change in v1.16.2 — version bump coupled with backend so they redeploy together.",
|
package/src/welcome.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// stripped. `create_full_workspace` is the only workspace-creation
|
|
9
9
|
// path mentioned anywhere in this briefing.
|
|
10
10
|
|
|
11
|
-
export const VERSION = "1.18.
|
|
11
|
+
export const VERSION = "1.18.1";
|
|
12
12
|
|
|
13
13
|
export const WELCOME_MARKDOWN = `# SeldonFrame — create a real Business OS in one conversation
|
|
14
14
|
|
|
@@ -306,4 +306,4 @@ admin dashboard. Pre-fills their email automatically.
|
|
|
306
306
|
<https://seldonframe.com> · **Discord:** <https://discord.gg/sbVUu976NW>
|
|
307
307
|
`;
|
|
308
308
|
|
|
309
|
-
export const FIRST_CALL_BANNER = `🚀 SeldonFrame v1.18.
|
|
309
|
+
export const FIRST_CALL_BANNER = `🚀 SeldonFrame v1.18.1 is connected. PREFERRED workspace creation: create_workspace_v2 → IN PARALLEL for all 7 recommended_blocks (hero, services, about, faq, cta, booking, intake): get_block_skill + persist_block → complete_workspace_v2 → finalize_workspace({ workspace_id, email }). The v2 flow puts YOUR LLM in charge of every operator-facing surface using one SKILL.md per block. Each block's prop schema is server-validated. Run blocks in PARALLEL (Promise.all) — sequential takes 60+ seconds. v1.10+ TIER 2 CUSTOMIZE TOOLS: regenerate_block (re-do one block with operator instructions; thin-harness — server bundles context, your LLM generates), upload_workspace_image (set logo/hero_background; v1.10.1+ accepts image_url or local_file_path — DON'T base64 unless you have to, the encoded string eats your tool-call token budget). v1.11+ STRUCTURAL PRIMITIVES: get_landing_structure → move_section → delete_section. INDEX-based, handle duplicate section types, atomic. v1.12+ COMPOSITE TREES: add_composite_section / update_composite_section — manifest ANY block (comparison, pricing, "how it works," stats, custom CTAs) from 12 low-level primitives. Server validates + renders; YOUR LLM composes. Read the SKILL.md via get_block_skill('composite') before composing. Every URL is real. NEVER create local files. Skipping finalize_workspace leaves the operator with no admin login.`;
|