sandpi/ platform

Configure the workspace

MCP servers

Connect tools with credentials, OAuth and tool policies.

On this page

Connect an Environment tool server

MCP servers belong to the Environment and apply across its harness Sessions. Manage them in TUI Settings or the Platform console, or use the MCP API details. Hosted Environments support HTTP, SSE and local stdio commands, secret header credentials, OAuth and exact-name tool allow/deny policies. MCP credentials are separate from model provider credentials. Checks and authorization execute inside the Environment under its network policy.

Updates require the current configuration revision and conflict while a Run or rollback holds the Environment lifecycle lock. Restart an open terminal after changing the tool catalog. A fork copies configuration without credentials; rollback retains the current configuration. Read APIs never reveal secret values.

Create an Environment MCP server

POST /v1/environments/{environmentId}/mcp-servers

MCP configuration belongs to the Environment and is shared by its harness Sessions. Secrets are write-only and remain outside RootFS snapshots. Configuration changes apply to subsequent Runs and restarted terminals. Operations require the Environment to be idle; active Runs return 409.

Authentication: Platform API bearer token

Parameters and headers
FieldType and constraintsRequiredDescription
path: environmentIdstring · min length 1YesEnvironment identifier. It must belong to the caller’s account or Project.

Request example

sh
curl -X POST \
    "https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/mcp-servers" \
    -H "Authorization: Bearer $SANDPI_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
  "name": "tools",
  "transport": "http",
  "url": "https://mcp.example.com/mcp",
  "enabled": true,
  "authentication": "none",
  "toolPolicy": {
    "mode": "all",
    "tools": []
  }
}'
Request body · required application/json

MCP configuration and optional write-only credentials for creation.

FieldType and constraintsRequiredDescription
namestring
Validation pattern^[a-z][a-z0-9_-]{0,47}$
YesHuman-readable name for this resource.
transportstring · values: "stdio" | "http" | "sse"YesMCP transport: sandbox-local stdio, HTTP or legacy SSE.
urlstring · format: uri; max length 2048NoRemote MCP endpoint for HTTP or SSE transport; not used for sandbox-local stdio.
commandstring · min length 1; max length 2048NoCommand executable to launch inside the Environment for stdio transport.
argsarray · max 64 itemsNoArguments passed to the stdio command inside the Environment.
args[]string · max length 4096Yeseach array item—
enabledbooleanYesWhether this configuration is enabled for future use.
authenticationstring · values: "none" | "headers" | "oauth"YesAuthentication mode used for this MCP connection.
oauthobject · extra fields rejectedNoOAuth client configuration for an HTTP or SSE MCP server.
oauth.clientIdstring · min length 1; max length 512Nowithin oauthOAuth client identifier; provide one when the upstream service requires it.
oauth.scopesarray · max 32 itemsNowithin oauthOAuth scopes requested from the upstream service.
oauth.scopes[]string · min length 1; max length 128Yeseach array item—
toolPolicyobject · extra fields rejectedYesManaged MCP policy: all tools, exact-name allow list or exact-name deny list.
toolPolicy.modestring · values: "all" | "allow" | "deny"Yeswithin toolPolicySelected behavior variant; use one of the allowed values.
toolPolicy.toolsarray · max 256 itemsYeswithin toolPolicyTool names associated with this resource or policy.
toolPolicy.tools[]string · min length 1; max length 128Yeseach array item—
materialobject · write only; extra fields rejectedNoWrite-only MCP credentials. Reads expose only credential presence.
material.headersobject · max 32 keysNowithin materialHeader definitions or secret header values applied by this configuration.
material.headers.{key}string · max length 8192Noadditional keys—
material.envobject · max 64 keysNowithin materialWrite-only environment variables supplied to a stdio MCP command.
material.env.{key}string · max length 8192Noadditional keys—
material.clientSecretstring · max length 8192Nowithin materialWrite-only OAuth client secret, when the service requires one.
Example
Example
{
  "name": "tools",
  "transport": "http",
  "url": "https://mcp.example.com/mcp",
  "enabled": true,
  "authentication": "none",
  "toolPolicy": {
    "mode": "all",
    "tools": []
  }
}

Responses

201 Successful response.
Response body application/json
FieldType and constraintsRequiredDescription
dataobject · extra fields rejectedYesNon-secret MCP configuration, revision and observed connection state.
data.namestring
Validation pattern^[a-z][a-z0-9_-]{0,47}$
Yeswithin dataHuman-readable name for this resource.
data.transportstring · values: "stdio" | "http" | "sse"Yeswithin dataMCP transport: sandbox-local stdio, HTTP or legacy SSE.
data.urlstring · format: uri; max length 2048Nowithin dataRemote MCP endpoint for HTTP or SSE transport; not used for sandbox-local stdio.
data.commandstring · min length 1; max length 2048Nowithin dataCommand executable to launch inside the Environment for stdio transport.
data.argsarray · max 64 itemsNowithin dataArguments passed to the stdio command inside the Environment.
data.args[]string · max length 4096Yeseach array item—
data.enabledbooleanYeswithin dataWhether this configuration is enabled for future use.
data.authenticationstring · values: "none" | "headers" | "oauth"Yeswithin dataAuthentication mode used for this MCP connection.
data.oauthobject · extra fields rejectedNowithin dataOAuth client configuration for an HTTP or SSE MCP server.
data.oauth.clientIdstring · min length 1; max length 512Nowithin dataOAuth client identifier; provide one when the upstream service requires it.
data.oauth.scopesarray · max 32 itemsNowithin dataOAuth scopes requested from the upstream service.
data.oauth.scopes[]string · min length 1; max length 128Yeseach array item—
data.toolPolicyobject · extra fields rejectedYeswithin dataManaged MCP policy: all tools, exact-name allow list or exact-name deny list.
data.toolPolicy.modestring · values: "all" | "allow" | "deny"Yeswithin dataSelected behavior variant; use one of the allowed values.
data.toolPolicy.toolsarray · max 256 itemsYeswithin dataTool names associated with this resource or policy.
data.toolPolicy.tools[]string · min length 1; max length 128Yeseach array item—
data.idstringYeswithin dataResource identifier used to read or manage this resource.
data.environmentIdstringYeswithin dataEnvironment identifier. It must belong to the caller’s account or Project.
data.revisioninteger · ≥ 1Yeswithin dataConfiguration revision. MCP updates must use the currently observed revision.
data.credentialConfiguredbooleanYeswithin dataWhether secret or OAuth credentials have been configured; values are not returned.
data.lastCheckobject · extra fields rejectedNowithin dataObserved connectivity and tool-discovery result from inside the Environment.
data.lastCheck.statusstring · values: "connected" | "authentication-required" | "unavailable"Yeswithin dataCurrent resource state; inspect the allowed values and the operation’s lifecycle notes.
data.lastCheck.toolsarrayYeswithin dataTool names associated with this resource or policy.
data.lastCheck.tools[]object · extra fields rejectedYeseach array item—
data.lastCheck.tools[].namestringYeseach array itemHuman-readable name for this resource.
data.lastCheck.tools[].descriptionstringNoeach array itemSkill description from SKILL.md frontmatter, used by native discovery.
data.lastCheck.tools[].inputSchemaobject · additional fields allowedYeseach array itemJSON Schema accepted by this discovered MCP tool.
data.lastCheck.checkedAtstring · format: date-timeYeswithin dataTime of the most recent MCP connection check.
data.lastCheck.messagestringNowithin dataHuman-readable diagnostic text.
Example
Example
{
  "data": {
    "name": "",
    "transport": "stdio",
    "enabled": false,
    "authentication": "none",
    "toolPolicy": {
      "mode": "all",
      "tools": [
        "example"
      ]
    },
    "id": "",
    "environmentId": "",
    "revision": 1,
    "credentialConfigured": false
  }
}
Error responses
default Sandpi error.
Error body application/json

Standard error envelope containing a stable code, diagnostic message and request identity.

FieldType and constraintsRequiredDescription
errorobject · extra fields rejectedYesStructured failure information. Inspect the stable code and retain the request ID for investigation.
error.codestringYeswithin errorStable error code used to distinguish failures programmatically.
error.messagestringYeswithin errorHuman-readable diagnostic text.
error.requestIdstringYeswithin errorRequest identifier for correlating diagnostics and support investigations.
error.detailsanyNowithin errorOptional structured error context. Its shape is specific to the service failure.
error.loginUrlstringNowithin errorAuthentication URL supplied when a browser login is required.
error.registrationOpenbooleanNowithin errorWhether new account registration is enabled for this deployment.
Example
Example
{
  "error": {
    "code": "platform_balance_insufficient",
    "message": "Top up Platform credits before submitting a Run.",
    "requestId": "req_example"
  }
}

Check connectivity before a Run

Run a connection check to discover tools and validate the transport. Checks and OAuth discovery happen inside the Environment, under its network policy. For stdio, install the command in that workspace first; it does not run on the Sandpi control plane.

Check MCP connectivity and list allowed tools inside the Environment

POST /v1/environments/{environmentId}/mcp-servers/{serverId}/check

MCP configuration belongs to the Environment and is shared by its harness Sessions. Secrets are write-only and remain outside RootFS snapshots. Configuration changes apply to subsequent Runs and restarted terminals. Operations require the Environment to be idle; active Runs return 409.

Authentication: Platform API bearer token

Parameters and headers
FieldType and constraintsRequiredDescription
path: environmentIdstring · min length 1YesEnvironment identifier. It must belong to the caller’s account or Project.
path: serverIdstring · min length 1YesMCP server identifier within this Environment.

Request example

sh
curl -X POST \
    "https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/mcp-servers/$SERVER_ID/check" \
    -H "Authorization: Bearer $SANDPI_API_TOKEN"

No request body.

Responses

200 Successful response.
Response body application/json
FieldType and constraintsRequiredDescription
dataobject · extra fields rejectedYesObserved connectivity and tool-discovery result from inside the Environment.
data.statusstring · values: "connected" | "authentication-required" | "unavailable"Yeswithin dataCurrent resource state; inspect the allowed values and the operation’s lifecycle notes.
data.toolsarrayYeswithin dataTool names associated with this resource or policy.
data.tools[]object · extra fields rejectedYeseach array item—
data.tools[].namestringYeseach array itemHuman-readable name for this resource.
data.tools[].descriptionstringNoeach array itemSkill description from SKILL.md frontmatter, used by native discovery.
data.tools[].inputSchemaobject · additional fields allowedYeseach array itemJSON Schema accepted by this discovered MCP tool.
data.checkedAtstring · format: date-timeYeswithin dataTime of the most recent MCP connection check.
data.messagestringNowithin dataHuman-readable diagnostic text.
Example
Example
{
  "data": {
    "status": "connected",
    "tools": [
      {
        "name": "",
        "inputSchema": {}
      }
    ],
    "checkedAt": "2026-10-12T01:00:00Z"
  }
}
Error responses
default Sandpi error.
Error body application/json

Standard error envelope containing a stable code, diagnostic message and request identity.

FieldType and constraintsRequiredDescription
errorobject · extra fields rejectedYesStructured failure information. Inspect the stable code and retain the request ID for investigation.
error.codestringYeswithin errorStable error code used to distinguish failures programmatically.
error.messagestringYeswithin errorHuman-readable diagnostic text.
error.requestIdstringYeswithin errorRequest identifier for correlating diagnostics and support investigations.
error.detailsanyNowithin errorOptional structured error context. Its shape is specific to the service failure.
error.loginUrlstringNowithin errorAuthentication URL supplied when a browser login is required.
error.registrationOpenbooleanNowithin errorWhether new account registration is enabled for this deployment.
Example
Example
{
  "error": {
    "code": "platform_balance_insufficient",
    "message": "Top up Platform credits before submitting a Run.",
    "requestId": "req_example"
  }
}

Authenticate

HTTP and SSE servers can use secret headers or OAuth. Secret values are write-only. For OAuth, begin authorization, follow the returned flow, and complete the exchange using the API details’s completion operation. Removing stored credentials clears Sandpi’s local grant; revoke remote consent using the upstream provider’s account controls.

Update tool access

Read the configuration and use its current revision when replacing it. Exact-name allow and deny policies filter discovery and calls for Sandpi-managed MCP connections. They do not restrict the agent’s shell or other native tool connections. A changed revision fences existing managed connections. Subsequent Runs receive the current configuration.

Fork and rollback

Forks copy configuration with new server IDs and no credentials. Authorize each child separately. RootFS rollback retains the current MCP configuration. Managed tool calls have no fixed elapsed-time limit; initialization and discovery retain short timeouts.

Inspect and replace server configuration

List the Environment’s servers and read the server you want to update. Send its current revision when replacing the configuration.

List Environment MCP servers

GET /v1/environments/{environmentId}/mcp-servers

MCP configuration belongs to the Environment and is shared by its harness Sessions. Secrets are write-only and remain outside RootFS snapshots. Configuration changes apply to subsequent Runs and restarted terminals. Operations require the Environment to be idle; active Runs return 409.

Authentication: Platform API bearer token

Parameters and headers
FieldType and constraintsRequiredDescription
path: environmentIdstring · min length 1YesEnvironment identifier. It must belong to the caller’s account or Project.

Request example

sh
curl \
    "https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/mcp-servers" \
    -H "Authorization: Bearer $SANDPI_API_TOKEN"

No request body.

Responses

200 Successful response.
Response body application/json
FieldType and constraintsRequiredDescription
dataarrayYesSuccessful result wrapped by the API. The child fields describe its content.
data[]object · extra fields rejectedYeseach array itemNon-secret MCP configuration, revision and observed connection state.
data[].namestring
Validation pattern^[a-z][a-z0-9_-]{0,47}$
Yeseach array itemHuman-readable name for this resource.
data[].transportstring · values: "stdio" | "http" | "sse"Yeseach array itemMCP transport: sandbox-local stdio, HTTP or legacy SSE.
data[].urlstring · format: uri; max length 2048Noeach array itemRemote MCP endpoint for HTTP or SSE transport; not used for sandbox-local stdio.
data[].commandstring · min length 1; max length 2048Noeach array itemCommand executable to launch inside the Environment for stdio transport.
data[].argsarray · max 64 itemsNoeach array itemArguments passed to the stdio command inside the Environment.
data[].args[]string · max length 4096Yeseach array item—
data[].enabledbooleanYeseach array itemWhether this configuration is enabled for future use.
data[].authenticationstring · values: "none" | "headers" | "oauth"Yeseach array itemAuthentication mode used for this MCP connection.
data[].oauthobject · extra fields rejectedNoeach array itemOAuth client configuration for an HTTP or SSE MCP server.
data[].oauth.clientIdstring · min length 1; max length 512Noeach array itemOAuth client identifier; provide one when the upstream service requires it.
data[].oauth.scopesarray · max 32 itemsNoeach array itemOAuth scopes requested from the upstream service.
data[].oauth.scopes[]string · min length 1; max length 128Yeseach array item—
data[].toolPolicyobject · extra fields rejectedYeseach array itemManaged MCP policy: all tools, exact-name allow list or exact-name deny list.
data[].toolPolicy.modestring · values: "all" | "allow" | "deny"Yeseach array itemSelected behavior variant; use one of the allowed values.
data[].toolPolicy.toolsarray · max 256 itemsYeseach array itemTool names associated with this resource or policy.
data[].toolPolicy.tools[]string · min length 1; max length 128Yeseach array item—
data[].idstringYeseach array itemResource identifier used to read or manage this resource.
data[].environmentIdstringYeseach array itemEnvironment identifier. It must belong to the caller’s account or Project.
data[].revisioninteger · ≥ 1Yeseach array itemConfiguration revision. MCP updates must use the currently observed revision.
data[].credentialConfiguredbooleanYeseach array itemWhether secret or OAuth credentials have been configured; values are not returned.
data[].lastCheckobject · extra fields rejectedNoeach array itemObserved connectivity and tool-discovery result from inside the Environment.
data[].lastCheck.statusstring · values: "connected" | "authentication-required" | "unavailable"Yeseach array itemCurrent resource state; inspect the allowed values and the operation’s lifecycle notes.
data[].lastCheck.toolsarrayYeseach array itemTool names associated with this resource or policy.
data[].lastCheck.tools[]object · extra fields rejectedYeseach array item—
data[].lastCheck.tools[].namestringYeseach array itemHuman-readable name for this resource.
data[].lastCheck.tools[].descriptionstringNoeach array itemSkill description from SKILL.md frontmatter, used by native discovery.
data[].lastCheck.tools[].inputSchemaobject · additional fields allowedYeseach array itemJSON Schema accepted by this discovered MCP tool.
data[].lastCheck.checkedAtstring · format: date-timeYeseach array itemTime of the most recent MCP connection check.
data[].lastCheck.messagestringNoeach array itemHuman-readable diagnostic text.
Example
Example
{
  "data": [
    {
      "name": "",
      "transport": "stdio",
      "enabled": false,
      "authentication": "none",
      "toolPolicy": {
        "mode": "all",
        "tools": [
          "example"
        ]
      },
      "id": "",
      "environmentId": "",
      "revision": 1,
      "credentialConfigured": false
    }
  ]
}
Error responses
default Sandpi error.
Error body application/json

Standard error envelope containing a stable code, diagnostic message and request identity.

FieldType and constraintsRequiredDescription
errorobject · extra fields rejectedYesStructured failure information. Inspect the stable code and retain the request ID for investigation.
error.codestringYeswithin errorStable error code used to distinguish failures programmatically.
error.messagestringYeswithin errorHuman-readable diagnostic text.
error.requestIdstringYeswithin errorRequest identifier for correlating diagnostics and support investigations.
error.detailsanyNowithin errorOptional structured error context. Its shape is specific to the service failure.
error.loginUrlstringNowithin errorAuthentication URL supplied when a browser login is required.
error.registrationOpenbooleanNowithin errorWhether new account registration is enabled for this deployment.
Example
Example
{
  "error": {
    "code": "platform_balance_insufficient",
    "message": "Top up Platform credits before submitting a Run.",
    "requestId": "req_example"
  }
}

Get an Environment MCP server

GET /v1/environments/{environmentId}/mcp-servers/{serverId}

MCP configuration belongs to the Environment and is shared by its harness Sessions. Secrets are write-only and remain outside RootFS snapshots. Configuration changes apply to subsequent Runs and restarted terminals. Operations require the Environment to be idle; active Runs return 409.

Authentication: Platform API bearer token

Parameters and headers
FieldType and constraintsRequiredDescription
path: environmentIdstring · min length 1YesEnvironment identifier. It must belong to the caller’s account or Project.
path: serverIdstring · min length 1YesMCP server identifier within this Environment.

Request example

sh
curl \
    "https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/mcp-servers/$SERVER_ID" \
    -H "Authorization: Bearer $SANDPI_API_TOKEN"

No request body.

Responses

200 Successful response.
Response body application/json
FieldType and constraintsRequiredDescription
dataobject · extra fields rejectedYesNon-secret MCP configuration, revision and observed connection state.
data.namestring
Validation pattern^[a-z][a-z0-9_-]{0,47}$
Yeswithin dataHuman-readable name for this resource.
data.transportstring · values: "stdio" | "http" | "sse"Yeswithin dataMCP transport: sandbox-local stdio, HTTP or legacy SSE.
data.urlstring · format: uri; max length 2048Nowithin dataRemote MCP endpoint for HTTP or SSE transport; not used for sandbox-local stdio.
data.commandstring · min length 1; max length 2048Nowithin dataCommand executable to launch inside the Environment for stdio transport.
data.argsarray · max 64 itemsNowithin dataArguments passed to the stdio command inside the Environment.
data.args[]string · max length 4096Yeseach array item—
data.enabledbooleanYeswithin dataWhether this configuration is enabled for future use.
data.authenticationstring · values: "none" | "headers" | "oauth"Yeswithin dataAuthentication mode used for this MCP connection.
data.oauthobject · extra fields rejectedNowithin dataOAuth client configuration for an HTTP or SSE MCP server.
data.oauth.clientIdstring · min length 1; max length 512Nowithin dataOAuth client identifier; provide one when the upstream service requires it.
data.oauth.scopesarray · max 32 itemsNowithin dataOAuth scopes requested from the upstream service.
data.oauth.scopes[]string · min length 1; max length 128Yeseach array item—
data.toolPolicyobject · extra fields rejectedYeswithin dataManaged MCP policy: all tools, exact-name allow list or exact-name deny list.
data.toolPolicy.modestring · values: "all" | "allow" | "deny"Yeswithin dataSelected behavior variant; use one of the allowed values.
data.toolPolicy.toolsarray · max 256 itemsYeswithin dataTool names associated with this resource or policy.
data.toolPolicy.tools[]string · min length 1; max length 128Yeseach array item—
data.idstringYeswithin dataResource identifier used to read or manage this resource.
data.environmentIdstringYeswithin dataEnvironment identifier. It must belong to the caller’s account or Project.
data.revisioninteger · ≥ 1Yeswithin dataConfiguration revision. MCP updates must use the currently observed revision.
data.credentialConfiguredbooleanYeswithin dataWhether secret or OAuth credentials have been configured; values are not returned.
data.lastCheckobject · extra fields rejectedNowithin dataObserved connectivity and tool-discovery result from inside the Environment.
data.lastCheck.statusstring · values: "connected" | "authentication-required" | "unavailable"Yeswithin dataCurrent resource state; inspect the allowed values and the operation’s lifecycle notes.
data.lastCheck.toolsarrayYeswithin dataTool names associated with this resource or policy.
data.lastCheck.tools[]object · extra fields rejectedYeseach array item—
data.lastCheck.tools[].namestringYeseach array itemHuman-readable name for this resource.
data.lastCheck.tools[].descriptionstringNoeach array itemSkill description from SKILL.md frontmatter, used by native discovery.
data.lastCheck.tools[].inputSchemaobject · additional fields allowedYeseach array itemJSON Schema accepted by this discovered MCP tool.
data.lastCheck.checkedAtstring · format: date-timeYeswithin dataTime of the most recent MCP connection check.
data.lastCheck.messagestringNowithin dataHuman-readable diagnostic text.
Example
Example
{
  "data": {
    "name": "",
    "transport": "stdio",
    "enabled": false,
    "authentication": "none",
    "toolPolicy": {
      "mode": "all",
      "tools": [
        "example"
      ]
    },
    "id": "",
    "environmentId": "",
    "revision": 1,
    "credentialConfigured": false
  }
}
Error responses
default Sandpi error.
Error body application/json

Standard error envelope containing a stable code, diagnostic message and request identity.

FieldType and constraintsRequiredDescription
errorobject · extra fields rejectedYesStructured failure information. Inspect the stable code and retain the request ID for investigation.
error.codestringYeswithin errorStable error code used to distinguish failures programmatically.
error.messagestringYeswithin errorHuman-readable diagnostic text.
error.requestIdstringYeswithin errorRequest identifier for correlating diagnostics and support investigations.
error.detailsanyNowithin errorOptional structured error context. Its shape is specific to the service failure.
error.loginUrlstringNowithin errorAuthentication URL supplied when a browser login is required.
error.registrationOpenbooleanNowithin errorWhether new account registration is enabled for this deployment.
Example
Example
{
  "error": {
    "code": "platform_balance_insufficient",
    "message": "Top up Platform credits before submitting a Run.",
    "requestId": "req_example"
  }
}

Update an Environment MCP server with revision checking

PUT /v1/environments/{environmentId}/mcp-servers/{serverId}

MCP configuration belongs to the Environment and is shared by its harness Sessions. Secrets are write-only and remain outside RootFS snapshots. Configuration changes apply to subsequent Runs and restarted terminals. Operations require the Environment to be idle; active Runs return 409.

Authentication: Platform API bearer token

Parameters and headers
FieldType and constraintsRequiredDescription
path: environmentIdstring · min length 1YesEnvironment identifier. It must belong to the caller’s account or Project.
path: serverIdstring · min length 1YesMCP server identifier within this Environment.

Request example

sh
curl -X PUT \
    "https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/mcp-servers/$SERVER_ID" \
    -H "Authorization: Bearer $SANDPI_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
  "name": "tools",
  "transport": "http",
  "url": "https://mcp.example.com/mcp",
  "enabled": true,
  "authentication": "none",
  "toolPolicy": {
    "mode": "all",
    "tools": []
  },
  "revision": 1
}'
Request body · required application/json

Replacement MCP configuration with the currently observed revision.

FieldType and constraintsRequiredDescription
namestring
Validation pattern^[a-z][a-z0-9_-]{0,47}$
YesHuman-readable name for this resource.
transportstring · values: "stdio" | "http" | "sse"YesMCP transport: sandbox-local stdio, HTTP or legacy SSE.
urlstring · format: uri; max length 2048NoRemote MCP endpoint for HTTP or SSE transport; not used for sandbox-local stdio.
commandstring · min length 1; max length 2048NoCommand executable to launch inside the Environment for stdio transport.
argsarray · max 64 itemsNoArguments passed to the stdio command inside the Environment.
args[]string · max length 4096Yeseach array item—
enabledbooleanYesWhether this configuration is enabled for future use.
authenticationstring · values: "none" | "headers" | "oauth"YesAuthentication mode used for this MCP connection.
oauthobject · extra fields rejectedNoOAuth client configuration for an HTTP or SSE MCP server.
oauth.clientIdstring · min length 1; max length 512Nowithin oauthOAuth client identifier; provide one when the upstream service requires it.
oauth.scopesarray · max 32 itemsNowithin oauthOAuth scopes requested from the upstream service.
oauth.scopes[]string · min length 1; max length 128Yeseach array item—
toolPolicyobject · extra fields rejectedYesManaged MCP policy: all tools, exact-name allow list or exact-name deny list.
toolPolicy.modestring · values: "all" | "allow" | "deny"Yeswithin toolPolicySelected behavior variant; use one of the allowed values.
toolPolicy.toolsarray · max 256 itemsYeswithin toolPolicyTool names associated with this resource or policy.
toolPolicy.tools[]string · min length 1; max length 128Yeseach array item—
materialobject · write only; extra fields rejectedNoWrite-only MCP credentials. Reads expose only credential presence.
material.headersobject · max 32 keysNowithin materialHeader definitions or secret header values applied by this configuration.
material.headers.{key}string · max length 8192Noadditional keys—
material.envobject · max 64 keysNowithin materialWrite-only environment variables supplied to a stdio MCP command.
material.env.{key}string · max length 8192Noadditional keys—
material.clientSecretstring · max length 8192Nowithin materialWrite-only OAuth client secret, when the service requires one.
revisioninteger · ≥ 1YesConfiguration revision. MCP updates must use the currently observed revision.
Example
Example
{
  "name": "tools",
  "transport": "http",
  "url": "https://mcp.example.com/mcp",
  "enabled": true,
  "authentication": "none",
  "toolPolicy": {
    "mode": "all",
    "tools": []
  },
  "revision": 1
}

Responses

200 Successful response.
Response body application/json
FieldType and constraintsRequiredDescription
dataobject · extra fields rejectedYesNon-secret MCP configuration, revision and observed connection state.
data.namestring
Validation pattern^[a-z][a-z0-9_-]{0,47}$
Yeswithin dataHuman-readable name for this resource.
data.transportstring · values: "stdio" | "http" | "sse"Yeswithin dataMCP transport: sandbox-local stdio, HTTP or legacy SSE.
data.urlstring · format: uri; max length 2048Nowithin dataRemote MCP endpoint for HTTP or SSE transport; not used for sandbox-local stdio.
data.commandstring · min length 1; max length 2048Nowithin dataCommand executable to launch inside the Environment for stdio transport.
data.argsarray · max 64 itemsNowithin dataArguments passed to the stdio command inside the Environment.
data.args[]string · max length 4096Yeseach array item—
data.enabledbooleanYeswithin dataWhether this configuration is enabled for future use.
data.authenticationstring · values: "none" | "headers" | "oauth"Yeswithin dataAuthentication mode used for this MCP connection.
data.oauthobject · extra fields rejectedNowithin dataOAuth client configuration for an HTTP or SSE MCP server.
data.oauth.clientIdstring · min length 1; max length 512Nowithin dataOAuth client identifier; provide one when the upstream service requires it.
data.oauth.scopesarray · max 32 itemsNowithin dataOAuth scopes requested from the upstream service.
data.oauth.scopes[]string · min length 1; max length 128Yeseach array item—
data.toolPolicyobject · extra fields rejectedYeswithin dataManaged MCP policy: all tools, exact-name allow list or exact-name deny list.
data.toolPolicy.modestring · values: "all" | "allow" | "deny"Yeswithin dataSelected behavior variant; use one of the allowed values.
data.toolPolicy.toolsarray · max 256 itemsYeswithin dataTool names associated with this resource or policy.
data.toolPolicy.tools[]string · min length 1; max length 128Yeseach array item—
data.idstringYeswithin dataResource identifier used to read or manage this resource.
data.environmentIdstringYeswithin dataEnvironment identifier. It must belong to the caller’s account or Project.
data.revisioninteger · ≥ 1Yeswithin dataConfiguration revision. MCP updates must use the currently observed revision.
data.credentialConfiguredbooleanYeswithin dataWhether secret or OAuth credentials have been configured; values are not returned.
data.lastCheckobject · extra fields rejectedNowithin dataObserved connectivity and tool-discovery result from inside the Environment.
data.lastCheck.statusstring · values: "connected" | "authentication-required" | "unavailable"Yeswithin dataCurrent resource state; inspect the allowed values and the operation’s lifecycle notes.
data.lastCheck.toolsarrayYeswithin dataTool names associated with this resource or policy.
data.lastCheck.tools[]object · extra fields rejectedYeseach array item—
data.lastCheck.tools[].namestringYeseach array itemHuman-readable name for this resource.
data.lastCheck.tools[].descriptionstringNoeach array itemSkill description from SKILL.md frontmatter, used by native discovery.
data.lastCheck.tools[].inputSchemaobject · additional fields allowedYeseach array itemJSON Schema accepted by this discovered MCP tool.
data.lastCheck.checkedAtstring · format: date-timeYeswithin dataTime of the most recent MCP connection check.
data.lastCheck.messagestringNowithin dataHuman-readable diagnostic text.
Example
Example
{
  "data": {
    "name": "",
    "transport": "stdio",
    "enabled": false,
    "authentication": "none",
    "toolPolicy": {
      "mode": "all",
      "tools": [
        "example"
      ]
    },
    "id": "",
    "environmentId": "",
    "revision": 1,
    "credentialConfigured": false
  }
}
Error responses
default Sandpi error.
Error body application/json

Standard error envelope containing a stable code, diagnostic message and request identity.

FieldType and constraintsRequiredDescription
errorobject · extra fields rejectedYesStructured failure information. Inspect the stable code and retain the request ID for investigation.
error.codestringYeswithin errorStable error code used to distinguish failures programmatically.
error.messagestringYeswithin errorHuman-readable diagnostic text.
error.requestIdstringYeswithin errorRequest identifier for correlating diagnostics and support investigations.
error.detailsanyNowithin errorOptional structured error context. Its shape is specific to the service failure.
error.loginUrlstringNowithin errorAuthentication URL supplied when a browser login is required.
error.registrationOpenbooleanNowithin errorWhether new account registration is enabled for this deployment.
Example
Example
{
  "error": {
    "code": "platform_balance_insufficient",
    "message": "Top up Platform credits before submitting a Run.",
    "requestId": "req_example"
  }
}

Complete an OAuth connection

Start authorization, open the returned URL and complete the callback exchange with its state and code. Remove the local authorization when the Environment should no longer use it.

Start MCP OAuth authorization with PKCE

POST /v1/environments/{environmentId}/mcp-servers/{serverId}/authorization

MCP configuration belongs to the Environment and is shared by its harness Sessions. Secrets are write-only and remain outside RootFS snapshots. Configuration changes apply to subsequent Runs and restarted terminals. Operations require the Environment to be idle; active Runs return 409.

Authentication: Platform API bearer token

Parameters and headers
FieldType and constraintsRequiredDescription
path: environmentIdstring · min length 1YesEnvironment identifier. It must belong to the caller’s account or Project.
path: serverIdstring · min length 1YesMCP server identifier within this Environment.

Request example

sh
curl -X POST \
    "https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/mcp-servers/$SERVER_ID/authorization" \
    -H "Authorization: Bearer $SANDPI_API_TOKEN"

No request body.

Responses

200 Successful response.
Response body application/json
FieldType and constraintsRequiredDescription
dataobject · extra fields rejectedYesTemporary OAuth authorization URL and one-time state.
data.statestringYeswithin dataOne-time OAuth flow state that must match the pending authorization.
data.authorizationUrlstring · format: uriYeswithin dataUpstream OAuth URL to open to authorize the MCP connection.
data.expiresAtstring · format: date-timeYeswithin dataExpiration time for this temporary authorization flow.
Example
Example
{
  "data": {
    "state": "",
    "authorizationUrl": "https://example.com/repository.git",
    "expiresAt": "2026-10-12T01:00:00Z"
  }
}
Error responses
default Sandpi error.
Error body application/json

Standard error envelope containing a stable code, diagnostic message and request identity.

FieldType and constraintsRequiredDescription
errorobject · extra fields rejectedYesStructured failure information. Inspect the stable code and retain the request ID for investigation.
error.codestringYeswithin errorStable error code used to distinguish failures programmatically.
error.messagestringYeswithin errorHuman-readable diagnostic text.
error.requestIdstringYeswithin errorRequest identifier for correlating diagnostics and support investigations.
error.detailsanyNowithin errorOptional structured error context. Its shape is specific to the service failure.
error.loginUrlstringNowithin errorAuthentication URL supplied when a browser login is required.
error.registrationOpenbooleanNowithin errorWhether new account registration is enabled for this deployment.
Example
Example
{
  "error": {
    "code": "platform_balance_insufficient",
    "message": "Top up Platform credits before submitting a Run.",
    "requestId": "req_example"
  }
}

Complete MCP OAuth authorization

PUT /v1/environments/{environmentId}/mcp-servers/{serverId}/authorization

MCP configuration belongs to the Environment and is shared by its harness Sessions. Secrets are write-only and remain outside RootFS snapshots. Configuration changes apply to subsequent Runs and restarted terminals. Operations require the Environment to be idle; active Runs return 409.

Authentication: Platform API bearer token

Parameters and headers
FieldType and constraintsRequiredDescription
path: environmentIdstring · min length 1YesEnvironment identifier. It must belong to the caller’s account or Project.
path: serverIdstring · min length 1YesMCP server identifier within this Environment.

Request example

sh
curl -X PUT \
    "https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/mcp-servers/$SERVER_ID/authorization" \
    -H "Authorization: Bearer $SANDPI_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
  "state": "example",
  "code": "example"
}'
Request body · required application/json

State and authorization code used to complete the pending MCP OAuth flow.

FieldType and constraintsRequiredDescription
statestring · min length 32; max length 200YesOne-time OAuth flow state that must match the pending authorization.
codestring · min length 1; max length 4096YesAuthorization code returned by the upstream OAuth callback.
Example
Example
{
  "state": "example",
  "code": "example"
}

Responses

200 Successful response.
Response body application/json
FieldType and constraintsRequiredDescription
dataobject · extra fields rejectedYesNon-secret MCP configuration, revision and observed connection state.
data.namestring
Validation pattern^[a-z][a-z0-9_-]{0,47}$
Yeswithin dataHuman-readable name for this resource.
data.transportstring · values: "stdio" | "http" | "sse"Yeswithin dataMCP transport: sandbox-local stdio, HTTP or legacy SSE.
data.urlstring · format: uri; max length 2048Nowithin dataRemote MCP endpoint for HTTP or SSE transport; not used for sandbox-local stdio.
data.commandstring · min length 1; max length 2048Nowithin dataCommand executable to launch inside the Environment for stdio transport.
data.argsarray · max 64 itemsNowithin dataArguments passed to the stdio command inside the Environment.
data.args[]string · max length 4096Yeseach array item—
data.enabledbooleanYeswithin dataWhether this configuration is enabled for future use.
data.authenticationstring · values: "none" | "headers" | "oauth"Yeswithin dataAuthentication mode used for this MCP connection.
data.oauthobject · extra fields rejectedNowithin dataOAuth client configuration for an HTTP or SSE MCP server.
data.oauth.clientIdstring · min length 1; max length 512Nowithin dataOAuth client identifier; provide one when the upstream service requires it.
data.oauth.scopesarray · max 32 itemsNowithin dataOAuth scopes requested from the upstream service.
data.oauth.scopes[]string · min length 1; max length 128Yeseach array item—
data.toolPolicyobject · extra fields rejectedYeswithin dataManaged MCP policy: all tools, exact-name allow list or exact-name deny list.
data.toolPolicy.modestring · values: "all" | "allow" | "deny"Yeswithin dataSelected behavior variant; use one of the allowed values.
data.toolPolicy.toolsarray · max 256 itemsYeswithin dataTool names associated with this resource or policy.
data.toolPolicy.tools[]string · min length 1; max length 128Yeseach array item—
data.idstringYeswithin dataResource identifier used to read or manage this resource.
data.environmentIdstringYeswithin dataEnvironment identifier. It must belong to the caller’s account or Project.
data.revisioninteger · ≥ 1Yeswithin dataConfiguration revision. MCP updates must use the currently observed revision.
data.credentialConfiguredbooleanYeswithin dataWhether secret or OAuth credentials have been configured; values are not returned.
data.lastCheckobject · extra fields rejectedNowithin dataObserved connectivity and tool-discovery result from inside the Environment.
data.lastCheck.statusstring · values: "connected" | "authentication-required" | "unavailable"Yeswithin dataCurrent resource state; inspect the allowed values and the operation’s lifecycle notes.
data.lastCheck.toolsarrayYeswithin dataTool names associated with this resource or policy.
data.lastCheck.tools[]object · extra fields rejectedYeseach array item—
data.lastCheck.tools[].namestringYeseach array itemHuman-readable name for this resource.
data.lastCheck.tools[].descriptionstringNoeach array itemSkill description from SKILL.md frontmatter, used by native discovery.
data.lastCheck.tools[].inputSchemaobject · additional fields allowedYeseach array itemJSON Schema accepted by this discovered MCP tool.
data.lastCheck.checkedAtstring · format: date-timeYeswithin dataTime of the most recent MCP connection check.
data.lastCheck.messagestringNowithin dataHuman-readable diagnostic text.
Example
Example
{
  "data": {
    "name": "",
    "transport": "stdio",
    "enabled": false,
    "authentication": "none",
    "toolPolicy": {
      "mode": "all",
      "tools": [
        "example"
      ]
    },
    "id": "",
    "environmentId": "",
    "revision": 1,
    "credentialConfigured": false
  }
}
Error responses
default Sandpi error.
Error body application/json

Standard error envelope containing a stable code, diagnostic message and request identity.

FieldType and constraintsRequiredDescription
errorobject · extra fields rejectedYesStructured failure information. Inspect the stable code and retain the request ID for investigation.
error.codestringYeswithin errorStable error code used to distinguish failures programmatically.
error.messagestringYeswithin errorHuman-readable diagnostic text.
error.requestIdstringYeswithin errorRequest identifier for correlating diagnostics and support investigations.
error.detailsanyNowithin errorOptional structured error context. Its shape is specific to the service failure.
error.loginUrlstringNowithin errorAuthentication URL supplied when a browser login is required.
error.registrationOpenbooleanNowithin errorWhether new account registration is enabled for this deployment.
Example
Example
{
  "error": {
    "code": "platform_balance_insufficient",
    "message": "Top up Platform credits before submitting a Run.",
    "requestId": "req_example"
  }
}

Remove stored MCP credentials and OAuth grants

DELETE /v1/environments/{environmentId}/mcp-servers/{serverId}/authorization

MCP configuration belongs to the Environment and is shared by its harness Sessions. Secrets are write-only and remain outside RootFS snapshots. Configuration changes apply to subsequent Runs and restarted terminals. Operations require the Environment to be idle; active Runs return 409.

Authentication: Platform API bearer token

Parameters and headers
FieldType and constraintsRequiredDescription
path: environmentIdstring · min length 1YesEnvironment identifier. It must belong to the caller’s account or Project.
path: serverIdstring · min length 1YesMCP server identifier within this Environment.

Request example

sh
curl -X DELETE \
    "https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/mcp-servers/$SERVER_ID/authorization" \
    -H "Authorization: Bearer $SANDPI_API_TOKEN"

No request body.

Responses

200 Successful response.
Response body application/json
FieldType and constraintsRequiredDescription
dataobject · extra fields rejectedYesNon-secret MCP configuration, revision and observed connection state.
data.namestring
Validation pattern^[a-z][a-z0-9_-]{0,47}$
Yeswithin dataHuman-readable name for this resource.
data.transportstring · values: "stdio" | "http" | "sse"Yeswithin dataMCP transport: sandbox-local stdio, HTTP or legacy SSE.
data.urlstring · format: uri; max length 2048Nowithin dataRemote MCP endpoint for HTTP or SSE transport; not used for sandbox-local stdio.
data.commandstring · min length 1; max length 2048Nowithin dataCommand executable to launch inside the Environment for stdio transport.
data.argsarray · max 64 itemsNowithin dataArguments passed to the stdio command inside the Environment.
data.args[]string · max length 4096Yeseach array item—
data.enabledbooleanYeswithin dataWhether this configuration is enabled for future use.
data.authenticationstring · values: "none" | "headers" | "oauth"Yeswithin dataAuthentication mode used for this MCP connection.
data.oauthobject · extra fields rejectedNowithin dataOAuth client configuration for an HTTP or SSE MCP server.
data.oauth.clientIdstring · min length 1; max length 512Nowithin dataOAuth client identifier; provide one when the upstream service requires it.
data.oauth.scopesarray · max 32 itemsNowithin dataOAuth scopes requested from the upstream service.
data.oauth.scopes[]string · min length 1; max length 128Yeseach array item—
data.toolPolicyobject · extra fields rejectedYeswithin dataManaged MCP policy: all tools, exact-name allow list or exact-name deny list.
data.toolPolicy.modestring · values: "all" | "allow" | "deny"Yeswithin dataSelected behavior variant; use one of the allowed values.
data.toolPolicy.toolsarray · max 256 itemsYeswithin dataTool names associated with this resource or policy.
data.toolPolicy.tools[]string · min length 1; max length 128Yeseach array item—
data.idstringYeswithin dataResource identifier used to read or manage this resource.
data.environmentIdstringYeswithin dataEnvironment identifier. It must belong to the caller’s account or Project.
data.revisioninteger · ≥ 1Yeswithin dataConfiguration revision. MCP updates must use the currently observed revision.
data.credentialConfiguredbooleanYeswithin dataWhether secret or OAuth credentials have been configured; values are not returned.
data.lastCheckobject · extra fields rejectedNowithin dataObserved connectivity and tool-discovery result from inside the Environment.
data.lastCheck.statusstring · values: "connected" | "authentication-required" | "unavailable"Yeswithin dataCurrent resource state; inspect the allowed values and the operation’s lifecycle notes.
data.lastCheck.toolsarrayYeswithin dataTool names associated with this resource or policy.
data.lastCheck.tools[]object · extra fields rejectedYeseach array item—
data.lastCheck.tools[].namestringYeseach array itemHuman-readable name for this resource.
data.lastCheck.tools[].descriptionstringNoeach array itemSkill description from SKILL.md frontmatter, used by native discovery.
data.lastCheck.tools[].inputSchemaobject · additional fields allowedYeseach array itemJSON Schema accepted by this discovered MCP tool.
data.lastCheck.checkedAtstring · format: date-timeYeswithin dataTime of the most recent MCP connection check.
data.lastCheck.messagestringNowithin dataHuman-readable diagnostic text.
Example
Example
{
  "data": {
    "name": "",
    "transport": "stdio",
    "enabled": false,
    "authentication": "none",
    "toolPolicy": {
      "mode": "all",
      "tools": [
        "example"
      ]
    },
    "id": "",
    "environmentId": "",
    "revision": 1,
    "credentialConfigured": false
  }
}
Error responses
default Sandpi error.
Error body application/json

Standard error envelope containing a stable code, diagnostic message and request identity.

FieldType and constraintsRequiredDescription
errorobject · extra fields rejectedYesStructured failure information. Inspect the stable code and retain the request ID for investigation.
error.codestringYeswithin errorStable error code used to distinguish failures programmatically.
error.messagestringYeswithin errorHuman-readable diagnostic text.
error.requestIdstringYeswithin errorRequest identifier for correlating diagnostics and support investigations.
error.detailsanyNowithin errorOptional structured error context. Its shape is specific to the service failure.
error.loginUrlstringNowithin errorAuthentication URL supplied when a browser login is required.
error.registrationOpenbooleanNowithin errorWhether new account registration is enabled for this deployment.
Example
Example
{
  "error": {
    "code": "platform_balance_insufficient",
    "message": "Top up Platform credits before submitting a Run.",
    "requestId": "req_example"
  }
}

Remove a server

Deleting the definition removes the managed connection. Revoke remote consent separately where required.

Delete an Environment MCP server

DELETE /v1/environments/{environmentId}/mcp-servers/{serverId}

MCP configuration belongs to the Environment and is shared by its harness Sessions. Secrets are write-only and remain outside RootFS snapshots. Configuration changes apply to subsequent Runs and restarted terminals. Operations require the Environment to be idle; active Runs return 409.

Authentication: Platform API bearer token

Parameters and headers
FieldType and constraintsRequiredDescription
path: environmentIdstring · min length 1YesEnvironment identifier. It must belong to the caller’s account or Project.
path: serverIdstring · min length 1YesMCP server identifier within this Environment.

Request example

sh
curl -X DELETE \
    "https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/mcp-servers/$SERVER_ID" \
    -H "Authorization: Bearer $SANDPI_API_TOKEN"

No request body.

Responses

204 Successful response.

Empty response body.

Error responses
default Sandpi error.
Error body application/json

Standard error envelope containing a stable code, diagnostic message and request identity.

FieldType and constraintsRequiredDescription
errorobject · extra fields rejectedYesStructured failure information. Inspect the stable code and retain the request ID for investigation.
error.codestringYeswithin errorStable error code used to distinguish failures programmatically.
error.messagestringYeswithin errorHuman-readable diagnostic text.
error.requestIdstringYeswithin errorRequest identifier for correlating diagnostics and support investigations.
error.detailsanyNowithin errorOptional structured error context. Its shape is specific to the service failure.
error.loginUrlstringNowithin errorAuthentication URL supplied when a browser login is required.
error.registrationOpenbooleanNowithin errorWhether new account registration is enabled for this deployment.
Example
Example
{
  "error": {
    "code": "platform_balance_insufficient",
    "message": "Top up Platform credits before submitting a Run.",
    "requestId": "req_example"
  }
}