## Create a new tool set `tool_sets.create(workspace_id, **kwargs) -> ToolSet` **post** `/v1/workspaces/{workspaceId}/tool_sets` Creates a new tool set in the workspace ### Parameters - `workspace_id: String` - `metadata: CreateResourceMetadata` CreateResourceMetadata contains the user-provided fields for creating a workspace-scoped resource. Read-only fields (id, account_id, workspace_id, profile_id, created_at) are excluded since they are set by the server. - `name: String` Human-readable name for the resource (e.g., "Customer Support Agent", "Email Tool") - `bundle_key: String` Optional bundle ownership key. See ResourceMetadata.bundle_key. - `external_id: String` External ID for the resource (e.g., a workflow ID from an external system) - `labels: Hash[Symbol, String]` Arbitrary key-value pairs for categorization and filtering Examples: {"environment": "production", "team": "platform", "version": "v2"} - `spec: ToolSetSpec` - `adapter: ToolSetAdapter` - `http: ToolSetAdapterHTTP` - `base_url: String` - `headers: Hash[Symbol, String]` - `mcp: ToolSetAdapterMcp` - `exclude_tools: ToolFilter` Top-level filter with simple boolean logic (no nesting) - `operator: :OPERATOR_UNSPECIFIED | :OPERATOR_AND | :OPERATOR_OR` - `:OPERATOR_UNSPECIFIED` - `:OPERATOR_AND` - `:OPERATOR_OR` - `filters: Array[AttributeFilter]` - `attribute: :ATTRIBUTE_UNSPECIFIED | :ATTRIBUTE_NAME | :ATTRIBUTE_TITLE | :ATTRIBUTE_DESCRIPTION` - `:ATTRIBUTE_UNSPECIFIED` - `:ATTRIBUTE_NAME` - `:ATTRIBUTE_TITLE` - `:ATTRIBUTE_DESCRIPTION` - `matcher: StringMatcher` String matching operations - `case_sensitive: bool` - `contains: String` - `ends_with: String` - `exact: String` - `regex: String` - `starts_with: String` - `headers: Hash[Symbol, String]` - `include_tools: ToolFilter` Top-level filter with simple boolean logic (no nesting) - `tool_approvals: ApprovalRequirementFilter` Approval filters that will automatically set the approval requirement on tools synced from an external source - `always: bool` - `only: ToolFilter` Top-level filter with simple boolean logic (no nesting) - `url: String` - `openapi: ToolSetAdapterOpenAPI` - `base_url: String` Base URL for dispatching tool calls. If set, overrides the server resolved from the spec's servers array. - `exclude_tools: ToolFilter` Top-level filter with simple boolean logic (no nesting) - `headers: Hash[Symbol, String]` Headers sent when fetching the spec from a URL and when dispatching tool calls. - `include_tools: ToolFilter` Top-level filter with simple boolean logic (no nesting) - `server_name: String` Name of the server entry in the spec's servers array (OpenAPI 3.2 server.name field). Used to select which server URL to dispatch to when base_url is not set. If unset, the first server is used. Ignored when base_url is set. - `tool_approvals: ApprovalRequirementFilter` Approval filters that will automatically set the approval requirement on tools synced from an external source - `upload_id: String` ID of a COMPLETE Upload containing the OpenAPI spec document. - `url: String` URL to fetch the OpenAPI spec from. Synced automatically every hour. - `description: String` ### Returns - `class ToolSet` - `metadata: ResourceMetadata` Standard metadata for persistent, named resources (e.g., agents, tools, prompts) - `id: String` Unique identifier for the resource (prefixed ULID, e.g., "agent_01HXK...") - `account_id: String` Account this resource belongs to for multi-tenant isolation (prefixed ULID) - `created_at: Time` Timestamp when this resource was created - `name: String` Human-readable name for the resource (e.g., "Customer Support Agent", "Email Tool") Required for resources that users interact with directly - `profile_id: String` ID of the actor (user or service account) that created this resource - `workspace_id: String` Workspace this resource belongs to for organizational grouping (prefixed ULID) - `bundle_key: String` Optional bundle ownership key. When set, indicates the resource is managed by a configuration bundle identified by this key. Used by BulkWorkspaceResources.Apply to track which resources belong to which bundle for reconciliation / soft-delete on re-apply. - `external_id: String` External ID for the resource (e.g., a workflow ID from an external system) - `labels: Hash[Symbol, String]` Arbitrary key-value pairs for categorization and filtering Examples: {"environment": "production", "team": "platform", "version": "v2"} - `spec: ToolSetSpec` - `adapter: ToolSetAdapter` - `http: ToolSetAdapterHTTP` - `base_url: String` - `headers: Hash[Symbol, String]` - `mcp: ToolSetAdapterMcp` - `exclude_tools: ToolFilter` Top-level filter with simple boolean logic (no nesting) - `operator: :OPERATOR_UNSPECIFIED | :OPERATOR_AND | :OPERATOR_OR` - `:OPERATOR_UNSPECIFIED` - `:OPERATOR_AND` - `:OPERATOR_OR` - `filters: Array[AttributeFilter]` - `attribute: :ATTRIBUTE_UNSPECIFIED | :ATTRIBUTE_NAME | :ATTRIBUTE_TITLE | :ATTRIBUTE_DESCRIPTION` - `:ATTRIBUTE_UNSPECIFIED` - `:ATTRIBUTE_NAME` - `:ATTRIBUTE_TITLE` - `:ATTRIBUTE_DESCRIPTION` - `matcher: StringMatcher` String matching operations - `case_sensitive: bool` - `contains: String` - `ends_with: String` - `exact: String` - `regex: String` - `starts_with: String` - `headers: Hash[Symbol, String]` - `include_tools: ToolFilter` Top-level filter with simple boolean logic (no nesting) - `tool_approvals: ApprovalRequirementFilter` Approval filters that will automatically set the approval requirement on tools synced from an external source - `always: bool` - `only: ToolFilter` Top-level filter with simple boolean logic (no nesting) - `url: String` - `openapi: ToolSetAdapterOpenAPI` - `base_url: String` Base URL for dispatching tool calls. If set, overrides the server resolved from the spec's servers array. - `exclude_tools: ToolFilter` Top-level filter with simple boolean logic (no nesting) - `headers: Hash[Symbol, String]` Headers sent when fetching the spec from a URL and when dispatching tool calls. - `include_tools: ToolFilter` Top-level filter with simple boolean logic (no nesting) - `server_name: String` Name of the server entry in the spec's servers array (OpenAPI 3.2 server.name field). Used to select which server URL to dispatch to when base_url is not set. If unset, the first server is used. Ignored when base_url is set. - `tool_approvals: ApprovalRequirementFilter` Approval filters that will automatically set the approval requirement on tools synced from an external source - `upload_id: String` ID of a COMPLETE Upload containing the OpenAPI spec document. - `url: String` URL to fetch the OpenAPI spec from. Synced automatically every hour. - `description: String` - `info: ToolSetInfo` Tool set information - `agent_count: Integer` - `created_by: Profile` A profile identifies a user or non-human principal (such as an API key) at the account level. Profiles are account-scoped and can be granted access to multiple workspaces. - `metadata: AccountResourceMetadata` AccountResourceMetadata is used to represent a resource that is associated to an account but not to a workspace. - `id: String` Unique identifier for the resource (prefixed ULID, e.g., "apikey_01HXK...") - `account_id: String` Account this resource belongs to for multi-tenant isolation (prefixed ULID) - `name: String` Human-readable name for the resource (e.g., "Customer Support Agent", "Email Tool") Required for resources that users interact with directly - `profile_id: String` - `external_id: String` External ID for the resource (e.g., a workflow ID from an external system) - `labels: Hash[Symbol, String]` Arbitrary key-value pairs for categorization and filtering Examples: {"environment": "production", "team": "platform", "version": "v2"} - `spec: ProfileSpec` Configuration for a profile. - `type: :PROFILE_TYPE_UNSPECIFIED | :PROFILE_TYPE_USER | :PROFILE_TYPE_API_KEY | :PROFILE_TYPE_SYSTEM` Whether this profile represents a human user, an API key, or a system principal. - `:PROFILE_TYPE_UNSPECIFIED` - `:PROFILE_TYPE_USER` - `:PROFILE_TYPE_API_KEY` - `:PROFILE_TYPE_SYSTEM` - `email: String` Email address of the profile. Required and unique within an account for user profiles. - `name: String` Display name (e.g., "Bobby Tables"). - `last_sync: Time` - `tool_count: Integer` ### Example ```ruby require "cadenya" cadenya = Cadenya::Client.new(api_key: "My API Key") tool_set = cadenya.tool_sets.create("workspaceId", metadata: {name: "name"}, spec: {}) puts(tool_set) ``` #### Response ```json { "metadata": { "id": "id", "accountId": "accountId", "createdAt": "2019-12-27T18:11:19.117Z", "name": "name", "profileId": "profileId", "workspaceId": "workspaceId", "bundleKey": "bundleKey", "externalId": "externalId", "labels": { "foo": "string" } }, "spec": { "adapter": { "http": { "baseUrl": "baseUrl", "headers": { "foo": "string" } }, "mcp": { "excludeTools": { "operator": "OPERATOR_UNSPECIFIED", "filters": [ { "attribute": "ATTRIBUTE_UNSPECIFIED", "matcher": { "caseSensitive": true, "contains": "contains", "endsWith": "endsWith", "exact": "exact", "regex": "regex", "startsWith": "startsWith" } } ] }, "headers": { "foo": "string" }, "includeTools": { "operator": "OPERATOR_UNSPECIFIED", "filters": [ { "attribute": "ATTRIBUTE_UNSPECIFIED", "matcher": { "caseSensitive": true, "contains": "contains", "endsWith": "endsWith", "exact": "exact", "regex": "regex", "startsWith": "startsWith" } } ] }, "toolApprovals": { "always": true, "only": { "operator": "OPERATOR_UNSPECIFIED", "filters": [ { "attribute": "ATTRIBUTE_UNSPECIFIED", "matcher": { "caseSensitive": true, "contains": "contains", "endsWith": "endsWith", "exact": "exact", "regex": "regex", "startsWith": "startsWith" } } ] } }, "url": "url" }, "openapi": { "baseUrl": "baseUrl", "excludeTools": { "operator": "OPERATOR_UNSPECIFIED", "filters": [ { "attribute": "ATTRIBUTE_UNSPECIFIED", "matcher": { "caseSensitive": true, "contains": "contains", "endsWith": "endsWith", "exact": "exact", "regex": "regex", "startsWith": "startsWith" } } ] }, "headers": { "foo": "string" }, "includeTools": { "operator": "OPERATOR_UNSPECIFIED", "filters": [ { "attribute": "ATTRIBUTE_UNSPECIFIED", "matcher": { "caseSensitive": true, "contains": "contains", "endsWith": "endsWith", "exact": "exact", "regex": "regex", "startsWith": "startsWith" } } ] }, "serverName": "serverName", "toolApprovals": { "always": true, "only": { "operator": "OPERATOR_UNSPECIFIED", "filters": [ { "attribute": "ATTRIBUTE_UNSPECIFIED", "matcher": { "caseSensitive": true, "contains": "contains", "endsWith": "endsWith", "exact": "exact", "regex": "regex", "startsWith": "startsWith" } } ] } }, "uploadId": "uploadId", "url": "url" } }, "description": "description" }, "info": { "agentCount": 0, "createdBy": { "metadata": { "id": "id", "accountId": "accountId", "name": "name", "profileId": "profileId", "externalId": "externalId", "labels": { "foo": "string" } }, "spec": { "type": "PROFILE_TYPE_UNSPECIFIED", "email": "email", "name": "name" } }, "lastSync": "2019-12-27T18:11:19.117Z", "toolCount": 0 } } ```