内容
<!-- 由 https://github.com/flowgent-labs/mcpfather 生成 -->
# Jira MCP 服务器
[](https://go.dev/)
[](https://modelcontextprotocol.io/)
[](https://prometheus.io/)
[](https://opentelemetry.io/)
[](https://openid.net/connect/)
[](https://ldap.com/)
[](https://helm.sh/)
> 企业级 MCP 服务器,专为 AI 调用 Jira Software Data Center REST API 参考 API 而设计,由 MCPFather 生成 — 暴露 **435 个原生工具**。每个 API 操作都成为一个 AI 可调用的工具,具有类型化的模式和自定义的聚合虚拟工具、身份验证转发和可观察性内置,甚至可以作为普通的 CLI 使用。
## 快速开始
```sh
make
# 或使用 OpenTelemetry 分布式跟踪(gRPC 或 HTTP)
make build-with-otel-grpc # OTLP gRPC 导出器
make build-with-otel-http # OTLP HTTP/Protobuf 导出器
```
### 以 `HTTP` 模式启动(示例)
```sh
# 配置上游 API
export MCP__UPSTREAM__ENDPOINT=https://api.example.com
export MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN=your-token
./bin/jira-mcp --transport http --port 8080 &
```
- 检查 MCP 前端身份验证(OAuth2.1)。
```bash
export MCP__AUTH__FRONTEND__OIDC__ENABLED=true
export MCP__AUTH__FRONTEND__OIDC__ISSUER="https://keycloak.example.com/realms/master"
export MCP__AUTH__FRONTEND__OIDC__AUDIENCE="jira-mcp"
./bin/jira-mcp -v 10 --transport http --port 8080
# 获取 OAuth2.1 元数据。
curl -s https://iam.example.com/realms/master/.well-known/openid-configuration
curl -s localhost:8080/.well-known/oauth-protected-resource
#{"resource":"jira-mcp","authorization_servers":["https://keycloak.example.com/realms/master"],"bearer_methods_supported":["header"]}
```
### 以 `CLI` 模式运行(示例)
```sh
./bin/jira-mcp -v 1 -t cli list
./bin/jira-mcp -v 1 -t cli <工具名称> [选项]
```
## 选项
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `-t, --transport` | `stdio` | `stdio` / `http` / `cli` |
| `-p, --port` | `8080` | HTTP 服务器端口 |
| `--metrics-port` | `0` | 覆盖管理端口(0 = 使用配置) |
| `-v, --verbose` | `0` | 日志详细程度(0–10) |
| `--print-default-config` | — | 将默认配置输出到 stdout |
## 身份验证
身份验证分为两个独立的层 — 它们之间不共享凭证:
| 层 | 配置 YAML 路径 | 环境变量前缀 | 角色 |
|---|---|---|---|
| **前端** | `auth.frontend.oidc` | `MCP__AUTH__FRONTEND__OIDC__*` | 验证 AI 代理的持有者令牌(入站) |
| **后端 OIDC** | `auth.backend.oidc` | `MCP__AUTH__BACKEND__OIDC__*` | 服务器自己的 OIDC 客户端凭证,用于上游 API |
| **后端 LDAP** | `auth.backend.ldap` | `MCP__AUTH__BACKEND__LDAP__*` | 服务器自己的 LDAP 服务帐户绑定,用于上游 API |
| **后端静态** | `auth.backend.static` | `MCP__AUTH__BACKEND__STATIC__*` | 服务器自己的静态令牌/cookie,用于上游 API |
**前端(入站)** — 验证 AI 代理呈现的持有者令牌。仅适用于 `--transport http`;stdio 没有网络边界。按照 RFC 9728 / MCP 授权规范进行标准 OIDC JWT 持有者验证。
**后端(出站)** — 服务器用于调用上游 API 的凭证。令牌优先级(第一个可用者获胜):
1. **OIDC** 客户端凭证授权(`auth.backend.oidc.*`)
2. **LDAP** 服务帐户绑定(`auth.backend.ldap.*`)
3. **静态** 持有者令牌(`auth.backend.static.bearer_token`)
AI 代理的入站令牌 **永远不会** 被转发到上游(MCP 规范:令牌传通禁止)。基于 cookie 的身份验证也通过 `auth.backend.static.cookie_token` 提供。
## 配置
创建 `~/.jira-mcp/config.yaml`(运行 `--print-default-config` 获取完整模板):
```yaml
upstream:
endpoint: "" # 上游 API 基本 URL(例如 https://api.example.com)
# 当为真时,MCP 会话 ID 作为 X-MCP-Session-ID 头部转发。
enable_mcp_session_forward: true
runtime:
download_dir: ""
log_authorization: false
# ---- 身份验证 ----
# frontend = 入站:验证 AI 代理呈现的持有者令牌。
# backend = 出站:服务器用于调用上游 API 的凭证。
# 它们是独立的 — 入站令牌永远不会被重复用于出站
# (参见 MCP 授权规范:令牌传通禁止)。
auth:
frontend:
# 标准 OAuth 2.1 / OIDC JWT 持有者验证(资源服务器角色,RFC 9728)。
# 仅在 http 传输中强制执行;stdio 没有网络边界。
oidc:
enabled: false
issuer: "" # 例如 https://idp.example.com/realms/myrealm
jwks_uri: "" # 可选覆盖(如果为空,则从发行者自动发现)
audience: "" # 预期 JWT "aud" 声明;也作为 RFC 9728 受保护资源标识符发布
# 当为真时,验证的前端 JWT 声明(sub, email)作为头部转发到上游
# X-MCP-Client-Token-Sub 和 X-MCP-Client-Token-Email。
enable_client_token_claim_forward: true
# 要作为头部转发到上游的额外 JWT 声明
# X-MCP-Client-Token-<Header-Name>。
# 例如 ["given_name", "family_name", "preferred_username"]
# additional_client_token_claim_forward: []
# 出站:服务器用于调用上游 API 的凭证。
backend:
oidc:
enabled: true
issuer: https://idp.example.com/realms/myrealm
client_id: my-client
client_secret: "${MCP__AUTH__BACKEND__OIDC__CLIENT_SECRET}"
scopes: openid
# token_url: "" # 从发行者 /.well-known 自动发现
ldap:
enabled: false
url: ldaps://ldap.example.com
base_dn: dc=example,dc=com
bind_dn: cn=svc,dc=example,dc=com
bind_password: "${MCP__AUTH__BACKEND__LDAP__BIND_PASSWORD}"
static:
bearer_token: "${MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN}" # 或设置 cookie_token
nativeTools:
expose:
register_all_tools_by_default: true # 暴露所有原生工具
# includes: [Tool1, Tool2] # 或白名单特定工具
# excludes: [Tool3] # 隐藏嘈杂的工具
```
所有值都可以通过 `MCP__`-前缀环境变量设置(例如 `MCP__AUTH__BACKEND__OIDC__CLIENT_ID`)。
## 管理 — 指标、跟踪、Pprof
```yaml
mgmt:
enabled: true
host: 0.0.0.0
port: 9991
otel:
enabled: false
endpoint: localhost:4317
protocol: grpc
sample_rate: 1.0
metrics:
enabled: true
prometheus: true
export_interval: 30s
pprof:
enabled: false
server_bind: 0.0.0.0:6669
```
```sh
./bin/jira-mcp --transport http --port 8080
curl http://localhost:9991/metrics # Prometheus 端点
curl http://localhost:9991/health # 健康检查
```
跟踪跨度命名为 `mcp.tool.<name>`。W3C `traceparent` 被传播到上游调用。
## 可用工具(435 个)
| 工具 | 描述 |
|------|-------------|
| `AcknowledgeErrors` | 重试集群升级 - 重试集群升级。 |
| `AddActorUsers` | 将参与者添加到项目角色 - 将参与者(用户或组)添加到项目角色。对于用户参与者,应使用其用户名。 |
| `AddAttachment` | 添加一个或多个附件到问题 - 添加一个或多个附件到问题。此资源需要 multipart post。 multipart/form-data 媒体类型在 RFC 1867 中定义。大多数客户端库都有处理 multipart post 的类。例如,在 Java 中,Apache HTTP Components 库提供了一个 MultiPartEntity,使提交 multipart POST 变得简单。为了防止 XSRF 攻击,由于此方法接受 multipart/form-data,因此它具有 XSRF 保护。这意味着您必须在请求中提交 X-Atlassian-Token: no-check 头部,否则它将被阻止。 multipart/form-data 参数的名称必须为 file。上传文件到问题 TEST-123 的简单示例:curl -D- -u admin:admin -X POST -H "X-Atlassian-Token: no-check" -F "file=@myfile.txt" http://myhost/rest/api/2/issue/TEST-123/attachments |
| `AddComment` | 添加评论 - 在问题中添加新评论。 |
| `AddField` | 将字段添加到选项卡 - 将字段添加到给定选项卡。 |
| `AddFieldToDefaultScreen` | 将字段添加到默认屏幕 - 在给定选项卡上移动字段。 |
| `AddProjectAssociationsToScheme` | 将项目关联添加到方案 - 将其他项目添加到已与指定问题类型方案关联的项目中 |
| `AddProjectRoleActorsToRole` | 将默认参与者添加到角色 - 将默认参与者添加到给定角色中。请求数据应包含用户名或组列表。 |
| `AddSharePermission` | 将共享权限添加到筛选器 - 将共享权限添加到给定筛选器中。添加全局权限会删除筛选器上的所有先前权限 |
| `AddTab` | 创建选项卡用于屏幕 - 为给定屏幕创建选项卡。 |
| `AddUserToApplication1` | 将用户添加到应用程序 - 将用户添加到给定应用程序中。执行此操作需要管理员权限。 |
| `AddUserToGroup` | 将用户添加到指定组 - 将给定用户添加到组中 |
| `AddVote` | 将投票添加到问题 - 将投票者(当前登录用户)添加到特定票。您需要登录才能使用此方法。 |
| `AddWatcher1` | 将用户添加为观察者 - 将用户添加到问题的观察者列表中。 |
| `AddWorklog` | 添加工作日志条目 - 在问题中添加新的工作日志条目。 |
| … | *420 多个工具未显示* |
## 虚拟工具
通过声明性管道 DSL 组合原生工具:
```yaml
virtualTools:
- name: MyVirtualTool
description: 链式调用多个原生工具
inputSchema:
type: object
properties:
appId: { type: string }
required: [appId]
pipeline:
- id: getApp
kind: call
spec: { tool: GetApplication, args: { applicationId: "$input.appId" } }
- id: appName
kind: jq
spec: { from: "$getApp", expr: .name }
- id: done
kind: return
spec: { from: "$appName" }
```
管道种类:`call`、`jq`、`foreach`、`emit`、`return`。
## 代理集成
### OpenCode
- `~/.config/opencode/opencode.json`:
```json
{
"mcp": {
"jira-mcp": {
"type": "local",
"command": ["bash", "-c", "/path/to/jira-mcp"],
"args": ["--transport", "stdio"],
"env": {
"MCP__UPSTREAM__ENDPOINT": "https://api.example.com",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN": "your-token",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN_FILE": "/path/to/fallback/.credentials"
},
"enabled": true
}
}
}
```
### Claude 代码
- `~/.claude.json`:
```json
{
"mcpServers": {
"jira-mcp": {
"command": "/path/to/jira-mcp",
"args": ["--transport", "stdio"],
"env": {
"MCP__UPSTREAM__ENDPOINT": "https://api.example.com",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN": "your-token",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN_FILE": "/path/to/fallback/.credentials"
}
}
}
}
```
### Codex CLI
- `~/.codex/config.toml`:
```toml
[mcp_servers.jira-mcp]
url = "http://localhost:8080/mcp"
bearer_token_env_var = "MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN"
```
### 游标
- `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"jira-mcp": {
"command": "/path/to/jira-mcp",
"args": ["--transport", "stdio"],
"env": {
"MCP__UPSTREAM__ENDPOINT": "https://api.example.com",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN": "your-token",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN_FILE": "/path/to/fallback/.credentials"
}
}
}
}
```
### OpenCode(远程)
- `~/.config/opencode/opencode.json`:
```json
{
"mcp": {
"jira-mcp": {
"type": "remote",
"url": "http://localhost:8080/mcp",
"env": {
"MCP__UPSTREAM__ENDPOINT": "https://api.example.com",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN": "your-token",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN_FILE": "/path/to/fallback/.credentials"
}
}
}
}
```
### Claude 代码(远程)
- `~/.claude.json` (用户MCP):
```json
{
"mcpServers": {
"jira-mcp": {
"url": "http://localhost:8080/mcp",
"env": {
"MCP__UPSTREAM__ENDPOINT": "https://api.example.com",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN": "your-token",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN_FILE": "/path/to/fallback/.credentials"
}
}
}
}
```
### Codex CLI(远程)
- `~/.codex/config.toml`:
```toml
[mcp_servers.jira-mcp]
url = "http://localhost:8080/mcp"
bearer_token_env_var = "MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN"
```
### 游标(远程)
- `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"jira-mcp": {
"url": "http://localhost:8080/mcp"
}
}
}
```
## 部署 — Docker
### 构建
```sh
make build-image
```
或手动:
```sh
docker build -t ghcr.io/<YOUR_ORG>/jira-mcp:latest -f deploy/docker/Dockerfile .
docker push ghcr.io/<YOUR_ORG>/jira-mcp:latest
```
### 运行
从 GitHub 容器注册表拉取预构建的镜像:
```sh
docker pull ghcr.io/<YOUR_ORG>/jira-mcp:latest
```
首先生成默认配置,然后在运行时将其挂载:
```sh
docker run --rm ghcr.io/<YOUR_ORG>/jira-mcp:latest --print-default-config > ~/.jira-mcp/config.yaml
```
- **静态持有者令牌**
```sh
docker run -d --name jira-mcp \
-p 8080:8080 -p 9991:9991 \
-e MCP__UPSTREAM__ENDPOINT="https://api.example.com" \
-e MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN="YOUR_BEARER_TOKEN" \
-v ~/.jira-mcp:/home/mcp/.jira-mcp \
ghcr.io/<YOUR_ORG>/jira-mcp:latest \
--transport http --port 8080
```
- **OIDC 后端身份验证**
```sh
docker run -d --name jira-mcp \
-p 8080:8080 -p 9991:9991 \
-e MCP__UPSTREAM__ENDPOINT="https://api.example.com" \
-e MCP__AUTH__BACKEND__OIDC__ENABLED=true \
-e MCP__AUTH__BACKEND__OIDC__ISSUER="https://idp.example.com/realms/myrealm" \
-e MCP__AUTH__BACKEND__OIDC__CLIENT_ID="my-client" \
-e MCP__AUTH__BACKEND__OIDC__CLIENT_SECRET="YOUR_CLIENT_SECRET" \
-v ~/.jira-mcp:/home/mcp/.jira-mcp \
ghcr.io/<YOUR_ORG>/jira-mcp:latest \
--transport http --port 8080
```
- **LDAP 后端身份验证**
```sh
docker run -d --name jira-mcp \
-p 8080:8080 -p 9991:9991 \
-e MCP__UPSTREAM__ENDPOINT="https://api.example.com" \
-e MCP__AUTH__BACKEND__LDAP__ENABLED=true \
-e MCP__AUTH__BACKEND__LDAP__URL="ldaps://ldap.example.com" \
-e MCP__AUTH__BACKEND__LDAP__BASE_DN="dc=example,dc=com" \
-e MCP__AUTH__BACKEND__LDAP__BIND_DN="cn=svc,dc=example,dc=com" \
-e MCP__AUTH__BACKEND__LDAP__BIND_PASSWORD="YOUR_BIND_PASSWORD" \
-v ~/.jira-mcp:/home/mcp/.jira-mcp \
ghcr.io/<YOUR_ORG>/jira-mcp:latest \
--transport http --port 8080
```
### 使用 mcpclient.sh 测试
容器启动后,使用捆绑的 `mcpclient.sh` 进行验证。
> **注意:** `mcpclient.sh` 仅支持 **后端静态** 令牌身份验证。如果服务器需要
> **前端OIDC/LDAP** 身份验证,请改用真正的AI代理MCP客户端。
```sh
# 指向映射的主机端口(包括 /mcp 路径)
export MCP_SERVER_ENDPOINT=http://localhost:18080/mcp
# 调用任意工具(示例:AcknowledgeErrors)
./mcpclient.sh call AcknowledgeErrors '{"<param>":"<value>"}'
# 列出所有可用工具
./mcpclient.sh list-tools
```
> **提示:** 映射主机配置目录以实现持久化配置:
> `-v ~/.jira-mcp:/home/mcp/.jira-mcp`
## 部署 — Kubernetes (Helm)
首先生成默认配置,然后在运行时将其挂载:
```sh
docker run --rm ghcr.io/<YOUR_ORG>/jira-mcp:latest --print-default-config > ~/.jira-mcp/config.yaml
```
- **静态持有者令牌**
```sh
helm upgrade -i jira-mcp deploy/helm \
--set image.repository=ghcr.io/<YOUR_ORG>/jira-mcp \
--set image.tag=latest \
--set secret.static.create=true \
--set secret.static.bearerToken="YOUR_BEARER_TOKEN" \
--set config.upstream.endpoint="https://api.example.com"
```
- **OIDC 身份验证**
```sh
helm upgrade -i jira-mcp deploy/helm \
--set image.repository=ghcr.io/<YOUR_ORG>/jira-mcp \
--set image.tag=latest \
--set secret.static.create=true \
--set secret.static.oidcClientSecret="YOUR_OIDC_CLIENT_SECRET" \
--set config.auth.backend.oidc.enabled=true \
--set config.auth.backend.oidc.issuer="https://idp.example.com" \
--set config.auth.backend.oidc.clientId="my-client" \
--set config.upstream.endpoint="https://api.example.com"
```
- **LDAP 身份验证**
```sh
helm upgrade -i jira-mcp deploy/helm \
--set image.repository=ghcr.io/<YOUR_ORG>/jira-mcp \
--set image.tag=latest \
--set secret.static.create=true \
--set secret.static.ldapBindPassword="YOUR_LDAP_BIND_PASSWORD" \
--set config.auth.backend.ldap.enabled=true \
--set config.auth.backend.ldap.url="ldaps://ldap.example.com" \
--set config.auth.backend.ldap.bindDN="cn=svc,dc=example,dc=com" \
--set config.upstream.endpoint="https://api.example.com"
```
参见 `deploy/helm/values.yaml` 获取所有可配置参数。
## 贡献
我们欢迎贡献!以下是您可以帮助的方式:
1. **Fork** 仓库并创建功能分支
2. **进行更改** — 添加功能、修复错误或改进文档
3. **添加测试** — 每个新功能或错误修复都应包含单元测试
4. **运行测试套件** — `make test` 必须通过且无回归
5. **提交拉取请求** — 描述您所更改的内容以及原因
### 开发设置
```sh
git clone https://github.com/<YOUR_ORG>/jira-mcp.git
cd jira-mcp
make build
make test
```
### 代码风格
- 遵循标准 Go 约定(`go fmt`、`go vet`)
- 保持函数小且专注
- 编写清晰的提交消息
请阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 获取详细指南和我们的 [行为准则](CODE_OF_CONDUCT.md)。
## 许可证
该项目在 MIT 许可证下获得许可 — 请参阅 [LICENSE](LICENSE) 文件获取详细信息。
## 联系方式
有关问题、建议或支持:
- **GitHub 问题:** [创建问题](../../jira-mcp/issues)
- **讨论:** [开始讨论](../../jira-mcp/discussions)
- **电子邮件:** <jameswong1376@gmail.com>
## 致谢
此 MCP 服务器由 [MCPFather](https://github.com/flowgent-labs/mcpfather) 生成,企业级 OpenAPI 到 MCP 代码生成器。
使用以下优秀的开源项目构建:
- [mcp-go](https://github.com/mark3labs/mcp-go) — Go SDK for the Model Context Protocol
- [OpenTelemetry](https://opentelemetry.io/) — 指标和跟踪的可观察性框架
- [Prometheus](https://prometheus.io/) — 指标收集和警报
- [Viper](https://github.com/spf13/viper) — Go 配置管理
- [go-jq](https://github.com/itchyny/gojq) — jq 的纯 Go 实现
- [Keycloak](https://www.keycloak.org/) — 开源身份和访问管理
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器