Skip to main content
Glama

NiChart DLMUSE MCP server

cbica/nichart_dlmuse(T1 MRI スカルストリップ + MUSE ROI セグメンテーション)を GPU EC2 インスタンス上の MCP サーバーの背後にホストし、すべてのユーザーがローカル GPU を必要とする代わりに Claude Code がリモートでセグメンテーションを実行できるようにします。

なぜこのような構成なのか

MCP ツールの引数は JSON です。.nii.gz は数十 MB のバイナリであり、セグメンテーションには GPU で約 1〜2 分かかります。単一のブロッキングツールコールには遅すぎ、大きすぎます。そこで:

  • ファイル転送は MCP プロトコルの外部で行われ、プレーンな認証付き POST /upload エンドポイントを介します。小さな upload_id だけが MCP ツールの引数として渡されます。

  • ジョブは非同期です: run_dlmuse_segmentation はキューに投入してすぐに戻ります。get_job_status はポーリングし、get_job_result は CSV をインラインで取得し、マスクファイルのダウンロードリンクも返します。

  • ワーカーは 1 つで直列化: 共有 GPU が 1 つのため、docker run は一度に 1 つだけ実行され、asyncio.Queue の背後でキューイングされます。

  • Bearer トークン認証/healthz を除くすべてのエンドポイントでチームメンバーごとに要求されます。

  • プライベートインスタンス、パブリック Web 層なし: アプリは 127.0.0.1 のみにバインドされ、セキュリティグループは SSH (22) 以外は開放しません。ユーザーは SSH ポートフォワーディングにより、各自のノートパソコンをそのループバックポートに秘密鍵で接続します。攻撃対象となるドメインもインターネット公開もありません。

  • TLS は自己署名証明書 で、インスタンス上で一度だけ生成されます。公開発行の証明書 (Let's Encrypt など) はドメイン検証のためにインスタンスがインターネットから到達可能である必要がありますが、このインスタンスは該当しないためです。各ユーザーはその証明書をラップトップで信頼します (下記参照)。

  • スキャンは永久に保存されません: アップロードとジョブ出力は RETENTION_HOURS (デフォルト 24 時間) 後に削除されます。

アーキテクチャ

Claude Code (laptop)                    SSH tunnel                  EC2 (private, SG: 22 only)
  │  ssh -i key.pem -L 8420:127.0.0.1:8420 user@instance ─────────────────►  │
  │                                                                          │
  │  1. curl https://127.0.0.1:8420/upload ─────(via tunnel)──────────►  MCP server :8420 (127.0.0.1, self-signed TLS)
  │  2. run_dlmuse_segmentation ────────────────(via tunnel)──────────►         │
  │  3. get_job_status (poll) ──────────────────(via tunnel)──────────►  asyncio job queue (1 worker)
  │  4. get_job_result ─────────────────────────(via tunnel)──────────►         │
                                                                   docker run --gpus all cbica/nichart_dlmuse

リポジトリ構成

server/app.py     MCP tools (run_dlmuse_segmentation, get_job_status, get_job_result)
                  + HTTP routes (/upload, /download/{job_id}/{filename}, /healthz)
server/jobs.py    job queue/worker, docker invocation, root-owned-output cleanup
server/auth.py    bearer-token ASGI middleware
server/config.py  env-driven settings
deploy/           EC2 provisioning script (installs Docker, GPU toolkit, self-signed cert, systemd unit)

EC2 の初回セットアップ

既存の GPU EC2 インスタンスが必要です (AWS Deep Learning AMI 推奨 — NVIDIA ドライバーと Docker が通常すでにインストールされています)。

  1. このリポジトリをインスタンスにコピーします (git clone / scp -r)。

  2. cp .env.example .env を実行し、少なくとも TOKENS を入力します — チームメンバーごとに name:token のペアをカンマ区切りで指定します。openssl rand -hex 32 でトークンを生成します。

  3. インスタンスのセキュリティグループで、インバウンド 22 (SSH) のみを許可し、チームの IP または踏み台に制限します。それ以外は開放しないでください — 4438420 も不要です。アプリは 127.0.0.1 にバインドされ、SSH トンネル経由以外では到達できません。

  4. プロビジョニングスクリプトを実行します:

    sudo ./deploy/setup_ec2.sh

    これは冪等です — Docker/nvidia-container-toolkit がなければインストールし、DLMUSE イメージをプルし、専用の nichart-mcp サービスユーザーを作成し、コードを /opt/nichart-mcp にデプロイし、自己署名 TLS 証明書 (SAN = 127.0.0.1/localhost) を生成し、nichart-mcp systemd サービスをインストールします。

  5. インスタンス自体から確認します:

    curl --cacert /opt/nichart-mcp/tls/server.crt https://127.0.0.1:8420/healthz
  6. /opt/nichart-mcp/tls/server.crt をインスタンスからコピーして、各チームメンバーに渡せるようにします (例: scp -i key.pem ec2-user@<instance-ip>:/opt/nichart-mcp/tls/server.crt .)。

後からユーザーを追加または失効させるには: インスタンス上の /opt/nichart-mcp/.envTOKENS を編集し、sudo systemctl restart nichart-mcp を実行します。

コードの更新

インスタンス上の更新済みチェックアウトから sudo ./deploy/setup_ec2.sh を再実行します — /opt/nichart-mcp を再同期し (既存の TLS 証明書はそのまま)、依存関係を再インストールし、サービスを再起動します。

ラップトップから接続する

各チームメンバーには、SSH 秘密鍵 (Windows の PuTTY .ppk キーの場合は、標準の ssh クライアントが使用できるように puttygen key.ppk -O private-openssh -o key.pem で一度変換します)、Bearer トークン、およびセットアップ手順 6 の server.crt ファイルが必要です。

1. 自己署名証明書を一度信頼します。これで curl/Claude Code が証明書を拒否しなくなります:

  • macOS: security add-trusted-cert -d -r trustRoot -k ~/Library/Keychains/login.keychain-db server.crt

  • Linux: sudo cp server.crt /usr/local/share/ca-certificates/nichart-mcp.crt && sudo update-ca-certificates

  • Windows: certutil -addstore -f "ROOT" server.crt

2. SSH トンネルを開きます (Claude Code を使用している間はターミナルで実行したままにします):

ssh -i key.pem -N -L 8420:127.0.0.1:8420 <ssh_user>@<instance-ip>

インスタンスにパブリック IP がなく、踏み台経由でしか到達できない場合は、-J <bastion_user>@<bastion_host> を追加します。

3. MCP サーバーを Claude Code に登録します (一度だけ):

claude mcp add --transport http nichart-dlmuse https://127.0.0.1:8420/mcp \
  --header "Authorization: Bearer <their-token>"

使用方法

トンネルを開いた状態で、Claude Code にスキャンのセグメンテーションを依頼すると、次の手順が実行されます:

  1. ファイルをアップロードします (トンネル経由なので、ファイルはリモートインスタンス宛てですが 127.0.0.1:8420 が正しいです):

    curl -X POST -H "Authorization: Bearer <token>" \
      -F "file=@/path/to/scan.nii.gz" \
      https://127.0.0.1:8420/upload
    # -> {"upload_id": "..."}
  2. その upload_id を指定して run_dlmuse_segmentation ツールを呼び出すと、job_id が返ります。

  3. get_job_status(job_id)status == "done" になるまでポーリングします (通常 GPU で約 1〜2 分)。

  4. get_job_result(job_id) を呼び出すと、ROI ボリュームの CSV がインラインで返り、ICV および MUSE マスク NIfTI ファイルの /download/{job_id}/{filename} リンクも返ります (同じ Bearer トークンを使い、同じトンネル経由で https://127.0.0.1:8420/download/... から取得します)。

運用上の注意

  • GPU 並行性: 設計上、一度に実行されるジョブは 1 つです (共有 GPU が 1 つ)。チームが忙しいとジョブがキューに溜まります。get_job_statusqueue_position を報告します。

  • ジョブ状態はインメモリです: systemctl restart nichart-mcp を実行すると、進行中のジョブレコードが失われます (アップロード済みスキャンとディスク上の部分出力は影響を受けませんが、再送信が必要です)。小規模チームの規模では問題ありません。規模が大きくなったら、server/jobs.py のインメモリ dict を Redis/RQ に置き換えてください。

  • PHI: スキャンは実際の患者データです。RETENTION_HOURS はディスク上に保存される期間を制限しますが、実際の患者に使用する前に、これがデータ取り扱い要件と互換性があることを確認してください。まだ有効にしていない場合は、インスタンスのボリュームで EBS 暗号化を有効にすることを検討してください。

  • DLMUSE コンテナは内部で root として実行されます (/app/pipeline.log への書き込みがハードコードされているため、--user では実行できません)。その出力は root 所有になります。server/jobs.py のクリーンアップは、使い捨ての alpine コンテナにフォールバックしてそれらのディレクトリを強制削除します。

ローカル開発

python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
cp .env.example .env   # fill in TOKENS
TOKENS=dev:devtoken DATA_DIR=/tmp/nichart-dev .venv/bin/python -m server.app

これにより、フルサーバー (認証、アップロード、ジョブキュー、MCP ツール) がローカルで実行されます。実際にセグメンテーションを実行するには、GPU アクセスを持つ Docker がまだ必要です。GPU のないマシンでは、ジョブは docker run ステップで失敗しますが、その他すべて (ルーティング、認証、キューイング、ステータス/エラー報告) は試すことができます。

-
license - not tested
-
quality - not tested
-
maintenance - not tested

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Remote MCP server for RunComfy Serverless API (ComfyUI): deployments and async inference.

  • Cloud-hosted MCP server for durable AI memory

  • Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer

View all MCP Connectors

Latest Blog Posts

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/euroso97/DLMUSE_MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server