@seldonframe/mcp 1.3.4 → 1.3.5
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/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seldonframe/mcp",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.5",
|
|
4
|
+
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.3.5: Three Karpathy-flavored root-cause fixes shipped in one cycle, all motivated by what the Iron & Oak Barbershop test surfaced. (FIX D — booking + intake 400 on subdomains) The C4 booking client and C5 intake client both extracted orgSlug from window.location.pathname, expecting /book/<slug>/<bookingSlug> or /forms/<slug>/<formSlug>. On a workspace subdomain (<slug>.app.seldonframe.com) the proxy rewrites the path server-side but the BROWSER URL stays at /book or /intake — clients saw no slug, posted orgSlug='', and every visitor's submission rejected with missing_required_field 400. Server-side defense in depth: new resolveWorkspaceSlugFromHostHeader helper in lib/workspace/host-to-slug.ts mirrors proxy.ts logic; both public POST routes now derive orgSlug from the Host header when the body value is missing. Client-side defense in depth: both renderers fall back to `window.location.hostname.split('.')[0]` when pathParts[1] is empty. Plus public_intake_succeeded/_rejected logs (parity with v1.3.3 booking observability) so the intake funnel is visible end-to-end. New slug_source tag on success logs lets us measure how often the host fallback rescues a request. (FIX E — pipeline validator's HTML-entity blind spot) The 'BUSINESS NAME NOT IN HTML' check in pipeline-validator.ts did a literal substring search on the rendered HTML. Business names with HTML-special chars ('Iron & Oak Barbershop', \"Joe's Plumbing\", '<3 Salon') get entity-encoded by the renderer ('Iron & Oak Barbershop'), so the literal check missed them and emitted false-positive blocking errors even though the name WAS rendered correctly. New htmlContainsText helper tries the literal needle, then its HTML-escaped form, then the ' variant — same logic for the first-offering fallback. Validator was wrong, not the rendering pipeline. (FIX F — model upgrade) Default ANTHROPIC_MODEL is now claude-opus-4-7 (was claude-sonnet-4-20250514). Personality generation is a once-per-niche cost — the cache amortizes Opus across every future workspace in that vertical, so the per-workspace blended cost stays near-zero while cold-call quality improves meaningfully on long-tail niches (pet grooming, accounting, voiceover, etc.). Three-tier fallback chain: Opus 4.7 (primary) → Sonnet 4.5 / claude-sonnet-4-5-20250929 (secondary) → Haiku 3.5 (tertiary). Each tier overridable via ANTHROPIC_MODEL / ANTHROPIC_MODEL_FALLBACK / ANTHROPIC_MODEL_TERTIARY env vars; chain walks down on any 404 so a single model retirement never takes the system offline. ⚠️ BACKEND REDEPLOY REQUIRED. No env vars to set on Vercel — Opus is the new default; if cost is a concern set ANTHROPIC_MODEL=claude-sonnet-4-5-20250929 to revert.",
|
|
4
5
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.3.4: ROOT-CAUSE the last 3 'wrong default everywhere' bugs from the Iron & Oak Barbershop test by extending CRMPersonality with two new LLM-populated fields + closing the booking → CRM kanban loop. (FIX A — booking metadata personalization) Pre-1.3.4 the booking calendar showed 'Free consultation / 30-minute conversation' for ANY niche not in personalityBookingDefaults (only 7 hardcoded verticals — barbershop, photography, accounting, tutoring, etc. all leaked the general.json template default). New optional CRMPersonality.booking field { title, description, duration_minutes, location_kind } populated by the LLM via the personality generator's prompt. createAnonymousWorkspace applies it as the highest-priority source (LLM > personalityBookingDefaults > JSON template). location_kind enum mirrors the blueprint's eventType.location.kind exactly (on-site-business / on-site-customer / phone / video / hybrid) so there's zero translation. (FIX B — hero image relevance) Pre-1.3.4 every workspace whose vertical wasn't in the curated IMAGES map fell back to GENERAL_IMAGES (hand-picked CONTRACTOR photos — bizarre for nail salons, tutoring, barbershops). New optional CRMPersonality.images.hero_query field — free-text Unsplash search query the LLM picks per-niche ('barbershop interior', 'math tutoring student', 'nail salon manicure'). New resolveHeroImageUrlForQuery function tries the official Unsplash API first when UNSPLASH_ACCESS_KEY is set, then falls back to source.unsplash.com keyless redirect. applyPersonalityImagesToSchema is now async and prefers LLM > curated > skip. (FIX C — bookings appear in CRM kanban) Pre-1.3.4 submitPublicBookingAction inserted into bookings + activities + contacts but NEVER into deals — so the visitor's confirmed appointment never appeared in /deals where operators actually triage their pipeline. v1.3.4 calls ensureDefaultPipelineForOrg (lazy-seeds when missing) and INSERTs a deal at the first stage on every successful free booking, with customFields.bookingId for reconciliation against future booking events. Wrapped in try/catch + structured public_booking_deal_created/_failed events — a deal-insert failure does NOT roll back the booking. (VALIDATOR) +3 new checks: hero_image_loadable (asserts the rendered URL belongs to a known Unsplash host pattern + has sizing params), booking_title_personalized (asserts the booking title doesn't contain 'Free consultation' / '30-minute conversation' AND uses the personality's title if declared), booking_to_deal_pipeline_ready (asserts the org's first pipeline stage has a non-empty name so deal-insertion lands in a renderable kanban column). ⚠️ BACKEND REDEPLOY REQUIRED. Optional: set UNSPLASH_ACCESS_KEY on Vercel to use the official API for hero images instead of the keyless source.unsplash.com redirect.",
|
|
5
6
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.3.3: ROOT CAUSE for the recurring 'wrong personality everywhere except landing' bug pattern + booking observability + per-service enrichment. (FIX 1) The booking POST /api/v1/public/bookings was returning 400 with literally NO LOGS ('No logs found for this request' in Vercel UI). Every reject path now emits a single-line structured JSON event (event: public_booking_rejected, reason: <stable_id>, ...context) so we can finally see WHICH validation is rejecting bookings. submitPublicBookingAction got the same treatment: every throw now logs reason + booking context (org_slug, weekday_in_workspace_tz, slot_local_hhmm, day_start, day_end, ...). The next time someone hits 'Couldn't book that time', the Vercel log will name the exact cause. (FIX 2 — REAL ROOT CAUSE) The LLM-generated CRMPersonality from create-full.ts was being THROWN AWAY by createAnonymousWorkspace — which called selectCRMPersonality (keyword-based) internally, ignoring the resolved personality. So booking template + intake form + landing seed all used the keyword-fallback personality (e.g. 'general' for nail salons → 'Get in Touch' intake title, 'New Lead → Quoted → ...' pipeline) while only the post-seed defensive override updated settings.crmPersonality with the LLM personality. Result: rendered intake HTML never had the personality title; that's why intake_title_rendered_html: FAIL kept appearing. Fix: createAnonymousWorkspace now accepts an opts.personality parameter; create-full.ts passes the LLM-resolved personality through. Booking template + intake form + landing seed all use the LLM personality from the start. (FIX 3a) Light mode is now the default fallback when personality.theme.mode is unset — premium verticals must opt in to dark via theme.mode='dark'. Previously the fallback used the BusinessType heuristic which routed saas/agency to cinematic (dark) by default. (FIX 3d/e) New optional services_enrichment field on CRMPersonality: array with one entry per operator service { service_name, description, icon }. The LLM is prompted to populate it with customer-facing descriptions + distinct icons per service from a known allowlist. Pipeline merges descriptions onto soul.offerings (so service cards show body copy) and overrides applyServiceIconsFromPersonality (so each card has a distinct LLM-picked icon instead of the keyword classifier's homogenous defaults). ⚠️ BACKEND REDEPLOY REQUIRED. Run a niche test post-deploy: every personality_resolved log line now also tells you whether bookings persist (public_booking_succeeded) or why they reject (public_booking_rejected with reason).",
|
|
6
7
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.3.2: 3 fixes from the Bright Futures Tutoring test. (FIX 1, CRITICAL) Hardcoded model 'claude-3-5-sonnet-latest' returns 404 from the Anthropic API; every LLM personality call fell through to keyword fallback (coaching for everything that wasn't a known vertical). Replaced with ANTHROPIC_MODEL env var (default: claude-sonnet-4-20250514) + ANTHROPIC_MODEL_FALLBACK (default: claude-3-5-haiku-20241022) + a 404-detection retry that swaps to the haiku fallback. Model id is logged in the personality_resolved event so prod observability shows which model is actually serving. Zero-deploy rotation: when Anthropic retires another model, set the env var on Vercel and the next request picks it up. (FIX 2) Booking confirmation rejected every valid slot with 'Selected slot is no longer available'. Root cause: the strict slot inclusion check compared format strings produced from server-local time (Vercel = UTC), but the client picked the slot in the workspace's timezone (e.g. 4pm Vancouver). The UTC ISO landed on the server as 23:00 UTC, formatted as 'YYYY-MM-DDT23:00', which never appeared in the server-generated slot list (UTC 09:00–16:30). Replaced with timezone-aware validation: derive workspace-local components via Intl.DateTimeFormat.formatToParts (new partsInTimezone helper), check the day-of-week is enabled, the time-of-day is within business hours, the slot aligns to a 15-minute boundary, and there's no overlap with existing bookings. Works regardless of where the server runs. (FIX 3) Light mode is now the default. Added theme.mode ('light'|'dark') to CRMPersonality. Populated for the 7 hardcoded verticals: medspa+agency stay dark/cinematic; everything else (general, hvac, dental, legal, coaching) renders in light/clean. The LLM personality generator's prompt now instructs the model to choose 'light' for trades/tutoring/professional-services and 'dark' only for premium/luxury/aesthetic verticals. seedLandingFromSoul reads personality.theme.mode and selects the cinematic vs clean PagePersonality accordingly. ⚠️ BACKEND REDEPLOY REQUIRED + set ANTHROPIC_MODEL=claude-sonnet-4-20250514 in Vercel.",
|