tavus-cli 0.3.2__tar.gz → 0.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/.env.example +7 -0
  2. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/.github/workflows/ci.yml +19 -0
  3. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/.github/workflows/pr-reviews.yml +1 -1
  4. tavus_cli-0.3.3/AGENTS.md +37 -0
  5. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/PKG-INFO +65 -7
  6. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/README.md +61 -5
  7. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/docs/gemini-enterprise/README.md +48 -52
  8. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/docs/gemini-enterprise/listing.md +4 -5
  9. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/docs/gemini-enterprise/test-queries.md +12 -12
  10. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/pyproject.toml +6 -1
  11. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/skills/tavus-agentic-pals/SKILL.md +16 -23
  12. tavus_cli-0.3.3/skills/tavus-agentic-pals/references/build-and-verify.md +72 -0
  13. tavus_cli-0.3.3/skills/tavus-agentic-pals/references/builder-workflow.md +74 -0
  14. tavus_cli-0.3.3/skills/tavus-agentic-pals/references/chat-mode.md +93 -0
  15. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/__init__.py +1 -1
  16. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/cli/main.py +38 -106
  17. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/client/http.py +52 -134
  18. tavus_cli-0.3.3/src/tavus_mcp/sdk/daily_transport.py +275 -0
  19. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/env.py +24 -1
  20. tavus_cli-0.3.3/src/tavus_mcp/sdk/pal_urls.py +24 -0
  21. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/patch.py +0 -4
  22. tavus_cli-0.3.3/src/tavus_mcp/sdk/recipes/build_and_verify.py +348 -0
  23. tavus_cli-0.3.3/src/tavus_mcp/sdk/recipes/carrier_builder.py +932 -0
  24. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/schemas/pal.py +26 -4
  25. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/server.py +83 -75
  26. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/integration/test_cli.py +36 -0
  27. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/integration/test_mcp_server.py +32 -2
  28. tavus_cli-0.3.3/tests/unit/test_build_and_verify.py +552 -0
  29. tavus_cli-0.3.3/tests/unit/test_builder.py +77 -0
  30. tavus_cli-0.3.3/tests/unit/test_daily_transport.py +178 -0
  31. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_env.py +7 -0
  32. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_pal_schema.py +31 -0
  33. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_patch.py +11 -6
  34. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/uv.lock +703 -686
  35. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/workers/tavus-mcp/.dev.vars.example +1 -0
  36. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/workers/tavus-mcp/package-lock.json +18 -0
  37. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/workers/tavus-mcp/package.json +1 -0
  38. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/workers/tavus-mcp/src/index.ts +2 -0
  39. tavus_cli-0.3.3/workers/tavus-mcp/src/oauth-grant.ts +82 -0
  40. tavus_cli-0.3.3/workers/tavus-mcp/src/oauth.ts +1024 -0
  41. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/workers/tavus-mcp/src/tavus.ts +712 -29
  42. tavus_cli-0.3.3/workers/tavus-mcp/test/parity.test.ts +60 -0
  43. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/workers/tavus-mcp/test/tavus.test.ts +343 -40
  44. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/workers/tavus-mcp/tsconfig.json +1 -1
  45. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/workers/tavus-mcp/wrangler.jsonc +26 -1
  46. tavus_cli-0.3.2/skills/tavus-agentic-pals/references/build-and-verify.md +0 -183
  47. tavus_cli-0.3.2/skills/tavus-agentic-pals/references/builder-workflow.md +0 -172
  48. tavus_cli-0.3.2/skills/tavus-agentic-pals/references/chat-mode.md +0 -313
  49. tavus_cli-0.3.2/src/tavus_mcp/sdk/recipes/build_and_verify.py +0 -630
  50. tavus_cli-0.3.2/tests/unit/test_build_and_verify.py +0 -523
  51. tavus_cli-0.3.2/tests/unit/test_builder.py +0 -155
  52. tavus_cli-0.3.2/tests/unit/test_conversation_chat.py +0 -82
  53. tavus_cli-0.3.2/workers/tavus-mcp/src/oauth.ts +0 -460
  54. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/.github/workflows/deploy-cloudflare-worker.yml +0 -0
  55. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/.github/workflows/pypi-cli.yml +0 -0
  56. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/.gitignore +0 -0
  57. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/docs/usage-observability.md +0 -0
  58. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/skills/tavus-agentic-pals/agents/openai.yaml +0 -0
  59. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/skills/tavus-agentic-pals/references/examples.md +0 -0
  60. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/cli/__init__.py +0 -0
  61. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/__init__.py +0 -0
  62. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/auth/__init__.py +0 -0
  63. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/auth/keyring_store.py +0 -0
  64. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/auth/oauth.py +0 -0
  65. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/auth/session.py +0 -0
  66. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/client/__init__.py +0 -0
  67. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/errors.py +0 -0
  68. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/recipes/__init__.py +0 -0
  69. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/recipes/capabilities.py +0 -0
  70. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/recipes/knowledge.py +0 -0
  71. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/recipes/options.py +0 -0
  72. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/recipes/quickstart.py +0 -0
  73. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/recipes/scaffold_embed.py +0 -0
  74. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/recipes/templates.py +0 -0
  75. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/recipes/tool_reuse.py +0 -0
  76. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/schemas/__init__.py +0 -0
  77. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/schemas/file_manifest.py +0 -0
  78. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/schemas/guardrail.py +0 -0
  79. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/schemas/objective.py +0 -0
  80. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/schemas/pronunciation.py +0 -0
  81. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/src/tavus_mcp/sdk/schemas/tool.py +0 -0
  82. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/conftest.py +0 -0
  83. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/integration/test_client.py +0 -0
  84. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/integration/test_oauth.py +0 -0
  85. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_auth.py +0 -0
  86. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_capabilities.py +0 -0
  87. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_guardrail_schema.py +0 -0
  88. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_objective_schema.py +0 -0
  89. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_pronunciation_schema.py +0 -0
  90. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_scaffold_embed.py +0 -0
  91. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_tool_reuse.py +0 -0
  92. {tavus_cli-0.3.2 → tavus_cli-0.3.3}/tests/unit/test_tool_schema.py +0 -0
@@ -8,28 +8,35 @@
8
8
  # TAVUS_PUBLIC_API_BASE_URL=https://test.rqh.tavusapi.com/v2
9
9
  # TAVUS_PORTAL_API_BASE_URL=https://test-api.tavus.io/api
10
10
  # TAVUS_DEV_PORTAL_URL=https://dev.platform.tavus.io
11
+ # TAVUS_PAL_MAKER_URL=https://dev.maker.tavus.io
11
12
  # STG defaults:
12
13
  # TAVUS_PUBLIC_API_BASE_URL=https://stg.rqh.tavusapi.com/v2
13
14
  # TAVUS_PORTAL_API_BASE_URL=https://stg-api.tavus.io/api
14
15
  # TAVUS_DEV_PORTAL_URL=https://stage.platform.tavus.io
16
+ # TAVUS_PAL_MAKER_URL=https://stage.maker.tavus.io
15
17
  # PROD defaults:
16
18
  # TAVUS_PUBLIC_API_BASE_URL=https://tavusapi.com/v2
17
19
  # TAVUS_PORTAL_API_BASE_URL=https://prod-api.tavus.io/api
18
20
  # TAVUS_DEV_PORTAL_URL=https://platform.tavus.io
21
+ # TAVUS_PAL_MAKER_URL=https://maker.tavus.io
19
22
  TAVUS_PUBLIC_API_BASE_URL=
20
23
  TAVUS_PORTAL_API_BASE_URL=
21
24
  TAVUS_DEV_PORTAL_URL=
25
+ TAVUS_PAL_MAKER_URL=
22
26
 
23
27
  # Optional per-env overrides. These beat the defaults but not the generic vars above.
24
28
  TAVUS_TEST_PUBLIC_API_BASE_URL=
25
29
  TAVUS_TEST_PORTAL_API_BASE_URL=
26
30
  TAVUS_TEST_DEV_PORTAL_URL=
31
+ TAVUS_TEST_PAL_MAKER_URL=
27
32
  TAVUS_STG_PUBLIC_API_BASE_URL=
28
33
  TAVUS_STG_PORTAL_API_BASE_URL=
29
34
  TAVUS_STG_DEV_PORTAL_URL=
35
+ TAVUS_STG_PAL_MAKER_URL=
30
36
  TAVUS_PROD_PUBLIC_API_BASE_URL=
31
37
  TAVUS_PROD_PORTAL_API_BASE_URL=
32
38
  TAVUS_PROD_DEV_PORTAL_URL=
39
+ TAVUS_PROD_PAL_MAKER_URL=
33
40
 
34
41
  # Optional auth fallback. If set, it wins over keyring for the selected env.
35
42
  TAVUS_API_KEY=
@@ -38,3 +38,22 @@ jobs:
38
38
  run: uv run pytest -q
39
39
  - name: Build
40
40
  run: uv build
41
+
42
+ worker:
43
+ runs-on: ubuntu-latest
44
+ timeout-minutes: 10
45
+ defaults:
46
+ run:
47
+ working-directory: workers/tavus-mcp
48
+ steps:
49
+ - uses: actions/checkout@v4
50
+ - uses: actions/setup-node@v4
51
+ with:
52
+ node-version: 24
53
+ cache: npm
54
+ cache-dependency-path: workers/tavus-mcp/package-lock.json
55
+ - run: npm ci
56
+ - name: Type-check
57
+ run: npm run build
58
+ - name: Test hosted MCP and parity
59
+ run: npm test
@@ -17,7 +17,7 @@ jobs:
17
17
  uses: Tavus-Engineering/pr-changelog-action/review@main
18
18
  with:
19
19
  slack-bot-token: ${{ secrets.CVI_BOT_SLACK_TOKEN }}
20
- slack-channel-id: C0AFT2E9D5Y
20
+ slack-channel-id: C0AGPSMKQ3Z
21
21
  github-token: ${{ secrets.GITHUB_TOKEN }}
22
22
  repo: ${{ github.repository }}
23
23
  pr-number: ${{ github.event.pull_request.number }}
@@ -0,0 +1,37 @@
1
+ # Repository instructions
2
+
3
+ ## Git worktrees
4
+
5
+ - Do not create or use Git worktrees in this repository. Use the primary checkout and ordinary branches.
6
+ - If an exceptional task already uses a worktree, remove it immediately after its pull request is merged or closed.
7
+ - Before removing a worktree, verify that it has no uncommitted work and that its pull request or branch state is accounted for. After removal, prune the worktree metadata and delete the merged local branch.
8
+
9
+ ## Plain language for published writing (ISO 24495-1)
10
+
11
+ Anything an agent writes for people to read follows ISO 24495-1, the plain
12
+ language standard. That covers PR titles and descriptions, PR and review
13
+ comments, commit message bodies, release notes, Slack posts, docs, MCP tool
14
+ descriptions, and CLI help text. The standard's four principles, applied to
15
+ this repo's output:
16
+
17
+ 1. **Relevant** — decide who will read this and what they need from it, and
18
+ write only that. A reviewer needs the goal, the approach, and the risks,
19
+ not a file-by-file tour. Cut anything the reader can't act on.
20
+ 2. **Findable** — put the most important information first. Use informative
21
+ headings and short paragraphs so the reader can scan. One idea per
22
+ paragraph. In a PR body, the first sentence says what the change does and
23
+ why.
24
+ 3. **Understandable** — short sentences, active voice, everyday words. Expand
25
+ project shorthand (RQH, CVI, PAL, carrier) on first use unless every
26
+ reader shares it. Use one term per concept; don't alternate between
27
+ synonyms.
28
+ 4. **Usable** — the reader should know what to do after reading: what to
29
+ review, what to decide, what to verify. When there's an action, state it
30
+ explicitly.
31
+
32
+ Write like a person. Skip AI-tell words ("delve", "comprehensive",
33
+ "leverage"), filler openings ("This PR aims to..."), and dense em-dash or
34
+ arrow-chain shorthand where a full sentence is clearer.
35
+
36
+ MCP tool descriptions and CLI `--help` text ship to end users; hold them to
37
+ the same standard as any other published writing.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: tavus-cli
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Tavus CLI and MCP server for agentic PAL creation and editing.
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: fastmcp>=2.0.0
@@ -11,6 +11,8 @@ Requires-Dist: pydantic>=2.7.0
11
11
  Requires-Dist: python-dotenv>=1.0.0
12
12
  Requires-Dist: rich>=13.7.0
13
13
  Requires-Dist: typer>=0.12.0
14
+ Provides-Extra: daily
15
+ Requires-Dist: daily-python>=0.31.0; extra == 'daily'
14
16
  Provides-Extra: dev
15
17
  Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
16
18
  Requires-Dist: pytest>=8.2.0; extra == 'dev'
@@ -38,9 +40,9 @@ The PAL Maker project is the **human** builder — face-driven, in-product. This
38
40
 
39
41
  ## Out of scope (for now)
40
42
 
41
- - Face/video preview surfaces (live in the PAL Maker)
42
43
  - Marketplace / sharing UX
43
44
  - Multi-tenant auth beyond the existing dev-portal token model
45
+ - Deploying customer applications or infrastructure
44
46
 
45
47
  ## Local Setup
46
48
 
@@ -68,6 +70,11 @@ TAVUS_ENV=TEST TAVUS_API_KEY=... uv run tavus pal list
68
70
  uv run tavus --env TEST pal list
69
71
  ```
70
72
 
73
+ PAL creation responses include `pal_url`, a direct link to the matching
74
+ `dev.maker.tavus.io`, `stage.maker.tavus.io`, or `maker.tavus.io` editor.
75
+ Set `TAVUS_PAL_MAKER_URL` (or its environment-specific variant) only when a
76
+ custom PAL Maker deployment should override that default.
77
+
71
78
  The login flow opens the dev-portal at `/dev/cli-authorize` with a loopback callback URL and an
72
79
  anti-CSRF state. The dev-portal mints an API key for your signed-in user (tagged `source: cli`) and
73
80
  POSTs it back to the loopback receiver. The CLI stores that key in the OS keychain under the
@@ -132,6 +139,14 @@ requires `TAVUS_PORTAL_BEARER_TOKEN`. PAL Knowledge attachment uses
132
139
 
133
140
  MCP tools return data and file manifests. They do not write files.
134
141
 
142
+ Full-pipeline PAL creation defaults to `tavus-gemma-4` with speculative
143
+ inference enabled. Tools are first-class
144
+ `/v2/tools` resources and attach through top-level `tool_ids` or
145
+ `tavus_pal_tools_attach`; inline `layers.llm.tools` and perception tool arrays
146
+ are not accepted by the MCP or CLI. `tavus_voice_list` exposes new stock Voice
147
+ releases directly instead of requiring callers to discover the generic
148
+ `tavus_resource_list` form.
149
+
135
150
  ## Cloudflare Worker
136
151
 
137
152
  The remote MCP server lives in `workers/tavus-mcp/` and uses Cloudflare's
@@ -159,12 +174,24 @@ Claude Code example:
159
174
  claude mcp add -s user --transport http tavus https://mcp.tavus.io/mcp
160
175
  ```
161
176
 
177
+ Claude.ai and ChatGPT custom connectors use the same URL:
178
+ `https://mcp.tavus.io/mcp`. Their remote HTTPS OAuth callback URLs are accepted
179
+ through dynamic client registration. The Worker accepts only the documented
180
+ Claude and ChatGPT callback shapes; other hosted clients must be explicitly
181
+ registered with `MCP_OAUTH_CLIENTS`. No manually copied OAuth client ID is
182
+ required for Claude or ChatGPT.
183
+
162
184
  The OAuth authorize step redirects to Tavus developer portal
163
185
  `/dev/cli-authorize?mode=oauth`. After the user signs in, the portal mints a
164
- per-user Tavus API key and redirects back to the MCP client's loopback callback.
165
- The Worker exchanges that code for an MCP bearer token, then forwards the bearer
166
- to RQH as `x-api-key`. This keeps Tavus API keys user-scoped and out of MCP
167
- client configuration.
186
+ per-user Tavus API key and returns it to the Worker's trusted
187
+ `/oauth/callback`. The Worker issues an opaque, short-lived authorization code,
188
+ verifies PKCE plus the client, redirect, and MCP resource at `/token`, then
189
+ forwards the resulting bearer to RQH as `x-api-key`. This keeps Tavus API keys
190
+ user-scoped and out of MCP client configuration and browser callback URLs.
191
+ The portal first verifies the Worker's signed request, posts the API key only to
192
+ the callback for the matching environment, and shows the final connector
193
+ destination before the user authorizes it. A SQLite-backed Durable Object makes
194
+ both the authorization request and code one-time to prevent replay.
168
195
 
169
196
  Developer portal must support the `mode=oauth` authorize flow for remote MCP
170
197
  auth to complete. If a local portal is running on port 3000, test the full
@@ -192,6 +219,17 @@ Worker runtime secrets, such as the legacy `TAVUS_API_KEY` or
192
219
  `wrangler secret put <NAME> --env <environment>`. They persist across deploys;
193
220
  the GitHub workflow does not read or overwrite them.
194
221
 
222
+ Remote OAuth also requires a random secret of at least 32 characters in every
223
+ deployed Worker environment:
224
+
225
+ ```bash
226
+ npx wrangler secret put MCP_OAUTH_SIGNING_SECRET --env stg
227
+ npx wrangler secret put MCP_OAUTH_SIGNING_SECRET --env prod
228
+ ```
229
+
230
+ Use different values in staging and production. Do not store either value in
231
+ Git or a Wrangler vars block.
232
+
195
233
  Merges to `main` automatically run the `Deploy Tavus MCP Worker` workflow for
196
234
  `prod`. You can also run the workflow manually for `test`, `stg`, or `prod`.
197
235
  The public MCP endpoint is always `https://mcp.tavus.io/mcp`. The
@@ -220,6 +258,26 @@ points at the protected-resource metadata URL. A `404 Not Found` at discovery
220
258
  usually means the Worker version serving the custom domain does not include the
221
259
  OAuth routes yet.
222
260
 
261
+ ### Keeping local and hosted MCP current
262
+
263
+ Every remotely usable Tavus feature must be added to the Python MCP/CLI and the
264
+ hosted Worker in the same change. The Worker parity test compares both tool
265
+ manifests and fails CI when a new difference is not explicitly classified.
266
+ Local-file uploads and the legacy Builder flow are the current documented
267
+ exceptions.
268
+
269
+ For each feature release:
270
+
271
+ 1. Add or update the local SDK/MCP/CLI contract and the hosted Worker tool.
272
+ 2. Add schema and transport tests, including the hosted tool name in the parity
273
+ test automatically by registering it in `tavus.ts`.
274
+ 3. Run `uv run ruff check .`, `uv run pytest -q`, `npm run build`, and
275
+ `npm test`. CI runs both Python and Worker suites on every PR.
276
+ 4. Deploy and test `mcp.tavus-preview.io/mcp` first, including a real connector
277
+ OAuth login and the feature's write/read/cleanup cycle.
278
+ 5. Merge to deploy production, then repeat the connector and MCP tool smoke test
279
+ at `mcp.tavus.io/mcp`.
280
+
223
281
  ## Codex Skill
224
282
 
225
283
  A publishable Codex skill for this repo lives at `skills/tavus-agentic-pals/`.
@@ -18,9 +18,9 @@ The PAL Maker project is the **human** builder — face-driven, in-product. This
18
18
 
19
19
  ## Out of scope (for now)
20
20
 
21
- - Face/video preview surfaces (live in the PAL Maker)
22
21
  - Marketplace / sharing UX
23
22
  - Multi-tenant auth beyond the existing dev-portal token model
23
+ - Deploying customer applications or infrastructure
24
24
 
25
25
  ## Local Setup
26
26
 
@@ -48,6 +48,11 @@ TAVUS_ENV=TEST TAVUS_API_KEY=... uv run tavus pal list
48
48
  uv run tavus --env TEST pal list
49
49
  ```
50
50
 
51
+ PAL creation responses include `pal_url`, a direct link to the matching
52
+ `dev.maker.tavus.io`, `stage.maker.tavus.io`, or `maker.tavus.io` editor.
53
+ Set `TAVUS_PAL_MAKER_URL` (or its environment-specific variant) only when a
54
+ custom PAL Maker deployment should override that default.
55
+
51
56
  The login flow opens the dev-portal at `/dev/cli-authorize` with a loopback callback URL and an
52
57
  anti-CSRF state. The dev-portal mints an API key for your signed-in user (tagged `source: cli`) and
53
58
  POSTs it back to the loopback receiver. The CLI stores that key in the OS keychain under the
@@ -112,6 +117,14 @@ requires `TAVUS_PORTAL_BEARER_TOKEN`. PAL Knowledge attachment uses
112
117
 
113
118
  MCP tools return data and file manifests. They do not write files.
114
119
 
120
+ Full-pipeline PAL creation defaults to `tavus-gemma-4` with speculative
121
+ inference enabled. Tools are first-class
122
+ `/v2/tools` resources and attach through top-level `tool_ids` or
123
+ `tavus_pal_tools_attach`; inline `layers.llm.tools` and perception tool arrays
124
+ are not accepted by the MCP or CLI. `tavus_voice_list` exposes new stock Voice
125
+ releases directly instead of requiring callers to discover the generic
126
+ `tavus_resource_list` form.
127
+
115
128
  ## Cloudflare Worker
116
129
 
117
130
  The remote MCP server lives in `workers/tavus-mcp/` and uses Cloudflare's
@@ -139,12 +152,24 @@ Claude Code example:
139
152
  claude mcp add -s user --transport http tavus https://mcp.tavus.io/mcp
140
153
  ```
141
154
 
155
+ Claude.ai and ChatGPT custom connectors use the same URL:
156
+ `https://mcp.tavus.io/mcp`. Their remote HTTPS OAuth callback URLs are accepted
157
+ through dynamic client registration. The Worker accepts only the documented
158
+ Claude and ChatGPT callback shapes; other hosted clients must be explicitly
159
+ registered with `MCP_OAUTH_CLIENTS`. No manually copied OAuth client ID is
160
+ required for Claude or ChatGPT.
161
+
142
162
  The OAuth authorize step redirects to Tavus developer portal
143
163
  `/dev/cli-authorize?mode=oauth`. After the user signs in, the portal mints a
144
- per-user Tavus API key and redirects back to the MCP client's loopback callback.
145
- The Worker exchanges that code for an MCP bearer token, then forwards the bearer
146
- to RQH as `x-api-key`. This keeps Tavus API keys user-scoped and out of MCP
147
- client configuration.
164
+ per-user Tavus API key and returns it to the Worker's trusted
165
+ `/oauth/callback`. The Worker issues an opaque, short-lived authorization code,
166
+ verifies PKCE plus the client, redirect, and MCP resource at `/token`, then
167
+ forwards the resulting bearer to RQH as `x-api-key`. This keeps Tavus API keys
168
+ user-scoped and out of MCP client configuration and browser callback URLs.
169
+ The portal first verifies the Worker's signed request, posts the API key only to
170
+ the callback for the matching environment, and shows the final connector
171
+ destination before the user authorizes it. A SQLite-backed Durable Object makes
172
+ both the authorization request and code one-time to prevent replay.
148
173
 
149
174
  Developer portal must support the `mode=oauth` authorize flow for remote MCP
150
175
  auth to complete. If a local portal is running on port 3000, test the full
@@ -172,6 +197,17 @@ Worker runtime secrets, such as the legacy `TAVUS_API_KEY` or
172
197
  `wrangler secret put <NAME> --env <environment>`. They persist across deploys;
173
198
  the GitHub workflow does not read or overwrite them.
174
199
 
200
+ Remote OAuth also requires a random secret of at least 32 characters in every
201
+ deployed Worker environment:
202
+
203
+ ```bash
204
+ npx wrangler secret put MCP_OAUTH_SIGNING_SECRET --env stg
205
+ npx wrangler secret put MCP_OAUTH_SIGNING_SECRET --env prod
206
+ ```
207
+
208
+ Use different values in staging and production. Do not store either value in
209
+ Git or a Wrangler vars block.
210
+
175
211
  Merges to `main` automatically run the `Deploy Tavus MCP Worker` workflow for
176
212
  `prod`. You can also run the workflow manually for `test`, `stg`, or `prod`.
177
213
  The public MCP endpoint is always `https://mcp.tavus.io/mcp`. The
@@ -200,6 +236,26 @@ points at the protected-resource metadata URL. A `404 Not Found` at discovery
200
236
  usually means the Worker version serving the custom domain does not include the
201
237
  OAuth routes yet.
202
238
 
239
+ ### Keeping local and hosted MCP current
240
+
241
+ Every remotely usable Tavus feature must be added to the Python MCP/CLI and the
242
+ hosted Worker in the same change. The Worker parity test compares both tool
243
+ manifests and fails CI when a new difference is not explicitly classified.
244
+ Local-file uploads and the legacy Builder flow are the current documented
245
+ exceptions.
246
+
247
+ For each feature release:
248
+
249
+ 1. Add or update the local SDK/MCP/CLI contract and the hosted Worker tool.
250
+ 2. Add schema and transport tests, including the hosted tool name in the parity
251
+ test automatically by registering it in `tavus.ts`.
252
+ 3. Run `uv run ruff check .`, `uv run pytest -q`, `npm run build`, and
253
+ `npm test`. CI runs both Python and Worker suites on every PR.
254
+ 4. Deploy and test `mcp.tavus-preview.io/mcp` first, including a real connector
255
+ OAuth login and the feature's write/read/cleanup cycle.
256
+ 5. Merge to deploy production, then repeat the connector and MCP tool smoke test
257
+ at `mcp.tavus.io/mcp`.
258
+
203
259
  ## Codex Skill
204
260
 
205
261
  A publishable Codex skill for this repo lives at `skills/tavus-agentic-pals/`.
@@ -2,7 +2,7 @@
2
2
 
3
3
  This document is the public reference Google's Gemini Enterprise team uses to
4
4
  review and register the Tavus MCP server as a managed connector. It covers the
5
- server URL, OAuth metadata, scope-to-tool map, and the step-by-step admin
5
+ server URL, OAuth metadata, access model, and the step-by-step admin
6
6
  workflow for adding Tavus to a Gemini Enterprise instance.
7
7
 
8
8
  ## At a glance
@@ -42,35 +42,33 @@ returns:
42
42
  "client_secret_post",
43
43
  "client_secret_basic"
44
44
  ],
45
- "scopes_supported": [
46
- "tavus",
47
- "tavus.personas.read",
48
- "tavus.personas.write",
49
- "tavus.conversations.read",
50
- "tavus.conversations.write",
51
- "tavus.resources.read"
52
- ]
45
+ "scopes_supported": ["tavus"]
53
46
  }
54
47
  ```
55
48
 
56
49
  The authorize endpoint redirects the user's browser to
57
50
  `https://platform.tavus.io/dev/cli-authorize?mode=oauth`. Tavus authenticates
58
51
  the user (Google SSO or email/password), mints a user-scoped Tavus API key
59
- tagged `source: cli`, and redirects back to the registered `redirect_uri`. The
60
- token endpoint then exchanges that code for a bearer token the MCP client
61
- sends as `Authorization: Bearer …` on every `/mcp` call.
52
+ tagged `source: cli`, and returns to the trusted Worker callback. The Worker
53
+ redirects an opaque, short-lived code to the registered client. The token
54
+ endpoint verifies PKCE, client, redirect URI, and MCP resource before returning
55
+ a bearer token the MCP client sends as `Authorization: Bearer …` on every
56
+ `/mcp` call.
62
57
 
63
- ## Manual OAuth client registration
58
+ ## OAuth client registration
64
59
 
65
- Gemini Enterprise cannot use the loopback Dynamic Client Registration path
66
- that local IDE clients use. Send the following to
67
- [mcp-connectors@tavus.io](mailto:mcp-connectors@tavus.io) and Tavus will mint a
68
- pre-registered client for the requested environments:
60
+ The Dynamic Client Registration endpoint accepts the documented Claude and
61
+ ChatGPT HTTPS callback shapes plus local loopback callbacks. Gemini uses an
62
+ explicitly registered client with exact redirect URIs. Use
63
+ `token_endpoint_auth_method=none` when Gemini supports it.
64
+
65
+ If Gemini requires a confidential static client, send the following to
66
+ [mcp-connectors@tavus.io](mailto:mcp-connectors@tavus.io):
69
67
 
70
68
  - Display name (shown on the consent screen)
71
69
  - Redirect URI(s) — exact match enforced
72
70
  - Whether you want a `client_secret` (recommended)
73
- - Required scopes (see table below)
71
+ - Required scope (`tavus`)
74
72
  - Target environment(s) — `test`, `stg`, `prod`
75
73
 
76
74
  Tavus returns:
@@ -82,42 +80,36 @@ Tavus returns:
82
80
  The credentials are scoped per environment; production keys are issued only
83
81
  after the connector passes Gemini Enterprise's review in `stg`.
84
82
 
85
- ## Scopes
83
+ ## Scope
86
84
 
87
- > **Naming note.** Tools and API paths use the new **pal/face** vocabulary
88
- > (`tavus_pal_*`, `/v2/pals`, `/v2/faces`). The OAuth **scope** strings remain
89
- > `tavus.personas.*` / `tavus.resources.*` — they are an auth-server contract and
90
- > are intentionally left unchanged until the auth team confirms pal-named scopes.
85
+ The connector currently exposes one honest umbrella scope because its bearer
86
+ credential is a Tavus API key. It does not advertise granular scopes that the
87
+ API key cannot enforce.
91
88
 
92
89
  | Scope | Grants |
93
90
  | --- | --- |
94
- | `tavus` | All scopes below (umbrella; default when no scope requested) |
95
- | `tavus.personas.read` | List, get, and describe pals + attached resources |
96
- | `tavus.personas.write` | Create, patch, delete pals; create from templates |
97
- | `tavus.conversations.read` | (Reserved — read-only conversation tools land in a follow-up) |
98
- | `tavus.conversations.write` | Create + end conversations; run `tavus_quickstart` |
99
- | `tavus.resources.read` | List faces, voices, guardrails, objectives, documents, llm tools; scaffold embed code |
91
+ | `tavus` | All Tavus MCP tools; default when no scope is requested |
100
92
 
101
- ## Tools → scope → API
93
+ ## Tools → API
102
94
 
103
95
  All tools call `https://tavusapi.com/v2/*` with the per-user `x-api-key`
104
96
  forwarded from the bearer token.
105
97
 
106
- | Tool | Scope | Tavus API path |
107
- | --- | --- | --- |
108
- | `tavus_pal_list` | `tavus.personas.read` | `GET /v2/pals` |
109
- | `tavus_pal_get` | `tavus.personas.read` | `GET /v2/pals/{id}` |
110
- | `tavus_describe_pal_options` | `tavus.personas.read` | `GET /v2/pals/{id}` + `GET /v2/{faces,voices,guardrails,objectives,documents,tools}` |
111
- | `tavus_pal_create` | `tavus.personas.write` | `POST /v2/pals` |
112
- | `tavus_pal_from_template` | `tavus.personas.write` | `POST /v2/pals` |
113
- | `tavus_pal_delete` | `tavus.personas.write` | `DELETE /v2/pals/{id}` |
114
- | `tavus_patch_pal` | `tavus.personas.write` | `PATCH /v2/pals/{id}` |
115
- | `tavus_conversation_create` | `tavus.conversations.write` | `POST /v2/conversations` |
116
- | `tavus_conversation_end` | `tavus.conversations.write` | `POST /v2/conversations/{id}/end` |
117
- | `tavus_quickstart` | `tavus.conversations.write` (+ implicit `tavus.personas.write`) | `POST /v2/pals` + `POST /v2/conversations` |
118
- | `tavus_face_list` | `tavus.resources.read` | `GET /v2/faces` |
119
- | `tavus_resource_list` | `tavus.resources.read` | `GET /v2/{guardrails,objectives,documents,voices,tools}` |
120
- | `tavus_scaffold_embed` | `tavus.resources.read` | none (returns starter HTML/TSX locally) |
98
+ | Tool | Tavus API path |
99
+ | --- | --- |
100
+ | `tavus_pal_list` | `GET /v2/pals` |
101
+ | `tavus_pal_get` | `GET /v2/pals/{id}` |
102
+ | `tavus_describe_pal_options` | `GET /v2/pals/{id}` + `GET /v2/{faces,voices,guardrails,objectives,documents,tools}` |
103
+ | `tavus_pal_create` | `POST /v2/pals` |
104
+ | `tavus_pal_from_template` | `POST /v2/pals` |
105
+ | `tavus_pal_delete` | `DELETE /v2/pals/{id}` |
106
+ | `tavus_patch_pal` | `PATCH /v2/pals/{id}` |
107
+ | `tavus_conversation_create` | `POST /v2/conversations` |
108
+ | `tavus_conversation_end` | `POST /v2/conversations/{id}/end` |
109
+ | `tavus_quickstart` | `POST /v2/pals` + `POST /v2/conversations` |
110
+ | `tavus_face_list` | `GET /v2/faces` |
111
+ | `tavus_resource_list` | `GET /v2/{guardrails,objectives,documents,voices,tools}` |
112
+ | `tavus_scaffold_embed` | none (returns starter HTML/TSX locally) |
121
113
 
122
114
  ## Tool annotations
123
115
 
@@ -142,8 +134,7 @@ pal or conversation ID.
142
134
  - **Auth type:** OAuth 2 / 3LO
143
135
  - **Client ID / Client secret:** the values Tavus issued in
144
136
  [Manual OAuth client registration](#manual-oauth-client-registration).
145
- - **Scopes:** start with `tavus.personas.read tavus.conversations.write`
146
- and add more as needed.
137
+ - **Scope:** `tavus`
147
138
  3. Run the **Test connection** flow. Gemini Enterprise will:
148
139
  1. `GET /.well-known/oauth-protected-resource/mcp`
149
140
  2. `GET /.well-known/oauth-authorization-server`
@@ -161,11 +152,16 @@ Public documentation and customer integrations must use only
161
152
  credentials privately for connector certification; they are not production
162
153
  mirrors or customer-facing fallbacks.
163
154
 
164
- | Env | MCP access | API base | Dev portal | Test account |
165
- | --- | --- | --- | --- | --- |
166
- | Test | provided privately | `https://test.rqh.tavusapi.com/v2` | `https://dev.platform.tavus.io` | provided privately |
167
- | Staging | provided privately | `https://stg.rqh.tavusapi.com/v2` | `https://stage.platform.tavus.io` | provided privately |
168
- | Production | `https://mcp.tavus.io/mcp` | `https://tavusapi.com/v2` | `https://platform.tavus.io` | provided privately |
155
+ | Env | MCP access | API base | Dev portal | PAL Maker | Test account |
156
+ | --- | --- | --- | --- | --- | --- |
157
+ | Test | provided privately | `https://test.rqh.tavusapi.com/v2` | `https://dev.platform.tavus.io` | `https://dev.maker.tavus.io` | provided privately |
158
+ | Staging | provided privately | `https://stg.rqh.tavusapi.com/v2` | `https://stage.platform.tavus.io` | `https://stage.maker.tavus.io` | provided privately |
159
+ | Production | `https://mcp.tavus.io/mcp` | `https://tavusapi.com/v2` | `https://platform.tavus.io` | `https://maker.tavus.io` | provided privately |
160
+
161
+ The hosted staging Worker overrides its PAL Maker link to
162
+ `https://maker.tavus.io` because its PALs are edited in the production PAL
163
+ Maker. Local staging configurations keep the `stage.maker.tavus.io` default
164
+ unless `TAVUS_PAL_MAKER_URL` overrides it.
169
165
 
170
166
  Each env has a dedicated `gemini-enterprise-test@tavus.io` account pre-seeded
171
167
  with eval pals, faces, and documents. Credentials and the golden query
@@ -20,9 +20,8 @@ intake. Edit here; ship the final values to the Gemini Enterprise admin.
20
20
  > a conversation," "rename pal X and swap its face," "list all pals
21
21
  > tagged as customer-support and end any active conversations on them," or
22
22
  > "scaffold the React snippet I need to embed conversation Y in our portal."
23
- > Every write tool declares a destructive hint, every read tool declares a
24
- > read-only hint, and OAuth scopes are split per resource group so admins can
25
- > consent to exactly what they need.
23
+ > Every write tool declares a destructive hint and every read tool declares a
24
+ > read-only hint. The current `tavus` OAuth scope grants the full connector.
26
25
 
27
26
  ## Connector identity
28
27
 
@@ -39,13 +38,13 @@ intake. Edit here; ship the final values to the Gemini Enterprise admin.
39
38
 
40
39
  | Field | Value |
41
40
  | --- | --- |
42
- | OAuth client type | Confidential (`client_secret_post` + PKCE S256). Public client (`none` + PKCE) is supported for loopback/IDE clients only. |
41
+ | OAuth client type | Public DCR (`none` + PKCE S256) supports approved Claude/ChatGPT HTTPS callbacks and loopback callbacks. Confidential static clients (`client_secret_post` + PKCE) support explicitly registered redirect URIs. |
43
42
  | Authorization endpoint | `https://mcp.tavus.io/authorize` |
44
43
  | Token endpoint | `https://mcp.tavus.io/token` |
45
44
  | Discovery (protected resource) | `https://mcp.tavus.io/.well-known/oauth-protected-resource/mcp` |
46
45
  | Discovery (authorization server) | `https://mcp.tavus.io/.well-known/oauth-authorization-server` |
47
46
  | Default scope | `tavus` |
48
- | Granular scopes | `tavus.personas.read`, `tavus.personas.write`, `tavus.conversations.read`, `tavus.conversations.write`, `tavus.resources.read` |
47
+ | Granular scopes | Not advertised; the Tavus API key currently grants the full connector |
49
48
 
50
49
  ## Test credentials (delivered out-of-band)
51
50
 
@@ -20,18 +20,18 @@ Credentials and exact pal/face IDs are delivered out-of-band per
20
20
 
21
21
  | # | Query intent | Tool exercised | Scope required |
22
22
  | --- | --- | --- | --- |
23
- | 1 | List pals | `tavus_pal_list` | `tavus.personas.read` |
24
- | 2 | Get a pal | `tavus_pal_get` | `tavus.personas.read` |
25
- | 3 | Describe pal options | `tavus_describe_pal_options` | `tavus.personas.read` |
26
- | 4 | Create a pal | `tavus_pal_create` | `tavus.personas.write` |
27
- | 5 | Create pal from template | `tavus_pal_from_template` | `tavus.personas.write` |
28
- | 6 | Patch a pal | `tavus_patch_pal` | `tavus.personas.write` |
29
- | 7 | Delete a pal | `tavus_pal_delete` | `tavus.personas.write` |
30
- | 8 | List faces | `tavus_face_list` | `tavus.resources.read` |
31
- | 9 | List voices | `tavus_resource_list` | `tavus.resources.read` |
32
- | 10 | Scaffold embed code | `tavus_scaffold_embed` | `tavus.resources.read` |
33
- | 11 | Quickstart end-to-end | `tavus_quickstart` | `tavus.personas.write` + `tavus.conversations.write` |
34
- | 12 | Create + end a conversation | `tavus_conversation_create`, `tavus_conversation_end` | `tavus.conversations.write` |
23
+ | 1 | List pals | `tavus_pal_list` | `tavus` |
24
+ | 2 | Get a pal | `tavus_pal_get` | `tavus` |
25
+ | 3 | Describe pal options | `tavus_describe_pal_options` | `tavus` |
26
+ | 4 | Create a pal | `tavus_pal_create` | `tavus` |
27
+ | 5 | Create pal from template | `tavus_pal_from_template` | `tavus` |
28
+ | 6 | Patch a pal | `tavus_patch_pal` | `tavus` |
29
+ | 7 | Delete a pal | `tavus_pal_delete` | `tavus` |
30
+ | 8 | List faces | `tavus_face_list` | `tavus` |
31
+ | 9 | List voices | `tavus_resource_list` | `tavus` |
32
+ | 10 | Scaffold embed code | `tavus_scaffold_embed` | `tavus` |
33
+ | 11 | Quickstart end-to-end | `tavus_quickstart` | `tavus` |
34
+ | 12 | Create + end a conversation | `tavus_conversation_create`, `tavus_conversation_end` | `tavus` |
35
35
 
36
36
  ## Queries
37
37
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tavus-cli"
3
- version = "0.3.2"
3
+ version = "0.3.3"
4
4
  description = "Tavus CLI and MCP server for agentic PAL creation and editing."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -16,6 +16,11 @@ dependencies = [
16
16
  ]
17
17
 
18
18
  [project.optional-dependencies]
19
+ # Direct CVI transport (Daily room join). Optional because daily-python
20
+ # ships native wheels for macOS/Linux only.
21
+ daily = [
22
+ "daily-python>=0.31.0",
23
+ ]
19
24
  dev = [
20
25
  "pytest>=8.2.0",
21
26
  "pytest-asyncio>=0.23.0",