Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 32 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
- run: uv tool install poethepoet
- run: uv sync --all-extras
- run: uv sync
- run: poe bridge-lint
if: ${{ matrix.clippyLinter }}
- run: poe build-develop
Expand All @@ -73,14 +73,6 @@ jobs:
timeout-minutes: 10
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- name: "Upload junit-xml artifacts"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
if: always()
with:
name: junit-xml--${{github.run_id}}--${{github.run_attempt}}--${{ matrix.python }}--${{ matrix.os }}
path: junit-xml
retention-days: 14

# Do docs stuff (only on one host)
- name: Build API docs
if: ${{ matrix.docsTarget }}
Expand All @@ -100,6 +92,31 @@ jobs:
npx doctoc README.md
[[ -z $(git status --porcelain README.md) ]] || (git diff README.md; echo "README changed"; exit 1)

# Poe syncs these MCP v1 integrations into their own environment, leaving
# the default MCP v2 environment intact.
- name: Type-check MCP v1 integrations
if: ${{ matrix.docsTarget }}
run: poe lint-types-mcp-v1
- name: Test MCP v1 integrations
if: ${{ matrix.docsTarget }}
run: >-
poe test-mcp-v1 -s tests/contrib/google_adk_agents
tests/contrib/google_genai tests/contrib/strands
--junit-xml=junit-xml/mcp-v1-integrations.xml
- name: Test deprecated OpenAI MCP APIs with MCP v1
if: ${{ matrix.docsTarget }}
run: >-
poe test-mcp-v1 -s tests/contrib/openai_agents/test_openai.py
-m mcp_v1 --junit-xml=junit-xml/openai-mcp-v1.xml

- name: "Upload junit-xml artifacts"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
if: always()
with:
name: junit-xml--${{github.run_id}}--${{github.run_attempt}}--${{ matrix.python }}--${{ matrix.os }}
path: junit-xml
retention-days: 14

# Verify the optional FIPS build: the Rust core must link aws-lc-fips-sys
# (aws-lc-rs FIPS mode) and must NOT link `ring` (the cargo-tree guard, ported
# from sdk-ruby PR #466's `fips_tree` guard); then run the test suite against the
Expand Down Expand Up @@ -160,7 +177,7 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
- run: uv tool install poethepoet
- run: uv sync --all-extras
- run: uv sync
# Develop build so the FIPS extension is importable, then run the suite
# against it to confirm the aws-lc-rs stack works end to end (not just links).
- run: poe build-develop-fips
Expand Down Expand Up @@ -202,7 +219,7 @@ jobs:
with:
python-version: "3.14"
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
- run: uv sync --all-extras
- run: uv sync
- name: Build Alpine wheel
run: uv run cibuildwheel --output-dir dist
env:
Expand Down Expand Up @@ -235,9 +252,9 @@ jobs:
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
- run: uv tool install poethepoet
- run: uv remove google-adk --optional google-adk
- run: uv add --dev --python 3.10 "googleapis-common-protos==1.70.0"
- run: uv add --group dev-common --python 3.10 "googleapis-common-protos==1.70.0"
- run: uv add --python 3.10 "protobuf<4"
- run: uv sync --all-extras
- run: uv sync
- run: cargo install --locked nexgen --version 0.2.2 --features advanced --force
- run: poe build-develop
- run: poe gen-protos
Expand Down Expand Up @@ -274,7 +291,7 @@ jobs:
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
- run: uv tool install poethepoet
- run: uv lock --upgrade
- run: uv sync --all-extras
- run: uv sync
- run: poe build-develop
- run: poe lint
- run: mkdir junit-xml
Expand Down Expand Up @@ -312,7 +329,7 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
- run: uv tool install poethepoet
- run: uv sync --all-extras
- run: uv sync
- run: poe build-develop
- name: Generate Cloud test certificates
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
workspaces: temporalio/bridge -> target
key: ${{ env.pythonLocation }}
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
- run: uv sync --all-extras
- run: uv sync

# Add the source dist only for Linux x64 for now
- if: ${{ matrix.package-suffix == 'linux-amd64' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-bench.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
# Build
- run: uv tool install poethepoet
- run: uv sync --all-extras
- run: uv sync
- run: poe build-develop-with-release

# Run a bunch of bench tests. We run multiple times since results vary.
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.venv
.venv-*
__pycache__
/build
/dist
Expand Down
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ document as a quick reference when submitting pull requests.
The common local commands are:

```bash
uv sync --all-extras
uv sync
poe build-develop
poe lint
poe test
Expand All @@ -63,6 +63,7 @@ For focused iteration, prefer:

```bash
poe test -s -k <test_or_pattern>
poe test-mcp-v1 -s <google_adk_or_strands_test>
uv run pytest tests/path/test_file.py::test_name
```

Expand Down
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,49 @@ to include examples, links to docs, or any other relevant information.

### Added

- Added an `mcp` extra pinning MCP Python SDK v2, for use alongside the
`openai-agents` extra.
- Added experimental `temporalio.contrib.mcp.MCPPlugin` and
`TemporalMCPClient` for using stdio, streamable HTTP, in-process, and custom
MCP Python SDK v2 clients from native workflow code. Tools, prompts, and
resources run durably through Activities, with fully paginated list results
and replay-safe tool discovery caching.

### Changed

- `OpenAIAgentsPlugin` now accepts named OpenAI `MCPServer` factories through
`mcp_servers`, and `workflow.temporal_mcp_server()` proxies them durably from
workflow code. Each MCP operation runs as an Activity, list operations are
fully paginated, and tool discovery is cached by default. The servers keep
their OpenAI-specific configuration. Parameterless modern connections are
reused for up to five idle minutes by default.

### Deprecated

- Deprecated the OpenAI Agents integration's legacy
`StatelessMCPServerProvider`, `StatefulMCPServerProvider`,
`workflow.stateless_mcp_server()`, `workflow.stateful_mcp_server()`, and
`mcp_server_providers` plugin option. They remain available for source and
workflow-history compatibility; use `mcp_servers` with
`workflow.temporal_mcp_server()` for new integrations.

### :boom: Breaking Changes

- The OpenAI Agents integration now requires `openai-agents>=0.20,<0.21`. Its
deprecated provider APIs continue to work with MCP v1, while the new
`mcp_servers` API requires MCP v2. Existing Activity history contracts remain
supported.
- MCP v1 and MCP v2 cannot coexist in one environment, so the `mcp` extra cannot
be installed alongside the extras that require MCP v1. Resolution fails for
`uv add "temporalio[mcp,google-adk]"` and for
`uv add "temporalio[mcp,strands-agents]"`; install those integrations in
separate environments.

### Fixed

- The `Worker` async context manager now waits for plugin run-context cleanup
after worker shutdown instead of cancelling it.

### Security

## [1.32.0] - 2026-08-24
Expand Down
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2044,7 +2044,7 @@ cd sdk-python
Install the dependencies:

```bash
uv sync --all-extras
uv sync
```

#### Build
Expand Down Expand Up @@ -2167,7 +2167,7 @@ installing dependencies:
```bash
git clone --recursive https://github.com/temporalio/sdk-python.git
cd sdk-python
uv sync --all-extras
uv sync
```

Now compile the Rust extension in develop mode which is quicker than release mode:
Expand Down Expand Up @@ -2200,6 +2200,17 @@ To execute a single test:
poe test -s --log-cli-level=DEBUG -k test_sync_activity_thread_cancel_caught
```

The default development environment uses MCP v2. Google ADK and Strands tests use
MCP v1 in a separate `.venv-mcp-v1` environment, which Poe creates and updates
automatically:

```bash
poe test-mcp-v1 -s tests/contrib/google_adk_agents tests/contrib/strands
```

Run `poe sync-mcp-v1` separately when an editor or another tool needs the MCP v1
environment without running tests.

**Temporal Server**

- Tests that use the workflow test environment run against the [Temporal CLI dev server](https://docs.temporal.io/cli#start-dev-server).
Expand All @@ -2218,9 +2229,9 @@ poe gen-protos-docker
```

Alternatively: to generate protobuf code, you must be on Python <= 3.10, and then run `uv add
"protobuf<4"` + `uv sync --all-extras`. Then the protobuf files can be generated via `poe
"protobuf<4"` + `uv sync`. Then the protobuf files can be generated via `poe
gen-protos` followed by `poe format`. Do not commit `uv.lock` or `pyproject.toml` changes. To go
back from this downgrade, restore both of those files and run `uv sync --all-extras`. Tests can be
back from this downgrade, restore both of those files and run `uv sync`. Tests can be
run for protobuf version 3 by setting the `TEMPORAL_TEST_PROTO3` env var to `1` prior to running
tests.

Expand Down
Loading
Loading