Skip to main content
Glama

Jira MCP Server

index.ts6.52 kB
import * as yup from "yup"; /** * Schema for validating basic Jira API requests * Contains common fields used by all Jira API requests * * @type {yup.ObjectSchema} */ export const JiraApiRequestSchema = yup.object({ jiraHost: yup.string() .default(process.env.JIRA_HOST || "") .test( 'check-jira-host', 'Jira host is required and must be a valid domain (e.g., "company.atlassian.net")', (value) => !!value && value.trim().length > 0 ), email: yup.string() .email('Invalid email format. Please provide a valid email associated with your Jira account') .default(process.env.JIRA_EMAIL || "") .test( 'check-email', 'Email is required for Jira authentication', (value) => !!value && value.trim().length > 0 ), apiToken: yup.string() .default(process.env.JIRA_API_TOKEN || "") .test( 'check-api-token', 'API token is required for Jira authentication', (value) => !!value && value.trim().length > 0 ), }); /** * Schema for validating Jira issue requests * Extends the base API schema with the issueKey field * * @type {yup.ObjectSchema} */ export const JiraIssueRequestSchema = JiraApiRequestSchema.shape({ issueKey: yup.string() .required("Issue key is required") .matches(/^[A-Z][A-Z0-9_]+-[1-9][0-9]*$/, "Invalid issue key format. The correct format is PROJECT-123"), }); /** * Schema for validating Jira search issues requests * Extends the base API schema with the projectKey and optional assigneeName fields * * @type {yup.ObjectSchema} */ export const JiraSearchIssuesRequestSchema = JiraApiRequestSchema.shape({ projectKey: yup.string() .required("Project key is required") .matches(/^[A-Z][A-Z0-9_]+$/, "Invalid project key format. Only uppercase letters, numbers, and underscores are allowed"), assigneeName: yup.string() .optional() .min(2, "Assignee name must be at least 2 characters long"), }); /** * Schema for validating Jira project members requests * Extends the base API schema with the projectKey field * * @type {yup.ObjectSchema} */ export const JiraProjectMembersRequestSchema = JiraApiRequestSchema.shape({ projectKey: yup.string() .required("Project key is required") .matches(/^[A-Z][A-Z0-9_]+$/, "Invalid project key format. Only uppercase letters, numbers, and underscores are allowed"), }); /** * Schema for validating Jira check user issues requests * Extends the base API schema with the projectKey and userName fields * * @type {yup.ObjectSchema} */ export const JiraCheckUserIssuesRequestSchema = JiraApiRequestSchema.shape({ projectKey: yup.string() .required("Project key is required") .matches(/^[A-Z][A-Z0-9_]+$/, "Invalid project key format. Only uppercase letters, numbers, and underscores are allowed"), userName: yup.string() .required("Username is required") .min(2, "Username must be at least 2 characters long"), }); /** * Schema for validating Jira create issue requests * Extends the base API schema with fields needed for issue creation * * @type {yup.ObjectSchema} */ export const JiraCreateIssueRequestSchema = JiraApiRequestSchema.shape({ projectKey: yup.string() .required("Project key is required") .matches(/^[A-Z][A-Z0-9_]+$/, "Invalid project key format. Only uppercase letters, numbers, and underscores are allowed") .test( 'not-empty-project', 'Project key cannot be empty', (value) => !!value && value.trim().length > 0 ), summary: yup.string() .required("Issue summary/title is required") .min(3, "Issue title must be at least 3 characters long") .max(255, "Issue title must be at most 255 characters long"), description: yup.object({ type: yup.string() .oneOf(['doc'], 'ADF document type must be "doc". Use: {"type": "doc", ...}') .required('ADF document type is required. Add "type": "doc" to your description object'), version: yup.number() .oneOf([1], 'ADF document version must be 1. Use: {"version": 1, ...}') .required('ADF document version is required. Add "version": 1 to your description object'), content: yup.array() .required('ADF document content is required. Add "content": [...] array to your description object') .min(1, 'ADF document content cannot be empty. Include at least one paragraph in the content array'), }).required('Issue description (in ADF format) is required. Use this format: {"type": "doc", "version": 1, "content": [{"type": "paragraph", "content": [{"type": "text", "text": "Your text here"}]}]}') .typeError('❌ CRITICAL: Description must be an ADF object, NOT a string! Use: {"type": "doc", "version": 1, "content": [{"type": "paragraph", "content": [{"type": "text", "text": "Your description text"}]}]}'), issueType: yup.string() .oneOf( ['Task', 'Bug', 'Story', 'Epic'], "Issue type must be one of: Task, Bug, Story, Epic" ) .default("Task"), assigneeName: yup.string() .optional() .min(2, "Assignee name must be at least 2 characters long"), reporterName: yup.string() .optional() .min(2, "Reporter name must be at least 2 characters long"), sprintId: yup.string() .optional() .test( 'valid-sprint-id', 'Sprint ID must be numeric', (value) => !value || /^\d+$/.test(value) ), }); /** * Schema for validating Jira sprint query requests * Extends the base API schema with optional fields for filtering sprints * * @type {yup.ObjectSchema} */ export const JiraSprintRequestSchema = JiraApiRequestSchema.shape({ boardId: yup.string() .optional() .test( 'valid-board-id', 'Board ID must be numeric', (value) => !value || /^\d+$/.test(value) ), projectKey: yup.string() .optional() .matches(/^[A-Z][A-Z0-9_]+$/, "Invalid project key format. Only uppercase letters, numbers, and underscores are allowed"), state: yup.string() .oneOf( ['active', 'future', 'closed', 'all'], "Sprint state must be one of: active, future, closed, all" ) .default('active'), });

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/samuelrizzo/jira-mcp-server'

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