Skip to content

Commit 0d0a3fa

Browse files
committed
cp dines
1 parent 81c4975 commit 0d0a3fa

7 files changed

Lines changed: 514 additions & 0 deletions

File tree

src/runloop_api_client/sdk/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
SnapshotOps,
1515
BenchmarkOps,
1616
BlueprintOps,
17+
McpConfigOps,
1718
GatewayConfigOps,
1819
NetworkPolicyOps,
1920
StorageObjectOps,
@@ -29,6 +30,7 @@
2930
AsyncSnapshotOps,
3031
AsyncBenchmarkOps,
3132
AsyncBlueprintOps,
33+
AsyncMcpConfigOps,
3234
AsyncGatewayConfigOps,
3335
AsyncNetworkPolicyOps,
3436
AsyncStorageObjectOps,
@@ -47,6 +49,7 @@
4749
from .benchmark_run import BenchmarkRun
4850
from .async_scenario import AsyncScenario
4951
from .async_snapshot import AsyncSnapshot
52+
from .mcp_config import McpConfig
5053
from .gateway_config import GatewayConfig
5154
from .network_policy import NetworkPolicy
5255
from .storage_object import StorageObject
@@ -57,6 +60,7 @@
5760
from .scenario_builder import ScenarioBuilder
5861
from .async_scenario_run import AsyncScenarioRun
5962
from .async_benchmark_run import AsyncBenchmarkRun
63+
from .async_mcp_config import AsyncMcpConfig
6064
from .async_gateway_config import AsyncGatewayConfig
6165
from .async_network_policy import AsyncNetworkPolicy
6266
from .async_storage_object import AsyncStorageObject
@@ -86,6 +90,8 @@
8690
"AsyncStorageObjectOps",
8791
"NetworkPolicyOps",
8892
"AsyncNetworkPolicyOps",
93+
"McpConfigOps",
94+
"AsyncMcpConfigOps",
8995
"GatewayConfigOps",
9096
"AsyncGatewayConfigOps",
9197
# Resource classes
@@ -118,6 +124,8 @@
118124
"AsyncStorageObject",
119125
"NetworkPolicy",
120126
"AsyncNetworkPolicy",
127+
"McpConfig",
128+
"AsyncMcpConfig",
121129
"GatewayConfig",
122130
"AsyncGatewayConfig",
123131
"NamedShell",

src/runloop_api_client/sdk/_types.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@
1919
BenchmarkUpdateParams,
2020
BlueprintCreateParams,
2121
DevboxUploadFileParams,
22+
McpConfigListParams,
2223
GatewayConfigListParams,
2324
NetworkPolicyListParams,
2425
DevboxCreateTunnelParams,
2526
DevboxDownloadFileParams,
2627
DevboxEnableTunnelParams,
2728
DevboxRemoveTunnelParams,
2829
DevboxSnapshotDiskParams,
30+
McpConfigCreateParams,
31+
McpConfigUpdateParams,
2932
GatewayConfigCreateParams,
3033
GatewayConfigUpdateParams,
3134
NetworkPolicyCreateParams,
@@ -266,6 +269,18 @@ class SDKNetworkPolicyUpdateParams(NetworkPolicyUpdateParams, LongRequestOptions
266269
pass
267270

268271

272+
class SDKMcpConfigCreateParams(McpConfigCreateParams, LongRequestOptions):
273+
pass
274+
275+
276+
class SDKMcpConfigListParams(McpConfigListParams, BaseRequestOptions):
277+
pass
278+
279+
280+
class SDKMcpConfigUpdateParams(McpConfigUpdateParams, LongRequestOptions):
281+
pass
282+
283+
269284
class SDKGatewayConfigCreateParams(GatewayConfigCreateParams, LongRequestOptions):
270285
pass
271286

src/runloop_api_client/sdk/async_.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
SDKBenchmarkCreateParams,
2727
SDKBlueprintCreateParams,
2828
SDKDiskSnapshotListParams,
29+
SDKMcpConfigListParams,
2930
SDKGatewayConfigListParams,
3031
SDKNetworkPolicyListParams,
32+
SDKMcpConfigCreateParams,
3133
SDKGatewayConfigCreateParams,
3234
SDKNetworkPolicyCreateParams,
3335
SDKDevboxCreateFromImageParams,
@@ -43,6 +45,7 @@
4345
from .async_benchmark import AsyncBenchmark
4446
from .async_blueprint import AsyncBlueprint
4547
from ..lib.context_loader import TarFilter, build_directory_tar
48+
from .async_mcp_config import AsyncMcpConfig
4649
from .async_gateway_config import AsyncGatewayConfig
4750
from .async_network_policy import AsyncNetworkPolicy
4851
from .async_storage_object import AsyncStorageObject
@@ -1011,6 +1014,80 @@ async def list(self, **params: Unpack[SDKGatewayConfigListParams]) -> list[Async
10111014
return [AsyncGatewayConfig(self._client, item.id) for item in page.gateway_configs]
10121015

10131016

1017+
class AsyncMcpConfigOps:
1018+
"""High-level async manager for creating and managing MCP configurations.
1019+
1020+
Accessed via ``runloop.mcp_config`` from :class:`AsyncRunloopSDK`, provides methods
1021+
to create, retrieve, update, delete, and list MCP configs. MCP configs define
1022+
how to connect to upstream MCP (Model Context Protocol) servers, specifying the
1023+
target endpoint and which tools are allowed.
1024+
1025+
Example:
1026+
>>> runloop = AsyncRunloopSDK()
1027+
>>> mcp_config = await runloop.mcp_config.create(
1028+
... name="my-mcp-server",
1029+
... endpoint="https://mcp.example.com",
1030+
... allowed_tools=["*"],
1031+
... )
1032+
"""
1033+
1034+
def __init__(self, client: AsyncRunloop) -> None:
1035+
"""Initialize AsyncMcpConfigOps.
1036+
1037+
:param client: AsyncRunloop client instance
1038+
:type client: AsyncRunloop
1039+
"""
1040+
self._client = client
1041+
1042+
async def create(self, **params: Unpack[SDKMcpConfigCreateParams]) -> AsyncMcpConfig:
1043+
"""Create a new MCP config.
1044+
1045+
Example:
1046+
>>> mcp_config = await runloop.mcp_config.create(
1047+
... name="my-mcp-server",
1048+
... endpoint="https://mcp.example.com",
1049+
... allowed_tools=["*"],
1050+
... description="MCP server for my tools",
1051+
... )
1052+
1053+
:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKMcpConfigCreateParams` for available parameters
1054+
:return: The newly created MCP config
1055+
:rtype: AsyncMcpConfig
1056+
"""
1057+
response = await self._client.mcp_configs.create(**params)
1058+
return AsyncMcpConfig(self._client, response.id)
1059+
1060+
def from_id(self, mcp_config_id: str) -> AsyncMcpConfig:
1061+
"""Get an AsyncMcpConfig instance for an existing MCP config ID.
1062+
1063+
Example:
1064+
>>> mcp_config = runloop.mcp_config.from_id("mcp_1234567890")
1065+
>>> info = await mcp_config.get_info()
1066+
>>> print(f"MCP Config name: {info.name}")
1067+
1068+
:param mcp_config_id: ID of the MCP config
1069+
:type mcp_config_id: str
1070+
:return: AsyncMcpConfig instance for the given ID
1071+
:rtype: AsyncMcpConfig
1072+
"""
1073+
return AsyncMcpConfig(self._client, mcp_config_id)
1074+
1075+
async def list(self, **params: Unpack[SDKMcpConfigListParams]) -> list[AsyncMcpConfig]:
1076+
"""List all MCP configs, optionally filtered by parameters.
1077+
1078+
Example:
1079+
>>> configs = await runloop.mcp_config.list(limit=10)
1080+
>>> for config in configs:
1081+
... print(config.id)
1082+
1083+
:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKMcpConfigListParams` for available parameters
1084+
:return: List of MCP configs
1085+
:rtype: list[AsyncMcpConfig]
1086+
"""
1087+
page = await self._client.mcp_configs.list(**params)
1088+
return [AsyncMcpConfig(self._client, item.id) for item in page.mcp_configs]
1089+
1090+
10141091
class AsyncRunloopSDK:
10151092
"""High-level asynchronous entry point for the Runloop SDK.
10161093
@@ -1040,6 +1117,8 @@ class AsyncRunloopSDK:
10401117
:vartype network_policy: AsyncNetworkPolicyOps
10411118
:ivar gateway_config: High-level async interface for gateway config management
10421119
:vartype gateway_config: AsyncGatewayConfigOps
1120+
:ivar mcp_config: High-level async interface for MCP config management
1121+
:vartype mcp_config: AsyncMcpConfigOps
10431122
10441123
Example:
10451124
>>> runloop = AsyncRunloopSDK() # Uses RUNLOOP_API_KEY env var
@@ -1055,6 +1134,7 @@ class AsyncRunloopSDK:
10551134
devbox: AsyncDevboxOps
10561135
blueprint: AsyncBlueprintOps
10571136
gateway_config: AsyncGatewayConfigOps
1137+
mcp_config: AsyncMcpConfigOps
10581138
network_policy: AsyncNetworkPolicyOps
10591139
scenario: AsyncScenarioOps
10601140
scorer: AsyncScorerOps
@@ -1104,6 +1184,7 @@ def __init__(
11041184
self.devbox = AsyncDevboxOps(self.api)
11051185
self.blueprint = AsyncBlueprintOps(self.api)
11061186
self.gateway_config = AsyncGatewayConfigOps(self.api)
1187+
self.mcp_config = AsyncMcpConfigOps(self.api)
11071188
self.network_policy = AsyncNetworkPolicyOps(self.api)
11081189
self.scenario = AsyncScenarioOps(self.api)
11091190
self.scorer = AsyncScorerOps(self.api)
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"""McpConfig resource class for asynchronous operations."""
2+
3+
from __future__ import annotations
4+
5+
from typing_extensions import Unpack, override
6+
7+
from ._types import BaseRequestOptions, LongRequestOptions, SDKMcpConfigUpdateParams
8+
from .._client import AsyncRunloop
9+
from ..types.mcp_config_view import McpConfigView
10+
11+
12+
class AsyncMcpConfig:
13+
"""Asynchronous wrapper around an MCP config resource.
14+
15+
MCP configs define how to connect to upstream MCP (Model Context Protocol) servers.
16+
They specify the target endpoint and which tools are allowed. Use with devboxes to
17+
securely connect to MCP servers.
18+
19+
Example:
20+
>>> runloop = AsyncRunloopSDK()
21+
>>> mcp_config = await runloop.mcp_config.create(
22+
... name="my-mcp-server",
23+
... endpoint="https://mcp.example.com",
24+
... allowed_tools=["*"],
25+
... )
26+
>>> info = await mcp_config.get_info()
27+
>>> print(f"MCP Config: {info.name}")
28+
"""
29+
30+
def __init__(
31+
self,
32+
client: AsyncRunloop,
33+
mcp_config_id: str,
34+
) -> None:
35+
"""Initialize the wrapper.
36+
37+
:param client: Generated AsyncRunloop client
38+
:type client: AsyncRunloop
39+
:param mcp_config_id: McpConfig ID returned by the API
40+
:type mcp_config_id: str
41+
"""
42+
self._client = client
43+
self._id = mcp_config_id
44+
45+
@override
46+
def __repr__(self) -> str:
47+
return f"<AsyncMcpConfig id={self._id!r}>"
48+
49+
@property
50+
def id(self) -> str:
51+
"""Return the MCP config ID.
52+
53+
:return: Unique MCP config ID
54+
:rtype: str
55+
"""
56+
return self._id
57+
58+
async def get_info(
59+
self,
60+
**options: Unpack[BaseRequestOptions],
61+
) -> McpConfigView:
62+
"""Retrieve the latest MCP config details.
63+
64+
Example:
65+
>>> info = await mcp_config.get_info()
66+
>>> print(f"MCP Config: {info.name}, endpoint: {info.endpoint}")
67+
68+
:param options: Optional request configuration
69+
:return: API response describing the MCP config
70+
:rtype: McpConfigView
71+
"""
72+
return await self._client.mcp_configs.retrieve(
73+
self._id,
74+
**options,
75+
)
76+
77+
async def update(self, **params: Unpack[SDKMcpConfigUpdateParams]) -> McpConfigView:
78+
"""Update the MCP config.
79+
80+
Example:
81+
>>> updated = await mcp_config.update(
82+
... name="updated-mcp-name",
83+
... description="Updated description",
84+
... )
85+
86+
:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKMcpConfigUpdateParams` for available parameters
87+
:return: Updated MCP config view
88+
:rtype: McpConfigView
89+
"""
90+
return await self._client.mcp_configs.update(self._id, **params)
91+
92+
async def delete(
93+
self,
94+
**options: Unpack[LongRequestOptions],
95+
) -> McpConfigView:
96+
"""Delete the MCP config. This action is irreversible.
97+
98+
Example:
99+
>>> await mcp_config.delete()
100+
101+
:param options: Optional long-running request configuration
102+
:return: API response acknowledging deletion
103+
:rtype: McpConfigView
104+
"""
105+
return await self._client.mcp_configs.delete(
106+
self._id,
107+
**options,
108+
)

0 commit comments

Comments
 (0)