diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 0d1bebe1c..64e0684f3 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "1.6.0"
+ ".": "1.7.0"
}
diff --git a/.stats.yml b/.stats.yml
index 4df441fe0..73c283357 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 113
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-37187e72e61b850045924e6cb40207159ab794114add75a2bf36c87915326306.yml
-openapi_spec_hash: 33510c114bef0847855cdaf8f55c0774
-config_hash: 9f86425631c30497276e58b744dd3654
+configured_endpoints: 117
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-15b7fd06098d8cb3639efb3b401a03d7d97a8ab4960b08077aa871f0cacb33d3.yml
+openapi_spec_hash: 93ab2fe88f9e57d8f262ad6d1179190e
+config_hash: eb28692edd68a6ae95cf92af931c9976
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 074a8b888..0b9af4f20 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,26 @@
# Changelog
+## 1.7.0 (2026-02-05)
+
+Full Changelog: [v1.6.0...v1.7.0](https://github.com/runloopai/api-client-ts/compare/v1.6.0...v1.7.0)
+
+### Features
+
+* adding MCP Config routes ([#7331](https://github.com/runloopai/api-client-ts/issues/7331)) ([81054b5](https://github.com/runloopai/api-client-ts/commit/81054b5b53a4e5244d1bf8489b610deda650600e))
+* **devbox:** add mcp configuration to devbox create ([#7341](https://github.com/runloopai/api-client-ts/issues/7341)) ([6ed219b](https://github.com/runloopai/api-client-ts/commit/6ed219bbbc44d105ca43be3f2e4265263d259b22))
+
+
+### Bug Fixes
+
+* publish-docs.yml on main failing b/c yarn binary missing in ubuntu-slim ([#712](https://github.com/runloopai/api-client-ts/issues/712)) ([13c187b](https://github.com/runloopai/api-client-ts/commit/13c187b3efa409ecad35910b11bf041217dd7679))
+
+
+### Chores
+
+* additional e2e tests for gatewayconfig + network config ([#709](https://github.com/runloopai/api-client-ts/issues/709)) ([ed48249](https://github.com/runloopai/api-client-ts/commit/ed482490613dc503893edaa2808aaad10c7f75c5))
+* **ci:** migrate fast and simple actions to ubuntu-slim runner ([#703](https://github.com/runloopai/api-client-ts/issues/703)) ([3c06589](https://github.com/runloopai/api-client-ts/commit/3c06589447650885fe143c8e5470e6231473f4e8))
+* fix workflow using slim not having yarn ([#713](https://github.com/runloopai/api-client-ts/issues/713)) ([261fc58](https://github.com/runloopai/api-client-ts/commit/261fc580c7ccd3aeda0dbd99af31c2b42b4882ae))
+
## 1.6.0 (2026-02-04)
Full Changelog: [v1.5.1...v1.6.0](https://github.com/runloopai/api-client-ts/compare/v1.5.1...v1.6.0)
diff --git a/api.md b/api.md
index 3e18b4fb5..27681f9f7 100644
--- a/api.md
+++ b/api.md
@@ -267,7 +267,6 @@ Types:
- ScorerRetrieveResponse
- ScorerUpdateResponse
- ScorerListResponse
-- ScorerValidateResponse
Methods:
@@ -275,7 +274,6 @@ Methods:
- client.scenarios.scorers.retrieve(id) -> ScorerRetrieveResponse
- client.scenarios.scorers.update(id, { ...params }) -> ScorerUpdateResponse
- client.scenarios.scorers.list({ ...params }) -> ScorerListResponsesScenarioScorersCursorIDPage
-- client.scenarios.scorers.validate(id, { ...params }) -> ScorerValidateResponse
# Objects
@@ -368,3 +366,20 @@ Methods:
- client.gatewayConfigs.update(id, { ...params }) -> GatewayConfigView
- client.gatewayConfigs.list({ ...params }) -> GatewayConfigViewsGatewayConfigsCursorIDPage
- client.gatewayConfigs.delete(id) -> GatewayConfigView
+
+# McpConfigs
+
+Types:
+
+- McpConfigCreateParameters
+- McpConfigListView
+- McpConfigUpdateParameters
+- McpConfigView
+
+Methods:
+
+- client.mcpConfigs.create({ ...params }) -> McpConfigView
+- client.mcpConfigs.retrieve(id) -> McpConfigView
+- client.mcpConfigs.update(id, { ...params }) -> McpConfigView
+- client.mcpConfigs.list({ ...params }) -> McpConfigViewsMcpConfigsCursorIDPage
+- client.mcpConfigs.delete(id) -> McpConfigView
diff --git a/package.json b/package.json
index 6730742a1..83d1de3de 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@runloop/api-client",
- "version": "1.6.0",
+ "version": "1.7.0",
"description": "The official TypeScript library for the Runloop API",
"author": "Runloop ",
"types": "dist/sdk.d.ts",
diff --git a/src/index.ts b/src/index.ts
index 9b97bf0e3..15e19ad55 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -19,6 +19,8 @@ import {
DiskSnapshotsCursorIDPageResponse,
type GatewayConfigsCursorIDPageParams,
GatewayConfigsCursorIDPageResponse,
+ type McpConfigsCursorIDPageParams,
+ McpConfigsCursorIDPageResponse,
type NetworkPoliciesCursorIDPageParams,
NetworkPoliciesCursorIDPageResponse,
type ObjectsCursorIDPageParams,
@@ -106,6 +108,18 @@ import {
GatewayConfigViewsGatewayConfigsCursorIDPage,
GatewayConfigs,
} from './resources/gateway-configs';
+import {
+ McpConfigCreateParameters,
+ McpConfigCreateParams,
+ McpConfigDeleteParams,
+ McpConfigListParams,
+ McpConfigListView,
+ McpConfigUpdateParameters,
+ McpConfigUpdateParams,
+ McpConfigView,
+ McpConfigViewsMcpConfigsCursorIDPage,
+ McpConfigs,
+} from './resources/mcp-configs';
import {
NetworkPolicies,
NetworkPolicyCreateParameters,
@@ -359,6 +373,7 @@ export class Runloop extends Core.APIClient {
secrets: API.Secrets = new API.Secrets(this);
networkPolicies: API.NetworkPolicies = new API.NetworkPolicies(this);
gatewayConfigs: API.GatewayConfigs = new API.GatewayConfigs(this);
+ mcpConfigs: API.McpConfigs = new API.McpConfigs(this);
/**
* Check whether the base URL is set to its default.
@@ -426,6 +441,8 @@ Runloop.NetworkPolicies = NetworkPolicies;
Runloop.NetworkPolicyViewsNetworkPoliciesCursorIDPage = NetworkPolicyViewsNetworkPoliciesCursorIDPage;
Runloop.GatewayConfigs = GatewayConfigs;
Runloop.GatewayConfigViewsGatewayConfigsCursorIDPage = GatewayConfigViewsGatewayConfigsCursorIDPage;
+Runloop.McpConfigs = McpConfigs;
+Runloop.McpConfigViewsMcpConfigsCursorIDPage = McpConfigViewsMcpConfigsCursorIDPage;
export declare namespace Runloop {
export type RequestOptions = Core.RequestOptions;
@@ -508,6 +525,12 @@ export declare namespace Runloop {
type GatewayConfigsCursorIDPageResponse as GatewayConfigsCursorIDPageResponse,
};
+ export import McpConfigsCursorIDPage = Pagination.McpConfigsCursorIDPage;
+ export {
+ type McpConfigsCursorIDPageParams as McpConfigsCursorIDPageParams,
+ type McpConfigsCursorIDPageResponse as McpConfigsCursorIDPageResponse,
+ };
+
export {
Benchmarks as Benchmarks,
type BenchmarkCreateParameters as BenchmarkCreateParameters,
@@ -708,6 +731,19 @@ export declare namespace Runloop {
type GatewayConfigDeleteParams as GatewayConfigDeleteParams,
};
+ export {
+ McpConfigs as McpConfigs,
+ type McpConfigCreateParameters as McpConfigCreateParameters,
+ type McpConfigListView as McpConfigListView,
+ type McpConfigUpdateParameters as McpConfigUpdateParameters,
+ type McpConfigView as McpConfigView,
+ McpConfigViewsMcpConfigsCursorIDPage as McpConfigViewsMcpConfigsCursorIDPage,
+ type McpConfigCreateParams as McpConfigCreateParams,
+ type McpConfigUpdateParams as McpConfigUpdateParams,
+ type McpConfigListParams as McpConfigListParams,
+ type McpConfigDeleteParams as McpConfigDeleteParams,
+ };
+
export type AfterIdle = API.AfterIdle;
export type AgentMount = API.AgentMount;
export type AgentSource = API.AgentSource;
diff --git a/src/pagination.ts b/src/pagination.ts
index 3f8349214..1db21e1b7 100644
--- a/src/pagination.ts
+++ b/src/pagination.ts
@@ -963,3 +963,77 @@ export class GatewayConfigsCursorIDPage-
return { params: { starting_after: id } };
}
}
+
+export interface McpConfigsCursorIDPageResponse
- {
+ mcp_configs: Array
- ;
+
+ has_more: boolean;
+
+ total_count: number;
+}
+
+export interface McpConfigsCursorIDPageParams {
+ starting_after?: string;
+
+ limit?: number;
+}
+
+export class McpConfigsCursorIDPage
-
+ extends AbstractPage
-
+ implements McpConfigsCursorIDPageResponse
-
+{
+ mcp_configs: Array
- ;
+
+ has_more: boolean;
+
+ total_count: number;
+
+ constructor(
+ client: APIClient,
+ response: Response,
+ body: McpConfigsCursorIDPageResponse
- ,
+ options: FinalRequestOptions,
+ ) {
+ super(client, response, body, options);
+
+ this.mcp_configs = body.mcp_configs || [];
+ this.has_more = body.has_more || false;
+ this.total_count = body.total_count || 0;
+ }
+
+ getPaginatedItems(): Item[] {
+ return this.mcp_configs ?? [];
+ }
+
+ override hasNextPage(): boolean {
+ if (this.has_more === false) {
+ return false;
+ }
+
+ return super.hasNextPage();
+ }
+
+ // @deprecated Please use `nextPageInfo()` instead
+ nextPageParams(): Partial | null {
+ const info = this.nextPageInfo();
+ if (!info) return null;
+ if ('params' in info) return info.params;
+ const params = Object.fromEntries(info.url.searchParams);
+ if (!Object.keys(params).length) return null;
+ return params;
+ }
+
+ nextPageInfo(): PageInfo | null {
+ const mcpConfigs = this.getPaginatedItems();
+ if (!mcpConfigs.length) {
+ return null;
+ }
+
+ const id = mcpConfigs[mcpConfigs.length - 1]?.id;
+ if (!id) {
+ return null;
+ }
+
+ return { params: { starting_after: id } };
+ }
+}
diff --git a/src/resources/devboxes/devboxes.ts b/src/resources/devboxes/devboxes.ts
index 81390fe84..9210e2864 100644
--- a/src/resources/devboxes/devboxes.ts
+++ b/src/resources/devboxes/devboxes.ts
@@ -1104,6 +1104,14 @@ export interface DevboxCreateParams {
*/
launch_parameters?: Shared.LaunchParameters | null;
+ /**
+ * [Beta] (Optional) MCP specifications for MCP server access. Each spec links an
+ * MCP config to a secret. The devbox will receive environment variables
+ * (RL_MCP_URL, RL_MCP_TOKEN) for accessing MCP servers through the MCP hub.
+ * Example: [{'mcp_config': 'github-readonly', 'secret': 'MY_GITHUB_TOKEN'}]
+ */
+ mcp?: Array | null;
+
/**
* User defined metadata to attach to the devbox for organization.
*/
@@ -1164,6 +1172,24 @@ export namespace DevboxCreateParams {
secret: string;
}
+ /**
+ * [Beta] McpSpec links an MCP configuration to a secret for MCP server access in a
+ * devbox. The MCP hub will proxy requests to upstream MCP servers using the
+ * specified credential, with tool-level access control based on the MCP config's
+ * allowed_tools.
+ */
+ export interface Mcp {
+ /**
+ * The MCP config to use. Can be an MCP config ID (mcp_xxx) or name.
+ */
+ mcp_config: string;
+
+ /**
+ * The secret containing the MCP server credential. Can be a secret ID or name.
+ */
+ secret: string;
+ }
+
/**
* (Optional) Configuration for creating a V2 tunnel at Devbox launch time. When
* specified, a tunnel will be automatically provisioned and the tunnel details
diff --git a/src/resources/index.ts b/src/resources/index.ts
index c015661df..5ff244289 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -113,6 +113,18 @@ export {
type GatewayConfigListParams,
type GatewayConfigDeleteParams,
} from './gateway-configs';
+export {
+ McpConfigViewsMcpConfigsCursorIDPage,
+ McpConfigs,
+ type McpConfigCreateParameters,
+ type McpConfigListView,
+ type McpConfigUpdateParameters,
+ type McpConfigView,
+ type McpConfigCreateParams,
+ type McpConfigUpdateParams,
+ type McpConfigListParams,
+ type McpConfigDeleteParams,
+} from './mcp-configs';
export {
NetworkPolicyViewsNetworkPoliciesCursorIDPage,
NetworkPolicies,
diff --git a/src/resources/mcp-configs.ts b/src/resources/mcp-configs.ts
new file mode 100644
index 000000000..21a9e8939
--- /dev/null
+++ b/src/resources/mcp-configs.ts
@@ -0,0 +1,269 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../resource';
+import { isRequestOptions } from '../core';
+import * as Core from '../core';
+import { McpConfigsCursorIDPage, type McpConfigsCursorIDPageParams } from '../pagination';
+
+export class McpConfigs extends APIResource {
+ /**
+ * [Beta] Create a new McpConfig to connect to an upstream MCP (Model Context
+ * Protocol) server. The config specifies the target endpoint and which tools are
+ * allowed.
+ */
+ create(body: McpConfigCreateParams, options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.post('/v1/mcp-configs', { body, ...options });
+ }
+
+ /**
+ * [Beta] Get a specific McpConfig by its unique identifier.
+ */
+ retrieve(id: string, options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.get(`/v1/mcp-configs/${id}`, options);
+ }
+
+ /**
+ * [Beta] Update an existing McpConfig. All fields are optional.
+ */
+ update(
+ id: string,
+ body?: McpConfigUpdateParams,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise;
+ update(id: string, options?: Core.RequestOptions): Core.APIPromise;
+ update(
+ id: string,
+ body: McpConfigUpdateParams | Core.RequestOptions = {},
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ if (isRequestOptions(body)) {
+ return this.update(id, {}, body);
+ }
+ return this._client.post(`/v1/mcp-configs/${id}`, { body, ...options });
+ }
+
+ /**
+ * [Beta] List all McpConfigs for the authenticated account.
+ */
+ list(
+ query?: McpConfigListParams,
+ options?: Core.RequestOptions,
+ ): Core.PagePromise;
+ list(options?: Core.RequestOptions): Core.PagePromise;
+ list(
+ query: McpConfigListParams | Core.RequestOptions = {},
+ options?: Core.RequestOptions,
+ ): Core.PagePromise {
+ if (isRequestOptions(query)) {
+ return this.list({}, query);
+ }
+ return this._client.getAPIList('/v1/mcp-configs', McpConfigViewsMcpConfigsCursorIDPage, {
+ query,
+ ...options,
+ });
+ }
+
+ /**
+ * [Beta] Delete an existing McpConfig. This action is irreversible.
+ */
+ delete(
+ id: string,
+ body?: McpConfigDeleteParams | null | undefined,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ return this._client.post(`/v1/mcp-configs/${id}/delete`, { body, ...options });
+ }
+}
+
+export class McpConfigViewsMcpConfigsCursorIDPage extends McpConfigsCursorIDPage {}
+
+/**
+ * Parameters required to create a new McpConfig.
+ */
+export interface McpConfigCreateParameters {
+ /**
+ * Glob patterns specifying which tools are allowed from this MCP server. Examples:
+ * ['*'] for all tools, ['github.search_*', 'github.get_*'] for specific patterns.
+ */
+ allowed_tools: Array;
+
+ /**
+ * The target MCP server endpoint URL (e.g., 'https://mcp.example.com').
+ */
+ endpoint: string;
+
+ /**
+ * The human-readable name for the McpConfig. Must be unique within your account.
+ * The first segment before '-' is used as the service name for tool routing (e.g.,
+ * 'github-readonly' uses 'github' as the service name).
+ */
+ name: string;
+
+ /**
+ * Optional description for this MCP configuration.
+ */
+ description?: string | null;
+}
+
+/**
+ * A paginated list of McpConfigs.
+ */
+export interface McpConfigListView {
+ /**
+ * Whether there are more results available beyond this page.
+ */
+ has_more: boolean;
+
+ /**
+ * The list of McpConfigs.
+ */
+ mcp_configs: Array;
+
+ /**
+ * Total count of McpConfigs that match the query.
+ */
+ total_count: number;
+}
+
+/**
+ * Parameters for updating an existing McpConfig. All fields are optional - only
+ * specified fields will be updated.
+ */
+export interface McpConfigUpdateParameters {
+ /**
+ * New glob patterns specifying which tools are allowed. Examples: ['*'] for all
+ * tools, ['github.search_*'] for specific patterns.
+ */
+ allowed_tools?: Array | null;
+
+ /**
+ * New description for this MCP configuration.
+ */
+ description?: string | null;
+
+ /**
+ * New target MCP server endpoint URL.
+ */
+ endpoint?: string | null;
+
+ /**
+ * New name for the McpConfig. Must be unique within your account.
+ */
+ name?: string | null;
+}
+
+/**
+ * An McpConfig defines a configuration for connecting to an upstream MCP (Model
+ * Context Protocol) server. It specifies the target endpoint and which tools are
+ * allowed.
+ */
+export interface McpConfigView {
+ /**
+ * The unique identifier of the McpConfig.
+ */
+ id: string;
+
+ /**
+ * Glob patterns specifying which tools are allowed from this MCP server (e.g.,
+ * ['github.search_*', 'github.get_*'] or ['*'] for all tools).
+ */
+ allowed_tools: Array;
+
+ /**
+ * Creation time of the McpConfig (Unix timestamp in milliseconds).
+ */
+ create_time_ms: number;
+
+ /**
+ * The target MCP server endpoint URL (e.g., 'https://mcp.example.com').
+ */
+ endpoint: string;
+
+ /**
+ * The human-readable name of the McpConfig. Unique per account.
+ */
+ name: string;
+
+ /**
+ * Optional description for this MCP configuration.
+ */
+ description?: string | null;
+}
+
+export interface McpConfigCreateParams {
+ /**
+ * Glob patterns specifying which tools are allowed from this MCP server. Examples:
+ * ['*'] for all tools, ['github.search_*', 'github.get_*'] for specific patterns.
+ */
+ allowed_tools: Array;
+
+ /**
+ * The target MCP server endpoint URL (e.g., 'https://mcp.example.com').
+ */
+ endpoint: string;
+
+ /**
+ * The human-readable name for the McpConfig. Must be unique within your account.
+ * The first segment before '-' is used as the service name for tool routing (e.g.,
+ * 'github-readonly' uses 'github' as the service name).
+ */
+ name: string;
+
+ /**
+ * Optional description for this MCP configuration.
+ */
+ description?: string | null;
+}
+
+export interface McpConfigUpdateParams {
+ /**
+ * New glob patterns specifying which tools are allowed. Examples: ['*'] for all
+ * tools, ['github.search_*'] for specific patterns.
+ */
+ allowed_tools?: Array | null;
+
+ /**
+ * New description for this MCP configuration.
+ */
+ description?: string | null;
+
+ /**
+ * New target MCP server endpoint URL.
+ */
+ endpoint?: string | null;
+
+ /**
+ * New name for the McpConfig. Must be unique within your account.
+ */
+ name?: string | null;
+}
+
+export interface McpConfigListParams extends McpConfigsCursorIDPageParams {
+ /**
+ * Filter by ID.
+ */
+ id?: string;
+
+ /**
+ * Filter by name (prefix match supported).
+ */
+ name?: string;
+}
+
+export interface McpConfigDeleteParams {}
+
+McpConfigs.McpConfigViewsMcpConfigsCursorIDPage = McpConfigViewsMcpConfigsCursorIDPage;
+
+export declare namespace McpConfigs {
+ export {
+ type McpConfigCreateParameters as McpConfigCreateParameters,
+ type McpConfigListView as McpConfigListView,
+ type McpConfigUpdateParameters as McpConfigUpdateParameters,
+ type McpConfigView as McpConfigView,
+ McpConfigViewsMcpConfigsCursorIDPage as McpConfigViewsMcpConfigsCursorIDPage,
+ type McpConfigCreateParams as McpConfigCreateParams,
+ type McpConfigUpdateParams as McpConfigUpdateParams,
+ type McpConfigListParams as McpConfigListParams,
+ type McpConfigDeleteParams as McpConfigDeleteParams,
+ };
+}
diff --git a/src/resources/scenarios/index.ts b/src/resources/scenarios/index.ts
index bd2b01cc8..ae4589143 100644
--- a/src/resources/scenarios/index.ts
+++ b/src/resources/scenarios/index.ts
@@ -32,9 +32,7 @@ export {
type ScorerRetrieveResponse,
type ScorerUpdateResponse,
type ScorerListResponse,
- type ScorerValidateResponse,
type ScorerCreateParams,
type ScorerUpdateParams,
type ScorerListParams,
- type ScorerValidateParams,
} from './scorers';
diff --git a/src/resources/scenarios/scenarios.ts b/src/resources/scenarios/scenarios.ts
index 90d67878c..f0c127c7d 100644
--- a/src/resources/scenarios/scenarios.ts
+++ b/src/resources/scenarios/scenarios.ts
@@ -16,8 +16,6 @@ import {
ScorerRetrieveResponse,
ScorerUpdateParams,
ScorerUpdateResponse,
- ScorerValidateParams,
- ScorerValidateResponse,
Scorers,
} from './scorers';
import {
@@ -882,11 +880,9 @@ export declare namespace Scenarios {
type ScorerRetrieveResponse as ScorerRetrieveResponse,
type ScorerUpdateResponse as ScorerUpdateResponse,
type ScorerListResponse as ScorerListResponse,
- type ScorerValidateResponse as ScorerValidateResponse,
ScorerListResponsesScenarioScorersCursorIDPage as ScorerListResponsesScenarioScorersCursorIDPage,
type ScorerCreateParams as ScorerCreateParams,
type ScorerUpdateParams as ScorerUpdateParams,
type ScorerListParams as ScorerListParams,
- type ScorerValidateParams as ScorerValidateParams,
};
}
diff --git a/src/resources/scenarios/scorers.ts b/src/resources/scenarios/scorers.ts
index 5e5d0f892..86fbac8d8 100644
--- a/src/resources/scenarios/scorers.ts
+++ b/src/resources/scenarios/scorers.ts
@@ -3,7 +3,6 @@
import { APIResource } from '../../resource';
import { isRequestOptions } from '../../core';
import * as Core from '../../core';
-import * as ScenariosAPI from './scenarios';
import { ScenarioScorersCursorIDPage, type ScenarioScorersCursorIDPageParams } from '../../pagination';
export class Scorers extends APIResource {
@@ -54,17 +53,6 @@ export class Scorers extends APIResource {
...options,
});
}
-
- /**
- * Validate a scenario scorer.
- */
- validate(
- id: string,
- body: ScorerValidateParams,
- options?: Core.RequestOptions,
- ): Core.APIPromise {
- return this._client.post(`/v1/scenarios/scorers/${id}/validate`, { body, ...options });
- }
}
export class ScorerListResponsesScenarioScorersCursorIDPage extends ScenarioScorersCursorIDPage {}
@@ -149,28 +137,6 @@ export interface ScorerListResponse {
type: string;
}
-export interface ScorerValidateResponse {
- /**
- * Name of the custom scorer.
- */
- name: string;
-
- /**
- * Json context that gets passed to the custom scorer
- */
- scoring_context: unknown;
-
- /**
- * Result of the scoring function.
- */
- scoring_result: ScenariosAPI.ScoringFunctionResultView;
-
- /**
- * The Environment in which the Scenario will run.
- */
- environment_parameters?: ScenariosAPI.ScenarioEnvironment;
-}
-
export interface ScorerCreateParams {
/**
* Bash script for the custom scorer taking context as a json object
@@ -199,18 +165,6 @@ export interface ScorerUpdateParams {
export interface ScorerListParams extends ScenarioScorersCursorIDPageParams {}
-export interface ScorerValidateParams {
- /**
- * Json context that gets passed to the custom scorer
- */
- scoring_context: unknown;
-
- /**
- * The Environment in which the Scenario will run.
- */
- environment_parameters?: ScenariosAPI.ScenarioEnvironment;
-}
-
Scorers.ScorerListResponsesScenarioScorersCursorIDPage = ScorerListResponsesScenarioScorersCursorIDPage;
export declare namespace Scorers {
@@ -219,11 +173,9 @@ export declare namespace Scorers {
type ScorerRetrieveResponse as ScorerRetrieveResponse,
type ScorerUpdateResponse as ScorerUpdateResponse,
type ScorerListResponse as ScorerListResponse,
- type ScorerValidateResponse as ScorerValidateResponse,
ScorerListResponsesScenarioScorersCursorIDPage as ScorerListResponsesScenarioScorersCursorIDPage,
type ScorerCreateParams as ScorerCreateParams,
type ScorerUpdateParams as ScorerUpdateParams,
type ScorerListParams as ScorerListParams,
- type ScorerValidateParams as ScorerValidateParams,
};
}
diff --git a/src/sdk/scorer.ts b/src/sdk/scorer.ts
index 00241fca0..f7821c51b 100644
--- a/src/sdk/scorer.ts
+++ b/src/sdk/scorer.ts
@@ -6,8 +6,6 @@ import type {
ScorerRetrieveResponse,
ScorerUpdateResponse,
ScorerUpdateParams,
- ScorerValidateParams,
- ScorerValidateResponse,
} from '../resources/scenarios/scorers';
/**
@@ -32,8 +30,8 @@ import type {
* bash_script: 'echo "1.0"',
* });
*
- * const result = await scorer.validate({ scoring_context: { output: 'test' } });
- * console.log(`Score: ${result.scoring_result.score}`);
+ * const info = await scorer.getInfo();
+ * console.log(`Scorer type: ${info.type}`);
* ```
*/
export class Scorer {
@@ -176,27 +174,4 @@ export class Scorer {
async update(params: ScorerUpdateParams, options?: Core.RequestOptions): Promise {
return this.client.scenarios.scorers.update(this._id, params, options);
}
-
- /**
- * Run the scorer against the provided context and return the result.
- *
- * @example
- * ```typescript
- * const result = await scorer.validate({
- * scoring_context: { output: 'test output', expected: 'test output' }
- * });
- * console.log(`Validation score: ${result.scoring_result.score}`);
- * console.log(`Output: ${result.scoring_result.output}`);
- * ```
- *
- * @param {ScorerValidateParams} params - Validation parameters
- * @param {Core.RequestOptions} [options] - Request options
- * @returns {Promise} Validation result with score
- */
- async validate(
- params: ScorerValidateParams,
- options?: Core.RequestOptions,
- ): Promise {
- return this.client.scenarios.scorers.validate(this._id, params, options);
- }
}
diff --git a/src/version.ts b/src/version.ts
index 8fe4c2e5a..1c2e26105 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '1.6.0'; // x-release-please-version
+export const VERSION = '1.7.0'; // x-release-please-version
diff --git a/tests/api-resources/devboxes/devboxes.test.ts b/tests/api-resources/devboxes/devboxes.test.ts
index 87be10290..06d942371 100644
--- a/tests/api-resources/devboxes/devboxes.test.ts
+++ b/tests/api-resources/devboxes/devboxes.test.ts
@@ -61,6 +61,7 @@ describe('resource devboxes', () => {
resource_size_request: 'X_SMALL',
user_parameters: { uid: 0, username: 'username' },
},
+ mcp: [{ mcp_config: 'mcp_config', secret: 'secret' }],
metadata: { foo: 'string' },
mounts: [
{
diff --git a/tests/api-resources/mcp-configs.test.ts b/tests/api-resources/mcp-configs.test.ts
new file mode 100644
index 000000000..78a8f38bb
--- /dev/null
+++ b/tests/api-resources/mcp-configs.test.ts
@@ -0,0 +1,138 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Runloop from '@runloop/api-client';
+import { Response } from 'node-fetch';
+
+const client = new Runloop({
+ bearerToken: 'My Bearer Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource mcpConfigs', () => {
+ test('create: only required params', async () => {
+ const responsePromise = client.mcpConfigs.create({
+ allowed_tools: ['string'],
+ endpoint: 'endpoint',
+ name: 'name',
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('create: required and optional params', async () => {
+ const response = await client.mcpConfigs.create({
+ allowed_tools: ['string'],
+ endpoint: 'endpoint',
+ name: 'name',
+ description: 'description',
+ });
+ });
+
+ test('retrieve', async () => {
+ const responsePromise = client.mcpConfigs.retrieve('id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('retrieve: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.mcpConfigs.retrieve('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Runloop.NotFoundError,
+ );
+ });
+
+ test('update', async () => {
+ const responsePromise = client.mcpConfigs.update('id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('update: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.mcpConfigs.update('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Runloop.NotFoundError,
+ );
+ });
+
+ test('update: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.mcpConfigs.update(
+ 'id',
+ {
+ allowed_tools: ['string'],
+ description: 'description',
+ endpoint: 'endpoint',
+ name: 'name',
+ },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(Runloop.NotFoundError);
+ });
+
+ test('list', async () => {
+ const responsePromise = client.mcpConfigs.list();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('list: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.mcpConfigs.list({ path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Runloop.NotFoundError,
+ );
+ });
+
+ test('list: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.mcpConfigs.list(
+ {
+ id: 'id',
+ limit: 0,
+ name: 'name',
+ starting_after: 'starting_after',
+ },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(Runloop.NotFoundError);
+ });
+
+ test('delete', async () => {
+ const responsePromise = client.mcpConfigs.delete('id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('delete: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.mcpConfigs.delete('id', {}, { path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Runloop.NotFoundError,
+ );
+ });
+});
diff --git a/tests/api-resources/scenarios/scorers.test.ts b/tests/api-resources/scenarios/scorers.test.ts
index a5c36efe7..b78ab2bb0 100644
--- a/tests/api-resources/scenarios/scorers.test.ts
+++ b/tests/api-resources/scenarios/scorers.test.ts
@@ -90,40 +90,4 @@ describe('resource scorers', () => {
),
).rejects.toThrow(Runloop.NotFoundError);
});
-
- test('validate: only required params', async () => {
- const responsePromise = client.scenarios.scorers.validate('id', { scoring_context: {} });
- const rawResponse = await responsePromise.asResponse();
- expect(rawResponse).toBeInstanceOf(Response);
- const response = await responsePromise;
- expect(response).not.toBeInstanceOf(Response);
- const dataAndResponse = await responsePromise.withResponse();
- expect(dataAndResponse.data).toBe(response);
- expect(dataAndResponse.response).toBe(rawResponse);
- });
-
- test('validate: required and optional params', async () => {
- const response = await client.scenarios.scorers.validate('id', {
- scoring_context: {},
- environment_parameters: {
- blueprint_id: 'blueprint_id',
- launch_parameters: {
- after_idle: { idle_time_seconds: 0, on_idle: 'shutdown' },
- architecture: 'x86_64',
- available_ports: [0],
- custom_cpu_cores: 0,
- custom_disk_size: 0,
- custom_gb_memory: 0,
- keep_alive_time_seconds: 0,
- launch_commands: ['string'],
- network_policy_id: 'network_policy_id',
- required_services: ['string'],
- resource_size_request: 'X_SMALL',
- user_parameters: { uid: 0, username: 'username' },
- },
- snapshot_id: 'snapshot_id',
- working_directory: 'working_directory',
- },
- });
- });
});
diff --git a/tests/objects/scorer.test.ts b/tests/objects/scorer.test.ts
index 337555a1b..6cfbdfda1 100644
--- a/tests/objects/scorer.test.ts
+++ b/tests/objects/scorer.test.ts
@@ -2,7 +2,6 @@ import { Scorer } from '../../src/sdk/scorer';
import type {
ScorerRetrieveResponse,
ScorerUpdateResponse,
- ScorerValidateResponse,
} from '../../src/resources/scenarios/scorers';
// Mock the Runloop client
@@ -11,7 +10,6 @@ jest.mock('../../src/index');
describe('Scorer', () => {
let mockClient: any;
let mockScorerData: ScorerRetrieveResponse;
- let mockValidateResult: ScorerValidateResponse;
beforeEach(() => {
mockClient = {
@@ -20,7 +18,6 @@ describe('Scorer', () => {
create: jest.fn(),
retrieve: jest.fn(),
update: jest.fn(),
- validate: jest.fn(),
list: jest.fn(),
},
},
@@ -32,16 +29,6 @@ describe('Scorer', () => {
bash_script: 'echo "1.0"',
};
- mockValidateResult = {
- name: 'my_custom_scorer',
- scoring_context: { output: 'test' },
- scoring_result: {
- output: '1.0',
- score: 1.0,
- state: 'complete',
- scoring_function_name: 'test-scorer',
- },
- };
});
describe('fromId', () => {
@@ -188,38 +175,6 @@ describe('Scorer', () => {
});
});
- describe('validate', () => {
- it('should validate scorer with scoring context', async () => {
- mockClient.scenarios.scorers.validate.mockResolvedValue(mockValidateResult);
-
- const scorer = Scorer.fromId(mockClient, 'scs_123');
- const result = await scorer.validate({
- scoring_context: { output: 'test output', expected: 'expected output' },
- });
-
- expect(mockClient.scenarios.scorers.validate).toHaveBeenCalledWith(
- 'scs_123',
- { scoring_context: { output: 'test output', expected: 'expected output' } },
- undefined,
- );
- expect(result.scoring_result.score).toBe(1.0);
- expect(result.scoring_result.output).toBe('1.0');
- });
-
- it('should pass options to the API client', async () => {
- mockClient.scenarios.scorers.validate.mockResolvedValue(mockValidateResult);
-
- const scorer = Scorer.fromId(mockClient, 'scs_123');
- await scorer.validate({ scoring_context: {} }, { timeout: 30000 });
-
- expect(mockClient.scenarios.scorers.validate).toHaveBeenCalledWith(
- 'scs_123',
- { scoring_context: {} },
- { timeout: 30000 },
- );
- });
- });
-
describe('error handling', () => {
it('should handle API errors on getInfo', async () => {
const error = new Error('Scorer not found');
@@ -241,13 +196,5 @@ describe('Scorer', () => {
);
});
- it('should handle API errors on validate', async () => {
- const error = new Error('Validation timeout');
- mockClient.scenarios.scorers.validate.mockRejectedValue(error);
-
- const scorer = Scorer.fromId(mockClient, 'scs_123');
-
- await expect(scorer.validate({ scoring_context: {} })).rejects.toThrow('Validation timeout');
- });
});
});