@seldonframe/mcp 1.21.0 → 1.21.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/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seldonframe/mcp",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.1",
|
|
4
|
+
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.21.1: HOTFIX — customer-portal actions now bridge to operator's contact activity feed + reschedule UI upgraded from free-text textarea to structured date+time picker. TWO BUG CLASSES FIXED: (1) ACTIVITY BRIDGE. Pre-1.21.1 when a customer sent a message via /customer/<orgSlug>/messages, it inserted a row into portal_messages but NOT into activities. The contact's /contacts/<id>?tab=activity feed reads from activities, so customer messages were silently invisible to operators. Same gap existed for booking cancellations (cancelBookingAction) and reschedule requests (requestRescheduleAction) shipped in v1.21.0. v1.21.1: every customer-side action now ALSO inserts an activities row anchored to the workspace owner's userId (since activities.userId is NOT NULL and the actor is a contact, not a user). Activity types added: 'portal_message' (customer sent a message), 'booking_cancelled' (customer cancelled), 'reschedule_requested' (customer asked to reschedule). Each row carries metadata.source='customer_portal' so a future ops view can filter customer-side vs operator-side actions. Subject lines are scannable ('Customer cancelled: Booked consultation' vs operator-CRM 'Booking scheduled'). (2) RESCHEDULE PICKER. Pre-1.21.1 the reschedule action exposed a single free-text textarea ('When would you like to reschedule? e.g. next Tuesday afternoon'). v1.21.1 replaces this with a STRUCTURED DATE + TIME picker (HTML date input min'd to today, HTML time input stepped to 15-min) plus an optional notes textarea. The composed reason saved on the activity row carries both human-readable text + machine-parseable ISO ('Preferred: 2026-05-14 at 14:30. Note: afternoon works best (iso=2026-05-14T14:30)'), so v1.22 can plug this directly into the calendar slot validator and auto-create the new booking on operator approval. The cancel flow keeps the simple textarea ('Reason — optional'). NO migrations, NO new env vars, NO new MCP tools — backend hotfix only. Backend redeploy required. v1.22 still queued for: operator-portal /contacts /deals /bookings table mirrors; agency 'Open <workspace> portal' support sessions + agency_support_sessions audit table; TRUE self-service reschedule (slot picker integrated with /book — atomic update of bookings.startsAt with availability check, replacing the v1.21.1 'request' semantics).",
|
|
4
5
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.21.0: CUSTOMER PORTAL GROUND-UP REBUILD — light Twenty-CRM aesthetic, industry-aware copy, end-customer-focused information architecture. Pre-1.21 the customer portal at /customer/<orgSlug> was a dark-mode stat grid (Messages: 0 / Resources: 0 / Viewed Resources: 0) with operator-jargon nav (Pipeline / My Pipeline / Bookings / Resources). The end customer audience — homeowner who called HVAC, patient at the dentist, client of the coach — has zero use for any of that. v1.21 starts from first principles: what does the END customer actually need? (1) Their next appointment — when, where, who's coming, can I reschedule, can I cancel. (2) Quick way to reach the business — tap-to-call + tap-to-email. (3) History of their relationship with the business. (4) Documents shared with them. The portal is rebuilt around those needs. WHAT SHIPS: (1) Industry-aware copy packs (lib/customer-portal/copy-packs.ts) keyed by organizations.soul.industry — HVAC says 'service visit', dental says 'appointment', coaching says 'session', legal says 'consultation', accounting says 'meeting', medspa says 'appointment', agency says 'meeting'. Provider labels calibrated too (technician / doctor / coach / attorney / accountant / specialist / account manager). General fallback pack for unknown industries. 11 contract tests cover the picker shape (case-insensitive lookup, complete-pack invariant, no copy/paste pluralization bugs). (2) CustomerPortalShell (light mode FORCED regardless of workspace theme.mode — Twenty-CRM-quality customer experiences are light, neutral, dense). Sidebar nav on sm+ (Home / Appointments / Documents / Messages / Account); mobile top-tabs row below sm. Agency-branded chrome via deriveEffectiveBranding (Acme AI logo + 'on Acme AI' subtitle when active partner agency exists). Powered-by-SF footer respects agency.hide_powered_by_badge. Inter-style sans, 1px hairline borders (#E5E5E1), neutral grays (#F7F7F5 bg, #111 text). (3) NEW OVERVIEW page — hero NEXT APPOINTMENT card (date, time, notes, View details / Reschedule / Cancel buttons) + QUICK CONTACT card (tap-to-call + tap-to-email, mobile-first since this is overwhelmingly a phone surface) + RECENT ACTIVITY (2-3 most recent past bookings). 'Welcome back, <name>' with industry-aware subtitle. Empty state for new customers with zero appointments. (4) NEW APPOINTMENTS page (replaces /pipeline + /bookings). Upcoming + Past sections. Each upcoming row exposes inline Reschedule + Cancel actions powered by lib/customer-portal/appointment-actions.ts (cancelBookingAction = atomic update bookings.status='cancelled' scoped to session.contact.id; requestRescheduleAction = emits portal.reschedule_requested event for operator follow-up. Both enforce contact-scope so a customer can't touch another customer's bookings even with a guessed booking_id). (5) NEW ACCOUNT page — read-only contact info on file + tap-to-call/email business + signed-in-as block with sign-out. v1.22 will add self-edit. (6) DOCUMENTS page redesigned (renamed from /resources). Files (uploaded) + Links sections, light-mode rows, download/open buttons. (7) MESSAGES page redesigned with light shell. Same PortalMessagesClient component (data plumbing untouched). (8) Drop /pipeline (operator-jargon meaningless to customers) and /bookings (folded into /appointments). PIPELINE TAB REMOVED FROM NAV — customers don't have pipelines. (9) Auth + data plumbing UNCHANGED — same requirePortalSessionForOrg, listPortalBookings, listPortalDocuments, listPortalMessages, clearPortalSessionAction. Only the chrome + IA + copy change. NO MIGRATIONS, NO new env vars. Test count: +11 (copy pack picker invariants). Backend redeploy required. Deferred to v1.22: full /contacts /deals /bookings table mirrors inside operator portal; agency support sessions ('Open Cypress portal'); customer self-edit on Account page; true self-service reschedule (customer picks new slot from workspace availability) — currently the reschedule action emits an operator-followup event.",
|
|
5
6
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.20.1: HOTFIX — operator-initiated customer-portal invites now send a clickable MAGIC LINK instead of a 6-digit code. Pre-1.20.1 (and pre-1.20 entirely) the operator clicked 'Send invite email' on /contacts/<id>, the contact received an email containing JUST 'your code is 712420' with NO clickable URL. Customers had to know to navigate to /customer/<orgSlug>/login (or /portal/<slug>/login pre-rename) themselves — most don't know the URL. Confirmed in v1.20 production smoke 2026-05-06: customer received the access-code email but couldn't find the portal page; couldn't sign in. v1.20.1: sendPortalInviteAction (lib/portal/admin-actions.ts) now mints a /customer/<slug>/magic?token=... URL via the existing createPortalMagicLink primitive (token bound to a specific contact_id, 30-min TTL) and emails it via a new lib/emails/portal-invite-magic-link.ts template. Customer clicks → /customer/<slug>/magic verifies token + sets session cookie → lands signed-in at /customer/<slug>. Zero typing required. The 6-digit code self-service flow is UNCHANGED for customers who navigate directly to /customer/<slug>/login without an invite email — they type their email, get a code, type the code. That path covers customers who lost or deleted the invite email. Same v1.19 silent-no-op observability pattern: every short-circuit (org_not_found / plan_gate_denied / contact_not_found / portal_access_disabled / resend_not_configured / email_send_failed) emits a structured warn so production monitoring can attribute drop-offs. Same partner-agency branding override as the access-code email (footer + sender substitute when active partner agency is verified). NO migrations, NO env vars, NO new MCP tools — backend hotfix only. Backend redeploy required. The MCP package itself is unchanged in v1.20.1; version bump coupled with backend so they redeploy together. v1.21 still queued for /contacts /deals /bookings table mirrors inside operator portal + agency support sessions + customer-portal industry-aware copy.",
|
|
6
7
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.20.0: WHITE-LABEL CRM PHASE 3 — split the 'portal' concept into two distinct surfaces with the right URLs, auth ergonomics, and design language for each audience. WHY THIS MATTERS: pre-1.20 we had ONE surface called /portal/<orgSlug> doing one job (homeowner-facing customer portal, 6-digit code auth, dark cinematic theme). The white-label use case wants a DIFFERENT surface: a branded admin dashboard for sub-tenant operators (the HVAC owner / dentist / accountant who runs a workspace that an SF agency partner has white-labeled to them). One URL serving two audiences with conflicting auth ergonomics + UX languages was structurally wrong. v1.20 splits them. WHAT SHIPS: (1) RENAME /portal/<orgSlug>/* → /customer/<orgSlug>/* — the homeowner customer portal. Behavior unchanged (6-digit code auth, customer-facing copy, magic-code email). All 32 referencing files updated: lib/portal/auth.ts, lib/page-blocks/portal/structure.ts (customer_portal_url field surfaced via MCP), customer-login.tsx, portal-access-card.tsx, seldon/block-installer.ts, hub, settings/client-portal, api/v1/portal/invite, etc. Email-template comments + log lines also updated for clarity. (2) NEW OPERATOR PORTAL at /portal/<orgSlug>/* — the sub-tenant operator's branded admin dashboard. Twenty-CRM-inspired light-mode aesthetic (neutral grays, Inter-style sans, 1px hairline borders, dense rows, sidebar nav). Magic-link auth (single-use, 15-min TTL, JWT-only — no DB row, v1.21 adds nonce enforcement) instead of 6-digit code; operator-grade clickable URL, not consumer-grade type-the-code. Agency-branded chrome via deriveEffectiveBranding (Acme AI logo + 'on Acme AI' subtitle in header when active partner-agency exists; 'Powered by SeldonFrame' footer hidden when agency.hide_powered_by_badge=true). Sidebar nav exposes Dashboard (LIVE in v1.20) + Contacts/Deals/Bookings (placeholders for v1.21 mirrors). Dashboard surface: 4 stat cards (contacts, active deals, upcoming bookings, recent activity) + recent-activity feed, all scoped to session.orgId so URL slug tampering can't read another workspace's data. (3) OPERATOR INVITE UI on /settings/team. New OperatorInviteCard component lets the workspace owner mint a magic-link sign-in for any email — recipient becomes an operator of this workspace via the branded /portal/<orgSlug>. Email template (lib/emails/operator-magic-link.ts) carries optional 'invitedByName' for trust + context, agency-branded footer when applicable, distinct subject line ('Sign in to Cypress & Pine HVAC') from the customer-portal email. (4) AGENCY-IMPERSONATION HOOK: OperatorTokenPayload carries optional supportOriginUserId. When a session token has it set, the operator portal layout renders a yellow banner ('Agency support session active — you are signed in as <email>. All actions are audit-logged'). v1.21 will wire up the agency-side trigger (Acme AI clicks 'Open Cypress portal' from their agency dashboard → mints support-session token) + audit-log table. (5) SECURITY MODEL: Magic-link token is JWT-style HMAC-signed (kind='magic', 15-min TTL). The /portal/<slug>/magic route consumes it atomically, swaps it for a session cookie (kind='session', 7-day TTL, httpOnly, sameSite=lax, secure-in-prod). The session cookie is a DIFFERENT token shape so the magic-link can't be used as a session cookie even if leaked — the kind discriminator gates this. 10 contract tests cover the token primitives: round-trips, expiry, signature tampering, malformed input, kind discriminator, supportOriginUserId carry-through. (6) /contacts/<id>'s 'Send invite email' UNCHANGED in v1.20 (just URL-update from /portal → /customer). Operator invites originate from /settings/team (this v1.20 add); customer invites still originate from /contacts/<id> with the existing 6-digit code flow. Two clear surfaces, two clear flows, no ambiguity. v1.21 candidates: full /contacts /deals /bookings table mirrors inside /portal/<slug>; agency-side 'Open <workspace> portal' support-session UI + agency_support_sessions audit table; customer portal industry-aware copy (HVAC says 'service visits'; dental says 'appointments'); UX tightening on /customer/<slug> overview page. v1.22: agency self-serve mgmt + custom domains. NO MIGRATIONS. NO new env vars. Backend redeploy required. The MCP package itself is unchanged in v1.20; version bump coupled with backend so they redeploy together.",
|