mcp-server
mcp-server
チームのエンジニアリングツール(Bitbucket、Jira、Confluence、ArgoCD)をMCP対応エディタ(VS Code + Copilot、Claude Codeなど)に公開するTypeScript製MCPサーバー。
これは薄いラッパーです。Bitbucket/Jira/Confluence/ArgoCDと直接通信したり、それらのサービスの認証情報を保存したりしません。すべてを内部バックエンドeng-apiへのHTTP呼び出しに変換します。eng-apiは既に接続と認証情報を解決しています。
VS Code (dev A) ─┐
VS Code (dev B) ─┼─► MCP Server ───► eng-api ───► Bitbucket / Jira / Confluence / ArgoCD
VS Code (dev C) ─┘ (este repo) (credenciales viven aquí)
Streamable HTTP HTTP
+ API key por dev利点: 開発者はBitbucket/Jira/Confluence/ArgoCDの個人トークンを必要としません。このMCPサーバーのAPIキーのみで、個別に失効可能です。
1. 要件
Node.js ≥ 22
ENG_API_BASE_URL(eng-apiのURL)へのネットワークアクセス
Related MCP server: Work Integrations MCP
2. ローカルでの実行
npm ci
cp .env.example .env # y rellena los valores (ver sección 3)
npm run dev # hot-reload, lee .env automáticamenteその他のコマンド:
コマンド | 説明 |
|
|
| TypeScriptを |
| 出力なしで型チェック |
| コンパイル済みを起動(環境変数を使用。Podで実行されるもの) |
| コンパイル済みを |
動作確認のクイックチェック:
curl http://localhost:3000/healthz
# {"status":"ok","server":"mcp-server","version":"0.1.0"}3. 設定 (.env)
すべての変数はprocess.envから読み取られます。必須の変数がないか無効な値の場合、プロセスは起動せず、修正すべき点を正確に説明します。
変数 | 必須 | デフォルト | 説明 |
| ✅ | — | eng-apiのベースURL。末尾にスラッシュなし。 |
| ✅ | — | このMCPサーバーに対する開発者の有効なAPIキー(§4参照) |
| — |
| eng-api呼び出しのタイムアウト(1000–120000) |
| — |
| 5xx/429/タイムアウト時の追加リトライ回数(0–5) |
| — |
| MCPサーバーのHTTPポート |
| — |
|
|
起動失敗の例(意図的):
Configuración inválida: el MCP Server no puede arrancar.
- Falta la variable obligatoria ENG_API_BASE_URL. Debe apuntar a la URL base de eng-api, ej. https://eng-api.internal.example/api/v1
Revisa tu archivo .env (usa .env.example como plantilla) o el ConfigMap/Secret del Deployment.4. 認証: 開発者ごとに1つのAPIキー
この認証層はMCPサーバー独自のものであり、eng-apiが最終サービスに対して使用するものとは独立しています。
キーの生成
openssl rand -hex 32 # una por cada persona del equipo設定
MCP_DEV_API_KEYSは4つの形式を受け入れます(キーは最低24文字、重複不可):
MCP_DEV_API_KEYS=<key1>,<key2> # CSV simple
MCP_DEV_API_KEYS=alice:<key1>,bob:<key2> # CSV etiquetado ← recomendado
MCP_DEV_API_KEYS=["<key1>","<key2>"] # JSON array
MCP_DEV_API_KEYS={"alice":"<key1>","bob":"<key2>"} # JSON objetoラベル付き形式を使用してください。ラベルはMCPサーバーのログに表示され、X-Mcp-Devヘッダーとしてeng-apiに伝播されるため、キーを公開せずに誰が各操作(例:argocd_sync_app)を実行したかを監査できます。
使用
MCPクライアントは各リクエストで以下を送信する必要があります:
Authorization: Bearer <API_KEY>(または代替としてx-api-key: <API_KEY>)。比較はSHA-256ダイジェストに対するタイミングセーフです。
状況 | 応答 |
キーなし |
|
無効/失効キー |
|
| 認証なし(Kubernetesのプローブ用) |
誰かを失効させる = MCP_DEV_API_KEYSからそのキーを削除し、Deploymentを再起動します。各開発者が自分のキーを持っているため、他の開発者には影響しません。本番環境では、値をKubernetesのSecretに保存し、ConfigMapには決して保存しないでください。
5. ツールカタログ
名前にはサービスのプレフィックスが付き、アクション指向です。該当するものはすべてページネーションをサポートします(page、pageSizeは1~100、デフォルトは25)。
Bitbucket(読み取り専用)
ツール | 引数 | eng-apiエンドポイント |
|
|
|
|
|
|
|
|
|
Jira
ツール | 引数 | eng-apiエンドポイント |
|
|
|
|
|
|
|
|
|
Confluence(読み取り専用)
ツール | 引数 | eng-apiエンドポイント |
|
|
|
|
|
|
ArgoCD
ツール | 引数 | eng-apiエンドポイント |
|
|
|
|
|
|
|
|
|
注釈(MCPクライアントへのヒント)
ツール |
|
|
|
|
読み取り系すべて | ✅ | ❌ | ✅ | ✅ |
| ❌ | ❌ | ❌ | ✅ |
| ❌ | ✅ | ❌ | ✅ |
argocd_sync_appはアプリの正確な名前(ワイルドカードやデフォルト値なし)を要求し、prune/dryRunは明示的に要求されない限りfalseになります。
eng-apiのルートはすべてsrc/client/routes.tsにあります。eng-apiがパスを変更した場合、そのファイルのみを編集します。
6. VS Codeの設定(各開発者が自分のキーを使用)
ワークスペースに.vscode/mcp.jsonを作成します(またはすべてのプロジェクトで使用する場合はユーザーのmcp.json):
{
"inputs": [
{
"type": "promptString",
"id": "eng-mcp-api-key",
"description": "Tu API key personal del MCP Server de ingeniería",
"password": true
}
],
"servers": {
"eng": {
"type": "http",
"url": "https://<host-del-mcp-server>/mcp",
"headers": {
"Authorization": "Bearer ${input:eng-mcp-api-key}"
}
}
}
}VS Codeは初回にキーを要求し、暗号化して保存します。決してコミットしないでください。 その後、Agentモードでチャットを開くと、engサーバーの下に11個のツールが表示されます。
Claude Code(CLI)の場合、同等のものは:
claude mcp add --transport http eng https://<host-del-mcp-server>/mcp \
--header "Authorization: Bearer <TU_API_KEY>"ローカルでは、URLをhttp://localhost:3000/mcpに置き換えてください。
7. MCP Inspectorでテスト
npm run build && npm run start:local # en una terminal
npx @modelcontextprotocol/inspector # en otraInspectorのUIで:
Transport Type:
Streamable HTTPURL:
http://localhost:3000/mcpAuthenticationで、Header Nameに
Authorization、Bearer TokenにAPIキーを設定Connect → Toolsタブ → List Tools → 任意のツールをテスト
curlで直接テストすることもできます(CIやPodから便利):
KEY=<tu-api-key>
curl -s -X POST http://localhost:3000/mcp \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $KEY" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools[].name'ツールの呼び出し:
curl -s -X POST http://localhost:3000/mcp \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $KEY" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{
"name":"bitbucket_list_prs",
"arguments":{"workspace":"acme","repoSlug":"web-frontend","state":"OPEN","pageSize":10}}}'8. Docker
docker build -t mcp-server:0.1.0 .
docker run --rm -p 3000:3000 \
-e ENG_API_BASE_URL="https://<eng-api>/api/v1" \
-e MCP_DEV_API_KEYS="alice:<key1>,bob:<key2>" \
mcp-server:0.1.0node:22-alpine上のマルチステージイメージ: 最終イメージにはdist/ + 本番依存関係のみが含まれ、nodeユーザー(rootなし)として実行され、Node自身で/healthzを叩くHEALTHCHECKを含みます(curl/wgetなし)。
Kubernetes用(マニフェストはこのリポジトリにはありません):
サーバーはステートレス: セッションをメモリに保存しないため、スティッキーセッションなしでNレプリカにスケールします。
プローブ:
livenessProbe→GET /healthz、readinessProbe→GET /readyz(どちらも認証なし)。MCP_DEV_API_KEYSはSecretに、ENG_API_BASE_URLとタイムアウトはConfigMapに設定できます。SIGTERMを処理し、HTTPサーバーをグレースフルにシャットダウンします(最大10秒のドレイン)。
9. 新しいサービスやツールの追加方法
パターンは、新しいサービスを追加しても既存のものに触れないように設計されています。架空のGrafanaの例:
1. ルートを追加 src/client/routes.tsに:
grafana: {
listDashboards: (): string => "/grafana/dashboards",
getDashboard: (uid: string): string => `/grafana/dashboards/${seg(uid)}`,
},2. src/tools/grafana.tsを作成 他のものと同じテンプレートに従って:
export function registerGrafanaTools(server: McpServer, deps: ToolDeps): void {
registerEngTool(server, deps, {
name: "grafana_list_dashboards", // prefijo de servicio + acción
title: "Grafana: listar dashboards",
description: "Qué hace y cuándo usarlo.",
inputSchema: { query: z.string().optional().describe('Texto a buscar. Ejemplo: "latencia checkout".'),
...paginationShape },
annotations: readOnlyAnnotations("Grafana: listar dashboards"),
describeOperation: (args) => `listar dashboards de Grafana`, // encaja tras "al …"
execute: (args, { client, context }) =>
client.get(engApiRoutes.grafana.listDashboards(), {
query: { query: args.query, ...paginationQuery(args) },
context,
}),
});
}3. 登録 TOOL_REGISTRARS in src/server.tsに:
const TOOL_REGISTRARS = [ …, registerGrafanaTools ];以上です。registerEngToolはすでに以下を無料で提供します: Zod検証、レスポンスのフォーマット、巨大なペイロードの切り詰め、エラーキャプチャとアクション可能なメッセージへの変換、requestId付きのロギング。
新しいツールのスタイルルール:
名前は
サービス_アクション_オブジェクト、小文字。スキーマの各フィールドには**
.describe()と具体的な例**を付ける — モデルがそれを呼び出す方法を決定する唯一の情報です。正直な注釈: 書き込みなら
readOnlyHint: false、何かを削除する可能性があるならdestructiveHint: true。破壊的な操作には危険なデフォルトなし: 正確な識別子を要求。
リストを返すものにはすべてページネーション(
...paginationShape+paginationQuery(args))。tools/内でURLを手動で構築しない: 常にengApiRoutesを経由。
10. エラー処理
どのツールも生の「Error 500」を返しません。各エラーには何が失敗したか、何を確認すべきか、およびeng-apiのログと照合するためのrequestIdが含まれます。実際の例:
No existe el recurso al obtener el estado de la aplicación boom (404). Verifica los identificadores
exactos (workspace/repo, key de issue, id de página, nombre de app) — distinguen mayúsculas. Si los
identificadores son correctos, la ruta de eng-api puede haber cambiado (src/client/routes.ts).
[requestId=8a4bf9e6-…, intentos=1, upstream=GET /argocd/applications/boom]
Respuesta de eng-api: {"error":"application not found"}状況 | MCPサーバーの動作 |
タイムアウト / ネットワークエラー | 指数バックオフ+ジッターで再試行し( |
| 再試行する( |
| 再試行しない: パラメータが無効 |
| MCPのAPIキーではなく、eng-apiの認証情報/権限の問題であることを明確にする |
| 正確な識別子と |
| 状態の競合(例:ArgoCDの同期が進行中):状態を確認し、後で再試行する |
非JSON応答 | 通常はプロキシがHTMLを返している: ルートが存在しない可能性が高い |
巨大なペイロード | 120,000文字に切り詰め、 |
11. プロジェクト構造
src/
├── index.ts # entrypoint: Express + Streamable HTTP (stateless), /healthz, /readyz
├── config.ts # lectura y validación de env vars, fail-fast
├── auth.ts # middleware de API key (timing-safe)
├── logger.ts # logs JSON de una línea, aptos para Cloud Logging
├── server.ts # createMcpServer(): registra todas las familias de tools
├── client/
│ ├── routes.ts # ÚNICO sitio con las rutas de eng-api
│ ├── errors.ts # EngApiError → mensajes accionables
│ └── engApiClient.ts # fetch + timeout + retry con backoff
└── tools/
├── shared.ts # registerEngTool(), paginación, formateo, errores
├── bitbucket.ts ├── jira.ts ├── confluence.ts └── argocd.ts設計上の決定:
ステートレスモードのStreamable HTTP (
sessionIdGenerator: undefined,enableJsonResponse: true): リクエストごとにMcpServer+トランスポートが作成される。開発者間で状態を共有せず、スティッキーセッション不要で水平スケーリングが可能、レスポンスはプレーンJSON(SSEよりもイングレス/プロキシに優しい)。POST /mcpのみ:GET/DELETEは405を返す。ステートレスではサーバー→クライアントのストリームや閉じるべきセッションがないため。トレーサビリティ: 各リクエストは
X-Request-Id(クライアントから送信された場合はそれを尊重)と、開発者のタグが付いたX-Mcp-Devを持ち、両方ともeng-apiに伝搬される。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceA TypeScript-based MCP server that provides backend API handling and facilitates communication between microservices. Features an organized structure with controllers, routes, and models for easy extensibility and maintenance.2831MIT
- Alicense-qualityDmaintenanceAn MCP server that enables interaction with Jira to fetch issues by key and perform JQL searches. It provides a foundation for integrating multiple work systems, with planned support for Slack and GitHub.376MIT
- AlicenseBqualityDmaintenanceProduction-ready TypeScript MCP server exposing utility, GitHub, and Microsoft Teams tools over stdio.141MIT
- AlicenseBqualityCmaintenanceLightweight MCP server for Jira, Confluence, and Bitbucket — read, create, and update from your AI IDE.20MIT
Related MCP Connectors
A MCP server built for developers enabling Git based project management with project and personal…
MCP server for interacting with the Supabase platform
An MCP server that let you interact with Cycloid.io Internal Development Portal and Platform
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ElJijuna/mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server