内容
<!-- 由 https://github.com/flowgent-labs/mcpfather 生成 -->
# sonatypeiq-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 调用 Sonatype Lifecycle Public REST API 接口,由 MCPFather 生成 — 暴露 **252 个原生工具**。每个 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/sonatypeiq-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="sonatypeiq-mcp"
./bin/sonatypeiq-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":"sonatypeiq-mcp","authorization_servers":["https://keycloak.example.com/realms/master"],"bearer_methods_supported":["header"]}
```
### 以 `CLI` 模式运行(示例)
```sh
./bin/sonatypeiq-mcp -v 1 -t cli list
./bin/sonatypeiq-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` 提供。
## 配置
创建 `~/.sonatypeiq-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/sonatypeiq-mcp --transport http --port 8080
curl http://localhost:9991/metrics # Prometheus 端点
curl http://localhost:9991/health # 健康检查
```
追踪 span 命名为 `mcp.tool.<name>`。W3C `traceparent` 被传播到上游调用。
## 可用工具(252)
| 工具 | 描述 |
|------|-------------|
| `Add` | 使用此方法创建新用户。所需权限:编辑系统配置和用户 |
| `AddApplication` | 使用此方法在组织下创建应用程序。使用组织 REST API 获取 organizationId。所需权限:添加应用程序(在父组织上) |
| `AddArtifactoryConnection` | 使用此方法添加新的 Artifactory 连接。所需权限:编辑 IQ 元素 |
| `AddAutoPolicyWaiveExclusion` | 使用此方法为指定的自动策略豁免创建自动策略豁免排除。所需权限:豁免策略违规 |
| `AddAutoPolicyWaiver` | 使用此方法创建自动策略豁免配置。对于给定的应用程序或组织,每个配置只能存在一次。所需权限:豁免策略违规 |
| `AddAutoPolicyWaivers` | 使用此方法创建自动策略豁免配置。对于给定的应用程序或组织,最多可以存在三个配置。具有不同的组合,用于可达/路径转发。所需权限:豁免策略违规 |
| `AddBulkPolicyWaivers` | 使用此方法为多个策略违规创建策略豁免。所需权限:豁免策略违规 |
| `AddLabel` | 使用此方法为应用程序、组织或存储库创建和分配组件标签。所需权限:编辑 IQ 元素 |
| `AddLicenseOverride` | 使用此方法为给定所有者范围的组件添加或更新许可证覆盖。所需权限:更改许可证 |
| `AddOrganization` | 使用此方法添加新组织。所需权限:编辑 IQ 元素 |
| `AddPolicyWaiverByPolicyViolationId` | 使用此方法创建策略豁免。所需权限:豁免策略违规 |
| `AddPolicyWaiverRequestByPolicyViolationId` | 使用此方法创建策略豁免请求。所需权限:查看 IQ 元素 |
| `AddProprietaryComponentNames` | 为指定的格式添加私有组件命名空间列表,以防止命名空间混淆攻击。所需权限:评估单个组件 |
| `AddRepositoryManager` | 使用此方法添加新的存储库管理器。所需权限:编辑 IQ 元素 |
| `AddRole` | 使用此方法创建具有指定权限的新自定义角色。所需权限:编辑角色 |
| … | *237 更多工具未显示* |
## 虚拟工具
通过声明式管道 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": {
"sonatypeiq-mcp": {
"type": "local",
"command": ["bash", "-c", "/path/to/sonatypeiq-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": {
"sonatypeiq-mcp": {
"command": "/path/to/sonatypeiq-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.sonatypeiq-mcp]
url = "http://localhost:8080/mcp"
bearer_token_env_var = "MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN"
```
### 游标
- `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"sonatypeiq-mcp": {
"command": "/path/to/sonatypeiq-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": {
"sonatypeiq-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": {
"sonatypeiq-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.sonatypeiq-mcp]
url = "http://localhost:8080/mcp"
bearer_token_env_var = "MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN"
```
### 游标(远程)
- `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"sonatypeiq-mcp": {
"url": "http://localhost:8080/mcp"
}
}
}
```
## 部署 — Docker
### 构建
```sh
make build-image
```
或手动:
```sh
docker build -t ghcr.io/<YOUR_ORG>/sonatypeiq-mcp:latest -f deploy/docker/Dockerfile .
docker push ghcr.io/<YOUR_ORG>/sonatypeiq-mcp:latest
```
### 运行
从 GitHub 容器注册表拉取预构建的镜像:
```sh
docker pull ghcr.io/<YOUR_ORG>/sonatypeiq-mcp:latest
```
首先生成默认配置,然后在运行时将其挂载:
```sh
docker run --rm ghcr.io/<YOUR_ORG>/sonatypeiq-mcp:latest --print-default-config > ~/.sonatypeiq-mcp/config.yaml
```
- **静态持有者令牌**
```sh
docker run -d --name sonatypeiq-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 ~/.sonatypeiq-mcp:/home/mcp/.sonatypeiq-mcp \
ghcr.io/<YOUR_ORG>/sonatypeiq-mcp:latest \
--transport http --port 8080
```
- **OIDC后端身份验证**
```sh
docker run -d --name sonatypeiq-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 ~/.sonatypeiq-mcp:/home/mcp/.sonatypeiq-mcp \
ghcr.io/<YOUR_ORG>/sonatypeiq-mcp:latest \
--transport http --port 8080
```
- **LDAP后端身份验证**
```sh
docker run -d --name sonatypeiq-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 ~/.sonatypeiq-mcp:/home/mcp/.sonatypeiq-mcp \
ghcr.io/<YOUR_ORG>/sonatypeiq-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
# 调用任意工具(示例:Add)
./mcpclient.sh call Add '{"<param>":"<value>"}'
# 列出所有可用工具
./mcpclient.sh list-tools
```
> **提示:** 映射主机配置目录以实现持久化配置:
> `-v ~/.sonatypeiq-mcp:/home/mcp/.sonatypeiq-mcp`
## 部署 — Kubernetes (Helm)
首先生成默认配置,然后在运行时将其挂载:
```sh
docker run --rm ghcr.io/<YOUR_ORG>/sonatypeiq-mcp:latest --print-default-config > ~/.sonatypeiq-mcp/config.yaml
```
- **静态持有者令牌**
```sh
helm upgrade -i sonatypeiq-mcp deploy/helm \
--set image.repository=ghcr.io/<YOUR_ORG>/sonatypeiq-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 sonatypeiq-mcp deploy/helm \
--set image.repository=ghcr.io/<YOUR_ORG>/sonatypeiq-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 sonatypeiq-mcp deploy/helm \
--set image.repository=ghcr.io/<YOUR_ORG>/sonatypeiq-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>/sonatypeiq-mcp.git
cd sonatypeiq-mcp
make build
make test
```
### 代码风格
- 遵循标准Go约定(`go fmt`、`go vet`)
- 保持函数小且专注
- 编写清晰的提交消息
请阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 获取详细指南和我们的 [行为准则](CODE_OF_CONDUCT.md)。
## 许可证
该项目使用MIT许可证 — 请参阅 [LICENSE](LICENSE) 文件获取详细信息。
## 联系方式
如有问题、建议或支持:
- **GitHub问题:** [创建问题](../../sonatypeiq-mcp/issues)
- **讨论:** [开始讨论](../../sonatypeiq-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) — 纯Go实现的jq
- [Keycloak](https://www.keycloak.org/) — 开源身份和访问管理
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器