diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 31d823888..b8af36c3a 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "1.28.0"
+ ".": "1.29.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 63705699e..75c1b7196 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 120
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai/runloop-c1b0e0d2c2bf9d7888ddef0cfdfb390458875cd2c1feb48a06fcd06e92105326.yml
-openapi_spec_hash: ec61cf6d205251b54e1a6d68d9dd9860
-config_hash: 6d102da8b9fcc3d0deb42d7a707e78c6
+configured_endpoints: 121
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai/runloop-f8c19bf9329a554bedfbb8678d6d3cb8881a285d27b3d8ba078e2a573b597a17.yml
+openapi_spec_hash: 0c3d490050a9bbaa5cb7378bf55e8f37
+config_hash: 7afcebea2dd638ed0cf0d5367f820f73
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 492ac3a8a..aa709b138 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,25 @@
# Changelog
+## 1.29.0 (2026-08-20)
+
+Full Changelog: [v1.28.0...v1.29.0](https://github.com/runloopai/api-client-python/compare/v1.28.0...v1.29.0)
+
+### Features
+
+* **axon:** add registry delete endpoint ([#10769](https://github.com/runloopai/api-client-python/issues/10769)) ([c63f011](https://github.com/runloopai/api-client-python/commit/c63f01108d98785b358357e4e65e5e517dd0805e))
+* **broker:** plumb Pi protocol selection ([#10256](https://github.com/runloopai/api-client-python/issues/10256)) ([974d52b](https://github.com/runloopai/api-client-python/commit/974d52b8743ceda8a7127e3a3432ce51e71b1bfd))
+* **config:** custom_headers on McpConfig/GatewayConfig — persistence, REST, validation, provisioner, OpenAPI ([#11096](https://github.com/runloopai/api-client-python/issues/11096)) ([9482e47](https://github.com/runloopai/api-client-python/commit/9482e475d0ad6e2b1989ee25f66a759fe839065f))
+* **converter:** add Helm chart, container image, and enable in dev ([#10405](https://github.com/runloopai/api-client-python/issues/10405)) ([0d5ca34](https://github.com/runloopai/api-client-python/commit/0d5ca3438ac4cbcafdfaf7584042bd78a956e3ae))
+* **devbox:** recover resume provisioning failures ([#10597](https://github.com/runloopai/api-client-python/issues/10597)) ([518301e](https://github.com/runloopai/api-client-python/commit/518301e444b95bc5fa73cc0f13be67cf3f750024))
+* **gateway:** first-class BASIC auth mechanism ([#11063](https://github.com/runloopai/api-client-python/issues/11063)) ([1f50f93](https://github.com/runloopai/api-client-python/commit/1f50f93c26c6696d2a9f81b1b677eb9b7282601a))
+* **mcp:** configurable auth_mechanism on McpConfig, shared shape with gateway ([#11113](https://github.com/runloopai/api-client-python/issues/11113)) ([4dd9edd](https://github.com/runloopai/api-client-python/commit/4dd9edd5abbdfab0466826db8d18cbd2efae7b31))
+
+
+### Bug Fixes
+
+* **devbox:** make Devbox update API patch-like ([#10582](https://github.com/runloopai/api-client-python/issues/10582)) ([0a74521](https://github.com/runloopai/api-client-python/commit/0a7452145ee6d1689d8635e65f88b8f778a84820))
+* **gateway:** reject keyless HEADER auth_mechanism at admission and in looper ([#11120](https://github.com/runloopai/api-client-python/issues/11120)) ([194c060](https://github.com/runloopai/api-client-python/commit/194c060f4c95a85d895fc4e0d701e48b5222646c))
+
## 1.28.0 (2026-07-29)
Full Changelog: [v1.27.0...v1.28.0](https://github.com/runloopai/api-client-python/compare/v1.27.0...v1.28.0)
diff --git a/api.md b/api.md
index 6becb60c5..af9a3c239 100644
--- a/api.md
+++ b/api.md
@@ -5,8 +5,10 @@ from runloop_api_client.types import (
AfterIdle,
AgentMount,
AgentSource,
+ AuthMechanism,
BrokerMount,
CodeMountParameters,
+ CustomHeader,
LaunchParameters,
LifecycleConfiguration,
LifecycleHooks,
@@ -131,6 +133,7 @@ Methods:
- client.axons.create(\*\*params) -> AxonView
- client.axons.retrieve(id) -> AxonView
- client.axons.list(\*\*params) -> SyncAxonsCursorIDPage[AxonView]
+- client.axons.delete(id) -> object
- client.axons.publish(id, \*\*params) -> PublishResultView
- client.axons.subscribe_sse(id, \*\*params) -> AxonEventView
diff --git a/pyproject.toml b/pyproject.toml
index 364c6dedd..7974ff247 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "runloop_api_client"
-version = "1.28.0"
+version = "1.29.0"
description = "The official Python library for the runloop API"
dynamic = ["readme"]
license = "MIT"
diff --git a/src/runloop_api_client/_version.py b/src/runloop_api_client/_version.py
index 1a2d135f9..cb57bc803 100644
--- a/src/runloop_api_client/_version.py
+++ b/src/runloop_api_client/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "runloop_api_client"
-__version__ = "1.28.0" # x-release-please-version
+__version__ = "1.29.0" # x-release-please-version
diff --git a/src/runloop_api_client/resources/axons/axons.py b/src/runloop_api_client/resources/axons/axons.py
index fba62a339..232f6f4c2 100644
--- a/src/runloop_api_client/resources/axons/axons.py
+++ b/src/runloop_api_client/resources/axons/axons.py
@@ -210,6 +210,46 @@ def list(
model=AxonView,
)
+ def delete(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> object:
+ """
+ [Beta] Mark an axon deleted.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+
+ idempotency_key: Specify a custom idempotency key for this request
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._delete(
+ path_template("/v1/axons/{id}", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ idempotency_key=idempotency_key,
+ ),
+ cast_to=object,
+ )
+
def publish(
self,
id: str,
@@ -485,6 +525,46 @@ def list(
model=AxonView,
)
+ async def delete(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> object:
+ """
+ [Beta] Mark an axon deleted.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+
+ idempotency_key: Specify a custom idempotency key for this request
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._delete(
+ path_template("/v1/axons/{id}", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ idempotency_key=idempotency_key,
+ ),
+ cast_to=object,
+ )
+
async def publish(
self,
id: str,
@@ -607,6 +687,9 @@ def __init__(self, axons: AxonsResource) -> None:
self.list = to_raw_response_wrapper(
axons.list,
)
+ self.delete = to_raw_response_wrapper(
+ axons.delete,
+ )
self.publish = to_raw_response_wrapper(
axons.publish,
)
@@ -636,6 +719,9 @@ def __init__(self, axons: AsyncAxonsResource) -> None:
self.list = async_to_raw_response_wrapper(
axons.list,
)
+ self.delete = async_to_raw_response_wrapper(
+ axons.delete,
+ )
self.publish = async_to_raw_response_wrapper(
axons.publish,
)
@@ -665,6 +751,9 @@ def __init__(self, axons: AxonsResource) -> None:
self.list = to_streamed_response_wrapper(
axons.list,
)
+ self.delete = to_streamed_response_wrapper(
+ axons.delete,
+ )
self.publish = to_streamed_response_wrapper(
axons.publish,
)
@@ -694,6 +783,9 @@ def __init__(self, axons: AsyncAxonsResource) -> None:
self.list = async_to_streamed_response_wrapper(
axons.list,
)
+ self.delete = async_to_streamed_response_wrapper(
+ axons.delete,
+ )
self.publish = async_to_streamed_response_wrapper(
axons.publish,
)
diff --git a/src/runloop_api_client/resources/devboxes/devboxes.py b/src/runloop_api_client/resources/devboxes/devboxes.py
index 65d0dcbd3..0a0dea11a 100644
--- a/src/runloop_api_client/resources/devboxes/devboxes.py
+++ b/src/runloop_api_client/resources/devboxes/devboxes.py
@@ -338,14 +338,17 @@ def update(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
idempotency_key: str | None = None,
) -> DevboxView:
- """
- Updates a devbox by doing a complete update the existing name,metadata fields.
- It does not patch partial values.
+ """Updates the specified Devbox fields.
+
+ Omitted fields are left unchanged. An empty
+ name clears the name, and an empty metadata map clears the metadata.
Args:
- metadata: User defined metadata to attach to the devbox for organization.
+ metadata: User defined metadata to replace the Devbox metadata. Omit to leave unchanged or
+ set to an empty map to clear it.
- name: (Optional) A user specified name to give the Devbox.
+ name: A user specified name to give the Devbox. Omit to leave unchanged or set to an
+ empty string to clear it.
extra_headers: Send extra headers
@@ -2188,14 +2191,17 @@ async def update(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
idempotency_key: str | None = None,
) -> DevboxView:
- """
- Updates a devbox by doing a complete update the existing name,metadata fields.
- It does not patch partial values.
+ """Updates the specified Devbox fields.
+
+ Omitted fields are left unchanged. An empty
+ name clears the name, and an empty metadata map clears the metadata.
Args:
- metadata: User defined metadata to attach to the devbox for organization.
+ metadata: User defined metadata to replace the Devbox metadata. Omit to leave unchanged or
+ set to an empty map to clear it.
- name: (Optional) A user specified name to give the Devbox.
+ name: A user specified name to give the Devbox. Omit to leave unchanged or set to an
+ empty string to clear it.
extra_headers: Send extra headers
diff --git a/src/runloop_api_client/resources/gateway_configs.py b/src/runloop_api_client/resources/gateway_configs.py
index 34f0989cf..36e00fd2c 100644
--- a/src/runloop_api_client/resources/gateway_configs.py
+++ b/src/runloop_api_client/resources/gateway_configs.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Optional
+from typing import Iterable, Optional
import httpx
@@ -20,6 +20,8 @@
from ..pagination import SyncGatewayConfigsCursorIDPage, AsyncGatewayConfigsCursorIDPage
from .._base_client import AsyncPaginator, make_request_options
from ..types.gateway_config_view import GatewayConfigView
+from ..types.shared_params.custom_header import CustomHeader
+from ..types.shared_params.auth_mechanism import AuthMechanism
__all__ = ["GatewayConfigsResource", "AsyncGatewayConfigsResource"]
@@ -47,9 +49,10 @@ def with_streaming_response(self) -> GatewayConfigsResourceWithStreamingResponse
def create(
self,
*,
- auth_mechanism: gateway_config_create_params.AuthMechanism,
+ auth_mechanism: AuthMechanism,
endpoint: str,
name: str,
+ custom_headers: Optional[Iterable[CustomHeader]] | Omit = omit,
description: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -73,6 +76,9 @@ def create(
name: The human-readable name for the GatewayConfig. Must be unique within your
account.
+ custom_headers: Additional headers applied to proxied requests after the auth mechanism. At most
+ 8 entries.
+
description: Optional description for this gateway configuration.
extra_headers: Send extra headers
@@ -92,6 +98,7 @@ def create(
"auth_mechanism": auth_mechanism,
"endpoint": endpoint,
"name": name,
+ "custom_headers": custom_headers,
"description": description,
},
gateway_config_create_params.GatewayConfigCreateParams,
@@ -143,7 +150,8 @@ def update(
self,
id: str,
*,
- auth_mechanism: Optional[gateway_config_update_params.AuthMechanism] | Omit = omit,
+ auth_mechanism: Optional[AuthMechanism] | Omit = omit,
+ custom_headers: Optional[Iterable[CustomHeader]] | Omit = omit,
description: Optional[str] | Omit = omit,
endpoint: Optional[str] | Omit = omit,
name: Optional[str] | Omit = omit,
@@ -160,8 +168,11 @@ def update(
All fields are optional.
Args:
- auth_mechanism: Defines how credentials are applied to HTTP requests when proxying through the
- gateway.
+ auth_mechanism: Defines how the primary credential is applied to requests proxied to the
+ upstream.
+
+ custom_headers: New list of additional headers. Replaces the existing list entirely; use an
+ empty list to clear all custom headers. At most 8 entries.
description: New description for this gateway configuration.
@@ -186,6 +197,7 @@ def update(
body=maybe_transform(
{
"auth_mechanism": auth_mechanism,
+ "custom_headers": custom_headers,
"description": description,
"endpoint": endpoint,
"name": name,
@@ -332,9 +344,10 @@ def with_streaming_response(self) -> AsyncGatewayConfigsResourceWithStreamingRes
async def create(
self,
*,
- auth_mechanism: gateway_config_create_params.AuthMechanism,
+ auth_mechanism: AuthMechanism,
endpoint: str,
name: str,
+ custom_headers: Optional[Iterable[CustomHeader]] | Omit = omit,
description: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -358,6 +371,9 @@ async def create(
name: The human-readable name for the GatewayConfig. Must be unique within your
account.
+ custom_headers: Additional headers applied to proxied requests after the auth mechanism. At most
+ 8 entries.
+
description: Optional description for this gateway configuration.
extra_headers: Send extra headers
@@ -377,6 +393,7 @@ async def create(
"auth_mechanism": auth_mechanism,
"endpoint": endpoint,
"name": name,
+ "custom_headers": custom_headers,
"description": description,
},
gateway_config_create_params.GatewayConfigCreateParams,
@@ -428,7 +445,8 @@ async def update(
self,
id: str,
*,
- auth_mechanism: Optional[gateway_config_update_params.AuthMechanism] | Omit = omit,
+ auth_mechanism: Optional[AuthMechanism] | Omit = omit,
+ custom_headers: Optional[Iterable[CustomHeader]] | Omit = omit,
description: Optional[str] | Omit = omit,
endpoint: Optional[str] | Omit = omit,
name: Optional[str] | Omit = omit,
@@ -445,8 +463,11 @@ async def update(
All fields are optional.
Args:
- auth_mechanism: Defines how credentials are applied to HTTP requests when proxying through the
- gateway.
+ auth_mechanism: Defines how the primary credential is applied to requests proxied to the
+ upstream.
+
+ custom_headers: New list of additional headers. Replaces the existing list entirely; use an
+ empty list to clear all custom headers. At most 8 entries.
description: New description for this gateway configuration.
@@ -471,6 +492,7 @@ async def update(
body=await async_maybe_transform(
{
"auth_mechanism": auth_mechanism,
+ "custom_headers": custom_headers,
"description": description,
"endpoint": endpoint,
"name": name,
diff --git a/src/runloop_api_client/resources/mcp_configs.py b/src/runloop_api_client/resources/mcp_configs.py
index e96647c9c..c8b37a096 100644
--- a/src/runloop_api_client/resources/mcp_configs.py
+++ b/src/runloop_api_client/resources/mcp_configs.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Optional
+from typing import Iterable, Optional
import httpx
@@ -20,6 +20,8 @@
from ..pagination import SyncMcpConfigsCursorIDPage, AsyncMcpConfigsCursorIDPage
from .._base_client import AsyncPaginator, make_request_options
from ..types.mcp_config_view import McpConfigView
+from ..types.shared_params.custom_header import CustomHeader
+from ..types.shared_params.auth_mechanism import AuthMechanism
__all__ = ["McpConfigsResource", "AsyncMcpConfigsResource"]
@@ -50,6 +52,8 @@ def create(
allowed_tools: SequenceNotStr[str],
endpoint: str,
name: str,
+ auth_mechanism: Optional[AuthMechanism] | Omit = omit,
+ custom_headers: Optional[Iterable[CustomHeader]] | Omit = omit,
description: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -75,6 +79,12 @@ def create(
The first segment before '-' is used as the service name for tool routing (e.g.,
'github-readonly' uses 'github' as the service name).
+ auth_mechanism: Defines how the primary credential is applied to requests proxied to the
+ upstream.
+
+ custom_headers: Additional headers applied to upstream requests after the credential. At most 8
+ entries.
+
description: Optional description for this MCP configuration.
extra_headers: Send extra headers
@@ -94,6 +104,8 @@ def create(
"allowed_tools": allowed_tools,
"endpoint": endpoint,
"name": name,
+ "auth_mechanism": auth_mechanism,
+ "custom_headers": custom_headers,
"description": description,
},
mcp_config_create_params.McpConfigCreateParams,
@@ -146,6 +158,8 @@ def update(
id: str,
*,
allowed_tools: Optional[SequenceNotStr[str]] | Omit = omit,
+ auth_mechanism: Optional[AuthMechanism] | Omit = omit,
+ custom_headers: Optional[Iterable[CustomHeader]] | Omit = omit,
description: Optional[str] | Omit = omit,
endpoint: Optional[str] | Omit = omit,
name: Optional[str] | Omit = omit,
@@ -165,6 +179,12 @@ def update(
allowed_tools: New glob patterns specifying which tools are allowed. Examples: ['*'] for all
tools, ['github.search_*'] for specific patterns.
+ auth_mechanism: Defines how the primary credential is applied to requests proxied to the
+ upstream.
+
+ custom_headers: New list of additional headers. Replaces the existing list entirely; use an
+ empty list to clear all custom headers. At most 8 entries.
+
description: New description for this MCP configuration.
endpoint: New target MCP server endpoint URL.
@@ -188,6 +208,8 @@ def update(
body=maybe_transform(
{
"allowed_tools": allowed_tools,
+ "auth_mechanism": auth_mechanism,
+ "custom_headers": custom_headers,
"description": description,
"endpoint": endpoint,
"name": name,
@@ -336,6 +358,8 @@ async def create(
allowed_tools: SequenceNotStr[str],
endpoint: str,
name: str,
+ auth_mechanism: Optional[AuthMechanism] | Omit = omit,
+ custom_headers: Optional[Iterable[CustomHeader]] | Omit = omit,
description: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -361,6 +385,12 @@ async def create(
The first segment before '-' is used as the service name for tool routing (e.g.,
'github-readonly' uses 'github' as the service name).
+ auth_mechanism: Defines how the primary credential is applied to requests proxied to the
+ upstream.
+
+ custom_headers: Additional headers applied to upstream requests after the credential. At most 8
+ entries.
+
description: Optional description for this MCP configuration.
extra_headers: Send extra headers
@@ -380,6 +410,8 @@ async def create(
"allowed_tools": allowed_tools,
"endpoint": endpoint,
"name": name,
+ "auth_mechanism": auth_mechanism,
+ "custom_headers": custom_headers,
"description": description,
},
mcp_config_create_params.McpConfigCreateParams,
@@ -432,6 +464,8 @@ async def update(
id: str,
*,
allowed_tools: Optional[SequenceNotStr[str]] | Omit = omit,
+ auth_mechanism: Optional[AuthMechanism] | Omit = omit,
+ custom_headers: Optional[Iterable[CustomHeader]] | Omit = omit,
description: Optional[str] | Omit = omit,
endpoint: Optional[str] | Omit = omit,
name: Optional[str] | Omit = omit,
@@ -451,6 +485,12 @@ async def update(
allowed_tools: New glob patterns specifying which tools are allowed. Examples: ['*'] for all
tools, ['github.search_*'] for specific patterns.
+ auth_mechanism: Defines how the primary credential is applied to requests proxied to the
+ upstream.
+
+ custom_headers: New list of additional headers. Replaces the existing list entirely; use an
+ empty list to clear all custom headers. At most 8 entries.
+
description: New description for this MCP configuration.
endpoint: New target MCP server endpoint URL.
@@ -474,6 +514,8 @@ async def update(
body=await async_maybe_transform(
{
"allowed_tools": allowed_tools,
+ "auth_mechanism": auth_mechanism,
+ "custom_headers": custom_headers,
"description": description,
"endpoint": endpoint,
"name": name,
diff --git a/src/runloop_api_client/types/__init__.py b/src/runloop_api_client/types/__init__.py
index 0bda186a3..d7c17637c 100644
--- a/src/runloop_api_client/types/__init__.py
+++ b/src/runloop_api_client/types/__init__.py
@@ -10,6 +10,8 @@
AgentSource as AgentSource,
BrokerMount as BrokerMount,
ObjectMount as ObjectMount,
+ CustomHeader as CustomHeader,
+ AuthMechanism as AuthMechanism,
LifecycleHooks as LifecycleHooks,
ResumeTriggers as ResumeTriggers,
LaunchParameters as LaunchParameters,
diff --git a/src/runloop_api_client/types/blueprint_view.py b/src/runloop_api_client/types/blueprint_view.py
index 87c1eecab..b0bfefecd 100644
--- a/src/runloop_api_client/types/blueprint_view.py
+++ b/src/runloop_api_client/types/blueprint_view.py
@@ -63,7 +63,7 @@ class BlueprintView(BaseModel):
state: Literal["created", "deleted"]
"""The state of the Blueprint."""
- status: Literal["queued", "provisioning", "building", "failed", "build_complete"]
+ status: Literal["queued", "provisioning", "building", "awaiting_upload", "failed", "build_complete"]
"""The status of the Blueprint build."""
base_blueprint_id: Optional[str] = None
diff --git a/src/runloop_api_client/types/devbox_update_params.py b/src/runloop_api_client/types/devbox_update_params.py
index 2fbdae310..1e53b01a0 100644
--- a/src/runloop_api_client/types/devbox_update_params.py
+++ b/src/runloop_api_client/types/devbox_update_params.py
@@ -10,7 +10,13 @@
class DevboxUpdateParams(TypedDict, total=False):
metadata: Optional[Dict[str, str]]
- """User defined metadata to attach to the devbox for organization."""
+ """User defined metadata to replace the Devbox metadata.
+
+ Omit to leave unchanged or set to an empty map to clear it.
+ """
name: Optional[str]
- """(Optional) A user specified name to give the Devbox."""
+ """A user specified name to give the Devbox.
+
+ Omit to leave unchanged or set to an empty string to clear it.
+ """
diff --git a/src/runloop_api_client/types/devbox_view.py b/src/runloop_api_client/types/devbox_view.py
index 49ffc1ec8..504d1fe2e 100644
--- a/src/runloop_api_client/types/devbox_view.py
+++ b/src/runloop_api_client/types/devbox_view.py
@@ -11,6 +11,9 @@
class StateTransition(BaseModel):
+ failure_reason: Optional[str] = None
+ """The failure that caused this state transition, if applicable."""
+
status: Optional[
Literal[
"scheduled",
diff --git a/src/runloop_api_client/types/gateway_config_create_params.py b/src/runloop_api_client/types/gateway_config_create_params.py
index 6a39055e4..653a62940 100644
--- a/src/runloop_api_client/types/gateway_config_create_params.py
+++ b/src/runloop_api_client/types/gateway_config_create_params.py
@@ -2,10 +2,13 @@
from __future__ import annotations
-from typing import Optional
+from typing import Iterable, Optional
from typing_extensions import Required, TypedDict
-__all__ = ["GatewayConfigCreateParams", "AuthMechanism"]
+from .shared_params.custom_header import CustomHeader
+from .shared_params.auth_mechanism import AuthMechanism
+
+__all__ = ["GatewayConfigCreateParams"]
class GatewayConfigCreateParams(TypedDict, total=False):
@@ -24,18 +27,11 @@ class GatewayConfigCreateParams(TypedDict, total=False):
Must be unique within your account.
"""
- description: Optional[str]
- """Optional description for this gateway configuration."""
-
-
-class AuthMechanism(TypedDict, total=False):
- """How credentials should be applied to proxied requests.
+ custom_headers: Optional[Iterable[CustomHeader]]
+ """Additional headers applied to proxied requests after the auth mechanism.
- Specify the type ('header', 'bearer') and optional key field.
+ At most 8 entries.
"""
- type: Required[str]
- """The type of authentication mechanism: 'header', 'bearer'."""
-
- key: Optional[str]
- """For 'header' type: the header name (e.g., 'x-api-key')."""
+ description: Optional[str]
+ """Optional description for this gateway configuration."""
diff --git a/src/runloop_api_client/types/gateway_config_update_params.py b/src/runloop_api_client/types/gateway_config_update_params.py
index d639f3a39..64078933e 100644
--- a/src/runloop_api_client/types/gateway_config_update_params.py
+++ b/src/runloop_api_client/types/gateway_config_update_params.py
@@ -2,17 +2,27 @@
from __future__ import annotations
-from typing import Optional
-from typing_extensions import Required, TypedDict
+from typing import Iterable, Optional
+from typing_extensions import TypedDict
-__all__ = ["GatewayConfigUpdateParams", "AuthMechanism"]
+from .shared_params.custom_header import CustomHeader
+from .shared_params.auth_mechanism import AuthMechanism
+
+__all__ = ["GatewayConfigUpdateParams"]
class GatewayConfigUpdateParams(TypedDict, total=False):
auth_mechanism: Optional[AuthMechanism]
"""
- Defines how credentials are applied to HTTP requests when proxying through the
- gateway.
+ Defines how the primary credential is applied to requests proxied to the
+ upstream.
+ """
+
+ custom_headers: Optional[Iterable[CustomHeader]]
+ """New list of additional headers.
+
+ Replaces the existing list entirely; use an empty list to clear all custom
+ headers. At most 8 entries.
"""
description: Optional[str]
@@ -23,15 +33,3 @@ class GatewayConfigUpdateParams(TypedDict, total=False):
name: Optional[str]
"""New name for the GatewayConfig. Must be unique within your account."""
-
-
-class AuthMechanism(TypedDict, total=False):
- """
- Defines how credentials are applied to HTTP requests when proxying through the gateway.
- """
-
- type: Required[str]
- """The type of authentication mechanism: 'header', 'bearer'."""
-
- key: Optional[str]
- """For 'header' type: the header name (e.g., 'x-api-key')."""
diff --git a/src/runloop_api_client/types/gateway_config_view.py b/src/runloop_api_client/types/gateway_config_view.py
index c8fcc6e3c..7f7cf62d7 100644
--- a/src/runloop_api_client/types/gateway_config_view.py
+++ b/src/runloop_api_client/types/gateway_config_view.py
@@ -1,20 +1,12 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import List, Optional
from .._models import BaseModel
+from .shared.custom_header import CustomHeader
+from .shared.auth_mechanism import AuthMechanism
-__all__ = ["GatewayConfigView", "AuthMechanism"]
-
-
-class AuthMechanism(BaseModel):
- """How credentials should be applied to proxied requests."""
-
- type: str
- """The type of authentication mechanism: 'header', 'bearer'."""
-
- key: Optional[str] = None
- """For 'header' type: the header name (e.g., 'x-api-key')."""
+__all__ = ["GatewayConfigView"]
class GatewayConfigView(BaseModel):
@@ -43,5 +35,12 @@ class GatewayConfigView(BaseModel):
account_id: Optional[str] = None
"""The account ID that owns this config."""
+ custom_headers: Optional[List[CustomHeader]] = None
+ """Additional headers applied to proxied requests after the auth mechanism.
+
+ Secret-backed entries reference the secret by 'sec\\__' id; values are never
+ returned.
+ """
+
description: Optional[str] = None
"""Optional description for this gateway configuration."""
diff --git a/src/runloop_api_client/types/mcp_config_create_params.py b/src/runloop_api_client/types/mcp_config_create_params.py
index 4a2dcd9e2..cb4164863 100644
--- a/src/runloop_api_client/types/mcp_config_create_params.py
+++ b/src/runloop_api_client/types/mcp_config_create_params.py
@@ -2,10 +2,12 @@
from __future__ import annotations
-from typing import Optional
+from typing import Iterable, Optional
from typing_extensions import Required, TypedDict
from .._types import SequenceNotStr
+from .shared_params.custom_header import CustomHeader
+from .shared_params.auth_mechanism import AuthMechanism
__all__ = ["McpConfigCreateParams"]
@@ -29,5 +31,17 @@ class McpConfigCreateParams(TypedDict, total=False):
service name).
"""
+ auth_mechanism: Optional[AuthMechanism]
+ """
+ Defines how the primary credential is applied to requests proxied to the
+ upstream.
+ """
+
+ custom_headers: Optional[Iterable[CustomHeader]]
+ """Additional headers applied to upstream requests after the credential.
+
+ At most 8 entries.
+ """
+
description: Optional[str]
"""Optional description for this MCP configuration."""
diff --git a/src/runloop_api_client/types/mcp_config_update_params.py b/src/runloop_api_client/types/mcp_config_update_params.py
index 234ca939f..e57849953 100644
--- a/src/runloop_api_client/types/mcp_config_update_params.py
+++ b/src/runloop_api_client/types/mcp_config_update_params.py
@@ -2,10 +2,12 @@
from __future__ import annotations
-from typing import Optional
+from typing import Iterable, Optional
from typing_extensions import TypedDict
from .._types import SequenceNotStr
+from .shared_params.custom_header import CustomHeader
+from .shared_params.auth_mechanism import AuthMechanism
__all__ = ["McpConfigUpdateParams"]
@@ -17,6 +19,19 @@ class McpConfigUpdateParams(TypedDict, total=False):
Examples: ['*'] for all tools, ['github.search_*'] for specific patterns.
"""
+ auth_mechanism: Optional[AuthMechanism]
+ """
+ Defines how the primary credential is applied to requests proxied to the
+ upstream.
+ """
+
+ custom_headers: Optional[Iterable[CustomHeader]]
+ """New list of additional headers.
+
+ Replaces the existing list entirely; use an empty list to clear all custom
+ headers. At most 8 entries.
+ """
+
description: Optional[str]
"""New description for this MCP configuration."""
diff --git a/src/runloop_api_client/types/mcp_config_view.py b/src/runloop_api_client/types/mcp_config_view.py
index 988537a59..4dd65503d 100644
--- a/src/runloop_api_client/types/mcp_config_view.py
+++ b/src/runloop_api_client/types/mcp_config_view.py
@@ -3,6 +3,8 @@
from typing import List, Optional
from .._models import BaseModel
+from .shared.custom_header import CustomHeader
+from .shared.auth_mechanism import AuthMechanism
__all__ = ["McpConfigView"]
@@ -21,6 +23,9 @@ class McpConfigView(BaseModel):
['github.search_*', 'github.get_*'] or ['*'] for all tools).
"""
+ auth_mechanism: AuthMechanism
+ """How the primary credential is applied to upstream requests."""
+
create_time_ms: int
"""Creation time of the McpConfig (Unix timestamp in milliseconds)."""
@@ -30,5 +35,12 @@ class McpConfigView(BaseModel):
name: str
"""The human-readable name of the McpConfig. Unique per account."""
+ custom_headers: Optional[List[CustomHeader]] = None
+ """Additional headers applied to upstream requests after the credential.
+
+ Secret-backed entries reference the secret by 'sec\\__' id; values are never
+ returned.
+ """
+
description: Optional[str] = None
"""Optional description for this MCP configuration."""
diff --git a/src/runloop_api_client/types/shared/__init__.py b/src/runloop_api_client/types/shared/__init__.py
index 5463ca25c..d2276afb6 100644
--- a/src/runloop_api_client/types/shared/__init__.py
+++ b/src/runloop_api_client/types/shared/__init__.py
@@ -7,6 +7,8 @@
from .agent_source import AgentSource as AgentSource
from .broker_mount import BrokerMount as BrokerMount
from .object_mount import ObjectMount as ObjectMount
+from .custom_header import CustomHeader as CustomHeader
+from .auth_mechanism import AuthMechanism as AuthMechanism
from .lifecycle_hooks import LifecycleHooks as LifecycleHooks
from .resume_triggers import ResumeTriggers as ResumeTriggers
from .launch_parameters import LaunchParameters as LaunchParameters
diff --git a/src/runloop_api_client/types/shared/auth_mechanism.py b/src/runloop_api_client/types/shared/auth_mechanism.py
new file mode 100644
index 000000000..f046b0b25
--- /dev/null
+++ b/src/runloop_api_client/types/shared/auth_mechanism.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ..._models import BaseModel
+
+__all__ = ["AuthMechanism"]
+
+
+class AuthMechanism(BaseModel):
+ """
+ Defines how the primary credential is applied to requests proxied to the upstream.
+ """
+
+ type: str
+ """The type of authentication mechanism: 'header', 'bearer', or 'basic'.
+
+ For 'basic', store the secret as plain 'user:pass'; the proxy base64-encodes it.
+ """
+
+ key: Optional[str] = None
+ """The header name (e.g., 'x-api-key').
+
+ Required for 'header' type; invalid for other types.
+ """
diff --git a/src/runloop_api_client/types/shared/broker_mount.py b/src/runloop_api_client/types/shared/broker_mount.py
index adf49c04a..97e6c940a 100644
--- a/src/runloop_api_client/types/shared/broker_mount.py
+++ b/src/runloop_api_client/types/shared/broker_mount.py
@@ -17,16 +17,18 @@ class BrokerMount(BaseModel):
agent_binary: Optional[str] = None
"""Binary to launch the agent (e.g., 'opencode').
- Used by protocols that launch a subprocess (acp, claude_json, codex_json).
+ Used by protocols that launch a subprocess (acp, claude_json, codex_json,
+ pi_json).
"""
launch_args: Optional[List[str]] = None
"""Arguments to pass to the agent command (e.g., ['acp']).
- Used by protocols that launch a subprocess (acp, claude_json, codex_json).
+ Used by protocols that launch a subprocess (acp, claude_json, codex_json,
+ pi_json).
"""
- protocol: Optional[Literal["acp", "claude_json", "codex_json"]] = None
+ protocol: Optional[Literal["acp", "claude_json", "codex_json", "pi_json"]] = None
"""The protocol used by the broker to deliver events to the agent."""
working_directory: Optional[str] = None
diff --git a/src/runloop_api_client/types/shared/custom_header.py b/src/runloop_api_client/types/shared/custom_header.py
new file mode 100644
index 000000000..0888c074a
--- /dev/null
+++ b/src/runloop_api_client/types/shared/custom_header.py
@@ -0,0 +1,29 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ..._models import BaseModel
+
+__all__ = ["CustomHeader"]
+
+
+class CustomHeader(BaseModel):
+ """
+ An additional header applied to upstream requests alongside the primary credential. The value comes from an account secret or a literal string; exactly one of 'secret' and 'value' must be set.
+ """
+
+ name: str
+ """The header name (e.g., 'DD-APPLICATION-KEY')."""
+
+ secret: Optional[str] = None
+ """Account secret providing the header value.
+
+ Accepts a secret name or 'sec*' id on writes; reads always return the 'sec*' id.
+ """
+
+ value: Optional[str] = None
+ """Literal header value.
+
+ Stored in plaintext and returned by reads - use 'secret' for credentials or
+ other sensitive values.
+ """
diff --git a/src/runloop_api_client/types/shared_params/__init__.py b/src/runloop_api_client/types/shared_params/__init__.py
index 5463ca25c..d2276afb6 100644
--- a/src/runloop_api_client/types/shared_params/__init__.py
+++ b/src/runloop_api_client/types/shared_params/__init__.py
@@ -7,6 +7,8 @@
from .agent_source import AgentSource as AgentSource
from .broker_mount import BrokerMount as BrokerMount
from .object_mount import ObjectMount as ObjectMount
+from .custom_header import CustomHeader as CustomHeader
+from .auth_mechanism import AuthMechanism as AuthMechanism
from .lifecycle_hooks import LifecycleHooks as LifecycleHooks
from .resume_triggers import ResumeTriggers as ResumeTriggers
from .launch_parameters import LaunchParameters as LaunchParameters
diff --git a/src/runloop_api_client/types/shared_params/auth_mechanism.py b/src/runloop_api_client/types/shared_params/auth_mechanism.py
new file mode 100644
index 000000000..d2579df2b
--- /dev/null
+++ b/src/runloop_api_client/types/shared_params/auth_mechanism.py
@@ -0,0 +1,26 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["AuthMechanism"]
+
+
+class AuthMechanism(TypedDict, total=False):
+ """
+ Defines how the primary credential is applied to requests proxied to the upstream.
+ """
+
+ type: Required[str]
+ """The type of authentication mechanism: 'header', 'bearer', or 'basic'.
+
+ For 'basic', store the secret as plain 'user:pass'; the proxy base64-encodes it.
+ """
+
+ key: Optional[str]
+ """The header name (e.g., 'x-api-key').
+
+ Required for 'header' type; invalid for other types.
+ """
diff --git a/src/runloop_api_client/types/shared_params/broker_mount.py b/src/runloop_api_client/types/shared_params/broker_mount.py
index e62bd59e5..55e6b6661 100644
--- a/src/runloop_api_client/types/shared_params/broker_mount.py
+++ b/src/runloop_api_client/types/shared_params/broker_mount.py
@@ -19,16 +19,18 @@ class BrokerMount(TypedDict, total=False):
agent_binary: Optional[str]
"""Binary to launch the agent (e.g., 'opencode').
- Used by protocols that launch a subprocess (acp, claude_json, codex_json).
+ Used by protocols that launch a subprocess (acp, claude_json, codex_json,
+ pi_json).
"""
launch_args: Optional[SequenceNotStr[str]]
"""Arguments to pass to the agent command (e.g., ['acp']).
- Used by protocols that launch a subprocess (acp, claude_json, codex_json).
+ Used by protocols that launch a subprocess (acp, claude_json, codex_json,
+ pi_json).
"""
- protocol: Optional[Literal["acp", "claude_json", "codex_json"]]
+ protocol: Optional[Literal["acp", "claude_json", "codex_json", "pi_json"]]
"""The protocol used by the broker to deliver events to the agent."""
working_directory: Optional[str]
diff --git a/src/runloop_api_client/types/shared_params/custom_header.py b/src/runloop_api_client/types/shared_params/custom_header.py
new file mode 100644
index 000000000..1b249be42
--- /dev/null
+++ b/src/runloop_api_client/types/shared_params/custom_header.py
@@ -0,0 +1,30 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["CustomHeader"]
+
+
+class CustomHeader(TypedDict, total=False):
+ """
+ An additional header applied to upstream requests alongside the primary credential. The value comes from an account secret or a literal string; exactly one of 'secret' and 'value' must be set.
+ """
+
+ name: Required[str]
+ """The header name (e.g., 'DD-APPLICATION-KEY')."""
+
+ secret: Optional[str]
+ """Account secret providing the header value.
+
+ Accepts a secret name or 'sec*' id on writes; reads always return the 'sec*' id.
+ """
+
+ value: Optional[str]
+ """Literal header value.
+
+ Stored in plaintext and returned by reads - use 'secret' for credentials or
+ other sensitive values.
+ """
diff --git a/tests/api_resources/test_axons.py b/tests/api_resources/test_axons.py
index 8764443bb..97f4f663c 100644
--- a/tests/api_resources/test_axons.py
+++ b/tests/api_resources/test_axons.py
@@ -128,6 +128,44 @@ def test_streaming_response_list(self, client: Runloop) -> None:
assert cast(Any, response.is_closed) is True
+ @parametrize
+ def test_method_delete(self, client: Runloop) -> None:
+ axon = client.axons.delete(
+ "id",
+ )
+ assert_matches_type(object, axon, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Runloop) -> None:
+ response = client.axons.with_raw_response.delete(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ axon = response.parse()
+ assert_matches_type(object, axon, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Runloop) -> None:
+ with client.axons.with_streaming_response.delete(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ axon = response.parse()
+ assert_matches_type(object, axon, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_delete(self, client: Runloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.axons.with_raw_response.delete(
+ "",
+ )
+
@parametrize
def test_method_publish(self, client: Runloop) -> None:
axon = client.axons.publish(
@@ -340,6 +378,44 @@ async def test_streaming_response_list(self, async_client: AsyncRunloop) -> None
assert cast(Any, response.is_closed) is True
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncRunloop) -> None:
+ axon = await async_client.axons.delete(
+ "id",
+ )
+ assert_matches_type(object, axon, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.axons.with_raw_response.delete(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ axon = await response.parse()
+ assert_matches_type(object, axon, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncRunloop) -> None:
+ async with async_client.axons.with_streaming_response.delete(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ axon = await response.parse()
+ assert_matches_type(object, axon, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncRunloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.axons.with_raw_response.delete(
+ "",
+ )
+
@parametrize
async def test_method_publish(self, async_client: AsyncRunloop) -> None:
axon = await async_client.axons.publish(
diff --git a/tests/api_resources/test_gateway_configs.py b/tests/api_resources/test_gateway_configs.py
index 64e35b11f..5111aa542 100644
--- a/tests/api_resources/test_gateway_configs.py
+++ b/tests/api_resources/test_gateway_configs.py
@@ -38,6 +38,13 @@ def test_method_create_with_all_params(self, client: Runloop) -> None:
},
endpoint="endpoint",
name="name",
+ custom_headers=[
+ {
+ "name": "name",
+ "secret": "secret",
+ "value": "value",
+ }
+ ],
description="description",
)
assert_matches_type(GatewayConfigView, gateway_config, path=["response"])
@@ -123,6 +130,13 @@ def test_method_update_with_all_params(self, client: Runloop) -> None:
"type": "type",
"key": "key",
},
+ custom_headers=[
+ {
+ "name": "name",
+ "secret": "secret",
+ "value": "value",
+ }
+ ],
description="description",
endpoint="endpoint",
name="name",
@@ -259,6 +273,13 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunloop) -
},
endpoint="endpoint",
name="name",
+ custom_headers=[
+ {
+ "name": "name",
+ "secret": "secret",
+ "value": "value",
+ }
+ ],
description="description",
)
assert_matches_type(GatewayConfigView, gateway_config, path=["response"])
@@ -344,6 +365,13 @@ async def test_method_update_with_all_params(self, async_client: AsyncRunloop) -
"type": "type",
"key": "key",
},
+ custom_headers=[
+ {
+ "name": "name",
+ "secret": "secret",
+ "value": "value",
+ }
+ ],
description="description",
endpoint="endpoint",
name="name",
diff --git a/tests/api_resources/test_mcp_configs.py b/tests/api_resources/test_mcp_configs.py
index 2e85d3d45..b67c3cf36 100644
--- a/tests/api_resources/test_mcp_configs.py
+++ b/tests/api_resources/test_mcp_configs.py
@@ -35,6 +35,17 @@ def test_method_create_with_all_params(self, client: Runloop) -> None:
allowed_tools=["string"],
endpoint="endpoint",
name="name",
+ auth_mechanism={
+ "type": "type",
+ "key": "key",
+ },
+ custom_headers=[
+ {
+ "name": "name",
+ "secret": "secret",
+ "value": "value",
+ }
+ ],
description="description",
)
assert_matches_type(McpConfigView, mcp_config, path=["response"])
@@ -117,6 +128,17 @@ def test_method_update_with_all_params(self, client: Runloop) -> None:
mcp_config = client.mcp_configs.update(
id="id",
allowed_tools=["string"],
+ auth_mechanism={
+ "type": "type",
+ "key": "key",
+ },
+ custom_headers=[
+ {
+ "name": "name",
+ "secret": "secret",
+ "value": "value",
+ }
+ ],
description="description",
endpoint="endpoint",
name="name",
@@ -250,6 +272,17 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunloop) -
allowed_tools=["string"],
endpoint="endpoint",
name="name",
+ auth_mechanism={
+ "type": "type",
+ "key": "key",
+ },
+ custom_headers=[
+ {
+ "name": "name",
+ "secret": "secret",
+ "value": "value",
+ }
+ ],
description="description",
)
assert_matches_type(McpConfigView, mcp_config, path=["response"])
@@ -332,6 +365,17 @@ async def test_method_update_with_all_params(self, async_client: AsyncRunloop) -
mcp_config = await async_client.mcp_configs.update(
id="id",
allowed_tools=["string"],
+ auth_mechanism={
+ "type": "type",
+ "key": "key",
+ },
+ custom_headers=[
+ {
+ "name": "name",
+ "secret": "secret",
+ "value": "value",
+ }
+ ],
description="description",
endpoint="endpoint",
name="name",