Spotted while fixing the provider-dependency failures in #4221.
## Problem
`python/examples/tool_router/tool_router_mcp.py` guarded a missing
credential like this:
```python
api_key = os.environ.get("COMPOSIO_API_KEY")
if not api_key:
print("Error: COMPOSIO_API_KEY environment variable not set")
print("Please set it using: export COMPOSIO_API_KEY='your_api_key'")
return
```
`return` exits the coroutine normally, so `asyncio.run(main())`
completes and the process exits **0**. The live-examples harness scores
entries by exit code, so a run that did nothing at all was recorded
**green** — the worst kind of failure for a canary, since it reports
success while testing nothing.
## Fix
Raise instead, using the `require_env` helper the sibling examples
already use (`examples/tool_router/preload.py`):
```python
def require_env(name: str) -> str:
value = os.environ.get(name)
if not value:
raise RuntimeError(f"Set {name} before running this example.")
return value
```
## Verification
Replaying the harness's own invocation with the variable unset:
```
$ unset COMPOSIO_API_KEY
$ uv run --project python --with 'openai-agents>=0.19' \
--with ./python/providers/openai_agents --with ./python \
python python/examples/tool_router/tool_router_mcp.py
before: exit=0 # silently "passes"
after: exit=1 # RuntimeError: Set COMPOSIO_API_KEY before running this example.
```
`ruff check`, `ruff format --check`, and `nox -s chk_examples` all pass.
## Scope
I checked whether other examples share the pattern.
`examples/tool_router/authorize.py` prints the same message, but calls
`exit(1)` at module level rather than returning from a coroutine, so it
already fails correctly — left alone. This was the only instance.
## Summary
- Repairs runnable TypeScript and Python examples for current backend
requirements, including authenticated MCP endpoints, current transports,
valid tool identifiers, provider limits, and resource uniqueness.
- Replaces placeholder resource IDs with explicit `COMPOSIO_EXAMPLES_*`
configuration and makes failed examples exit loudly.
- Adds `scripts/examples-provision.mjs` as an idempotent provisioning
check for a disposable examples project.
## Scope
- This PR no longer changes the Python SDK runtime or generated-client
dependency.
- Python remains pinned to the published `composio-client==1.43.0` in
`pyproject.toml`, `setup.py`, and `uv.lock`.
- The owned 2.x client integration is deferred until that client
completes its release guarantees and is explicitly published.
- The scheduled live workflow and manifest remain deferred until their
runner is tracked.
## Verification
- `make chk`
- `make tst` (`927 passed, 33 skipped`)
- Hosted checks rerun against commit `12691aca7`.