Skip to main content
Glama
event-inbox-tools.ts4.91 kB
/** * EVENT INBOX TOOLS * * MCP tools for interacting with the event inbox: * - poll_events: Get unread events (marks them consumed) * - push_event: Manually push an event (DM/system use) * - get_event_history: View recent events with filters */ import { z } from 'zod'; import { getDb } from '../storage/index.js'; import { EventInboxRepository, EventType, SourceType } from '../storage/repos/event-inbox.repo.js'; import { SessionContext } from './types.js'; const EventTypeEnum = z.enum([ 'npc_action', 'combat_update', 'world_change', 'quest_update', 'time_passage', 'environmental', 'system' ]); const SourceTypeEnum = z.enum(['npc', 'combat', 'world', 'system', 'scheduler']); // Tool Definitions export const EventInboxTools = { POLL_EVENTS: { name: 'poll_events', description: `Poll the event inbox for unread events. Returns events and marks them as consumed. Events are generated by NPCs, combat, world systems, and schedulers. They represent things that happened "while the player wasn't looking" - making NPCs feel autonomous. Example response: [ { "eventType": "npc_action", "payload": { "npcName": "Bartender", "action": "wipes a glass nervously" }}, { "eventType": "quest_update", "payload": { "questName": "Missing Merchant", "update": "New rumor heard" }} ]`, inputSchema: z.object({ limit: z.number().int().min(1).max(50).default(20).describe('Maximum events to return') }) }, PUSH_EVENT: { name: 'push_event', description: `Push an event to the inbox. Used by DM or internal systems to queue events. NPCs "doing things" on their own, combat updates, world changes - all go here. Frontend polls this to show what happened.`, inputSchema: z.object({ eventType: EventTypeEnum, payload: z.record(z.any()).describe('Event data (JSON object)'), sourceType: SourceTypeEnum.optional(), sourceId: z.string().optional().describe('ID of source NPC/entity'), priority: z.number().int().min(0).max(10).default(0).describe('0=normal, 10=urgent'), expiresAt: z.string().optional().describe('ISO timestamp when event expires') }) }, GET_EVENT_HISTORY: { name: 'get_event_history', description: 'Get recent event history with optional filters.', inputSchema: z.object({ limit: z.number().int().min(1).max(100).default(50), eventType: EventTypeEnum.optional(), sourceType: SourceTypeEnum.optional(), includeConsumed: z.boolean().default(true) }) }, GET_PENDING_COUNT: { name: 'get_pending_event_count', description: 'Get the count of unread events in the inbox.', inputSchema: z.object({}) } } as const; // Tool Handlers export async function handlePollEvents( args: z.infer<typeof EventInboxTools.POLL_EVENTS.inputSchema>, _ctx: SessionContext ) { const repo = new EventInboxRepository(getDb()); const events = repo.pollAndConsume(args.limit); return { content: [{ type: 'text' as const, text: JSON.stringify({ count: events.length, events: events.map(e => ({ id: e.id, eventType: e.eventType, payload: e.payload, sourceType: e.sourceType, sourceId: e.sourceId, priority: e.priority, createdAt: e.createdAt })) }, null, 2) }] }; } export async function handlePushEvent( args: z.infer<typeof EventInboxTools.PUSH_EVENT.inputSchema>, _ctx: SessionContext ) { const repo = new EventInboxRepository(getDb()); const id = repo.push({ eventType: args.eventType as EventType, payload: args.payload, sourceType: args.sourceType as SourceType | undefined, sourceId: args.sourceId, priority: args.priority, expiresAt: args.expiresAt }); return { content: [{ type: 'text' as const, text: JSON.stringify({ success: true, eventId: id, message: `Event queued with ID ${id}` }) }] }; } export async function handleGetEventHistory( args: z.infer<typeof EventInboxTools.GET_EVENT_HISTORY.inputSchema>, _ctx: SessionContext ) { const repo = new EventInboxRepository(getDb()); const events = repo.getHistory({ limit: args.limit, eventType: args.eventType as EventType | undefined, sourceType: args.sourceType as SourceType | undefined, includeConsumed: args.includeConsumed }); return { content: [{ type: 'text' as const, text: JSON.stringify({ count: events.length, events }, null, 2) }] }; } export async function handleGetPendingCount( _args: z.infer<typeof EventInboxTools.GET_PENDING_COUNT.inputSchema>, _ctx: SessionContext ) { const repo = new EventInboxRepository(getDb()); const count = repo.getPendingCount(); return { content: [{ type: 'text' as const, text: JSON.stringify({ pendingEvents: count }) }] }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mnehmos/rpg-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server