Claude agent skill のスクリプト、Node.js と Python どっち?プロキシ環境で動かない原因と対処法
Claude 向けの Agent Skills を作ろうとしたのですが、Node.js で書いたスクリプトが getaddrinfo EAI_AGAIN というエラーで動かなくなりました。この記事では、Claude のコ […]
目次
Claude 向けの Agent Skills を作ろうとしたのですが、Node.js で書いたスクリプトが getaddrinfo EAI_AGAIN というエラーで動かなくなりました。この記事では、Claude のコンテナ環境で外部データ取得を行うスクリプトを書く際に、なぜ Node.js だと動かず Python だと動くのかについて紹介します。
なぜ Node.js で書いたスクリプトが動かないのか
WordPress の公式ドキュメントを検索するためのREST API呼び出し処理を Node.js で実装したとき、以下のエラーが発生しました。
$ node dist/search.js "plugin rules" "plugin-handbook" 10
Error: Network error: getaddrinfo EAI_AGAIN developer.wordpress.org
スクリプトの実装は至ってシンプルで、Node.js 標準の https モジュールで developer.wordpress.org の REST API にアクセスしているだけです。
const https = require('https');
function httpsGet(url) {
return new Promise((resolve, reject) => {
const request = https.get(url, { timeout: 10000 }, (response) => {
// レスポンス処理
});
request.on('error', (error) => reject(new Error(`Network error: ${error.message}`)));
});
}
同じ URL に curl でアクセスすると問題なく通信できます。しかしAgent SkillのスクリプトでNode.js をじっこうしようとするとDNS 解決に失敗するという状況でした。
ClaudeのAgent Skillで実行するスクリプトはコンテナ内で動作する
原因ですが、スクリプトがコンテナ環境内で動くことに起因している様子でした。Claude は Ubuntu 24 の VM 環境で動作しており、セキュリティ上の理由から以下の制約があります。
- コンテナから直接インターネットへアクセスできない
- すべての外部通信は
HTTPS_PROXY環境変数で指定されたプロキシ経由が必須 - プロキシの許可リスト(JWT の
allowed_hostsフィールド)に含まれるドメインのみアクセス可能
環境変数を確認すると、確かにプロキシが設定されています。
$ echo $HTTPS_PROXY
http://container_xxx:jwt_yyy@21.0.0.143:15004
curl はこの環境変数を自動で読み込んでプロキシ経由で通信します。しかし Node.js の https.get() は環境変数を無視して、直接 DNS 解決を試みます。プロキシを経由しないため名前解決に失敗し、EAI_AGAIN エラーになります。
Python のスクリプトでは動作する
Python で同じことをすると、追加コードなしで動作します。
import urllib.request
url = "https://developer.wordpress.org/wp-json/wp/v2/search?search=test&per_page=1"
res = urllib.request.urlopen(url, timeout=10)
print("Status:", res.status)
print("Body:", res.read().decode()[:100])
実行結果:
Status: 200
Body: [{"id":11166,"title":"Testing of WP-Cron"}]
Node.js で実装する場合の対処法
Node.js で実装する必要がある場合、https-proxy-agent を導入してプロキシ対応を実装します。
1. パッケージをインストール
npm install https-proxy-agent
2. コードを修正
プロキシ環境変数を読み込み、https.get() の agent オプションに渡します。
const https = require('https');
const { HttpsProxyAgent } = require('https-proxy-agent');
// プロキシ環境変数を取得
const proxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy;
const agent = proxyUrl ? new HttpsProxyAgent(proxyUrl) : undefined;
function httpsGet(url) {
return new Promise((resolve, reject) => {
// agent オプションを追加
const request = https.get(url, { timeout: 10000, agent }, (response) => {
if (response.statusCode && response.statusCode >= 400) {
response.resume();
reject(new Error(`HTTP error ${response.statusCode}`));
return;
}
let data = "";
response.on("data", (chunk) => { data += chunk; });
response.on("end", () => { resolve(data); });
});
request.on("error", (error) => reject(new Error(`Network error: ${error.message}`)));
request.on("timeout", () => { request.destroy(); reject(new Error("Request timeout")); });
});
}
この変更だけで、プロキシ経由での通信が可能になります。
3. 動作確認
修正後、同じスクリプトを実行すると成功します。
$ node dist/search.js "plugin rules" "plugin-handbook" 5
[
{
"id": 11070,
"title": "Working with Custom Post Types",
"url": "https://developer.wordpress.org/plugins/post-types/...",
"subtype": "plugin-handbook"
}
]
まとめ
Claude の Agent Skills でスクリプトを書く際、外部データ取得を含む場合は以下を基準に判断しましょう。
- Python を優先検討する – プロキシ対応が標準で組み込まれており、追加実装が不要です
- Node.js を選ぶ場合 –
https-proxy-agentの導入が必須です。この追加コストを理解した上で選択してください