Secrets
Space MCP tools in the Secrets scope (secrets). Reach these with a wks_live_ key over space-mcp or space-api.
Tools in the secrets scope, callable over space-mcp (tools/call) or space-api (REST) with a wks_live_* key that grants secrets.
http_request
Scope: secrets:run
Make an HTTP request to an external API via the platform egress proxy (consequential — calls the outside world). Any ${secret:NAME} placeholders in the url, header values, or body are replaced with the real secret value server-side; the value is never visible to you, and any echo of it in the response is redacted. Redirects are not followed. Private/internal addresses are blocked.
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | yes | |
method | string | GET | POST | PUT | PATCH | DELETE | HEAD (default GET) | |
headers | object | Header name → value. Values may contain ${secret:NAME} placeholders. | |
body | string | Raw request body. For JSON, pass the serialized string. May contain placeholders. | |
timeout_ms | number | 1000–60000, default 30000 |
list_secret_names
Scope: secrets:read
List the secrets this space has, with where each one LIVES. Values are never returned. binding: 'proxy' = it stays in the owner's vault (say it that way to a human): usable only as ${secret:NAME} inside http_request, and you never see the value. binding: 'machine' = it is SHARED FROM their vault, so a copy is also present in THIS machine's environment under the reported env_vars — read it with os.environ when you need a vendor SDK or a websocket the egress proxy can't do. A shared secret missing from your environment means the machine hasn't restarted since it was shared.
request_secret_input
Scope: secrets:write
Ask a human for a credential you don't have, WITHOUT ever seeing it. Opens a secure box pinned in your PM chat (web + mobile); they paste the value straight into encrypted storage and it is auto-assigned to this space, ready for ${secret:NAME} in http_request. Use this whenever you need an API key, token or login that list_secret_names doesn't show — NEVER ask someone to type a credential into the chat (tell them not to: a message is stored and read like any other; if one is pasted anyway, don't use it — ask them to delete it and replace the key at the service), and never tell them to go hunting for a settings page. To connect a whole API (calls you'll make with the key) use request_integration instead. Pass secret_name to ask for a fresh value for a secret this space already has (rotation). You describe only the SHAPE (name + field labels); you never receive the value, on the way in or out.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Short identifier for the secret, e.g. stripe_api_key. Required unless rotating. | |
category | string | Grouping, e.g. credentials, payment, email. Default 'credentials'. | |
sub_type | string | Shape of the credential: api_key, bearer_token, oauth_token, username_password, email_account, ssh_key, private_key. Picks sensible default fields. Default 'api_key'. | |
fields | object[] | Optional explicit fields — [{ key, label, multiline?, optional? }]. LABELS ONLY, never values. Omit to use the sub_type default. | |
description | string | What this credential is, stored alongside the secret. | |
purpose | string | Why you're asking — shown to the person in the box. Be specific; it's how they decide to trust the request. | |
secret_name | string | Rotate an EXISTING secret of this space (as shown by list_secret_names) instead of creating a new one. | |
binding | proxy | machine | Where you need the credential to live. 'proxy' (default, ALWAYS prefer it) = it stays in their vault; you never see the value and use it as ${secret:NAME} in http_request. Ask for 'machine' — shared from their vault onto this computer — ONLY when that genuinely cannot work: a vendor SDK that reads os.environ, or a websocket/streaming feed. Say why in purpose, because sharing means you CAN read the value and the human is being asked to accept that. Your answer is only a request: the human picks. |
use_secret
Scope: secrets:run
Get a redacted placeholder (${secret:NAME} / ${secret:NAME:field}) for a secret assigned to this space, to embed in http_request. The platform substitutes the real value at egress — the value is NEVER returned to you. Use field_key to pick one field of a multi-field secret. Validates the secret exists and resolves.
| Parameter | Type | Required | Description |
|---|---|---|---|
secret_name | string | yes | Secret name as shown by list_secret_names |
field_key | string | Optional field of a multi-field secret (e.g. api_key) |