GitHubを徘徊していたらInneiのSKILLリポジトリを見つけ、その中にsession-to-skill-and-blogというスキルがあり、核となるアイデアが見事だった——あるエンジニアリングのセッションを、再利用可能なAIスキルとリンク付きブログ記事の2つの成果物に落とし込むというものだ。鉄則はスキルを先に書き、その後にブログを書くこと。なぜならブログはスキルのURLを必要とし、SKILL.mdのフォーマットによって操作手順を最初に整理せざるを得なくなるからだ。アイデア自体はとても良いが、Innei自身のインフラ向けにカスタマイズされている——スキルは彼のGitHubリポジトリに保存され、ブログはmxsCLI経由で彼のmx-spaceブログに投稿される。私もmx-space(pinw.ca)を持っているので、自分の環境に合うように改造することにした。この記事では、その改造中に踏んだ穴と学んだ教訓を記録する。第一の落とし穴:サーバーがローカルにないスキルをインストールした後、真っ先にmxs auth loginを実行した。結果はこうだ:TEXT → probing http://localhost:2333… ✘ connection refused 私のmx-spaceはリモートサーバー上で動作しており、APIのアドレスはhttps://api.pinw.caであり、ローカルホストではない。そこで--api-urlパラメータを追加してみた:BASH mxs --api-url https://api.pinw.ca auth login 効果はなく、依然としてlocalhostを探っていた。ソースを調べたところ、mxs auth loginの--api-urlの受け渡し経路に問題があることが判明した——グローバルフラグがauthサブコマンドで正しく引き継がれていないのだ。環境変数に切り替え:BASH MXS_API_URL=https://api.pinw.ca pnpm mxs auth login 今度は成功した。認証後、設定は~/.config/mxs/profiles/default/config.jsonに書き込まれた。Note教訓:mx-space CLIのグローバルフラグとサブコマンド間のオーバーライド優先順位は、バージョンによって動作が異なる。環境変数MXS_API_URLが最も信頼できるクロスバージョン設定方法である。第二の落とし穴:プロファイルが自動的にアクティブにならない認証に成功した後、すべてうまくいったと思った。そのまま実行:BASH pnpm mxs auth whoami # ✘ 未認証 しかしauth statusは正常だった:BASH pnpm mxs auth status # ● ログイン済み — pintaste · pintaste@outlook.com 次にmxs category listを実行:TEXT ✘ connection refused またしてもlocalhostに接続しようとしている。確かにconfig.jsonの中ではapi_urlが既にhttps://api.pinw.caになっており、currentポインタもdefaultを指している。しかしpnpm mxsがmonorepoコンテキストでプロファイルを正しく読み取れていないのだ。明示的にプロファイルを指定して解決:BASH pnpm mxs --profile default category list --output llm # ✅ 9個のカテゴリを返却 そこで私はresolve-mxs.shに--profile defaultを追加し、すべてのスクリプトがmxsを呼び出す際に自動的に付与されるようにした。Note教訓:monorepo内でpnpm mxsを介して呼び出す場合、プロファイルの解決パスがグローバルインストールとは異なる可能性がある。明示的な--profileの方がcurrentポインタに依存するより信頼性が高い。第三の落とし穴:snippet APIのバージョン違いオリジナルスキルのpush-skill.shは次のように使用していた:BASH mxs snippet create --mxs type skill --file SKILL.md "skills/名前/SKILL.md" のように指定する mxs snippet get "skill/skill-name" --json しかし私のmxsバージョン(0.13.2)のsnippetサブコマンドは全く異なる——VFSスタイルなのだ:BASH mxs snippet put --mxs snippet --path "skills/名前/SKILL.md" --content "..." の形式でVFSパスを渡す しかもパスは/SKILL.mdで終わらなければならない:TEXT ✘ skill snippet path must end with /SKILL.md この制約はドキュメントには一切記載されておらず、エラーメッセージから逆推測するしかなかった。適応後のpush-skill.shは60行から30行に削減された。VFS API自体が冪等だからだ——同じpathに対するputの繰り返しは更新になる。第四の落とし穴:早すぎる抽象化最初の改造版で、私は古典的なミスを犯した。ユーザーのブログディレクトリにhugo.pinw.ca/があったのを見て、ブログはHugoだと決めつけ、スキル全体をHugoワークフロー(hugo new、git push→ Netlify)に合わせて改造してしまった。ユーザーから「今のサイトもmx-spaceです」と訂正が入った——実際にはpinw.ca/core/とpinw.ca/Yohaku/がメインサイトだったのだ。このミスの根本原因は:現在のアーキテクチャを確認しないまま、ディレクトリ名だけで推測してしまったことにある。 hugo.pinw.caは旧ブログの残骸ディレクトリであり、実際に稼働しているmx-spaceバックエンドはすぐ隣のpinw.ca/core/にある。Warning教訓:ディレクトリ名で技術スタックを推測してはいけない。まずユーザーに確認するか、実際に動作しているサービスを調べるべきだ。ディレクトリ名がhugo.xxxだからといって、Hugoがメインサイトだとは限らない。最終的な改造計画以下は適応前後の比較である:コンポーネントInneiオリジナル版pinw.ca版スキルの保存先~/git/innei-repo/skill/~/.pi/agent/skills/mxsの呼び出し方グローバルmxspnpm mxs --profile defaultスキャフォールドREADME/symlink/git stage付きディレクトリ作成 + stubのみSnippet APIcreate --type skillput --type skill(VFS)設定~/.config/innei-skills/config.json設定ファイル不要全7スクリプトのうち、5つを書き換え(resolve-skill-repo.sh、scaffold-skill.sh、push-skill.sh、publish-post.sh、get-post.sh、update-post.sh)、1つを新規追加(resolve-mxs.sh)、1つはそのまま維持(load-litexml.sh)。持ち帰るべき判断基準今回の改造で明らかになった3つの汎用原則は、mx-spaceだけでなく他の場面にも当てはまる:実行状態を確認し、推測するな。ディレクトリ名がhugo.xxxだからといって、メインサイトがHugoとは限らない。まずps、docker ps、curlで確認してから行動に移せ。CLIツールのグローバルフラグが信頼できないなら、環境変数を使え。--api-urlのサブコマンドへの受け渡し動作はバージョンによって異なるが、MXS_API_URLはソースコード内で最優先される。Monorepo内のCLI呼び出しには明示的なプロファイルが必要だ。pnpm mxsのコンテキスト解決はグローバルのmxsとは異なり、--profileが唯一信頼できる指定方法である。改造完了後のスキルは、既に~/.pi/agent/skills/session-to-skill-and-blog/に配置されており、この記事こそがそれを使って公開されたものだ——まさにドッグフーディングである。スキルアドレス:Innei/SKILL — session-to-skill-and-blog(オリジナル版、本記事のインスピレーション元)
GitHubを徘徊していたらInneiのSKILLリポジトリを見つけ、その中にsession-to-skill-and-blogというスキルがあり、核となるアイデアが見事だった——あるエンジニアリングのセッションを、再利用可能なAIスキルとリンク付きブログ記事の2つの成果物に落とし込むというものだ。鉄則はスキルを先に書き、その後にブログを書くこと。なぜならブログはスキルのURLを必要とし、SKILL.mdのフォーマットによって操作手順を最初に整理せざるを得なくなるからだ。
アイデア自体はとても良いが、Innei自身のインフラ向けにカスタマイズされている——スキルは彼のGitHubリポジトリに保存され、ブログはmxsCLI経由で彼のmx-spaceブログに投稿される。私もmx-space(pinw.ca)を持っているので、自分の環境に合うように改造することにした。この記事では、その改造中に踏んだ穴と学んだ教訓を記録する。
第一の落とし穴:サーバーがローカルにない
スキルをインストールした後、真っ先にmxs auth loginを実行した。結果はこうだ:
私のmx-spaceはリモートサーバー上で動作しており、APIのアドレスはhttps://api.pinw.caであり、ローカルホストではない。そこで--api-urlパラメータを追加してみた:
効果はなく、依然としてlocalhostを探っていた。ソースを調べたところ、mxs auth loginの--api-urlの受け渡し経路に問題があることが判明した——グローバルフラグがauthサブコマンドで正しく引き継がれていないのだ。環境変数に切り替え:
今度は成功した。認証後、設定は~/.config/mxs/profiles/default/config.jsonに書き込まれた。
教訓:mx-space CLIのグローバルフラグとサブコマンド間のオーバーライド優先順位は、バージョンによって動作が異なる。環境変数MXS_API_URLが最も信頼できるクロスバージョン設定方法である。
第二の落とし穴:プロファイルが自動的にアクティブにならない
認証に成功した後、すべてうまくいったと思った。そのまま実行:
しかしauth statusは正常だった:
次にmxs category listを実行:
またしてもlocalhostに接続しようとしている。確かにconfig.jsonの中ではapi_urlが既にhttps://api.pinw.caになっており、currentポインタもdefaultを指している。しかしpnpm mxsがmonorepoコンテキストでプロファイルを正しく読み取れていないのだ。
明示的にプロファイルを指定して解決:
そこで私はresolve-mxs.shに--profile defaultを追加し、すべてのスクリプトがmxsを呼び出す際に自動的に付与されるようにした。
教訓:monorepo内でpnpm mxsを介して呼び出す場合、プロファイルの解決パスがグローバルインストールとは異なる可能性がある。明示的な--profileの方がcurrentポインタに依存するより信頼性が高い。
第三の落とし穴:snippet APIのバージョン違い
オリジナルスキルのpush-skill.shは次のように使用していた:
しかし私のmxsバージョン(0.13.2)のsnippetサブコマンドは全く異なる——VFSスタイルなのだ:
しかもパスは/SKILL.mdで終わらなければならない:
この制約はドキュメントには一切記載されておらず、エラーメッセージから逆推測するしかなかった。適応後のpush-skill.shは60行から30行に削減された。VFS API自体が冪等だからだ——同じpathに対するputの繰り返しは更新になる。
第四の落とし穴:早すぎる抽象化
最初の改造版で、私は古典的なミスを犯した。ユーザーのブログディレクトリにhugo.pinw.ca/があったのを見て、ブログはHugoだと決めつけ、スキル全体をHugoワークフロー(hugo new、git push→ Netlify)に合わせて改造してしまった。ユーザーから「今のサイトもmx-spaceです」と訂正が入った——実際にはpinw.ca/core/とpinw.ca/Yohaku/がメインサイトだったのだ。
このミスの根本原因は:現在のアーキテクチャを確認しないまま、ディレクトリ名だけで推測してしまったことにある。 hugo.pinw.caは旧ブログの残骸ディレクトリであり、実際に稼働しているmx-spaceバックエンドはすぐ隣のpinw.ca/core/にある。
教訓:ディレクトリ名で技術スタックを推測してはいけない。まずユーザーに確認するか、実際に動作しているサービスを調べるべきだ。ディレクトリ名がhugo.xxxだからといって、Hugoがメインサイトだとは限らない。
最終的な改造計画
以下は適応前後の比較である:
全7スクリプトのうち、5つを書き換え(resolve-skill-repo.sh、scaffold-skill.sh、push-skill.sh、publish-post.sh、get-post.sh、update-post.sh)、1つを新規追加(resolve-mxs.sh)、1つはそのまま維持(load-litexml.sh)。
持ち帰るべき判断基準
今回の改造で明らかになった3つの汎用原則は、mx-spaceだけでなく他の場面にも当てはまる:
改造完了後のスキルは、既に~/.pi/agent/skills/session-to-skill-and-blog/に配置されており、この記事こそがそれを使って公開されたものだ——まさにドッグフーディングである。
スキルアドレス:Innei/SKILL — session-to-skill-and-blog(オリジナル版、本記事のインスピレーション元)