## Summary
- classify detected Claude Code and Codex hosts as supported or
unsupported before plugin inspection
- verify both marketplace and plugin-list JSON capabilities; retain the
Codex 0.139.0 minimum
- in automatic mode, skip unsupported hosts and continue with supported
hosts
- honor `--if-present` when automatic detection leaves only unsupported
hosts
- fail before mutation when no supported host remains without
`--if-present`, or when an unsupported host is explicitly targeted
- turn expected setup, inspection, install, verification, and uninstall
failures into concise setup-specific errors with recovery commands
- keep failures nonzero while avoiding generic Effect diagnostics and
command-usage dumps
## Deferred follow-up
Install/setup/plugin lifecycle telemetry and direct PostHog delivery are
intentionally out of scope for this compatibility PR. They will be
implemented separately so anonymous first-install events have a working
delivery path.
## Regression coverage
- unit coverage exercises supported and unsupported Claude/Codex
combinations, explicit targets, `--if-present`, safe preflight, native
failures, timeouts, malformed responses, and verification failures
- Debian CLI E2E covers both unsupported-host directions,
unsupported-only `--if-present`, and packaged noninteractive failures
with concise output
- a fresh isolated macOS HOME matrix covers 16 host/state scenarios
using the exact standalone binary, real skill ZIP installation from a
localhost fixture, PTY transcripts, idempotence, uninstall, and
reinstall
## Verification
- `pnpm --filter @composio/cli test`: 781 passed, 1 skipped across 83
files
- `pnpm typecheck`: 12 tasks passed
- `bash test/install-sh-release-resolution.test.sh`: passed
- `pnpm --filter @e2e-tests/cli-setup-plugins test:e2e:cli`: 11 passed
in a rebuilt Debian image
- fresh isolated macOS HOME/PTY matrix: 16/16 passed
- `git diff --check`: passed
No changeset: this remains an unreleased CLI compatibility change;
stable promotion is separate.
This PR:
- supersedes https://github.com/ComposioHQ/composio/pull/3807 while
preserving Kshitij's original commits and authorship
- lets users configure the public Composio plugin for Claude Code,
Codex, or every detected host with `composio setup`
- centralizes host-specific commands, JSON keys, scope rules, and skill
policy in a typed adapter map
- requires explicit `--yes` approval outside an interactive terminal and
keeps action-command stdout empty
- accepts only canonical HTTPS marketplace sources, requires Claude's
user-scoped plugin, and verifies a readable release-matched skill
- preflights every selected host before mutation, reinstalls plugins
after marketplace repair, and reports partial completion if a later host
fails
- fails closed on native inspection errors or malformed JSON and bounds
host subprocesses to two minutes
- verifies final native state so successful subprocess exits cannot
masquerade as a ready setup
- uses Effect filesystem and path services throughout the touched
installer source and tests
## Validation
- `pnpm typecheck`: 12 tasks passed across the TypeScript workspace
- `pnpm --filter @composio/cli test`: 83 files passed; 760 tests passed;
1 skipped
- focused installer regressions: 18 passed
- focused ESLint, direct `node:fs` / `node:path` audit, and `git diff
--check`: clean
- Docker CLI E2E: Claude and Codex install once, remain idempotent on
rerun, and fail clearly when no host is available
## Known release artifact
The VHS recording remains deferred until the clean-home real-host smoke
test because recording this workflow mutates external agent-host state.
The deterministic Docker E2E covers the packaged CLI boundary in the
meantime.
## Summary
- run plugin setup automatically from the canonical `install.sh` flow
after shell integration
- configure every detected Claude Code and Codex host through the setup
engine from #3835
- add `composio setup --if-present` so installer automation succeeds
when no supported host is installed
- support `--no-plugins` and `COMPOSIO_INSTALL_PLUGINS=0` as explicit
opt-outs
- fail visibly with an exact retry command when a detected host cannot
be configured
## Stack
This is a deliberately small follow-up to #3835 and targets
`jk/cli-plugin-setup-review`. It should be rebased onto `next` after
#3835 merges.
## Behavior
The installer invokes the newly installed binary directly, so it does
not depend on the current shell reloading `PATH`:
```bash
"$exe" setup --target auto --yes --if-present
```
No detected host is a successful no-op. A detected host setup failure
leaves the CLI installed but fails the installer with `composio setup
--target auto --yes` as the retry path.
## Validation
- install.sh release-resolution, automatic setup, opt-out, and
setup-failure harness passed
- focused setup suite: 25 tests passed
- full CLI suite: 83 files passed; 761 tests passed; 1 skipped
- direct CLI source and test typechecks passed
- stable and beta skill validation passed
- focused ESLint, shell syntax checks, and `git diff --check` passed
- packaged setup E2E updated for the no-host installer path; local
launch is blocked by missing `mise`, so scratch-container CI is the
authoritative packaged check
## Recording
No VHS recording: this is installer orchestration plus a non-interactive
automation flag, covered at the shell-installer and packaged CLI
boundaries.
Replace direct Node filesystem and path access throughout the touched installer paths and tests. Preserve cleanup and replacement guarantees with focused lifecycle coverage.
## Summary
The AutoGen provider examples still used the legacy
`llm_config={"config_list": [...]}` dict form, which ag2 0.14 (the
distribution `composio-autogen` depends on since #3729) only keeps for
backport compatibility and marks deprecated in
`LLMConfig.ensure_config`. The install command also pulled
`autogen-agentchat` (Microsoft's next-gen AutoGen package), which the
provider never imports, while the `ag2` distribution the examples
actually import from was only installed transitively.
Fixes#3831
## Changes
- `docs/content/docs/providers/autogen.mdx`: example migrated to
`LLMConfig({...})`, install line changed to `composio composio_autogen
ag2`, added `ag2` keyword and a one-line note that the provider runs on
the ag2 distribution
- `python/providers/autogen/README.md`: same quickstart and install
fixes
- `python/providers/autogen/autogen_demo.py`: same `LLMConfig` migration
`initiate_chat` is left as is: it isn't deprecated in ag2 0.14, and it's
the flow `register_tools` (caller/executor) is verified against.
## Type of change
- [ ] Bug fix
- [ ] New feature
- [ ] Refactor/Chore
- [x] Documentation
- [ ] Breaking change
## How Has This Been Tested?
- Verified in a fresh venv with the local `composio` +
`composio-autogen` packages and `ag2==0.14.0`: the updated example
constructs both agents, wraps a Composio tool via `AutogenProvider`,
registers it with `register_tools`, and executes it through the
executor's function map
- `uv run nox -s chk` (ruff + mypy): green
- `ruff format --check providers/autogen/`: clean
- Docs: `bun run build` and `bun run lint:links` from `docs/`: green
## Screenshots (if applicable)
## Checklist
- [x] I have read the Code of Conduct and this PR adheres to it
- [x] I ran linters/tests locally and they passed
- [x] I updated documentation as needed
- [ ] I added tests or explain why not applicable
- [x] I added a changeset if this change affects published packages
## Additional context
No changeset added: docs and Python-only change, no published TypeScript
package affected. No tests added: example/docs change with no runtime
code paths; the updated example was exercised manually against ag2 0.14
as described above.
---------
Co-authored-by: Alberto Schiabel <jkomyno@users.noreply.github.com>
Co-authored-by: jkomyno <alberto@composio.dev>
This PR:
- validates Python package versions and release-note coverage before a
`py@*` tag can build or publish artifacts
- runs the existing repository release-workflow guard in the tag-release
workflow
- installs the pinned Node, pnpm, and Bun toolchain only for the
metadata validation step
- prevents a tag from publishing artifacts whose package, runtime,
provider, or docs versions drift apart
Validation:
- `pnpm test:release-workflow`
- `pnpm exec prettier --check .github/workflows/py.release.yml`
This PR:
- ports the TypeScript SDK's public-network guard to Python URL file
uploads
- rejects non-HTTP(S), private, loopback, link-local, reserved, and
mixed DNS targets before a request is made
- applies the guard to both `FileUploadable.from_url()` and Tool Router
session-file URL uploads
- redacts URL queries, Authorization credentials, and secret-like
key/value pairs before error telemetry leaves the process
- adds focused SSRF and redaction regressions alongside the existing
file-upload coverage
Validation:
- `uv run --frozen pytest tests/test_url_safety.py
tests/test_redaction.py tests/test_files.py -q`
- `uv run --frozen ruff check …`
- `uv run --frozen ruff format --check …`
## Summary
Adds a `--no-browser` flag to `composio link` (and `composio dev
connected-accounts link`) that skips auto-opening the browser and prints
the authorization URL for the user to open manually, while still waiting
for the connection to become `ACTIVE`.
Previously the only way to suppress the browser auto-open was
`--no-wait`, which also exits without waiting for authorization.
`--no-browser` fills the gap for users (and remote/SSH sessions) who
want to click the link themselves but still get the wait-for-ACTIVE
confirmation — matching the existing `composio login --no-browser`
behavior.
## Changes
- New `--no-browser` boolean option on both the root `link` command and
the `dev connected-accounts link` variant
- `waitForActiveConnection` skips `open()` and tells the user to open
the printed URL when the flag is set
- The unmanaged-auth dashboard fallback (`ToolRouterV2_NoManagedAuth`)
also respects the flag
- Root help (`root-help.ts`) documents the new flag
- Test: `link gmail --no-browser` waits for ACTIVE and never calls
`open`
No VHS recording added — this is a small flag addition to an existing
command surface, not a new documented workflow.
## Verification
- `pnpm typecheck` — passes
- `pnpm --filter @composio/cli test` — 81 files, 725 tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Adds a --no-browser flag to `composio link` (and `composio dev
connected-accounts link`) that prints the authorization URL instead of
auto-opening the browser, while still waiting for the connection to
become ACTIVE. Also respected on the unmanaged-auth dashboard fallback.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This PR:
- reverts https://github.com/ComposioHQ/composio/pull/3780
- restores the TypeScript `composio.create()` and `composio.use()`
session aliases, with their runtime and type-test coverage
- restores the prior deprecation state for
`BaseProvider.wrapMcpServerResponse`
- removes the pre-v1 breaking-change changeset so the release PR no
longer advertises this removal
The v1 API-freeze change should be recreated later as a draft PR and
kept out of the merge queue until v1 is ready.
```markdown
The `homepage` field in every published TypeScript package points at
`https://github.com/ComposioHQ/composio/tree/main/ts/packages/<pkg>#readme`. The
repository's default branch is `next` and there is no `main` branch, and GitHub
does not redirect `tree/<branch>` paths to the default branch when that branch
does not exist. As a result each of these homepage links returns a 404 wherever
it is surfaced (the package page on npmjs.com, editor/IntelliSense hovers, and
`npm view <pkg> homepage`).
This repoints each `homepage` to `tree/next/...` so the links resolve. The
`repository.url` (plain `.git` URL) and `bugs.url` fields were already correct
and are left untouched.
The metadata was originally added in #3611; this only corrects the branch in the
`homepage` URLs.
Fixes #
## Changes
- Update the `homepage` field from `tree/main/...` to `tree/next/...` in the 14
published packages that carry one: `@composio/core`, `@composio/slim`,
`@composio/experimental`, `@composio/json-schema-to-zod`, and the providers
`@composio/anthropic`, `@composio/claude-agent-sdk`, `@composio/cloudflare`,
`@composio/google`, `@composio/langchain`, `@composio/llamaindex`,
`@composio/mastra`, `@composio/openai`, `@composio/openai-agents`,
`@composio/vercel`.
- Add a Changeset (patch) covering those 14 published packages.
## Type of change
- [x] Bug fix
- [ ] New feature
- [ ] Refactor/Chore
- [ ] Documentation
- [ ] Breaking change
## How Has This Been Tested?
Metadata-only change, so there is no unit test to add. Verified with:
- Confirmed the target branch: `git ls-remote --symref origin HEAD` reports
`refs/heads/next`, and `git ls-remote --heads origin main` is empty (no `main`).
- Confirmed the links resolve: `https://github.com/ComposioHQ/composio/tree/main/ts/packages/core`
returns HTTP 404 while `.../tree/next/ts/packages/core` returns HTTP 200
(same for the provider packages).
- All 14 edited `package.json` files still parse as valid JSON.
- `pnpm exec prettier --check` on the 14 `package.json` files and the changeset:
all pass.
- `pnpm changeset status --since=origin/next` lists exactly these 14 packages
bumping at `patch` (no missing or extra packages), so the changeset CI check is
satisfied.
Environment: node 26, pnpm 10.28.0.
## Screenshots (if applicable)
## Checklist
- [x] I have read the Code of Conduct and this PR adheres to it
- [x] I ran linters/tests locally and they passed
- [ ] I updated documentation as needed
- [x] I added tests or explain why not applicable
- [x] I added a changeset if this change affects published packages
## Additional context
The `homepage` URLs pin an explicit branch (`tree/<branch>`), so they will break
again if the default branch is ever renamed. If you would prefer a
branch-agnostic form (for example dropping the `tree/<branch>` segment so the URL
tracks the default branch, or linking to the published README), I am happy to
switch to that instead; I went with the smallest correct fix of pointing at the
actual default branch.
```
Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
This PR:
- builds on top of https://github.com/ComposioHQ/composio/pull/3754
- normalizes list-valued JSON Schema `type` fields before scalar type
lookups
- applies the handling to direct fields and `anyOf`/`oneOf` options
- adds regressions for nullable, single, mixed, unknown, and
combiner-nested type lists
- credits @anxkhn as a Git co-author
## Context
JSON Schema Draft 2020-12 and OpenAPI 3.1 allow `type` to be an array.
The previous parser passed that list to a dictionary lookup, raising
`TypeError: unhashable type: 'list'`. This replacement covers the direct
case from #3754 and the same shape nested in a combiner.
---------
Co-authored-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
## Summary
Automated documentation updates triggered by new changelog entries
merged to next.
Generated by Codex via GitHub Actions.
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This PR:
- Adds public docs changelog entries for the Python and TypeScript SDK
releases since May 15, 2026, including the previously unmigrated Python
0.13.1 entry.
- Removes the Python-local changelog and replaces it with canonical
changelog links from the repository and Python READMEs.
- Retargets the Python release guard to the docs changelog, documents
its table contract, and covers prior-version plus PEP 440 version
parsing.
Validation:
- pnpm test:release-workflow
- docs: bun run test
- docs: bun run lint:links
- docs: bun run types:check
- docs: bun run build
- pnpm exec prettier --check test/release-workflow.test.ts
docs/agent-guidance/guides/changelog.md docs/content/changelog/*.mdx
Review:
- ce-code-review completed with correctness, testing, maintainability,
project-standards, agent-native, learnings, and adversarial passes. All
actionable findings were fixed; final adversarial re-review found no
remaining P0-P2 issue.
## Summary
- Ports support-workflows toolkit KB into public toolkit FAQ docs for 85
toolkit FAQ files.
- Creates 46 new toolkit FAQ files for toolkits that had KB but no FAQ
file yet.
- Updates existing toolkit FAQ files without deleting current public
answers.
## General docs updates
- Clarifies connected-account credential redaction and reconnect/refresh
semantics.
- Documents Proxy Execute scoped-key and v3.1/current-SDK requirements.
- Adds retry risk guidance for non-idempotent direct tool executions.
- Adds remote sandbox temporary state/file retention guidance.
- Adds Composio Connect vs developer project boundary guidance for MCP
app connections.
## Verification
- Hygiene grep passed on changed files:
`Plain|T-|SUP-|PRO-|Linear|plain.com|linear.app|/Users/|support-workflows|TODO|FIXME|\[eng:|customer`.
- `git diff --check` passed.
- `bun run lint:links` passed: 0 errored files, 0 errors.
- `bun run build` passed. Build emitted the existing Turbopack NFT
warning plus toolkit-detail fetch skips because `COMPOSIO_API_KEY` is
not set locally.
- Render spot checks passed for Gmail, Apollo, SharePoint, Google
Calendar, connected accounts, and remote sandbox pages.
## Deferred
- PowerPoint KB was not added because the current docs toolkit catalog
has no `powerpoint` toolkit slug/page. The KB describes a possible
future file-operations toolkit rather than an existing public toolkit
page.
---------
Co-authored-by: Sarah Simionescu <sarah@composio.dev>
Co-authored-by: Alberto Schiabel <jkomyno@users.noreply.github.com>
## Summary
Fixes `json_schema_to_model` when a top-level JSON schema omits `title`
or sets it to `null`. This is the remaining direct-helper path;
anonymous nested objects from #2435 are already handled by
`schema_converter.py`.
- falls back to `GeneratedModel` only when the title is `None`,
preserving intentionally empty string titles
- adds regression coverage for missing, `null`, and empty titles, model
construction, and required-field validation
## Validation
- `ruff format --check python/composio/utils/shared.py
python/tests/test_schema_parser.py`
- `ruff check python/composio/utils/shared.py
python/tests/test_schema_parser.py`
- `PYTHONPATH="$PWD/python"
/Users/jkomyno/work/composio/composio2/.venv/bin/pytest -q
python/tests/test_schema_parser.py`
This is a follow-up to #2435; it intentionally does not close that
already-resolved issue.
Co-authored-by: jkomyno <alberto@composio.dev>
Co-authored-by: Alberto Schiabel <jkomyno@users.noreply.github.com>
## What and why
This makes the intended v1 API cleanup real rather than postponing it to
v2:
- Remove the TypeScript root aliases `composio.create(...)` and
`composio.use(...)`. Session creation and reuse now live only at
`composio.sessions.create(...)` and `composio.sessions.use(...)`. This
is a deliberate breaking change, reflected by a major changeset.
- Retain `BaseProvider.wrapMcpServerResponse` as the stable v1 provider
SPI. Its earlier deprecation pointed to a method that was never
introduced.
The scope is intentionally narrow: it does **not** remove unrelated
deprecated APIs, and Python keeps its supported `Composio.create/use`
API. The TypeScript docs, examples, providers, runtime fixtures,
generated SDK reference, and API-reference indexes now use the
namespaced TypeScript API. Historical changelog examples are left as
history.
## Verification
- `pnpm typecheck`
- `pnpm --filter @composio/core test -- --run test/core/session.test.ts`
(42 files, 1,018 tests)
- `pnpm exec eslint ts/packages/core/src/composio.ts`
- `pnpm --filter @composio/core generate:docs`
- `cd docs && bun run generate:api-index`
- `cd docs && bun run types:check`
- `git diff --check` and targeted scans for removed TypeScript aliases
I also attempted the affected Node and Cloudflare runtime E2E suites.
They cannot initialize in this checkout without `COMPOSIO_API_KEY` (and,
for Cloudflare, `COMPOSIO_BASE_URL` and `OPENAI_API_KEY`); they did not
report a product assertion failure.
## What was wrong
The API reference docs were shipping staging URLs to users. There were
two separate leaks, both from the same source: the scheduled
`docs-update-data` workflow fetches the OpenAPI specs and toolkit data
from staging every 5 hours and auto-commits them.
The first leak was the curl base URL. `servers[0].url` in `openapi.json`
and `openapi-v3.json` rendered as `http://staging-apollo.composio.dev`
in every curl example. That is what
https://github.com/ComposioHQ/composio/pull/3761 tried to fix.
The second leak was in the toolkit data. `toolkits.json` carried 269
`https://staging-backend.composio.dev/api/v1/auth-apps/add` default
values, surfaced in the white-labeling and auth-config docs. #3761 never
touched this file.
## Which PR caused it
Karan asked on Slack whether we could pin down the PR that introduced
this. We can. It was https://github.com/ComposioHQ/composio/pull/3426
(commit `a3e58a421`, merged 2026-07-03), which flipped `servers[0].url`
from `https://backend.composio.dev` / `PRODUCTION API` to
`http://staging-apollo.composio.dev` / `STAGING API` in both specs.
It was not a hand-written change. #3426 is itself an auto-generated PR
from this same `docs-update-data` workflow, opened by
`github-actions[bot]` on the `docs/auto-update-data` branch. The
workflow fetched from staging, staging serves the staging server URL in
its spec, and the value landed in the committed files where nobody
caught it inside a large auto-generated diff. That is the reason the
real fix belongs in the generator and the workflow, not in a one-off
edit to the JSON.
## Why #3761 was not enough
#3761 pinned `spec.servers` to production inside `fetch-openapi.mjs`.
That closed the first leak, but three things stayed open.
It only covered the OpenAPI specs. The 269 staging hosts in
`toolkits.json` come from a different generator, `generate-toolkits.ts`,
and stayed live on the docs site.
It added no CI guard. The fix was a single line in a generator with
nothing asserting it. A later refactor that dropped or reordered that
line would republish staging on the next 5-hour regeneration, which is
precisely the recurring failure that produced the original report.
And it scrubbed the symptom rather than the source. The workflow kept
fetching from staging; the pin just rewrote one field afterward.
## The fix
I addressed it at four layers, so no single regression brings staging
back.
**Source.** `docs-update-data.yml` no longer overrides the base URL to
staging. The generators default to production, so the docs reflect
production.
**Generators.** The production URL now lives in one place,
`docs/scripts/production-api.mjs`. The toolkit and meta-tools generators
sanitize any staging host to production before writing, so a staging
fetch can no longer republish staging.
**Committed data.** I rewrote the 269 staging hosts already in
`toolkits.json` to production.
**Guard.** `docs/tests/static/production-urls.test.ts` asserts the
OpenAPI `servers` is production and scans both specs and every
`public/data/*.json` for any `staging-*.composio.dev` host. It is an
independent oracle: it hardcodes the expected value and deliberately
does not import the generator constants, so a wrong edit there fails CI
instead of moving both sides together. I verified it catches both the
original `staging-apollo` and the `staging-backend` leaks.
## One thing to confirm before merge
`COMPOSIO_API_KEY` is paired with `COMPOSIO_BASE_URL_STAGING` in every
other workflow, so it is most likely a staging key. If that is the case,
provision a production-capable key before the next scheduled run.
Otherwise that run fails on auth, which is loud and safe, rather than
silently republishing staging. The generator sanitizer and the guard
keep the output correct regardless of which environment the fetch hits,
so there is no risk in the interim.
## Testing
- `bun test tests/static/` passes 21 of 21 (16 existing, 5 new).
- The shared module loads and all three generators build under bun.
- No `staging-*.composio.dev` host remains under `docs/public/`.
- `docs-update-data.yml` re-validated as valid YAML.