Skip to main content
Glama

Jira-Context-MCP

server.ts6.73 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; import { JiraService } from "./services/jira"; import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js"; import express, { Request, Response } from "express"; import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js"; import { IncomingMessage, ServerResponse } from "http"; export class JiraMcpServer { private readonly server: McpServer; private readonly jiraService: JiraService; private sseTransport: SSEServerTransport | null = null; constructor(jiraUrl: string, username: string, apiToken: string) { this.jiraService = new JiraService(jiraUrl, username, apiToken); this.server = new McpServer({ name: "Jira MCP Server", version: "0.1.0", }); this.registerTools(); } private registerTools(): void { // Tool to get issue information this.server.tool( "get_issue", "Get detailed information about a Jira issue", { issueKey: z.string().describe("The key of the Jira issue to fetch (e.g., PROJECT-123)"), }, async ({ issueKey }) => { try { console.log(`Fetching issue: ${issueKey}`); const issue = await this.jiraService.getIssue(issueKey); console.log(`Successfully fetched issue: ${issue.key} - ${issue.fields.summary}`); return { content: [{ type: "text", text: JSON.stringify(issue, null, 2) }], }; } catch (error) { console.error(`Error fetching issue ${issueKey}:`, error); return { content: [{ type: "text", text: `Error fetching issue: ${error}` }], }; } }, ); // Tool to get assigned issues this.server.tool( "get_assigned_issues", "Get issues assigned to the current user in a project", { projectKey: z.string().optional().describe("The key of the Jira project to fetch issues from"), maxResults: z.number().optional().describe("Maximum number of results to return"), }, async ({ projectKey, maxResults }) => { try { console.log(`Fetching assigned issues${projectKey ? ` for project: ${projectKey}` : ''}`); const response = await this.jiraService.getAssignedIssues(projectKey, maxResults); console.log(`Successfully fetched ${response.issues.length} assigned issues`); return { content: [{ type: "text", text: JSON.stringify(response, null, 2) }], }; } catch (error) { console.error(`Error fetching assigned issues:`, error); return { content: [{ type: "text", text: `Error fetching assigned issues: ${error}` }], }; } }, ); // Tool to get issues by type this.server.tool( "get_issues_by_type", "Get issues of a specific type", { issueType: z.string().describe("The type of issue to fetch (e.g., Bug, Story, Epic)"), projectKey: z.string().optional().describe("The key of the Jira project to fetch issues from"), maxResults: z.number().optional().describe("Maximum number of results to return"), }, async ({ issueType, projectKey, maxResults }) => { try { console.log(`Fetching issues of type: ${issueType}${projectKey ? ` for project: ${projectKey}` : ''}`); const response = await this.jiraService.getIssuesByType(issueType, projectKey, maxResults); console.log(`Successfully fetched ${response.issues.length} issues of type ${issueType}`); return { content: [{ type: "text", text: JSON.stringify(response, null, 2) }], }; } catch (error) { console.error(`Error fetching issues by type:`, error); return { content: [{ type: "text", text: `Error fetching issues by type: ${error}` }], }; } }, ); // Tool to get projects this.server.tool( "get_projects", "Get list of available Jira projects", {}, async () => { try { console.log("Fetching projects"); const projects = await this.jiraService.getProjects(); console.log(`Successfully fetched ${projects.length} projects`); return { content: [{ type: "text", text: JSON.stringify(projects, null, 2) }], }; } catch (error) { console.error("Error fetching projects:", error); return { content: [{ type: "text", text: `Error fetching projects: ${error}` }], }; } }, ); // Tool to get issue types this.server.tool( "get_issue_types", "Get list of available Jira issue types", {}, async () => { try { console.log("Fetching issue types"); const issueTypes = await this.jiraService.getIssueTypes(); console.log(`Successfully fetched issue types`); return { content: [{ type: "text", text: JSON.stringify(issueTypes, null, 2) }], }; } catch (error) { console.error("Error fetching issue types:", error); return { content: [{ type: "text", text: `Error fetching issue types: ${error}` }], }; } }, ); } async connect(transport: Transport): Promise<void> { console.log("Connecting to transport..."); await this.server.connect(transport); console.log("Server connected and ready to process requests"); } async startHttpServer(port: number): Promise<void> { const app = express(); app.get("/sse", async (req: Request, res: Response) => { console.log("New SSE connection established"); this.sseTransport = new SSEServerTransport( "/messages", res as unknown as ServerResponse<IncomingMessage>, ); await this.server.connect(this.sseTransport); }); app.post("/messages", async (req: Request, res: Response) => { if (!this.sseTransport) { res.sendStatus(400); return; } await this.sseTransport.handlePostMessage( req as unknown as IncomingMessage, res as unknown as ServerResponse<IncomingMessage>, ); }); app.listen(port, () => { console.log(`HTTP server listening on port ${port}`); console.log(`SSE endpoint available at http://localhost:${port}/sse`); console.log(`Message endpoint available at http://localhost:${port}/messages`); }); } }

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/rahulthedevil/Jira-Context-MCP'

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