Skip to main content
Glama
perorin0418

atlassian-mcp-serverless

by perorin0418
README.md
# atlassian-mcp-serverless

Atlassian Jira の MCP サーバーを AWS API Gateway + Lambda 上で動かす。
[sooperset/mcp-atlassian](https://github.com/sooperset/mcp-atlassian) の Jira read 系ツールを移植したもの。

設計は `docs/superpowers/specs/2026-08-13-atlassian-mcp-serverless-design.md` を参照。

## 現在の実装状況

フェーズ1(基盤)が完了。実装済みのツールは 2 つ。

- `jira_search` — JQL で課題を検索する
- `jira_get_issue` — 課題を 1 件取得する

残りの 36 ツールはフェーズ2〜5 で追加する。

## 必要なもの

- Node.js 22 以上
- AWS SAM CLI
- Atlassian Cloud の API トークン(https://id.atlassian.com/manage-profile/security/api-tokens で発行)

## セットアップ

```bash
npm install
npm test
```

## デプロイ

```bash
npm run sam:build
npm run sam:deploy
```

`AtlassianSiteUrl` パラメータに接続先サイトを指定する(例: `https://example.atlassian.net`)。
接続先はサーバー側に固定される。クライアントから接続先ホストを指定することはできない(SSRF 防止のため)。

デプロイが完了すると `McpEndpoint` が出力される。

**Note:** SAM CLI was not executed in this environment (not installed). Run the commands above with your SAM CLI installation to complete the deployment to AWS.

## MCP クライアントの設定

エンドポイントに Atlassian の資格情報をヘッダで渡す。

```json
{
  "mcpServers": {
    "atlassian": {
      "type": "http",
      "url": "https://<api-id>.execute-api.<region>.amazonaws.com/prod/mcp",
      "headers": {
        "Authorization": "Basic <base64 of email:api_token>"
      }
    }
  }
}
```

`Authorization` ヘッダの値は次のように作る。

```bash
printf 'you@example.com:YOUR_API_TOKEN' | base64
```

代わりに個別のヘッダを使ってもよい。

```json
      "headers": {
        "X-Atlassian-Email": "you@example.com",
        "X-Atlassian-Api-Token": "YOUR_API_TOKEN"
      }
```

## 動作確認

```bash
ENDPOINT="https://<api-id>.execute-api.<region>.amazonaws.com/prod/mcp"
AUTH="Basic $(printf 'you@example.com:YOUR_API_TOKEN' | base64)"

curl -sS "$ENDPOINT" \
  -H "content-type: application/json" \
  -H "accept: application/json, text/event-stream" \
  -H "authorization: $AUTH" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
```

レスポンスは `text/event-stream` の SSE フレームで返る。これは 2025 年仕様の streamable HTTP における標準の応答形式で、MCP クライアントはそのまま解釈できる。`curl` で中身を読むときは `data:` 行を取り出す。

```bash
curl -sS "$ENDPOINT" \
  -H "content-type: application/json" \
  -H "accept: application/json, text/event-stream" \
  -H "authorization: $AUTH" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
  | sed -n 's/^data: //p' | jq .
```

資格情報を外すと `401` が返る。

### バンドル実体の検証

`npm test` はソースツリー上で動くため、esbuild が実際にバンドルした Lambda アーティファクトの挙動は検証しない。特に `adf-to-md` のような型定義のない CJS 依存は、バンドラの扱い次第で本番でだけ解決に失敗し得る。

```bash
npm run verify:bundle
```

`src/handler.ts` を `template.yaml` と同じ esbuild 設定でバンドルし、リポジトリ外の一時ディレクトリ(`adf-to-md` が `node_modules` 経由で解決できない場所)にコピーして実行する。ADF の見出し・太字が実際に Markdown(`##` / `**`)へ変換されることと、`handler` が呼び出し可能な関数としてエクスポートされていることを確認する。プレーンテキストにフォールバックしている場合は非ゼロ終了する。

## 環境変数

| 変数 | 必須 | 既定値 | 用途 |
|---|---|---|---|
| `ATLASSIAN_SITE_URL` | 必須 | — | 接続先サイト |
| `ENABLED_TOOLS` | 任意 | 全ツール | 公開するツールのカンマ区切りリスト |
| `MAX_ATTACHMENT_BYTES` | 任意 | `4194304` | 添付の base64 返却上限(`template.yaml` の `MaxAttachmentBytes` パラメータで変更可) |
| `LOG_LEVEL` | 任意 | `info` | `debug` / `info` / `warn` / `error` |
| `JIRA_TIMEOUT_MS` | 任意 | `20000` | Jira 呼び出しのタイムアウト(`template.yaml` の `JiraTimeoutMs` パラメータで変更可) |

## 設計上の注意

- `jira_search` は `total` を返さない。Jira が 2025年8月に旧検索エンドポイントを廃止し、後継の `/rest/api/3/search/jql` が件数を返さなくなったため。代わりに `nextPageToken` を使ってページングする
- 資格情報はログに出力されない
- Lambda はステートレス。MCP のセッションは使わず、リクエストごとにサーバーインスタンスを構築する
- レスポンスは SSE フレーム。API Gateway がバッファリングして一括で返すが、ストリームは結果送出後に自ら閉じるため正しく完結する

Maintenance

ActivityMaintained
ResponsivenessSyncing