appoiint 4.14.1 → 4.15.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/dist/mcp-tools.js +1 -1
- package/package.json +1 -1
package/dist/mcp-tools.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const TOOLS=[{name:"appoiint_status",description:"Get Appoiint platform status and version.",inputSchema:{type:"object",properties:{}},handler:async e=>e.status(),readOnly:!0},{name:"appoiint_create_room",description:"Create a video meeting room. Returns roomId and join URL.",inputSchema:{type:"object",properties:{title:{type:"string",description:'Meeting title (e.g. "Team Standup")'}},required:["title"]},handler:async(e,t)=>{const i=require("./config").loadConfig([]);return e.createRoom({title:t.title,hostId:i.userId})},readOnly:!1},{name:"appoiint_list_rooms",description:"List active meeting rooms.",inputSchema:{type:"object",properties:{}},handler:async e=>e.listRooms(),readOnly:!0},{name:"appoiint_room_status",description:"Get room status and participants.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t)=>e.roomStatus(t.roomId),readOnly:!0},{name:"appoiint_end_room",description:"End a meeting room.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t)=>e.endRoom(t.roomId),readOnly:!1},{name:"appoiint_invite",description:"Invite a human or agent to a meeting room.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},email:{type:"string",description:"Invitee email"},name:{type:"string",description:"Invitee name"},type:{type:"string",description:"human or agent (default: human)"}},required:["roomId","email"]},handler:async(e,t)=>e.invite(t.roomId,{email:t.email,name:t.name||"Guest",type:t.type||"human"}),readOnly:!1},{name:"appoiint_transcript",description:"Get meeting transcript.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},format:{type:"string",description:"json, text, or srt (default: json)"}},required:["roomId"]},handler:async(e,t)=>e.transcript(t.roomId,t.format||"json"),readOnly:!0},{name:"appoiint_join_meeting",description:"Join a meeting room as an AI agent. Creates persistent Socket.IO connection. You will hear transcripts and can send chat messages. Call appoiint_get_transcripts to read what was said, appoiint_send_chat to respond.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID to join"},agentName:{type:"string",description:"Your display name in the meeting (default: Claude Code)"},agentRole:{type:"string",description:"Your role badge (default: assistant)"}},required:["roomId"]},handler:async(e,t,i)=>{const{MeetingSession:n}=require("./meetingSession"),a=new n({baseUrl:i.config.baseUrl,roomId:t.roomId,agentName:t.agentName||"Claude Code",agentRole:t.agentRole||"assistant"}),r=await a.join();return i.meetingSessions.set(t.roomId,a),r},readOnly:!1},{name:"appoiint_get_transcripts",description:"Get speech transcripts from the meeting. Returns what participants have said since last read. Buffer is cleared after reading.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,i)=>{const n=i.meetingSessions.get(t.roomId);if(!n)return{error:"Not in this meeting. Call appoiint_join_meeting first."};const a=n.getTranscripts();return{roomId:t.roomId,count:a.length,transcripts:a}},readOnly:!0},{name:"appoiint_send_chat",description:"Send a chat message to all meeting participants. Your message appears in the AI chat panel with your role badge.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},message:{type:"string",description:"Message to send to meeting participants"}},required:["roomId","message"]},handler:async(e,t,i)=>{const n=i.meetingSessions.get(t.roomId);return n?n.sendChat(t.message):{error:"Not in this meeting. Call appoiint_join_meeting first."}},readOnly:!1},{name:"appoiint_meeting_status",description:"Check meeting connection status: connected, peer count, buffered transcript count.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,i)=>{const n=i.meetingSessions.get(t.roomId);return n?n.status():{error:"Not in this meeting.",connected:!1}},readOnly:!0},{name:"appoiint_leave_meeting",description:"Leave a meeting room and disconnect.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,i)=>{const n=i.meetingSessions.get(t.roomId);if(!n)return{error:"Not in this meeting."};const a=n.leave();return i.meetingSessions.delete(t.roomId),a},readOnly:!1},{name:"appoiint_speak",description:"Speak in a meeting room with an agent voice: synthesizes text via TTS and broadcasts the audio to all participants in one call. Requires an active appoiint_join_meeting session. Text is trimmed to 500 chars server-side; audio over 500KB is dropped by the relay.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID (must have joined via appoiint_join_meeting)"},text:{type:"string",description:"Text to speak (max 500 chars)"},voice:{type:"string",description:"Voice: cfo, cto, cmo, cco, cso, clo, heart, michael, nova, echo (default: heart)"}},required:["roomId","text"]},handler:async(e,t,i)=>{const n=i.meetingSessions.get(t.roomId);if(!n)return{error:"Not in this meeting. Call appoiint_join_meeting first."};const a=await e.synthesize({text:t.text,voice:t.voice||"heart",agentRole:t.voice});if(!a||!a.audio)return{error:"TTS synthesis failed",detail:a};const r=n.sendAudio({audio:a.audio,format:a.format});return{spoken:!0,roomId:t.roomId,voice:a.voice,provider:a.provider,bytes:r.bytes}},readOnly:!1},{name:"appoiint_list_events",description:"List bookable event types.",inputSchema:{type:"object",properties:{}},handler:async e=>e.events(),readOnly:!0},{name:"appoiint_check_availability",description:"Check available time slots for a host on a given date.",inputSchema:{type:"object",properties:{email:{type:"string",description:"Host email address"},date:{type:"string",description:"Date (YYYY-MM-DD)"},timezone:{type:"string",description:"Timezone (default: UTC)"}},required:["email","date"]},handler:async(e,t)=>e.slots(t.email,t.date,t.timezone||"UTC"),readOnly:!0},{name:"appoiint_create_booking",description:"Create a booking on behalf of a customer.",inputSchema:{type:"object",properties:{eventTypeId:{type:"string",description:"Event type ID"},scheduledAt:{type:"string",description:"ISO 8601 date-time (e.g. 2026-06-15T14:00:00Z)"},duration:{type:"number",description:"Duration in minutes (default: 30)"},customerName:{type:"string",description:"Customer name"},customerEmail:{type:"string",description:"Customer email"}},required:["scheduledAt","customerEmail"]},handler:async(e,t)=>e.book({eventTypeId:t.eventTypeId,scheduledAt:t.scheduledAt,duration:t.duration||30,customer:{name:t.customerName||"Guest",email:t.customerEmail},location:{type:"video"}}),readOnly:!1},{name:"appoiint_tts",description:"Synthesize text-to-speech with CxO agent voice.",inputSchema:{type:"object",properties:{text:{type:"string",description:"Text to synthesize"},voice:{type:"string",description:"Voice: cfo, cto, cmo, cco, cso, clo, heart, michael, nova, echo (default: heart)"}},required:["text"]},handler:async(e,t)=>e.synthesize({text:t.text,voice:t.voice||"heart",agentRole:t.voice}),readOnly:!0},{name:"appoiint_voices",description:"List available TTS voices and CxO agent voice mappings.",inputSchema:{type:"object",properties:{}},handler:async e=>e.voices(),readOnly:!0},{name:"appoiint_helpdesk_tickets",description:"List helpdesk tickets. Filter by status.",inputSchema:{type:"object",properties:{status:{type:"string",description:"Filter: open, resolved, closed"}}},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("GET","/saas/api/v1/sdk/helpdeskryClient/tickets"+(t.status?`?status=${t.status}`:""))},readOnly:!0},{name:"appoiint_helpdesk_ticket_show",description:"Get ticket detail with messages.",inputSchema:{type:"object",properties:{ticketId:{type:"string"}},required:["ticketId"]},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("GET",`/saas/api/v1/sdk/helpdeskryClient/tickets/${t.ticketId}`)},readOnly:!0},{name:"appoiint_helpdesk_ticket_create",description:"Create a helpdesk ticket.",inputSchema:{type:"object",properties:{subject:{type:"string"},priority:{type:"string"},category:{type:"string"}},required:["subject"]},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("POST","/saas/api/v1/sdk/helpdeskryClient/tickets",t)},readOnly:!1},{name:"appoiint_helpdesk_ticket_reply",description:"Reply to a helpdesk ticket.",inputSchema:{type:"object",properties:{ticketId:{type:"string"},message:{type:"string"}},required:["ticketId","message"]},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("POST",`/saas/api/v1/sdk/helpdeskryClient/tickets/${t.ticketId}/messages`,{content:t.message})},readOnly:!1},{name:"appoiint_crm_leads",description:"List CRM leads. Filter by status.",inputSchema:{type:"object",properties:{status:{type:"string"}}},handler:async(e,t,i)=>{const{rawApi:n}=require("./api"),a=t.status?`?status=${t.status}`:"";return n(i.config)("GET",`/saas/api/v1/sdk/crm/leads${a}`)},readOnly:!0},{name:"appoiint_crm_lead_show",description:"Get lead detail.",inputSchema:{type:"object",properties:{leadId:{type:"string"}},required:["leadId"]},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("GET",`/saas/api/v1/sdk/crm/leads/${t.leadId}`)},readOnly:!0},{name:"appoiint_crm_lead_create",description:"Create a CRM lead.",inputSchema:{type:"object",properties:{name:{type:"string"},email:{type:"string"},source:{type:"string"}},required:["name"]},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("POST","/saas/api/v1/sdk/crm/leads",t)},readOnly:!1},{name:"appoiint_crm_opportunities",description:"List CRM opportunities. Filter by stage.",inputSchema:{type:"object",properties:{stage:{type:"string"}}},handler:async(e,t,i)=>{const{rawApi:n}=require("./api"),a=t.stage?`?stage=${t.stage}`:"";return n(i.config)("GET",`/saas/api/v1/sdk/crm/opportunities${a}`)},readOnly:!0},{name:"appoiint_crm_pipelines",description:"List CRM pipelines with stages.",inputSchema:{type:"object",properties:{}},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("GET","/saas/api/v1/sdk/crm/pipelines")},readOnly:!0},{name:"appoiint_channel_send",description:"Send a 1:1 message to another agent. Use for ops requests, data queries, or notifications.",inputSchema:{type:"object",properties:{to:{type:"string",description:"Recipient agent ID"},message:{type:"string",description:"Message text"},action:{type:"string",description:"Intent/action (e.g. deploy, query, notify)"},payload:{type:"object",description:"Structured data payload"}},required:["to"]},handler:async(e,t)=>{const i={to:t.to,type:t.action?"request":"notify"};return t.message&&(i.payload={message:t.message}),t.action&&(i.action=t.action,i.requestId=`req_${Date.now()}`),t.payload&&(i.payload={...i.payload,...t.payload}),e.channelSend(i)},readOnly:!1},{name:"appoiint_channel_inbox",description:"Get unread messages from other agents.",inputSchema:{type:"object",properties:{}},handler:async e=>e.channelInbox(),readOnly:!0},{name:"appoiint_channel_history",description:"Get message history with a specific agent.",inputSchema:{type:"object",properties:{agentId:{type:"string",description:"Agent ID to get history with"},limit:{type:"number",description:"Max messages (default 50)"}},required:["agentId"]},handler:async(e,t)=>e.channelHistory(t.agentId,t.limit),readOnly:!0},{name:"appoiint_channel_agents",description:"List agents you have communicated with.",inputSchema:{type:"object",properties:{}},handler:async e=>e.channelAgents(),readOnly:!0},{name:"appoiint_wall",description:"All your message threads (DMs + channels) with unread badges, newest first. Start here to see what needs attention.",inputSchema:{type:"object",properties:{}},handler:async e=>e.wall(),readOnly:!0},{name:"appoiint_notifications",description:"Unread digest across all DM and channel threads. Reading a thread history marks it read.",inputSchema:{type:"object",properties:{}},handler:async e=>e.notificationsDigest(),readOnly:!0},{name:"appoiint_channel_create",description:"Create a named channel for multi-agent group messaging. You auto-join as creator.",inputSchema:{type:"object",properties:{name:{type:"string",description:'Channel name (slugified, e.g. "dev-ops")'},topic:{type:"string",description:"Optional channel topic"}},required:["name"]},handler:async(e,t)=>e.groupCreate(t.name,t.topic),readOnly:!1},{name:"appoiint_channel_join",description:"Join an existing named channel.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Channel name/slug"}},required:["name"]},handler:async(e,t)=>e.groupJoin(t.name),readOnly:!1},{name:"appoiint_channel_leave",description:"Leave a named channel.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Channel name/slug"}},required:["name"]},handler:async(e,t)=>e.groupLeave(t.name),readOnly:!1},{name:"appoiint_channel_list",description:"List named channels with membership and your unread counts.",inputSchema:{type:"object",properties:{}},handler:async e=>e.groupList(),readOnly:!0},{name:"appoiint_channel_post",description:"Post a message to a named channel (must be a member).",inputSchema:{type:"object",properties:{name:{type:"string",description:"Channel name/slug"},message:{type:"string",description:"Message text"},payload:{type:"object",description:"Optional structured payload"}},required:["name","message"]},handler:async(e,t)=>e.groupSend(t.name,{text:t.message,payload:t.payload||{message:t.message}}),readOnly:!1},{name:"appoiint_channel_messages",description:"Read a named channel history (reading marks it read).",inputSchema:{type:"object",properties:{name:{type:"string",description:"Channel name/slug"},limit:{type:"number",description:"Max messages (default 50)"}},required:["name"]},handler:async(e,t)=>e.groupHistory(t.name,t.limit),readOnly:!0},{name:"appoiint_admin_tenants",description:"List all tenants with plan, status, usage. Superadmin only.",inputSchema:{type:"object",properties:{}},handler:async e=>e.adminTenants(),readOnly:!0},{name:"appoiint_admin_tenant_view",description:"Full tenant detail: plan, stats, usage, created date.",inputSchema:{type:"object",properties:{slug:{type:"string",description:"Tenant slug"}},required:["slug"]},handler:async(e,t)=>e.adminTenantView(t.slug),readOnly:!0},{name:"appoiint_platform_stats",description:"Platform overview: tenants, users, rooms, bookings, meetings.",inputSchema:{type:"object",properties:{}},handler:async e=>e.platformStats(),readOnly:!0},{name:"appoiint_funnel",description:"Signup funnel with conversion rates.",inputSchema:{type:"object",properties:{}},handler:async e=>e.funnel(),readOnly:!0},{name:"appoiint_revenue",description:"Revenue breakdown: MRR, ARR, fees, payouts.",inputSchema:{type:"object",properties:{}},handler:async e=>e.revenue(),readOnly:!0},{name:"appoiint_audit",description:"Activity audit trail.",inputSchema:{type:"object",properties:{limit:{type:"number",description:"Max entries"},action:{type:"string",description:"Filter by action type"}}},handler:async(e,t)=>{const i=new URLSearchParams;return t.limit&&i.set("limit",t.limit),t.action&&i.set("action",t.action),e.audit(i.toString())},readOnly:!0}];module.exports={TOOLS:TOOLS};
|
|
1
|
+
const TOOLS=[{name:"appoiint_status",description:"Get Appoiint platform status and version.",inputSchema:{type:"object",properties:{}},handler:async e=>e.status(),readOnly:!0},{name:"appoiint_create_room",description:"Create a video meeting room. Returns roomId and join URL.",inputSchema:{type:"object",properties:{title:{type:"string",description:'Meeting title (e.g. "Team Standup")'}},required:["title"]},handler:async(e,t)=>{const n=require("./config").loadConfig([]);return e.createRoom({title:t.title,hostId:n.userId})},readOnly:!1},{name:"appoiint_list_rooms",description:"List active meeting rooms.",inputSchema:{type:"object",properties:{}},handler:async e=>e.listRooms(),readOnly:!0},{name:"appoiint_room_status",description:"Get room status and participants.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t)=>e.roomStatus(t.roomId),readOnly:!0},{name:"appoiint_end_room",description:"End a meeting room.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t)=>e.endRoom(t.roomId),readOnly:!1},{name:"appoiint_invite",description:"Invite a human or agent to a meeting room.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},email:{type:"string",description:"Invitee email"},name:{type:"string",description:"Invitee name"},type:{type:"string",description:"human or agent (default: human)"}},required:["roomId","email"]},handler:async(e,t)=>e.invite(t.roomId,{email:t.email,name:t.name||"Guest",type:t.type||"human"}),readOnly:!1},{name:"appoiint_transcript",description:"Get meeting transcript.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},format:{type:"string",description:"json, text, or srt (default: json)"}},required:["roomId"]},handler:async(e,t)=>e.transcript(t.roomId,t.format||"json"),readOnly:!0},{name:"appoiint_join_meeting",description:"Join a meeting room as an AI agent. Creates persistent Socket.IO connection. You will hear transcripts and can send chat messages. Call appoiint_get_transcripts to read what was said, appoiint_send_chat to respond.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID to join"},agentName:{type:"string",description:"Your display name in the meeting (default: Claude Code)"},agentRole:{type:"string",description:"Your role badge (default: assistant)"}},required:["roomId"]},handler:async(e,t,n)=>{const{MeetingSession:i}=require("./meetingSession"),a=new i({baseUrl:n.config.baseUrl,roomId:t.roomId,agentName:t.agentName||"Claude Code",agentRole:t.agentRole||"assistant"}),r=await a.join();return n.meetingSessions.set(t.roomId,a),r},readOnly:!1},{name:"appoiint_get_transcripts",description:"Get speech transcripts from the meeting. Returns what participants have said since last read. Buffer is cleared after reading.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,n)=>{const i=n.meetingSessions.get(t.roomId);if(!i)return{error:"Not in this meeting. Call appoiint_join_meeting first."};const a=i.getTranscripts();return{roomId:t.roomId,count:a.length,transcripts:a}},readOnly:!0},{name:"appoiint_send_chat",description:"Send a chat message to all meeting participants. Your message appears in the AI chat panel with your role badge.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},message:{type:"string",description:"Message to send to meeting participants"}},required:["roomId","message"]},handler:async(e,t,n)=>{const i=n.meetingSessions.get(t.roomId);return i?i.sendChat(t.message):{error:"Not in this meeting. Call appoiint_join_meeting first."}},readOnly:!1},{name:"appoiint_meeting_status",description:"Check meeting connection status: connected, peer count, buffered transcript count.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,n)=>{const i=n.meetingSessions.get(t.roomId);return i?i.status():{error:"Not in this meeting.",connected:!1}},readOnly:!0},{name:"appoiint_leave_meeting",description:"Leave a meeting room and disconnect.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,n)=>{const i=n.meetingSessions.get(t.roomId);if(!i)return{error:"Not in this meeting."};const a=i.leave();return n.meetingSessions.delete(t.roomId),a},readOnly:!1},{name:"appoiint_speak",description:"Speak in a meeting room with an agent voice: synthesizes text via TTS and broadcasts the audio to all participants in one call. Requires an active appoiint_join_meeting session. Text is trimmed to 500 chars server-side; audio over 500KB is dropped by the relay.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID (must have joined via appoiint_join_meeting)"},text:{type:"string",description:"Text to speak (max 500 chars)"},voice:{type:"string",description:"Voice: cfo, cto, cmo, cco, cso, clo, heart, michael, nova, echo (default: heart)"}},required:["roomId","text"]},handler:async(e,t,n)=>{const i=n.meetingSessions.get(t.roomId);if(!i)return{error:"Not in this meeting. Call appoiint_join_meeting first."};const a=await e.synthesize({text:t.text,voice:t.voice||"heart",agentRole:t.voice});if(!a||!a.audio)return{error:"TTS synthesis failed",detail:a};const r=i.sendAudio({audio:a.audio,format:a.format});return{spoken:!0,roomId:t.roomId,voice:a.voice,provider:a.provider,bytes:r.bytes}},readOnly:!1},{name:"appoiint_list_events",description:"List bookable event types.",inputSchema:{type:"object",properties:{}},handler:async e=>e.events(),readOnly:!0},{name:"appoiint_create_event",description:"Create a bookable event type for the authenticated host.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Event type name/title"},duration:{type:"number",description:"Duration in minutes (default: 30)"},slug:{type:"string",description:"URL slug (default: derived from name)"},description:{type:"string",description:"Short description"},timezone:{type:"string",description:"Availability timezone (default: Europe/London)"},price:{type:"number",description:"Price (default: 0 = free)"},currency:{type:"string",description:"Currency (default: USD)"}},required:["name"]},handler:async(e,t,n)=>{const i=t.slug||String(t.name).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""),a=Number(t.price)||0;return e.createEvent({userId:n.config.userId,name:t.name,slug:i,duration:t.duration||30,description:t.description||"",availability:{type:"inherit",timezone:t.timezone||"Europe/London"},pricing:{enabled:a>0,amount:a,currency:t.currency||"USD"},meetingSettings:{location:{type:"video"},autoCreateMeeting:!0}})},readOnly:!1},{name:"appoiint_delete_event",description:"Delete an event type. SAFETY: refuses to hard-delete when bookings are attached (would orphan meetings) unless force=true; use soft=true to deactivate while preserving bookings.",inputSchema:{type:"object",properties:{eventTypeId:{type:"string",description:"Event type id (from appoiint_list_events)"},soft:{type:"boolean",description:"Deactivate instead of hard delete (preserves bookings)"},force:{type:"boolean",description:"Hard delete even if bookings are attached"}},required:["eventTypeId"]},handler:async(e,t)=>{const n=t.eventTypeId;let i=null;try{const t=await e.events();i=(Array.isArray(t)?t:t.eventTypes||t.data&&(Array.isArray(t.data)?t.data:t.data.eventTypes)||[]).find(e=>e.id===n||e._id===n||e.eventTypeId===n||e.slug===n)}catch{}const a=i&&Number.isFinite(i.bookingCount)?i.bookingCount:null,r=i&&(i.name||i.slug)||n;if(!t.soft&&!t.force&&a>0)throw new Error(`Refusing to delete "${r}" — it has ${a} booking(s) attached and they would be orphaned. Re-run with soft:true (deactivate, keep bookings) or force:true (hard delete anyway).`);const o=await e.deleteEvent(n,!!t.soft);return{deleted:!t.soft,deactivated:!!t.soft,eventType:r,bookingsAffected:a||0,result:o}},readOnly:!1},{name:"appoiint_check_availability",description:"Check available time slots for a host on a given date.",inputSchema:{type:"object",properties:{email:{type:"string",description:"Host email address"},date:{type:"string",description:"Date (YYYY-MM-DD)"},timezone:{type:"string",description:"Timezone (default: UTC)"}},required:["email","date"]},handler:async(e,t)=>e.slots(t.email,t.date,t.timezone||"UTC"),readOnly:!0},{name:"appoiint_create_booking",description:"Create a booking on behalf of a customer.",inputSchema:{type:"object",properties:{eventTypeId:{type:"string",description:"Event type ID"},scheduledAt:{type:"string",description:"ISO 8601 date-time (e.g. 2026-06-15T14:00:00Z)"},duration:{type:"number",description:"Duration in minutes (default: 30)"},customerName:{type:"string",description:"Customer name"},customerEmail:{type:"string",description:"Customer email"}},required:["scheduledAt","customerEmail"]},handler:async(e,t)=>e.book({eventTypeId:t.eventTypeId,scheduledAt:t.scheduledAt,duration:t.duration||30,customer:{name:t.customerName||"Guest",email:t.customerEmail},location:{type:"video"}}),readOnly:!1},{name:"appoiint_tts",description:"Synthesize text-to-speech with CxO agent voice.",inputSchema:{type:"object",properties:{text:{type:"string",description:"Text to synthesize"},voice:{type:"string",description:"Voice: cfo, cto, cmo, cco, cso, clo, heart, michael, nova, echo (default: heart)"}},required:["text"]},handler:async(e,t)=>e.synthesize({text:t.text,voice:t.voice||"heart",agentRole:t.voice}),readOnly:!0},{name:"appoiint_voices",description:"List available TTS voices and CxO agent voice mappings.",inputSchema:{type:"object",properties:{}},handler:async e=>e.voices(),readOnly:!0},{name:"appoiint_helpdesk_tickets",description:"List helpdesk tickets. Filter by status.",inputSchema:{type:"object",properties:{status:{type:"string",description:"Filter: open, resolved, closed"}}},handler:async(e,t,n)=>{const{rawApi:i}=require("./api");return i(n.config)("GET","/saas/api/v1/sdk/helpdeskryClient/tickets"+(t.status?`?status=${t.status}`:""))},readOnly:!0},{name:"appoiint_helpdesk_ticket_show",description:"Get ticket detail with messages.",inputSchema:{type:"object",properties:{ticketId:{type:"string"}},required:["ticketId"]},handler:async(e,t,n)=>{const{rawApi:i}=require("./api");return i(n.config)("GET",`/saas/api/v1/sdk/helpdeskryClient/tickets/${t.ticketId}`)},readOnly:!0},{name:"appoiint_helpdesk_ticket_create",description:"Create a helpdesk ticket.",inputSchema:{type:"object",properties:{subject:{type:"string"},priority:{type:"string"},category:{type:"string"}},required:["subject"]},handler:async(e,t,n)=>{const{rawApi:i}=require("./api");return i(n.config)("POST","/saas/api/v1/sdk/helpdeskryClient/tickets",t)},readOnly:!1},{name:"appoiint_helpdesk_ticket_reply",description:"Reply to a helpdesk ticket.",inputSchema:{type:"object",properties:{ticketId:{type:"string"},message:{type:"string"}},required:["ticketId","message"]},handler:async(e,t,n)=>{const{rawApi:i}=require("./api");return i(n.config)("POST",`/saas/api/v1/sdk/helpdeskryClient/tickets/${t.ticketId}/messages`,{content:t.message})},readOnly:!1},{name:"appoiint_crm_leads",description:"List CRM leads. Filter by status.",inputSchema:{type:"object",properties:{status:{type:"string"}}},handler:async(e,t,n)=>{const{rawApi:i}=require("./api"),a=t.status?`?status=${t.status}`:"";return i(n.config)("GET",`/saas/api/v1/sdk/crm/leads${a}`)},readOnly:!0},{name:"appoiint_crm_lead_show",description:"Get lead detail.",inputSchema:{type:"object",properties:{leadId:{type:"string"}},required:["leadId"]},handler:async(e,t,n)=>{const{rawApi:i}=require("./api");return i(n.config)("GET",`/saas/api/v1/sdk/crm/leads/${t.leadId}`)},readOnly:!0},{name:"appoiint_crm_lead_create",description:"Create a CRM lead.",inputSchema:{type:"object",properties:{name:{type:"string"},email:{type:"string"},source:{type:"string"}},required:["name"]},handler:async(e,t,n)=>{const{rawApi:i}=require("./api");return i(n.config)("POST","/saas/api/v1/sdk/crm/leads",t)},readOnly:!1},{name:"appoiint_crm_opportunities",description:"List CRM opportunities. Filter by stage.",inputSchema:{type:"object",properties:{stage:{type:"string"}}},handler:async(e,t,n)=>{const{rawApi:i}=require("./api"),a=t.stage?`?stage=${t.stage}`:"";return i(n.config)("GET",`/saas/api/v1/sdk/crm/opportunities${a}`)},readOnly:!0},{name:"appoiint_crm_pipelines",description:"List CRM pipelines with stages.",inputSchema:{type:"object",properties:{}},handler:async(e,t,n)=>{const{rawApi:i}=require("./api");return i(n.config)("GET","/saas/api/v1/sdk/crm/pipelines")},readOnly:!0},{name:"appoiint_channel_send",description:"Send a 1:1 message to another agent. Use for ops requests, data queries, or notifications.",inputSchema:{type:"object",properties:{to:{type:"string",description:"Recipient agent ID"},message:{type:"string",description:"Message text"},action:{type:"string",description:"Intent/action (e.g. deploy, query, notify)"},payload:{type:"object",description:"Structured data payload"}},required:["to"]},handler:async(e,t)=>{const n={to:t.to,type:t.action?"request":"notify"};return t.message&&(n.payload={message:t.message}),t.action&&(n.action=t.action,n.requestId=`req_${Date.now()}`),t.payload&&(n.payload={...n.payload,...t.payload}),e.channelSend(n)},readOnly:!1},{name:"appoiint_channel_inbox",description:"Get unread messages from other agents.",inputSchema:{type:"object",properties:{}},handler:async e=>e.channelInbox(),readOnly:!0},{name:"appoiint_channel_history",description:"Get message history with a specific agent.",inputSchema:{type:"object",properties:{agentId:{type:"string",description:"Agent ID to get history with"},limit:{type:"number",description:"Max messages (default 50)"}},required:["agentId"]},handler:async(e,t)=>e.channelHistory(t.agentId,t.limit),readOnly:!0},{name:"appoiint_channel_agents",description:"List agents you have communicated with.",inputSchema:{type:"object",properties:{}},handler:async e=>e.channelAgents(),readOnly:!0},{name:"appoiint_wall",description:"All your message threads (DMs + channels) with unread badges, newest first. Start here to see what needs attention.",inputSchema:{type:"object",properties:{}},handler:async e=>e.wall(),readOnly:!0},{name:"appoiint_notifications",description:"Unread digest across all DM and channel threads. Reading a thread history marks it read.",inputSchema:{type:"object",properties:{}},handler:async e=>e.notificationsDigest(),readOnly:!0},{name:"appoiint_channel_create",description:"Create a named channel for multi-agent group messaging. You auto-join as creator.",inputSchema:{type:"object",properties:{name:{type:"string",description:'Channel name (slugified, e.g. "dev-ops")'},topic:{type:"string",description:"Optional channel topic"}},required:["name"]},handler:async(e,t)=>e.groupCreate(t.name,t.topic),readOnly:!1},{name:"appoiint_channel_join",description:"Join an existing named channel.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Channel name/slug"}},required:["name"]},handler:async(e,t)=>e.groupJoin(t.name),readOnly:!1},{name:"appoiint_channel_leave",description:"Leave a named channel.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Channel name/slug"}},required:["name"]},handler:async(e,t)=>e.groupLeave(t.name),readOnly:!1},{name:"appoiint_channel_list",description:"List named channels with membership and your unread counts.",inputSchema:{type:"object",properties:{}},handler:async e=>e.groupList(),readOnly:!0},{name:"appoiint_channel_post",description:"Post a message to a named channel (must be a member).",inputSchema:{type:"object",properties:{name:{type:"string",description:"Channel name/slug"},message:{type:"string",description:"Message text"},payload:{type:"object",description:"Optional structured payload"}},required:["name","message"]},handler:async(e,t)=>e.groupSend(t.name,{text:t.message,payload:t.payload||{message:t.message}}),readOnly:!1},{name:"appoiint_channel_messages",description:"Read a named channel history (reading marks it read).",inputSchema:{type:"object",properties:{name:{type:"string",description:"Channel name/slug"},limit:{type:"number",description:"Max messages (default 50)"}},required:["name"]},handler:async(e,t)=>e.groupHistory(t.name,t.limit),readOnly:!0},{name:"appoiint_admin_tenants",description:"List all tenants with plan, status, usage. Superadmin only.",inputSchema:{type:"object",properties:{}},handler:async e=>e.adminTenants(),readOnly:!0},{name:"appoiint_admin_tenant_view",description:"Full tenant detail: plan, stats, usage, created date.",inputSchema:{type:"object",properties:{slug:{type:"string",description:"Tenant slug"}},required:["slug"]},handler:async(e,t)=>e.adminTenantView(t.slug),readOnly:!0},{name:"appoiint_platform_stats",description:"Platform overview: tenants, users, rooms, bookings, meetings.",inputSchema:{type:"object",properties:{}},handler:async e=>e.platformStats(),readOnly:!0},{name:"appoiint_funnel",description:"Signup funnel with conversion rates.",inputSchema:{type:"object",properties:{}},handler:async e=>e.funnel(),readOnly:!0},{name:"appoiint_revenue",description:"Revenue breakdown: MRR, ARR, fees, payouts.",inputSchema:{type:"object",properties:{}},handler:async e=>e.revenue(),readOnly:!0},{name:"appoiint_audit",description:"Activity audit trail.",inputSchema:{type:"object",properties:{limit:{type:"number",description:"Max entries"},action:{type:"string",description:"Filter by action type"}}},handler:async(e,t)=>{const n=new URLSearchParams;return t.limit&&n.set("limit",t.limit),t.action&&n.set("action",t.action),e.audit(n.toString())},readOnly:!0},{name:"appoiint_list_bookings",description:"List bookings for a host (defaults to the authenticated user).",inputSchema:{type:"object",properties:{hostId:{type:"string",description:"Host user id (default: authenticated user)"}}},handler:async(e,t,n)=>e.bookingsByHost(t.hostId||n.config.userId),readOnly:!0},{name:"appoiint_get_booking",description:"Get a single booking by id.",inputSchema:{type:"object",properties:{bookingId:{type:"string",description:"Booking id"}},required:["bookingId"]},handler:async(e,t)=>e.getBooking(t.bookingId),readOnly:!0},{name:"appoiint_cancel_booking",description:"Cancel a booking.",inputSchema:{type:"object",properties:{bookingId:{type:"string",description:"Booking id"},reason:{type:"string",description:"Cancellation reason"}},required:["bookingId"]},handler:async(e,t)=>e.cancelBooking(t.bookingId,{reason:t.reason||"Cancelled via MCP"}),readOnly:!1},{name:"appoiint_reschedule_booking",description:"Reschedule a booking to a new date/time.",inputSchema:{type:"object",properties:{bookingId:{type:"string",description:"Booking id"},newDate:{type:"string",description:"ISO 8601 date-time (e.g. 2026-10-01T14:00:00Z)"},reason:{type:"string",description:"Reschedule reason"}},required:["bookingId","newDate"]},handler:async(e,t)=>{const n={newDate:t.newDate,newScheduledAt:t.newDate};return t.reason&&(n.reason=t.reason),e.rescheduleBooking(t.bookingId,n)},readOnly:!1},{name:"appoiint_get_availability",description:"Get weekly availability (working hours) for a user (defaults to the authenticated user).",inputSchema:{type:"object",properties:{userId:{type:"string",description:"User id (default: authenticated user)"}}},handler:async(e,t,n)=>e.availabilityGet(t.userId||n.config.userId),readOnly:!0},{name:"appoiint_set_availability",description:"Set weekly availability: one time window applied to the given days. Mirrors PUT /availability/:userId (body: userId, organizationId, workingHours, timezone).",inputSchema:{type:"object",properties:{from:{type:"string",description:"Start time HH:MM (default 09:00)"},to:{type:"string",description:"End time HH:MM (default 17:00)"},days:{type:"array",items:{type:"number"},description:"Days of week 0=Sun..6=Sat (default Mon-Fri [1,2,3,4,5])"},timezone:{type:"string",description:"IANA timezone (default Europe/London)"},organizationId:{type:"string",description:"Org id (auto-resolved from current availability or event types if omitted)"},userId:{type:"string",description:"Target user (default: authenticated user)"}}},handler:async(e,t,n)=>{const i=t.userId||n.config.userId;if(!i)throw new Error("No userId available — pass userId explicitly.");const a=t.from||"09:00",r=t.to||"17:00";if(!/^\d{2}:\d{2}$/.test(a)||!/^\d{2}:\d{2}$/.test(r))throw new Error("Times must be HH:MM (e.g. 09:00)");const o=Array.isArray(t.days)&&t.days.length?t.days:[1,2,3,4,5],s=[0,1,2,3,4,5,6].map(e=>({dayOfWeek:e,isAvailable:o.includes(e),timeSlots:o.includes(e)?[{startTime:a,endTime:r}]:[]})),p=t.organizationId||await _resolveOrgId(e,i);if(!p)throw new Error("Could not resolve organizationId — pass organizationId explicitly.");const d=t.timezone||"Europe/London";return e.availabilityUpdate(i,{userId:i,organizationId:p,workingHours:s,timezone:d})},readOnly:!1},{name:"appoiint_list_domains",description:"List custom meeting-page domains for this tenant.",inputSchema:{type:"object",properties:{}},handler:async e=>_domainArray(await e.domains()),readOnly:!0},{name:"appoiint_register_domain",description:"Register a custom domain for the tenant meetings page. Returns the CNAME target to publish, then verify with appoiint_verify_domain.",inputSchema:{type:"object",properties:{hostname:{type:"string",description:"e.g. meetings.yourdomain.com"}},required:["hostname"]},handler:async(e,t,n)=>{if(!/^[a-zA-Z0-9][a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(t.hostname))throw new Error("Invalid hostname");if(!n.config.userId)throw new Error("No userId on this API key — cannot register a tenant domain.");const i=_unwrap(await e.domainRegister({hostname:t.hostname,domainType:"custom",tenantId:n.config.userId,tenantType:"user",baseDomain:"appoiint.ai"})),a=i.dnsVerification&&i.dnsVerification.expectedValue;return{registered:!0,hostname:t.hostname,domainId:_idOf(i),cnameTarget:a||null,next:a?`Publish CNAME ${t.hostname} -> ${a}, then call appoiint_verify_domain.`:"SDK returned no CNAME target — inspect with appoiint_domain_status."}},readOnly:!1},{name:"appoiint_verify_domain",description:"Verify DNS for a custom domain and auto-activate it once verified (custom domains ride the wildcard cert, so activation gates on DNS only).",inputSchema:{type:"object",properties:{domain:{type:"string",description:"Hostname or domain id"}},required:["domain"]},handler:async(e,t)=>{const n=await _findDomain(e,t.domain);if(!n)throw new Error(`Domain not found: ${t.domain}`);const i=await e.domainVerify(_idOf(n)),a=_unwrap(i),r=a.verified||a.dnsVerification&&a.dnsVerification.verified||i.success&&"active"===a.status;let o=null;if(r&&"active"!==a.status)try{o=_unwrap(await e.domainActivate(_idOf(n)))}catch(e){o={error:e.message}}return{hostname:n.hostname,verified:!!r,status:o&&o.status||a.status||null,activate:o}},readOnly:!1},{name:"appoiint_domain_status",description:"DNS + SSL status for a custom domain.",inputSchema:{type:"object",properties:{domain:{type:"string",description:"Hostname or domain id"}},required:["domain"]},handler:async(e,t)=>{const n=await _findDomain(e,t.domain);if(!n)throw new Error(`Domain not found: ${t.domain}`);const i=_unwrap(await e.domainDnsStatus(_idOf(n)));return{hostname:n.hostname,domainId:_idOf(n),status:n.status,dns:i}},readOnly:!0},{name:"appoiint_remove_domain",description:"Delete a custom domain. IRREVERSIBLE — requires confirm=true.",inputSchema:{type:"object",properties:{domain:{type:"string",description:"Hostname or domain id"},confirm:{type:"boolean",description:"Must be true to delete"}},required:["domain"]},handler:async(e,t)=>{if(!0!==t.confirm)throw new Error("Refusing to delete without confirm=true (this cannot be undone).");const n=await _findDomain(e,t.domain);if(!n)throw new Error(`Domain not found: ${t.domain}`);const i=await e.domainDelete(_idOf(n));return{removed:!0,hostname:n.hostname,result:i}},readOnly:!1},{name:"appoiint_page",description:"Show the tenant meetings-page profile (name, title, company, website, slug — drives the vCard + OG tags).",inputSchema:{type:"object",properties:{}},handler:async e=>e.profileGet(),readOnly:!0},{name:"appoiint_page_set",description:"Update the tenant meetings-page profile. Verified-writable fields only: firstName, lastName, company, title (stored as position), phone (mobile_no), website (powers the vCard VISIT CTA).",inputSchema:{type:"object",properties:{firstName:{type:"string"},lastName:{type:"string"},company:{type:"string"},title:{type:"string",description:"Job title (stored as position)"},phone:{type:"string"},website:{type:"string",description:"https URL — powers the vCard VISIT CTA"}}},handler:async(e,t)=>{const n={};if(void 0!==t.firstName&&(n.firstName=t.firstName),void 0!==t.lastName&&(n.lastName=t.lastName),void 0!==t.company&&(n.company=t.company),void 0!==t.title&&(n.position=t.title),void 0!==t.phone&&(n.mobile_no=t.phone),void 0!==t.website&&(n.website=t.website),!Object.keys(n).length)throw new Error("No fields to update.");return e.profileUpdate(n)},readOnly:!1},{name:"appoiint_update_event",description:"Update an existing event type (PUT /eventtypes/:id). Pass only the fields to change.",inputSchema:{type:"object",properties:{eventTypeId:{type:"string",description:"Event type id"},updates:{type:"object",description:"Fields to update (name, duration, description, pricing, ...)"}},required:["eventTypeId","updates"]},handler:async(e,t)=>e.updateEvent(t.eventTypeId,t.updates),readOnly:!1},{name:"appoiint_resolve_domain",description:"Resolve which tenant a hostname routes to (GET /domains/resolve).",inputSchema:{type:"object",properties:{hostname:{type:"string"}},required:["hostname"]},handler:async(e,t)=>e.domainResolve(t.hostname),readOnly:!0},{name:"appoiint_stt_status",description:"Speech-to-text provider status.",inputSchema:{type:"object",properties:{}},handler:async e=>e.sttStatus(),readOnly:!0},{name:"appoiint_costs",description:"Usage costs summary for this account.",inputSchema:{type:"object",properties:{}},handler:async e=>e.costs(),readOnly:!0},{name:"appoiint_costs_room",description:"Usage costs for a specific room.",inputSchema:{type:"object",properties:{roomId:{type:"string"}},required:["roomId"]},handler:async(e,t)=>e.costsByRoom(t.roomId),readOnly:!0},{name:"appoiint_costs_pricing",description:"Current usage pricing table.",inputSchema:{type:"object",properties:{}},handler:async e=>e.costsPricing(),readOnly:!0},{name:"appoiint_channel_ack",description:"Acknowledge an agent-channel message by id.",inputSchema:{type:"object",properties:{messageId:{type:"string"}},required:["messageId"]},handler:async(e,t)=>e.channelAck(t.messageId),readOnly:!1},{name:"appoiint_signups",description:"SUPERADMIN: signup counts over the last N days.",inputSchema:{type:"object",properties:{days:{type:"number",description:"Window in days"}}},handler:async(e,t)=>e.signups(t.days),readOnly:!0},{name:"appoiint_audit_export",description:"SUPERADMIN: export the audit trail (json or csv).",inputSchema:{type:"object",properties:{format:{type:"string",description:"json or csv (default json)"}}},handler:async(e,t)=>e.auditExport(t.format||"json"),readOnly:!0},{name:"appoiint_admin_notifications",description:"SUPERADMIN: platform notifications feed.",inputSchema:{type:"object",properties:{since:{type:"string",description:"ISO timestamp — only newer items"}}},handler:async(e,t)=>e.notifications(t.since),readOnly:!0},{name:"appoiint_tickets",description:"SUPERADMIN: list support tickets.",inputSchema:{type:"object",properties:{status:{type:"string",description:"Filter: open, closed, ..."}}},handler:async(e,t)=>e.tickets(t.status),readOnly:!0},{name:"appoiint_ticket_show",description:"SUPERADMIN: show a support ticket.",inputSchema:{type:"object",properties:{ticketId:{type:"string"}},required:["ticketId"]},handler:async(e,t)=>e.ticketShow(t.ticketId),readOnly:!0},{name:"appoiint_ticket_reply",description:"SUPERADMIN: reply to a support ticket.",inputSchema:{type:"object",properties:{ticketId:{type:"string"},message:{type:"string"}},required:["ticketId","message"]},handler:async(e,t)=>e.ticketReply(t.ticketId,t.message),readOnly:!1},{name:"appoiint_ticket_close",description:"SUPERADMIN: close a support ticket.",inputSchema:{type:"object",properties:{ticketId:{type:"string"}},required:["ticketId"]},handler:async(e,t)=>e.ticketClose(t.ticketId),readOnly:!1},{name:"appoiint_admin_users",description:"SUPERADMIN: list platform users.",inputSchema:{type:"object",properties:{}},handler:async e=>e.adminUsers(),readOnly:!0},{name:"appoiint_admin_user_create",description:"SUPERADMIN: create a platform user.",inputSchema:{type:"object",properties:{email:{type:"string"},name:{type:"string"},organizationName:{type:"string"},planId:{type:"string",description:"e.g. appoiint-enterprise"},skipPayment:{type:"boolean"}},required:["email","name"]},handler:async(e,t)=>e.adminUserCreate(t),readOnly:!1},{name:"appoiint_admin_user_reset",description:"SUPERADMIN: reset a user password.",inputSchema:{type:"object",properties:{email:{type:"string"},newPassword:{type:"string",description:"Omit to auto-generate"}},required:["email"]},handler:async(e,t)=>e.adminUserReset(t.email,t.newPassword?{newPassword:t.newPassword}:{}),readOnly:!1},{name:"appoiint_admin_user_delete",description:"SUPERADMIN: delete a platform user. IRREVERSIBLE — requires confirm=true.",inputSchema:{type:"object",properties:{email:{type:"string"},confirm:{type:"boolean",description:"Must be true to delete"}},required:["email"]},handler:async(e,t)=>{if(!0!==t.confirm)throw new Error("Refusing to delete without confirm=true (this cannot be undone).");return e.adminUserDelete(t.email)},readOnly:!1},{name:"appoiint_admin_tenant_create",description:"SUPERADMIN: create a tenant.",inputSchema:{type:"object",properties:{data:{type:"object",description:"Tenant payload (slug, name, plan, ...)"}},required:["data"]},handler:async(e,t)=>e.adminTenantCreate(t.data),readOnly:!1},{name:"appoiint_admin_tenant_set",description:"SUPERADMIN: tenant lifecycle action — plan | verify | suspend | activate.",inputSchema:{type:"object",properties:{slug:{type:"string",description:"Tenant slug"},action:{type:"string",description:"plan | verify | suspend | activate"},plan:{type:"string",description:"Plan id (required when action=plan)"}},required:["slug","action"]},handler:async(e,t)=>{switch(t.action){case"plan":if(!t.plan)throw new Error("action=plan requires the plan parameter");return e.adminTenantPlan(t.slug,t.plan);case"verify":return e.adminTenantVerify(t.slug);case"suspend":return e.adminTenantSuspend(t.slug);case"activate":return e.adminTenantActivate(t.slug);default:throw new Error(`Unknown action: ${t.action} (use plan | verify | suspend | activate)`)}},readOnly:!1},{name:"appoiint_admin_tenant_delete",description:"SUPERADMIN: delete a tenant. IRREVERSIBLE — requires confirm=true.",inputSchema:{type:"object",properties:{slug:{type:"string"},confirm:{type:"boolean",description:"Must be true to delete"}},required:["slug"]},handler:async(e,t)=>{if(!0!==t.confirm)throw new Error("Refusing to delete without confirm=true (this cannot be undone).");return e.adminTenantDelete(t.slug)},readOnly:!1},{name:"appoiint_admin_billing",description:"SUPERADMIN: platform billing/revenue summary.",inputSchema:{type:"object",properties:{}},handler:async e=>e.adminBilling(),readOnly:!0},{name:"appoiint_admin_discount",description:"SUPERADMIN: apply a discount.",inputSchema:{type:"object",properties:{data:{type:"object",description:"Discount payload"}},required:["data"]},handler:async(e,t)=>e.adminDiscount(t.data),readOnly:!1}];function _unwrap(e){let t=e;for(;t&&"object"==typeof t&&t.data&&!Array.isArray(t);)t=t.data;return t||{}}function _domainArray(e){const t=_unwrap(e);return Array.isArray(t)?t:t.domains||t.tenantDomains||[]}function _idOf(e){return e.tenantDomainId||e._id||e.id||null}async function _findDomain(e,t){return _domainArray(await e.domains()).find(e=>e.hostname===t||_idOf(e)===t)||null}async function _resolveOrgId(e,t){try{const n=_unwrap(await e.availabilityGet(t)),i=n.settings&&n.settings.organizationId||n.organizationId;if(i)return i}catch{}try{const t=await e.events(),n=(Array.isArray(t)?t:t.eventTypes||t.data&&(Array.isArray(t.data)?t.data:t.data.eventTypes)||[]).find(e=>e.organization&&e.organization.id);if(n)return n.organization.id}catch{}return null}module.exports={TOOLS:TOOLS};
|