byo-proxy について
byo-proxyは、自分のIPRoyalアカウントを他のスキルで使うための設定スキルです。認証情報とスキルごとの設定を保存し、Python APIでプロキシURLを生成しますが、プロキシサーバーの運用や通信の中継は行いません。
主な機能
- 01IPRoyal認証情報の保存
- 02スキルごとのプロキシ設定
- 03ローテーション・固定セッションURLの生成
- 04専用ISPプロキシの登録
- 05プロキシ接続のテスト
活用シーン
- 01クローラーに国別の住宅IPを設定
- 02スキルに固定セッションまたは専用IPを割り当て
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ starchild-ai-agent/ official-skills --skill byo-proxyインストール後、Claude Code で/byo-proxyを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
exports.pyreferences/iproyal-isp.mdiproyal.mdscripts/add_isp_proxy.pybind_skill.pylist_providers.pyonboard.pysetup_provider.pytest_proxy.py詳細
byo-proxy — bring-your-own プロキシ
ユーザーが自分のプロキシアカウント(現在は IPRoyal)を用意する方式です。このスキルは認証情報を保存し、skill → provider のバインディングテーブルを維持し、他のスキルが任意で利用できる小さな Python API を公開します。
このスキルはプロキシサーバーを実行しませんし、いかなるトラフィックも傍受しません。これは設定センターと URL ビルダーです。他のスキルは、明示的に exports.py から import した場合にのみ動作が変わります。
既存のプロキシスキルとの境界
| スキル | 役割 | 使用場面 |
|---|---|---|
sc-vpn | 社内 VPN ゲートウェイ、18 の固定国、認証なし | Starchild 内で地理的にブロックされたリクエストの最終手段 |
transparent-proxy-maintenance | プラットフォームの課金プロキシプラグインの保守 | sc-proxy の運用作業 |
byo-proxy(本スキル) | ユーザー自身のプロバイダーキー + スキルごとのバインディングを管理 | ユーザーがレジデンシャル IP、有料アカウント、sc-vpn の 18 か国を超える国単位の指定、または専用の固定 IP を求める場合 |
対応プロバイダー
| プロバイダー | 種類 | エンドポイント | IP の挙動 | 認証 |
|---|---|---|---|---|
iproyal | gateway | geo.iproyal.com:12321 | ローテーションする。セッションごとに sticky ≤ 7 日 | アカウントのユーザー名 + パスワード |
iproyal-isp | isp | IP ごとの host:port(例: 191.116.125.248:12323) | 専用で、決して変わらない | プロキシごとのユーザー名 + パスワード |
「固定 IP」には 2 つの形があります:
- スティッキーセッション(
iproyal+--session+--sticky)→ 最大 7 日間同じ出口 IP を使用し、その後プールのローテーションで移動することがあります。安価です(GB 単位)。 - 専用静的 IP(
iproyal-isp)→ あなた専用に予約され、決して変わらない IP です。IP 単位の課金で、トラフィックは無制限です。これが「恒久的な固定 IP」です。
後でプロバイダーを追加する場合:PROVIDERS にエントリを追加し、exports.py に URL ビルダーを追加します。references/iproyal.md(レジデンシャル)と references/iproyal-isp.md(専用)を参照してください。
ストレージ
- アカウント認証情報(ゲートウェイプロバイダー)→
/data/workspace/.env(polymarket、birdeye、coingeckoと同じ規約)。キー:IPROYAL_USERNAME、IPROYAL_PASSWORD。 - バインディング + ISP プロキシインベントリ →
/data/workspace/.byo-proxy.json:
ISP の認証情報は IP ごとなので、{ "bindings": { "web-crawler": { "provider": "iproyal", "country": "jp", "session": "crawler-jp", "sticky_minutes": 360 } }, "isp_proxies": { "jp-1": { "host": "191.116.125.248", "port": 12323, "socks_port": 12324, "username": "…", "password": "…", "label": "Tokyo ISP" } } }.envではなくここに(ローカルのproxy_idをキーとして)保存されます。どちらのファイルもスクリプトを通じてのみ編集されます。エージェントが手で編集すべきではありません。バインディングのみの旧形式ファイルは、次回の保存時に自動的に移行されます。
ユーザーのワークフロー
SKILL=/data/workspace/skills/byo-proxy
# ── Residential gateway (rotating / sticky) ──────────────────────────────────
# 0. One-shot onboarding — prompts for creds only if missing, binds, live-tests:
python3 $SKILL/scripts/onboard.py web-crawler --provider iproyal --country jp
# 1. Register credentials (interactive — prompts for username/password)
python3 $SKILL/scripts/setup_provider.py iproyal
# 2. Bind a skill (long-term preference)
python3 $SKILL/scripts/bind_skill.py web-crawler --provider iproyal --country jp
# Pin one exit IP for up to 7 days (sticky needs a session id):
python3 $SKILL/scripts/bind_skill.py web-crawler --provider iproyal --country jp \
--session crawler-jp --sticky 360 # 6 hours
# ── Dedicated static IP (permanent) ─────────────────────────────────────────
# 3. Register a purchased ISP proxy (interactive if flags omitted), then bind:
python3 $SKILL/scripts/add_isp_proxy.py jp-1 \
--host 191.116.125.248 --port 12323 --socks-port 12324 \
--username <user> --password <pass> --label "Tokyo ISP"
python3 $SKILL/scripts/bind_skill.py web-crawler --provider iproyal-isp --proxy-id jp-1
# Or one-shot: python3 $SKILL/scripts/onboard.py web-crawler --provider iproyal-isp
# ── Inspect / verify / clean up ────────────────────────────────────────────
python3 $SKILL/scripts/list_providers.py # providers, ISP proxies, bindings
python3 $SKILL/scripts/test_proxy.py iproyal --country jp
python3 $SKILL/scripts/test_proxy.py iproyal-isp --proxy-id jp-1
python3 $SKILL/scripts/bind_skill.py web-crawler --unset
python3 $SKILL/scripts/add_isp_proxy.py --list
python3 $SKILL/scripts/add_isp_proxy.py --remove jp-1 [--force]
他のスキルがこれを利用する方法
2 つのパターンがあります。どちらも設定ミス時には ProxyNotConfiguredError を発生させます — 決してサイレントにフォールバックしません(プロキシユーザーは地理や身元の問題をデバッグしています。サイレントに直接接続へフォールバックすると、そのデバッグがはるかに難しくなります)。
パターン A — 明示的、単発
import sys, requests
sys.path.insert(0, "/data/workspace/skills/byo-proxy")
from exports import get_proxy_url
p = get_proxy_url(provider="iproyal", country="jp") # rotating
p = get_proxy_url(provider="iproyal", country="jp",
session="crawler-jp", sticky_minutes=360) # sticky 6h
p = get_proxy_url(provider="iproyal-isp", proxy_id="jp-1") # dedicated IP
r = requests.get("https://example.com", proxies={"http": p, "https": p}, timeout=30)
パターン B — バインド済み、長期的
スキルが、ユーザーがそのスキル向けに設定したものを通じて常にルーティングしたい場合に使用します:
import sys, requests
sys.path.insert(0, "/data/workspace/skills/byo-proxy")
from exports import get_proxy_for_skill, ProxyNotConfiguredError
try:
p = get_proxy_for_skill("web-crawler") # caller declares its own name
except ProxyNotConfiguredError as e:
# The exception message IS a multi-line onboarding guide for the user —
# surface it verbatim. It includes the signup URL, pricing note, and the
# one-shot `onboard.py` command to fix the situation.
raise SystemExit(str(e))
r = requests.get(url, proxies={"http": p, "https": p}, timeout=30)
get_proxy_for_skill はプロバイダー非依存です:ユーザーがローテーションする国、スティッキーセッション、専用 ISP IP のいずれをバインドしていても、正しい URL を返します。これを import していないスキルは、たとえユーザーがバインディングを設定していても影響を受けません。オプトインのみです。
未設定のスキル向けのオンボーディング
X に対して何も設定されていないために get_proxy_for_skill("X") が例外を発生させるとき、その例外メッセージはすでに完全なオンボーディングスクリプトです:サインアップ URL、料金、認証情報の場所、そして実行すべき正確な onboard.py コマンドが含まれます。このエラーをユーザーに提示するエージェントは、自然に登録とバインディングへと案内します — 呼び出し側のスキルに追加のロジックは不要です。
呼び出し側のスキルが(エラーメッセージに頼る代わりに)独自のオンボーディング UI をレンダリングしたい場合は、同じテキストを直接インポートできます:
from exports import onboarding_guide
print(onboarding_guide("web-crawler", provider="iproyal", country="jp"))
print(onboarding_guide("web-crawler", provider="iproyal-isp"))
公開 API (exports.py)
| 関数 | 戻り値 | 例外 |
|---|---|---|
get_proxy_url(provider, country=None, sticky_minutes=None, session=None, proxy_id=None) | str プロキシ URL | 認証情報/プロキシが存在しない場合は ProxyNotConfiguredError、不正な provider/country/param の場合は ValueError |
get_proxy_for_skill(skill_name) | str プロキシ URL | 未バインド、provider が消滅、認証情報または ISP プロキシが存在しない場合は ProxyNotConfiguredError(複数行のオンボーディングガイド) |
onboarding_guide(skill_name, provider="iproyal", country="<cc>", proxy_id=None) | str オンボーディングテキスト | 不正な provider の場合は ValueError |
list_providers() | list[dict] — {provider, kind, configured, …} + bound_skills | なし |
set_binding(skill_name, provider, country=None, sticky_minutes=None, session=None, proxy_id=None) | None | 不正な provider/country/param、または未登録の ISP プロキシの場合は ValueError |
unset_binding(skill_name) | None | なし |
add_isp_proxy(proxy_id, host, port, username, password, socks_port=None, label=None) | None | 不正な id/host/port の場合は ValueError |
remove_isp_proxy(proxy_id, force=False) | まだバインドされているスキルの list | バインド済みで force でない場合は ValueError |
list_isp_proxies() | list[dict] — {proxy_id, endpoint, socks_endpoint, label, bound_skills}(認証情報は伏せられます) | なし |
test_proxy(provider, country=None, proxy_id=None, timeout=15) | dict — {ok, exit_ip, geo_country, latency_ms} | ProxyNotConfiguredError / ValueError |
スティッキー制約: sticky_minutes は 1..10080(7 日間)の範囲です。sticky_minutes には
session が 必要 です(IPRoyal の lifetime- は session- にのみ適用されます)。
リクエストごとのみ — グローバルプロキシは使用しません
sc-vpn と同じルールです。このスキルの URL から export HTTP_PROXY=... を決して行わないでください。
特定のリクエストにのみ proxies= を渡します。グローバルな環境変数を設定すると、
無関係なスキル(特に有料 API 向けの sc-proxy トラフィック)が壊れます。
トラブルシューティング
| エラー | 原因 | 修正方法 |
|---|---|---|
Skill 'X' has no proxy binding | bindings に X のエントリがありません | python3 scripts/onboard.py X --provider iproyal --country <cc>(または --provider iproyal-isp) |
... USERNAME / ... PASSWORD not found | ゲートウェイの認証情報が保存されていません(または .env から削除されています) | python3 scripts/setup_provider.py iproyal(または onboard.py を再実行) |
ISP proxy 'X' is not registered | バインディングが .byo-proxy.json に存在しない id を参照しています | python3 scripts/add_isp_proxy.py X --host … --port … --username … --password … |
... bound to unknown provider | bindings が存在しなくなった provider を参照しています | 再バインドするか、bind_skill.py X --unset |
sticky_minutes requires a session id | --session なしで --sticky を指定しています | --session <id> を追加します(IPRoyal の lifetime- には session- が必要です) |
sticky_minutes must be between 1 and 10080 | 範囲外です | 最大は 7 日間です |
ValueError: Unknown country code 'XX' | IPRoyal のサポート対象リストにありません | references/iproyal.md を参照してください |
test_proxy が ok=false を返す | 認証情報/ホストが間違っている、アカウントの有効期限切れ、ネットワーク | ダッシュボードを確認してください。ISP の場合はプロキシ文字列を再登録してください |
ファイル
byo-proxy/
├── SKILL.md
├── exports.py # public API for other skills
├── scripts/
│ ├── onboard.py # one-shot: register (if needed) + bind + test
│ ├── setup_provider.py # interactive gateway credential setup
│ ├── add_isp_proxy.py # register/list/remove dedicated ISP proxies
│ ├── list_providers.py # show providers + ISP proxies + bindings
│ ├── bind_skill.py # set/unset skill→provider binding
│ └── test_proxy.py # verify exit IP via ifconfig.co
└── references/
├── iproyal.md # residential gateway: params, sticky sessions
└── iproyal-isp.md # dedicated static IPs: per-IP endpoint + auth