Skip to main content
Glama
paulsham

Wiki Analytics Specification MCP Server

by paulsham

validate_event_payload

Validate tracking implementation payloads against event specifications to identify errors, warnings, and valid fields for analytics data accuracy.

Instructions

Validate a tracking implementation payload against the event spec. Returns errors, warnings, and valid fields.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
event_nameYesName of the event to validate against
payloadYesThe payload object to validate

Implementation Reference

  • The main handler function for the 'validate_event_payload' tool. It retrieves the event specification, expands its properties, validates the provided payload by checking field presence, types, and constraints (enum, regex), collects errors and warnings for invalid or unknown fields and missing required properties, and returns validation results.
    handler: async (args) => { const event = eventsMap.get(args.event_name); if (!event) { throw new NotFoundError('Event', args.event_name); } const expanded = getExpandedProperties(event); const errors = []; const warnings = []; const validFields = []; // Collect all expected properties const expectedProps = new Map(); for (const group of expanded.property_groups) { for (const prop of group.properties) { expectedProps.set(prop.name, prop); } } for (const prop of expanded.additional_properties) { expectedProps.set(prop.name, prop); } // Check provided fields for (const [key, value] of Object.entries(args.payload)) { const prop = expectedProps.get(key); if (!prop) { warnings.push({ field: key, issue: 'Unknown property not in spec' }); continue; } // Remove from expected (field was provided, even if invalid) expectedProps.delete(key); // Type validation const actualType = Array.isArray(value) ? 'array' : typeof value; const expectedType = prop.type === 'timestamp' ? 'string' : prop.type; if (expectedType !== actualType && expectedType !== 'unknown') { errors.push({ field: key, issue: 'Type mismatch', expected: prop.type, got: actualType }); continue; } // Constraint validation if (prop.constraints && prop.constraints !== '-') { if (prop.constraints.startsWith('enum:')) { const allowedValues = prop.constraints.substring(5).split(',').map(s => s.trim()); if (!allowedValues.includes(value)) { errors.push({ field: key, issue: 'Invalid enum value', expected: allowedValues, got: value }); continue; } } else if (prop.constraints.startsWith('regex:')) { const pattern = prop.constraints.substring(6).trim(); try { const regex = new RegExp(pattern); if (!regex.test(value)) { errors.push({ field: key, issue: 'Regex validation failed', expected: pattern, got: value }); continue; } } catch (e) { // Invalid regex pattern in spec } } } validFields.push(key); } // Check for missing properties for (const [name] of expectedProps) { warnings.push({ field: name, issue: 'Missing property' }); } return { valid: errors.length === 0, errors, warnings, valid_fields: validFields }; }
  • Input schema defining the expected parameters: event_name (string, required) and payload (object, required).
    inputSchema: { type: 'object', properties: { event_name: { type: 'string', description: 'Name of the event to validate against' }, payload: { type: 'object', description: 'The payload object to validate' } }, required: ['event_name', 'payload'] },
  • The tool definition object within the exported 'tools' object, which is imported into index.js and registered dynamically via setRequestHandler for ListToolsRequestSchema and CallToolRequestSchema.
    validate_event_payload: { description: 'Validate a tracking implementation payload against the event spec. Returns errors, warnings, and valid fields.', inputSchema: { type: 'object', properties: { event_name: { type: 'string', description: 'Name of the event to validate against' }, payload: { type: 'object', description: 'The payload object to validate' } }, required: ['event_name', 'payload'] }, handler: async (args) => { const event = eventsMap.get(args.event_name); if (!event) { throw new NotFoundError('Event', args.event_name); } const expanded = getExpandedProperties(event); const errors = []; const warnings = []; const validFields = []; // Collect all expected properties const expectedProps = new Map(); for (const group of expanded.property_groups) { for (const prop of group.properties) { expectedProps.set(prop.name, prop); } } for (const prop of expanded.additional_properties) { expectedProps.set(prop.name, prop); } // Check provided fields for (const [key, value] of Object.entries(args.payload)) { const prop = expectedProps.get(key); if (!prop) { warnings.push({ field: key, issue: 'Unknown property not in spec' }); continue; } // Remove from expected (field was provided, even if invalid) expectedProps.delete(key); // Type validation const actualType = Array.isArray(value) ? 'array' : typeof value; const expectedType = prop.type === 'timestamp' ? 'string' : prop.type; if (expectedType !== actualType && expectedType !== 'unknown') { errors.push({ field: key, issue: 'Type mismatch', expected: prop.type, got: actualType }); continue; } // Constraint validation if (prop.constraints && prop.constraints !== '-') { if (prop.constraints.startsWith('enum:')) { const allowedValues = prop.constraints.substring(5).split(',').map(s => s.trim()); if (!allowedValues.includes(value)) { errors.push({ field: key, issue: 'Invalid enum value', expected: allowedValues, got: value }); continue; } } else if (prop.constraints.startsWith('regex:')) { const pattern = prop.constraints.substring(6).trim(); try { const regex = new RegExp(pattern); if (!regex.test(value)) { errors.push({ field: key, issue: 'Regex validation failed', expected: pattern, got: value }); continue; } } catch (e) { // Invalid regex pattern in spec } } } validFields.push(key); } // Check for missing properties for (const [name] of expectedProps) { warnings.push({ field: name, issue: 'Missing property' }); } return { valid: errors.length === 0, errors, warnings, valid_fields: validFields }; } },

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/paulsham/wiki-mcp-analytics-test-1.1.0'

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