jiramcp核心
用于构建模型上下文协议(MCP)服务器的共享JIRA API客户端和实用程序。
概述
jiramcp-core 是一个可重复使用的包,它提供:
- 完整的JIRA REST API客户端
- 多种身份验证方法(API令牌、PAT、基本身份验证)
- 类型实用程序和验证器
- 错误处理和重试逻辑
- 配置管理
- 常见JQL查询构建器
此包旨在在与JIRA交互的多个MCP服务器之间共享,消除代码重复并提供一致的接口。
安装
地方发展(npm链接)
# In the jiramcp-core directory
npm install
npm link
# In your MCP server project
npm link jiramcp-core用于生产(npm发布)
# Publish to npm
npm publish
# Install in your project
npm install jiramcp-core快速开始
1.设置环境变量
创建一个 .env 文件:
JIRA_BASE_URL=https://your-domain.atlassian.net
JIRA_EMAIL=your-email@example.com
JIRA_API_TOKEN=your-api-token-here2.在代码中使用
import { createClient } from 'jiramcp-core';
// Create client from environment variables
const jira = createClient();
// Get an issue
const issue = await jira.getIssue('PROJ-123');
console.log(issue.fields.summary);
// Search for issues
const results = await jira.searchIssues('assignee = currentUser()');
console.log(`Found ${results.total} issues`);
// Create a new issue
const newIssue = await jira.createIssue({
fields: {
project: { key: 'PROJ' },
summary: 'New bug report',
issuetype: { name: 'Bug' },
description: 'Bug description here'
}
});认证
JIRA云(API代币)
import { JiraClient, JiraAuth } from 'jiramcp-core';
const auth = JiraAuth.fromApiToken(
'your-email@example.com',
'your-api-token'
);
const client = new JiraClient('https://your-domain.atlassian.net', auth);如何获取API令牌:
- 首选https://id.atlassian.com/manage-profile/security/api-tokens
- 点击“创建API令牌”
- 复制令牌
JIRA服务器/数据中心(个人访问令牌)
const auth = JiraAuth.fromPersonalAccessToken('your-pat-token');
const client = new JiraClient('https://jira.yourcompany.com', auth);基本身份验证(不推荐)
const auth = JiraAuth.fromBasicAuth('username', 'password');
const client = new JiraClient('https://jira.yourcompany.com', auth);核心功能
问题操作
// Get issue
const issue = await jira.getIssue('PROJ-123');
// Search issues with JQL
const results = await jira.searchIssues('project = PROJ AND status = Open');
// Create issue
const newIssue = await jira.createIssue({
fields: {
project: { key: 'PROJ' },
summary: 'New feature request',
issuetype: { name: 'Story' },
description: 'Feature description'
}
});
// Update issue
await jira.updateIssue('PROJ-123', {
fields: {
summary: 'Updated summary',
priority: { name: 'High' }
}
});
// Add comment
await jira.addComment('PROJ-123', 'This is a comment');
// Transition issue
const transitions = await jira.getTransitions('PROJ-123');
await jira.transitionIssue('PROJ-123', transitions.transitions[0].id);
// Assign issue
await jira.assignIssue('PROJ-123', 'account-id-here');项目运营
// Get all projects
const projects = await jira.getProjects();
// Get specific project
const project = await jira.getProject('PROJ');
// Get issue types for project
const issueTypes = await jira.getIssueTypes('PROJ');敏捷/董事会运营
// Get all boards
const boards = await jira.getBoards();
// Get sprints for a board
const sprints = await jira.getSprints(boardId);
// Get active sprint
const activeSprint = await jira.getActiveSprint(boardId);
// Get sprint issues
const sprintIssues = await jira.getSprintIssues(sprintId);
// Get backlog
const backlog = await jira.getBacklog(boardId);用户运营
// Get current user
const currentUser = await jira.getCurrentUser();
// Search users
const users = await jira.searchUsers('john');类型实用程序
验证器
import { isValidIssueKey, isValidProjectKey, isValidJQL } from 'jiramcp-core';
isValidIssueKey('PROJ-123'); // true
isValidIssueKey('invalid'); // false
isValidProjectKey('PROJ'); // true
isValidProjectKey('proj'); // false (must be uppercase)
isValidJQL('status = Open'); // true建筑商
import { buildIssueData, JQLBuilder } from 'jiramcp-core';
// Build issue creation data
const issueData = buildIssueData({
projectKey: 'PROJ',
summary: 'New bug',
issueType: 'Bug',
description: 'Bug description',
priority: 'High'
});
// Use JQL query builders
const myIssues = await jira.searchIssues(JQLBuilder.myIssues());
const highPriorityBugs = await jira.searchIssues(JQLBuilder.highPriorityBugs());
const recentIssues = await jira.searchIssues(JQLBuilder.recentIssues(7)); // Last 7 days解析程序和格式化程序
import { parseIssue, formatIssue } from 'jiramcp-core';
const issue = await jira.getIssue('PROJ-123');
// Parse to simplified format
const simplified = parseIssue(issue);
console.log(simplified.summary);
// Format for display
console.log(formatIssue(issue));
// Output:
// [PROJ-123] Bug in login page
// Status: In Progress
// Type: Bug
// Priority: High
// Assignee: John Doe工具函数
重试逻辑
import { retry } from 'jiramcp-core';
// Retry with exponential backoff
const issue = await retry(
() => jira.getIssue('PROJ-123'),
{
maxRetries: 3,
initialDelay: 1000,
shouldRetry: (error) => error.statusCode === 429 // Retry on rate limit
}
);批处理
import { batchProcess } from 'jiramcp-core';
const issueKeys = ['PROJ-1', 'PROJ-2', 'PROJ-3', /* ... many more */];
// Process in batches with rate limiting
const issues = await batchProcess(
issueKeys,
(key) => jira.getIssue(key),
{
batchSize: 5,
delayBetweenBatches: 1000
}
);速率限制
import { createRateLimiter } from 'jiramcp-core';
const rateLimiter = createRateLimiter(10, 60000); // 10 requests per minute
for (const issueKey of issueKeys) {
await rateLimiter(() => jira.getIssue(issueKey));
}错误处理
import {
JiraError,
JiraAuthError,
JiraNotFoundError,
JiraValidationError,
JiraPermissionError,
JiraRateLimitError
} from 'jiramcp-core';
try {
const issue = await jira.getIssue('PROJ-999');
} catch (error) {
if (error instanceof JiraNotFoundError) {
console.log('Issue not found');
} else if (error instanceof JiraAuthError) {
console.log('Authentication failed');
} else if (error instanceof JiraRateLimitError) {
console.log('Rate limit exceeded, try again later');
} else {
console.log(`Error: ${error.message}`);
}
}配置
环境变量
# Required
JIRA_BASE_URL=https://your-domain.atlassian.net
# Authentication (choose one method)
# Method 1: API Token (JIRA Cloud)
JIRA_EMAIL=your-email@example.com
JIRA_API_TOKEN=your-api-token
# Method 2: Personal Access Token (JIRA Server/DC)
JIRA_PAT=your-personal-access-token
# Method 3: Basic Auth (not recommended)
JIRA_USERNAME=your-username
JIRA_PASSWORD=your-password
# Optional
JIRA_API_VERSION=3 # Default: 3 (use 2 for older JIRA versions)加载配置
import { loadConfig, validateConfig, getConfigSummary } from 'jiramcp-core';
// Load configuration
const config = loadConfig();
// Validate configuration (throws if invalid)
validateConfig();
// Get safe summary (no secrets)
const summary = getConfigSummary();
console.log(summary);
// Output: { baseUrl: '...', authType: 'api_token', apiVersion: '3' }API 参考
JiraClient
JIRA API操作的主要客户。
施工单位:
new JiraClient(baseUrl, auth, options)方法:
- 问题:
getIssue,searchIssues,createIssue,updateIssue,deleteIssue,addComment,getComments,assignIssue,getTransitions,transitionIssue - 项目:
getProjects,getProject,getIssueTypes - 董事会:
getBoards,getBoard,getSprints,getActiveSprint,getSprintIssues,getBacklog - 用户:
getCurrentUser,searchUsers - 公用设施:
testConnection,getServerInfo
JiraAuth
支持多种身份验证方法的身份验证处理程序。
静态方法:
JiraAuth.fromApiToken(email, apiToken)JiraAuth.fromPersonalAccessToken(token)JiraAuth.fromBasicAuth(username, password)
实例方法:
getHeaders()-返回请求的身份验证标头isValid()-验证凭据
例子
请参阅 examples/ 完整示例目录:
- 基本用法
- 制造问题
- 搜索和过滤
- Sprint管理
- 批量操作
贡献
这是多个MCP服务器使用的共享包。进行更改时:
- 更新中的版本
package.json - 使用所有依赖的MCP服务器进行测试
- 文档中断更改
- 发布新版本
许可证
麻省理工学院
