Skip to main content
Glama
schemas.ts12.3 kB
import { z } from 'zod'; // Regular expression for validating IDs consisting of letters, numbers, and hyphens const idPattern = /^[a-zA-Z0-9-]+$/; const idErrorMessage = 'ID must consist of letters, numbers, and hyphens'; const ListBaseRequestSchema = z.object({ page: z.number().min(1).describe('Page number').optional(), count: z.number().min(1).describe('Number of elements per page').optional(), }); const ListBaseResponseSchema = z.object({ pagination: z.object({ currentPage: z.number(), pagesCount: z.number(), }), }); // NOTE it strips some redundant fields export const CircleSchema = z .object({ id: z .string() .regex(idPattern, idErrorMessage) .describe('Unique identifier for the circle'), name: z.string(), role: z.string().regex(idPattern, idErrorMessage).optional(), parentCircle: z .string() .regex(idPattern, idErrorMessage) .nullable() .optional(), circleAdmins: z.array(z.string()).optional(), decisionMakers: z.array(z.string()).optional(), nonDecisionMakers: z.array(z.string()).optional(), coreRoles: z.array(z.string()).optional(), subRoles: z.array(z.string()).optional(), assigner: z.string().regex(idPattern, idErrorMessage).nullable().optional(), lead: z.string().regex(idPattern, idErrorMessage).nullable().optional(), }) .strip(); // NOTE it strips some redundant fields export const DomainSchema = z .object({ id: z.string().regex(idPattern, idErrorMessage), description: z.string(), role: z.string(), policies: z.array(z.string()), }) .strip(); // NOTE it strips some redundant fields export const MeetingSchema = z .object({ id: z.string().regex(idPattern, idErrorMessage), title: z.string().nullable().optional(), circle: z.string().regex(idPattern, idErrorMessage).nullable(), scheduledAt: z.string().nullable(), openedBy: z.string().nullable(), openedAt: z.string().nullable(), tensions: z.array(z.string()).optional(), attendees: z.array(z.string()).optional(), status: z.enum(['scheduled', 'processing', 'closed']), description: z.string().nullable(), }) .strip(); export const MemberSchema = z .object({ id: z.string().regex(idPattern, idErrorMessage), firstName: z.string().nullable().optional(), lastName: z.string().nullable().optional(), email: z.string().email().nullable().optional(), createdAt: z.string().optional(), }) .strip(); // NOTE it strips some redundant fields export const MetricSchema = z .object({ id: z.string().regex(idPattern, idErrorMessage), global: z.boolean().nullable(), title: z.string().nullable(), body: z.string().nullable(), role: z.string().regex(idPattern, idErrorMessage).optional().nullable(), members: z.array(z.string()).optional(), mainLink: z.string().optional().nullable(), circle: z.string().regex(idPattern, idErrorMessage).optional().nullable(), lastCheckDate: z.string().optional().nullable(), }) .strip(); // NOTE it strips some redundant fields export const PolicySchema = z .object({ id: z.string().regex(idPattern, idErrorMessage), title: z.string(), body: z.string().nullable(), circle: z.string().regex(idPattern, idErrorMessage).nullable().optional(), domain: z.string().nullable(), domainRole: z.string().nullable(), }) .strip(); // NOTE it strips some redundant fields export const RoleSchema = z .object({ id: z.string().regex(idPattern, idErrorMessage), name: z.string(), purpose: z.string().nullable().optional(), parentCircle: z .string() .regex(idPattern, idErrorMessage) .nullable() .optional(), circle: z.string().regex(idPattern, idErrorMessage).nullable().optional(), domains: z.array(z.string()).nullable().optional(), members: z.array(z.string()).nullable().optional(), accountabilities: z.array(z.string()).optional(), assignedMembers: z.array(z.string()).optional(), }) .strip(); // NOTE it strips some redundant fields export const TaskSchema = z.object({ id: z .string() .regex(idPattern, idErrorMessage) .describe('Unique identifier for the task'), title: z.string().nullable(), status: z.enum(['done', 'current']).nullable(), column: z.string().nullable().optional(), body: z.string().nullable(), startDate: z.string().nullable().optional(), term: z.string().nullable(), progressions: z.array(z.string()).optional(), objectives: z.array(z.string().nullable()).optional(), labels: z.array(z.string().nullable()).optional(), boardTitle: z.string().nullable().optional(), board: z.string().regex(idPattern, idErrorMessage).nullable().optional(), breadcrumb: z .array( z.object({ id: z.string().regex(idPattern, idErrorMessage).optional(), title: z.string().optional(), }) ) .optional(), tension: z.string().regex(idPattern, idErrorMessage).nullable().optional(), checked: z.boolean().nullable().optional(), todoLists: z.array(z.string()).optional(), rootTask: z.string().regex(idPattern, idErrorMessage).nullable().optional(), }); // NOTE it strips some redundant fields export const TensionSchema = z .object({ id: z.string().regex(idPattern, idErrorMessage), status: z.enum([ 'draft', 'ready', 'attached', 'gog', 'objected', 'accepted', 'rejected', 'stalled', 'archived', ]), name: z.string().nullable(), body: z.string().nullable(), member: z.string().regex(idPattern, idErrorMessage).nullable(), circle: z.string().regex(idPattern, idErrorMessage).nullable(), createdAt: z.string(), meeting: z.string().regex(idPattern, idErrorMessage).nullable().optional(), }) .strip(); // Common object type for foreignId, target, origin, tension const FeedObjectType = z.enum([ 'attachment', 'board', 'checklist', 'circle', 'column', 'objective', 'meeting', 'member', 'metric', 'policy', 'publication', 'role', 'task', 'tension', ]); const FeedBaseObjectSchema = z.object({ id: z.string().optional(), type: FeedObjectType.optional(), circle: z.string().optional(), title: z.string().optional(), name: z.string().optional(), deleted: z.boolean().optional(), }); export const FeedSchema = z.object({ id: z.string(), verb: z.string(), title: z.string(), object: FeedBaseObjectSchema, target: FeedBaseObjectSchema.nullable(), tension: z .object({ id: z.string().optional(), type: FeedObjectType.optional(), name: z.string().optional(), deleted: z.boolean().optional(), }) .nullable(), time: z.string(), updatedAt: z.string().nullable(), }); export type Feed = z.infer<typeof FeedSchema>; /** * Request Schemas */ export const ListTasksRequestSchema = ListBaseRequestSchema; export const ListMetricsRequestSchema = ListBaseRequestSchema; export const ListCirclesRequestSchema = ListBaseRequestSchema.extend({ member: z .string() .describe('Comma-separated unique identifiers for the member') .optional(), circle: z .string() .describe('Comma-separated unique identifiers for the circle') .optional(), }); export const GetCircleRequestSchema = z.object({ circleId: z .string() .regex(idPattern, idErrorMessage) .describe('Unique identifier for the circle'), }); export const ListRolesRequestSchema = ListBaseRequestSchema.extend({ member: z .string() .describe('Comma-separated unique identifiers for the member') .optional(), circle: z .string() .describe('Comma-separated unique identifiers for the circle') .optional(), }); export const GetRoleRequestSchema = z.object({ roleId: z .string() .regex(idPattern, idErrorMessage) .describe('Unique identifier for the role'), }); export const ListDomainsRequestSchema = ListBaseRequestSchema; export const ListPoliciesRequestSchema = ListBaseRequestSchema; export const ListMeetingsRequestSchema = ListBaseRequestSchema.extend({ circle: z .string() .describe('Comma-separated unique identifiers for the circle') .optional(), member: z .string() .describe('Comma-separated unique identifiers for the member') .optional(), }); export const GetMeetingRequestSchema = z.object({ meetingId: z .string() .regex(idPattern, idErrorMessage) .describe('Unique identifier for the meeting'), }); export const GetMemberFeedRequestSchema = z .object({ memberId: z .string() .regex(idPattern, idErrorMessage) .describe('Unique identifier for the member'), activityType: z .string() .optional() .describe( 'A comma separated list of: assignation|board|checklist|metric|objective|policy|publication|role|task|tension' ) .refine( (v) => v === undefined || v .split(',') .every((item) => [ 'assignation', 'board', 'checklist', 'metric', 'objective', 'policy', 'publication', 'role', 'task', 'tension', ].includes(item.trim()) ), { message: `activityType must be a comma-separated list of valid types: assignation, board, checklist, metric, objective, policy, publication, role, task, tension`, } ), event: z .enum(['assigned', 'unassigned', 'elected', 'scope']) .optional() .describe('Use only with activityType=assignation'), minTime: z .string() .optional() .describe('Filter elements by date (ISO 8601 format)'), maxTime: z .string() .optional() .describe( 'Pager: time of the last element of the previous page (ISO 8601 format)' ), count: z .number() .positive() .optional() .describe('Pager: number of elements per page'), }) .superRefine((data, ctx) => { if ( data.event && (!data.activityType || !data.activityType.split(',').includes('assignation')) ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'event can only be used when activityType includes "assignation"', path: ['event'], // Path to the field causing the error }); } }); export const GetTensionsRequestSchema = z.object({ meetingIds: z .array(z.string().regex(idPattern, idErrorMessage)) .min(1) .describe('List of unique meeting IDs'), }); export const SearchMemberRequestSchema = z.object({ email: z .string() .email() .describe('Email address of the member to search for'), }); /** * Response Schemas */ export const ListCirclesResponseSchema = ListBaseResponseSchema.extend({ items: z.array(CircleSchema), }); export const GetCircleResponseSchema = CircleSchema.extend({ linked: z .object({ roles: z.array(RoleSchema).optional(), }) .optional(), }); export const ListDomainsResponseSchema = ListBaseResponseSchema.extend({ items: z.array(DomainSchema), }); export const ListMeetingsResponseSchema = ListBaseResponseSchema.extend({ items: z.array(MeetingSchema), }); export const GetMeetingResponseSchema = MeetingSchema.extend({ linked: z .object({ tensions: z.array(TensionSchema).optional(), }) .optional(), }); export const ListMetricsResponseSchema = ListBaseResponseSchema.extend({ items: z.array(MeetingSchema), }); export const ListPoliciesResponseSchema = ListBaseResponseSchema.extend({ items: z.array(PolicySchema), }); export const ListRolesResponseSchema = ListBaseResponseSchema.extend({ items: z.array(RoleSchema), }); export const GetRoleResponseSchema = RoleSchema; export const ListTasksResponseSchema = ListBaseResponseSchema.extend({ items: z.array(TaskSchema), }); export const GetMemberFeedResponseSchema = z.array(FeedSchema); export const GetTensionsResponseSchema = z.object({ tensions: z.array(TensionSchema), failures: z.array( z.object({ meetingId: z.string(), error: z.string().optional(), }) ), }); export const SearchMemberResponseSchema = MemberSchema;

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/syucream/holaspirit-mcp-server'

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