はじめに
チームで Claude Code を使っていると、こういう場面に必ず出くわす。新しく入ったメンバーの環境には MCP サーバーの設定が入っていない。自分の .mcp.json には GitHub 用のサーバーが登録されているのに、隣の席の同僚の環境には無い。スキルやフックも人によってバラバラで、「あの人の環境ではできるのに自分の環境ではできない」という差分がじわじわ蓄積していく。
package.json と npm install がある Node.js の世界では、この手の差分はとっくに解決済みの問題だ。だとしたら、エージェント向けの設定(スキル・プロンプト・MCP サーバー・フック)にも同じ発想の依存関係マネージャーがあってもいいはずだ、と思って探したところ、Microsoft が公開している APM(Agent Package Manager) に行き着いた。
TL;DR
- APM は
apm.ymlに「エージェントが必要とする設定一式」を宣言し、apm installでどのマシンでも同じ状態を再現する OSS CLI(MIT ライセンス・3.3k stars・2026年7月時点の最新版 v0.26.0) - 実際に
pip installして MCP サーバーの検索・追加・インストールまで動かしてみたところ、確かにnpm installに近い体験だった - ただし実機で試すと、非対話環境で詰まる箇所と、失敗しているのに成功したように見える箇所の 2つの罠 が見つかった
APM とは何か
APM は Microsoft が公開している OSS で、エージェント向けの「パッケージマネージャー」を名乗っている。apm.yml という1つのマニフェストファイルに、スキル・プロンプト・エージェント・フック・MCP サーバーといったプリミティブと、それらの依存関係を宣言する。apm install を実行すると、apm.lock.yaml(package-lock.json に相当するロックファイル)を使って解決済みの依存ツリーを固定し、どのマシン・どのクライアントでも同じ構成を再現する。
対応ターゲットは claude / codex / cursor / copilot / gemini / windsurf など主要なコーディングエージェントを一通りカバーしている。GitHub 上のスター数は3.3k、ライセンスは MIT、最新リリースは v0.26.0(2026年7月18日付)である1。
実際にインストールして動かす
まず素直にインストールする。
pip install apm-cli
Python 3.11 環境で実行したところ、GitPython ・rich ・httpx などの依存パッケージと共に apm-cli-0.26.0 が入り、バージョン確認まで通った。
$ apm --version
Agent Package Manager (APM) CLI version 0.26.0
apm doctor で環境診断も走らせられる。
$ apm doctor
Check Status Detail
git [+] git version 2.43.0
network [+] github.com reachable
auth [i] Token detected
marketplace config [i] No marketplace authoring config in current directory
プロジェクトを初期化すると、apm.yml が1つ生成される。
$ apm init demo-project -y --target claude
生成された apm.yml はこうなっていた。
name: demo-project
version: 1.0.0
targets:
- claude
dependencies:
apm: []
mcp: []
includes: auto
scripts: {}
apm mcp search で MCP サーバーのレジストリを検索できる。試しに github で検索すると、context7 ・github-mcp-server ・desktop-commander など10件がヒットした。ここまでは npm search の感覚とほぼ同じだった。
罠その1: 対話的な入力を要求する MCP サーバーがある
検索結果から io.github.upstash/context7 を選び、そのままインストールしてみた。
$ apm mcp install io.github.upstash/context7
すると CONTEXT7_API_KEY の入力を求めるプロンプトが出た。CI やエージェントのセッションのような非対話シェルではこの入力を受け取れず、そのまま [x] Error installing dependencies: MCP integration failed で失敗する。apm.yml にはエントリだけ書き込まれ、実体は未設定のまま残った。
サーバーによっては API キーなどの追加入力を要求するため、非対話環境(CI・自動化パイプライン・エージェントの実行環境)で apm mcp install を組み込む場合は、事前に --env KEY=VALUE で値を渡しておくか、対話入力が不要なサーバーを選ぶ必要がある。
罠その2: .claude/ が無いと「成功したように見えて」実は未設定
次に、認証不要な io.github.wonderwhy-er/desktop-commander で試した。プロジェクト直下に .claude/ ディレクトリが無い状態で実行すると、次のようなログが出た。
$ apm mcp install io.github.wonderwhy-er/desktop-commander
+- Configuring for Claude...
Skipped Claude Code project MCP -- .claude/ not found in ...
x io.github.wonderwhy-er/desktop-commander installation failed
[+] Added MCP server 'io.github.wonderwhy-er/desktop-commander'
「installation failed」と表示されているにもかかわらず、コマンドの終了コードは 0(成功)で、apm.yml にはエントリが追加される。一見すると「追加できた」ように見えるが、実際には Claude Code 側の .mcp.json は書き込まれておらず、MCP サーバーは使える状態になっていない。
.claude/ ディレクトリを作ってから同じコマンドをやり直すと、今度は明確に成功した。
$ mkdir .claude
$ apm mcp install io.github.wonderwhy-er/desktop-commander
Successfully configured MCP server 'desktop-commander' for Claude Code
[+] io.github.wonderwhy-er/desktop-commander -> Claude (configured)
このときプロジェクト直下に生成された .mcp.json の中身は次のとおりだった。
{
"mcpServers": {
"desktop-commander": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@wonderwhy-er/desktop-commander"]
}
}
}
つまり .claude/ の有無が「Claude Code プロジェクトかどうか」の判定材料になっており、Claude Code をまだ一度も起動していない真っさらなリポジトリでは、apm mcp install を実行しても中身が伴わない可能性がある。CI のセットアップスクリプトに組み込む場合は、mkdir -p .claude を先に実行しておくのが安全策になる。
著者視点の発見ポイント
実際に動かしてみて意外だったのは、失敗のログの出し方だった。「installation failed」という文字列が画面に出ているのに終了コードは0で、apm.yml の差分だけを見ると正常に追加されたようにしか見えない。CI のログを流し読みする運用だと、この手の「表示上は失敗・扱いは成功」のギャップは見落としやすい。apm.yml の差分レビューだけでなく、実際に生成された .mcp.json の中身までセットで確認する習慣が要りそうだ。
まとめ
エージェント向けの設定をチームで揃えるという課題設定自体は正しく、apm.yml + apm.lock.yaml という設計は npm / pip の枯れた発想をうまく輸入できている。ただし実機で動かすと、非対話環境での API キー入力と、.claude/ の有無に依存した成否判定という2つの罠に当たった。導入するなら、CI やエージェントの自動セットアップに組み込む前に、対象の MCP サーバーが対話入力を要求しないか、そして .claude/ ディレクトリを事前に用意しているかを確認してから組み込むとよい。
参考リンク
-
microsoft/apm — GitHub (2026年7月時点) ↩