mcpField
B
byo-proxy

byo-proxy

github.com/starchild-ai-agentCloud & DevOps3089 installsUpdated 6d ago
Repository

About byo-proxy

byo-proxy is a configuration skill for people who want other skills to use their own IPRoyal proxy accounts. It stores credentials and per-skill bindings, then provides Python helpers to build proxy URLs; it does not run a proxy server or route traffic itself.

Key features

  1. 01Store IPRoyal credentials
  2. 02Bind proxy settings to skills
  3. 03Build rotating or sticky proxy URLs
  4. 04Register dedicated ISP proxies
  5. 05Test proxy connectivity

Use cases

  1. 01Configure a crawler to use a country-specific residential IP
  2. 02Bind a skill to a sticky session or dedicated IP

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/starchild-ai-agent/official-skills --skill byo-proxy

After installing, type/byo-proxyin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

exports.py
references/
iproyal-isp.md
iproyal.md
scripts/
add_isp_proxy.py
bind_skill.py
list_providers.py
onboard.py
setup_provider.py
test_proxy.py

Details

From the project README

byo-proxy — bring-your-own proxy

Users supply their own proxy account (currently IPRoyal); this skill stores the credentials, maintains a skill → provider binding table, and exposes a tiny Python API that other skills can opt into.

This skill does not run a proxy server and does not intercept any traffic. It is a configuration center plus a URL builder. Other skills only behave differently if they explicitly import from exports.py.

Boundaries vs. existing proxy skills

SkillWhat it doesWhen
sc-vpnInternal VPN gateway, 18 fixed countries, no authLast resort for geo-blocked requests inside Starchild
transparent-proxy-maintenanceMaintain the platform's billing proxy pluginsOps work on sc-proxy
byo-proxy (this)Manage user's own provider keys + per-skill bindingsUser wants residential IPs, paid accounts, country granularity beyond sc-vpn's 18, or a dedicated fixed IP

Supported providers

ProviderKindEndpointIP behaviourAuth
iproyalgatewaygeo.iproyal.com:12321rotates; sticky ≤ 7 days per sessionaccount username + password
iproyal-ispispper-IP host:port (e.g. 191.116.125.248:12323)dedicated, never changesper-proxy username + password

Two shapes of "fixed IP":

  • Sticky session (iproyal + --session + --sticky) → same exit IP for up to 7 days, then pool rotation can move it. Cheap (per GB).
  • Dedicated static IP (iproyal-isp) → an IP reserved for you that never changes. Priced per IP, unlimited traffic. This is the "permanent fixed IP".

Adding more providers later: add an entry to PROVIDERS + a URL builder in exports.py. See references/iproyal.md (residential) and references/iproyal-isp.md (dedicated).

Storage

  • Account credentials (gateway providers) → /data/workspace/.env (same convention as polymarket, birdeye, coingecko). Keys: IPROYAL_USERNAME, IPROYAL_PASSWORD.
  • Bindings + ISP proxy inventory → /data/workspace/.byo-proxy.json:
    {
      "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" } }
    }
    
    ISP credentials are per-IP, so they live here (keyed by local proxy_id) rather than in .env. Both files are edited only through scripts; agents should not hand-edit. Legacy bindings-only files are migrated automatically on next save.

User workflow

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]

How other skills consume it

Two patterns. Both raise ProxyNotConfiguredError on misconfiguration — never silent fallback (a proxy user is debugging a geo/identity problem; silently falling through to a direct connection makes that debugging much harder).

Pattern A — explicit, one-off
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)
Pattern B — bound, long-term

Use when a skill always wants to route through whatever the user configured for it:

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 is provider-agnostic: it returns the right URL whether the user bound a rotating country, a sticky session, or a dedicated ISP IP. A skill that does not import it is unaffected, even if the user has bindings configured. Opt-in only.

Onboarding for unconfigured skills

When get_proxy_for_skill("X") raises because nothing is configured for X, the exception message is already a complete onboarding script: signup URL, pricing, credential location, and the exact onboard.py command to run. Agents that surface this error to a user will naturally walk them through registration and binding — no extra logic needed in the calling skill.

If a calling skill wants to render its own onboarding UI (instead of relying on the error message), it can import the same text directly:

from exports import onboarding_guide
print(onboarding_guide("web-crawler", provider="iproyal", country="jp"))
print(onboarding_guide("web-crawler", provider="iproyal-isp"))

Public API (exports.py)

FunctionReturnsRaises
get_proxy_url(provider, country=None, sticky_minutes=None, session=None, proxy_id=None)str proxy URLProxyNotConfiguredError if creds/proxy missing; ValueError on bad provider/country/param
get_proxy_for_skill(skill_name)str proxy URLProxyNotConfiguredError (multi-line onboarding guide) if unbound, provider gone, creds or ISP proxy missing
onboarding_guide(skill_name, provider="iproyal", country="<cc>", proxy_id=None)str onboarding textValueError on bad provider
list_providers()list[dict] — {provider, kind, configured, …} + bound_skillsnever
set_binding(skill_name, provider, country=None, sticky_minutes=None, session=None, proxy_id=None)NoneValueError on bad provider/country/param or unregistered ISP proxy
unset_binding(skill_name)Nonenever
add_isp_proxy(proxy_id, host, port, username, password, socks_port=None, label=None)NoneValueError on bad id/host/port
remove_isp_proxy(proxy_id, force=False)list of still-bound skillsValueError if bound and not force
list_isp_proxies()list[dict] — {proxy_id, endpoint, socks_endpoint, label, bound_skills} (creds redacted)never
test_proxy(provider, country=None, proxy_id=None, timeout=15)dict — {ok, exit_ip, geo_country, latency_ms}ProxyNotConfiguredError / ValueError

Sticky bounds: sticky_minutes ∈ 1..10080 (7 days). sticky_minutes requires session (IPRoyal's lifetime- only applies to a session-).

Per-request only — no global proxy

Same rule as sc-vpn: never export HTTP_PROXY=... from this skill's URLs. Pass proxies= to the specific request only. Setting global env vars will break unrelated skills (notably sc-proxy traffic for paid APIs).

Troubleshooting

ErrorCauseFix
Skill 'X' has no proxy bindingbindings has no entry for Xpython3 scripts/onboard.py X --provider iproyal --country <cc> (or --provider iproyal-isp)
... USERNAME / ... PASSWORD not foundgateway creds never saved (or removed from .env)python3 scripts/setup_provider.py iproyal (or re-run onboard.py)
ISP proxy 'X' is not registeredbinding references an id absent from .byo-proxy.jsonpython3 scripts/add_isp_proxy.py X --host … --port … --username … --password …
... bound to unknown providerbindings references a provider that no longer existsrebind, or bind_skill.py X --unset
sticky_minutes requires a session id--sticky without --sessionadd --session <id> (IPRoyal's lifetime- needs session-)
sticky_minutes must be between 1 and 10080out of rangemax is 7 days
ValueError: Unknown country code 'XX'not in IPRoyal's supported listsee references/iproyal.md
test_proxy returns ok=falsewrong creds/host, expired account, networkcheck the dashboard; for ISP re-register the proxy string

Files

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

Comments

Markdown supported