Skip to content

The owner MCP server

View as Markdown

Endpoint: https://mcp.batondeck.com/mcp · Protocol: 2026-07-28 (stateless, no handshake), and the initialize handshake at 2025-11-25 or 2025-06-18 · Authorization: OAuth, discovered from https://mcp.batondeck.com/.well-known/oauth-protected-resource.

The server sends this text as its instructions on initialize:

The owner surface of a BatonDeck workspace: read and answer your inbox, manage the contacts who may reach you, issue invites, run your identities, their integrations and your workspace, and read the audit chain. Tools are routers named batondeck_<inbox|contacts|identity|workspace>_<read|write|change>: read tools change nothing but your own read marker, write tools only add, change tools alter or remove. Each takes action and arguments, and lists every action’s arguments. Every call acts as ONE identity: the one named by ?identity=<slug> on the server URL, else the first this connection may act as; batondeck_identity_read accounts lists them and marks the acting one. Every change is recorded on that identity’s audit chain, naming the owner behind this connection.

The listing has 12 tools. Each takes action and arguments; the actions it accepts, and each action’s arguments, are below. A client that connects with ?expanded=true on the server URL is listed one tool per action instead (95 tools, named <router>__<action>), with the same arguments.

Tool Title Actions Hints
batondeck_inbox_read Read the inbox 5 readOnlyHint: true · openWorldHint: false
batondeck_inbox_write Send a message or a file 2 readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true
batondeck_inbox_change Call, retry or answer 3 readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: true
batondeck_contacts_read List contacts and invites 6 readOnlyHint: true · openWorldHint: true
batondeck_contacts_change Manage contacts and invites 15 readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: true
batondeck_contacts_write Invite or ask 2 readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true
batondeck_identity_read Read the identity 14 readOnlyHint: true · openWorldHint: false
batondeck_identity_change Change the identity 10 readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: true
batondeck_identity_write Connect, share or open a wallet request 5 readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true
batondeck_workspace_read Read the workspace 15 readOnlyHint: true · openWorldHint: true
batondeck_workspace_change Change the workspace 12 readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: true
batondeck_workspace_write Create in the workspace 6 readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Read the inbox. Threads, messages, pending requests, waits and digests. Reading a thread moves your own read marker and nothing else.

readOnlyHint: true · openWorldHint: false

Action What it does Arguments Scope /v1 operation
list Threads newest first, with unread counts limit?, cursor? inbox:read listThreads
read The messages in one thread; reading advances your read cursor thread_id, limit? inbox:read listMessages
pending Requests waiting for the owner to answer — inbox:read listPendingRequests
wait Block until something changes, then report what moved since your cursor since?, timeout_sec? inbox:read watchChanges
digest What happened in a window and what is still open, per contact since? inbox:read getDigest
batondeck_inbox_read input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"list",
"read",
"pending",
"wait",
"digest"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "list",
"description": "Threads newest first, with unread counts",
"type": "object",
"properties": {
"limit": {
"default": 50,
"type": "integer",
"minimum": 1,
"maximum": 200
},
"cursor": {
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"limit": 20
}
]
},
{
"title": "read",
"description": "The messages in one thread; reading advances your read cursor",
"type": "object",
"properties": {
"thread_id": {
"type": "string",
"description": "the threadId this acts on"
},
"limit": {
"default": 50,
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"required": [
"thread_id"
],
"additionalProperties": false,
"examples": [
{
"thread_id": "t-1",
"limit": 50
}
]
},
{
"title": "pending",
"description": "Requests waiting for the owner to answer",
"type": "object",
"additionalProperties": false
},
{
"title": "wait",
"description": "Block until something changes, then report what moved since your cursor",
"type": "object",
"properties": {
"since": {
"description": "cursor from a previous answer; 0 starts from now with no backlog",
"default": 0,
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"timeout_sec": {
"description": "seconds to wait for something to happen, from 1 to 25",
"default": 25,
"type": "integer",
"minimum": 1,
"maximum": 25
}
},
"additionalProperties": false,
"examples": [
{
"since": 1757203200000,
"timeout_sec": 25
}
]
},
{
"title": "digest",
"description": "What happened in a window and what is still open, per contact",
"type": "object",
"properties": {
"since": {
"default": 0,
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"additionalProperties": false,
"examples": [
{}
]
}
]
}
},
"required": [
"action"
],
"additionalProperties": false
}

Send a message or a file. Send a message or a file to a contact.

readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Action What it does Arguments Scope /v1 operation
send Send a message to a contact fingerprint, text, thread_id?, msg_id? inbox:write sendMessage
send_file Send a file to a contact, base64 fingerprint, data, filename?, mime?, thread_id?, msg_id? inbox:write sendMedia
batondeck_inbox_write input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"send",
"send_file"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "send",
"description": "Send a message to a contact",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"minLength": 1
},
"text": {
"type": "string",
"minLength": 1,
"maxLength": 16384
},
"thread_id": {
"type": "string",
"maxLength": 128
},
"msg_id": {
"type": "string",
"maxLength": 128
}
},
"required": [
"fingerprint",
"text"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…",
"text": "on my way"
}
]
},
{
"title": "send_file",
"description": "Send a file to a contact, base64",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"minLength": 1
},
"data": {
"type": "string",
"minLength": 1
},
"filename": {
"default": "",
"type": "string",
"maxLength": 256
},
"mime": {
"default": "application/octet-stream",
"type": "string",
"maxLength": 128
},
"thread_id": {
"type": "string",
"maxLength": 128
},
"msg_id": {
"type": "string",
"maxLength": 128
}
},
"required": [
"fingerprint",
"data"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…",
"data": "aGVsbG8=",
"filename": "note.txt",
"mime": "text/plain"
}
]
}
]
}
},
"required": [
"action"
],
"additionalProperties": false
}

Call, retry or answer. Call a tool on a contact’s node, retry a message that did not arrive, or answer a request a contact is waiting on.

readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: true

Action What it does Arguments Scope /v1 operation
call Call a tool on a contact’s node; their switchboard still applies fingerprint, tool, arguments? inbox:write callContactTool
retry Retry an undelivered message message_id inbox:write retryMessage
answer Answer an agent-answered request request_id, answer requests:answer answerPendingRequest
batondeck_inbox_change input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"call",
"retry",
"answer"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "call",
"description": "Call a tool on a contact's node; their switchboard still applies",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
},
"tool": {
"type": "string",
"minLength": 1
},
"arguments": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
},
"required": [
"fingerprint",
"tool"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…",
"tool": "check_availability",
"arguments": {
"note": "coffee?"
}
}
]
},
{
"title": "retry",
"description": "Retry an undelivered message",
"type": "object",
"properties": {
"message_id": {
"type": "string",
"description": "the id this acts on"
}
},
"required": [
"message_id"
],
"additionalProperties": false,
"examples": [
{
"message_id": "m-1"
}
]
},
{
"title": "answer",
"description": "Answer an agent-answered request",
"type": "object",
"properties": {
"request_id": {
"type": "string",
"description": "the id this acts on"
},
"answer": {
"description": "the reply payload"
}
},
"required": [
"request_id",
"answer"
],
"additionalProperties": false,
"examples": [
{
"request_id": "r-1",
"answer": {
"ok": true
}
}
]
}
]
}
},
"required": [
"action"
],
"additionalProperties": false
}

List contacts and invites. Contacts with their status, preset and permissions, the tools a contact offers you, contacts waiting at a new address, and the invites this identity has issued.

readOnlyHint: true · openWorldHint: true

Action What it does Arguments Scope /v1 operation
list Contacts with their tier and permissions status? contacts:read listContacts
invites Invites this identity has issued: uses, and links if you may mint — contacts:read listInvites
tools The tools a contact offers you, asked of their node fingerprint contacts:read listContactTools
addresses Contacts waiting at a new address for your decision — contacts:read listPendingAddresses
preset_catalog The shipped presets and every permission a contact can be granted — identity:read listPresets
presets This identity’s own preset bundles, and which have been edited — contacts:read listIdentityPresets
batondeck_contacts_read input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"list",
"invites",
"tools",
"addresses",
"preset_catalog",
"presets"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "list",
"description": "Contacts with their tier and permissions",
"type": "object",
"properties": {
"status": {
"description": "only contacts in this state",
"type": "string",
"enum": [
"active",
"pending_in",
"pending_out",
"blocked"
]
}
},
"additionalProperties": false,
"examples": [
{}
]
},
{
"title": "invites",
"description": "Invites this identity has issued: uses, and links if you may mint",
"type": "object",
"additionalProperties": false
},
{
"title": "tools",
"description": "The tools a contact offers you, asked of their node",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
}
},
"required": [
"fingerprint"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…"
}
]
},
{
"title": "addresses",
"description": "Contacts waiting at a new address for your decision",
"type": "object",
"additionalProperties": false
},
{
"title": "preset_catalog",
"description": "The shipped presets and every permission a contact can be granted",
"type": "object",
"additionalProperties": false
},
{
"title": "presets",
"description": "This identity's own preset bundles, and which have been edited",
"type": "object",
"additionalProperties": false
}
]
}
},
"required": [
"action"
],
"additionalProperties": false
}

Manage contacts and invites. Approve, reject, block, unblock, remove, rename or refresh a contact, change what it may do or whether it may instruct you, decide on its new address, re-send your acceptance, accept its invite, or revoke one of yours.

readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: true

Action What it does Arguments Scope /v1 operation
approve Approve a pending contact request, applying a preset fingerprint, preset? contacts:manage approveContact
reject Refuse a pending contact request fingerprint contacts:manage rejectContact
block Stop a contact reaching you. Silent: they are not told (HDTP §6.2) fingerprint contacts:manage blockContact
unblock Undo a block: a former contact returns active, a declined request is forgotten fingerprint contacts:manage unblockContact
remove Remove a contact; an active one is told fingerprint contacts:manage removeContact
add Accept their invite link invite_url contacts:manage redeemInvite
tell_accepted Re-send your acceptance fingerprint contacts:manage notifyAcceptance
rename Set your own local name for a contact; empty clears it fingerprint, petname contacts:manage setPetname
permissions Change what a contact may do fingerprint, preset?, permissions? contacts:trust updateContact
trust Whether this contact’s text may instruct your agent fingerprint, trust contacts:trust setTrust
refresh Re-fetch a contact’s card fingerprint contacts:manage refreshContact
revoke_invite Revoke an invite; its link stops working invite_id invites:manage revokeInvite
approve_address Re-pin a contact at the new address it is waiting at root contacts:manage approvePendingAddress
reject_address Keep the pin where it is; the new address is a stranger root contacts:manage rejectPendingAddress
set_preset Change what a preset grants, for this identity; existing contacts keep theirs name, permissions contacts:trust setIdentityPreset
batondeck_contacts_change input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"approve",
"reject",
"block",
"unblock",
"remove",
"add",
"tell_accepted",
"rename",
"permissions",
"trust",
"refresh",
"revoke_invite",
"approve_address",
"reject_address",
"set_preset"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "approve",
"description": "Approve a pending contact request, applying a preset",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
},
"preset": {
"default": "basic",
"type": "string",
"enum": [
"basic",
"colleague",
"close",
"muted"
]
}
},
"required": [
"fingerprint"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…",
"preset": "colleague"
}
]
},
{
"title": "reject",
"description": "Refuse a pending contact request",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
}
},
"required": [
"fingerprint"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…"
}
]
},
{
"title": "block",
"description": "Stop a contact reaching you. Silent: they are not told (HDTP §6.2)",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
}
},
"required": [
"fingerprint"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…"
}
]
},
{
"title": "unblock",
"description": "Undo a block: a former contact returns active, a declined request is forgotten",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
}
},
"required": [
"fingerprint"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…"
}
]
},
{
"title": "remove",
"description": "Remove a contact; an active one is told",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
}
},
"required": [
"fingerprint"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…"
}
]
},
{
"title": "add",
"description": "Accept their invite link",
"type": "object",
"properties": {
"invite_url": {
"type": "string",
"minLength": 12,
"maxLength": 2048
}
},
"required": [
"invite_url"
],
"additionalProperties": false,
"examples": [
{
"invite_url": "https://alex-ws.batondeck.com/alex/i/abc123"
}
]
},
{
"title": "tell_accepted",
"description": "Re-send your acceptance",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
}
},
"required": [
"fingerprint"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…"
}
]
},
{
"title": "rename",
"description": "Set your own local name for a contact; empty clears it",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
},
"petname": {
"type": "string",
"maxLength": 64
}
},
"required": [
"fingerprint",
"petname"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…",
"petname": "Carol from Pune"
}
]
},
{
"title": "permissions",
"description": "Change what a contact may do",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
},
"preset": {
"type": "string",
"enum": [
"basic",
"colleague",
"close",
"muted"
]
},
"permissions": {
"maxItems": 64,
"type": "array",
"items": {
"type": "string",
"maxLength": 96
}
}
},
"required": [
"fingerprint"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…",
"preset": "close"
}
]
},
{
"title": "trust",
"description": "Whether this contact's text may instruct your agent",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
},
"trust": {
"type": "string",
"enum": [
"messages_only",
"may_instruct"
]
}
},
"required": [
"fingerprint",
"trust"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…",
"trust": "messages_only"
}
]
},
{
"title": "refresh",
"description": "Re-fetch a contact's card",
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "the fingerprint this acts on"
}
},
"required": [
"fingerprint"
],
"additionalProperties": false,
"examples": [
{
"fingerprint": "sha256:…"
}
]
},
{
"title": "revoke_invite",
"description": "Revoke an invite; its link stops working",
"type": "object",
"properties": {
"invite_id": {
"type": "string",
"description": "the id this acts on"
}
},
"required": [
"invite_id"
],
"additionalProperties": false,
"examples": [
{
"invite_id": "inv-1"
}
]
},
{
"title": "approve_address",
"description": "Re-pin a contact at the new address it is waiting at",
"type": "object",
"properties": {
"root": {
"type": "string",
"description": "the root this acts on"
}
},
"required": [
"root"
],
"additionalProperties": false,
"examples": [
{
"root": "sha256:…"
}
]
},
{
"title": "reject_address",
"description": "Keep the pin where it is; the new address is a stranger",
"type": "object",
"properties": {
"root": {
"type": "string",
"description": "the root this acts on"
}
},
"required": [
"root"
],
"additionalProperties": false,
"examples": [
{
"root": "sha256:…"
}
]
},
{
"title": "set_preset",
"description": "Change what a preset grants, for this identity; existing contacts keep theirs",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "the name this acts on"
},
"permissions": {
"maxItems": 64,
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"name",
"permissions"
],
"additionalProperties": false,
"examples": [
{
"name": "colleague",
"permissions": [
"message.text",
"status.view"
]
}
]
}
]
}
},
"required": [
"action"
],
"additionalProperties": false
}

Invite or ask. Mint an invite link, or ask the holder of a contact card to be your contact.

readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Action What it does Arguments Scope /v1 operation
invite Mint an invite link, optionally auto-accepting label?, preset?, max_uses?, auto_accept?, expires_in_days? invites:manage createInvite
request Ask the holder of a contact card to be your contact; they approve it card, note? contacts:manage requestContact
batondeck_contacts_write input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"invite",
"request"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "invite",
"description": "Mint an invite link, optionally auto-accepting",
"type": "object",
"properties": {
"label": {
"default": "",
"type": "string",
"maxLength": 128
},
"preset": {
"default": "basic",
"type": "string",
"enum": [
"basic",
"colleague",
"close",
"muted"
]
},
"max_uses": {
"description": "1 for one-time, 0 for unlimited",
"default": 1,
"type": "integer",
"minimum": 0,
"maximum": 1000
},
"auto_accept": {
"default": false,
"type": "boolean"
},
"expires_in_days": {
"default": 14,
"type": "integer",
"minimum": 1,
"maximum": 90
}
},
"additionalProperties": false,
"examples": [
{
"label": "Pune conference 2026",
"max_uses": 50,
"auto_accept": true,
"preset": "basic"
}
]
},
{
"title": "request",
"description": "Ask the holder of a contact card to be your contact; they approve it",
"type": "object",
"properties": {
"card": {
"type": "string",
"minLength": 1,
"maxLength": 16384
},
"note": {
"type": "string",
"maxLength": 1024
}
},
"required": [
"card"
],
"additionalProperties": false,
"examples": [
{
"card": "BEGIN:VCARD…",
"note": "we met at the Pune meetup"
}
]
}
]
}
},
"required": [
"action"
],
"additionalProperties": false
}

Read the identity. Accounts, this identity, its card, certificate, audit chain, storage and grants, a wallet request, and its integrations and what each exposes.

readOnlyHint: true · openWorldHint: false

Action What it does Arguments Scope /v1 operation
accounts The identities this connection may act as; the acting one is marked, another is reached with ?identity= — identity:read listIdentities
card The signed card peers receive — identity:read getIdentityCard
certificate Certificate state — identity:read getCertificate
audit The audit chain, newest first limit?, subject?, action_like? audit:read listIdentityAudit
integrations Connected integrations and their health — integrations:read listIntegrations
identity This identity: slug, root, address, status and whether it is certified — identity:read getIdentity
storage Bytes this identity holds, and the ceiling it is held against — identity:read getStorage
settings Your status, accept_new_hosts and moved_away_at, as last set — identity:read getIdentitySettings
grants Which owners may act as this identity; several is a shared inbox — identity:read listIdentityGrants
wallet_request What the wallet did with a request: still open, the chain it issued, or why not code identity:read readWalletRequest
export_report What this identity’s export would say of itself: each import ceiling it passes, and every message it leaves out, by id and why — identity:read getExportReport
export This identity’s export zip, unencrypted, base64, up to 5 MiB; send acknowledge: “unencrypted”; the owner approves it in the portal acknowledge? export:read exportIdentity
exposure What an integration offers, and which of its tools contacts may reach integration integrations:read getExposure
integration_catalogue The MCP servers that connect in one click — integrations:read listIntegrationCatalogue
batondeck_identity_read input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"accounts",
"card",
"certificate",
"audit",
"integrations",
"identity",
"storage",
"settings",
"grants",
"wallet_request",
"export_report",
"export",
"exposure",
"integration_catalogue"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "accounts",
"description": "The identities this connection may act as; the acting one is marked, another is reached with ?identity=<slug>",
"type": "object",
"additionalProperties": false
},
{
"title": "card",
"description": "The signed card peers receive",
"type": "object",
"additionalProperties": false
},
{
"title": "certificate",
"description": "Certificate state",
"type": "object",
"additionalProperties": false
},
{
"title": "audit",
"description": "The audit chain, newest first",
"type": "object",
"properties": {
"limit": {
"default": 100,
"type": "integer",
"minimum": 1,
"maximum": 500
},
"subject": {
"type": "string",
"maxLength": 128
},
"action_like": {
"description": "only actions containing this",
"type": "string",
"maxLength": 64
}
},
"additionalProperties": false,
"examples": [
{
"limit": 50
}
]
},
{
"title": "integrations",
"description": "Connected integrations and their health",
"type": "object",
"additionalProperties": false
},
{
"title": "identity",
"description": "This identity: slug, root, address, status and whether it is certified",
"type": "object",
"additionalProperties": false
},
{
"title": "storage",
"description": "Bytes this identity holds, and the ceiling it is held against",
"type": "object",
"additionalProperties": false
},
{
"title": "settings",
"description": "Your status, accept_new_hosts and moved_away_at, as last set",
"type": "object",
"additionalProperties": false
},
{
"title": "grants",
"description": "Which owners may act as this identity; several is a shared inbox",
"type": "object",
"additionalProperties": false
},
{
"title": "wallet_request",
"description": "What the wallet did with a request: still open, the chain it issued, or why not",
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "the code this acts on"
}
},
"required": [
"code"
],
"additionalProperties": false,
"examples": [
{
"code": "wr_1"
}
]
},
{
"title": "export_report",
"description": "What this identity's export would say of itself: each import ceiling it passes, and every message it leaves out, by id and why",
"type": "object",
"additionalProperties": false
},
{
"title": "export",
"description": "This identity's export zip, unencrypted, base64, up to 5 MiB; send acknowledge: \"unencrypted\"; the owner approves it in the portal",
"type": "object",
"properties": {
"acknowledge": {
"description": "Must be \"unencrypted\": This file is not encrypted. Anyone who gets it can read your contact list and all your conversations and files. It holds no keys, so it cannot be used to speak as you. Keep it where you keep private documents, and delete it once it has been imported.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"acknowledge": "unencrypted"
}
]
},
{
"title": "exposure",
"description": "What an integration offers, and which of its tools contacts may reach",
"type": "object",
"properties": {
"integration": {
"type": "string",
"description": "the name this acts on"
}
},
"required": [
"integration"
],
"additionalProperties": false,
"examples": [
{
"integration": "calendar"
}
]
},
{
"title": "integration_catalogue",
"description": "The MCP servers that connect in one click",
"type": "object",
"additionalProperties": false
}
]
},
"confirmation": {
"type": "string",
"description": "for an act that needs the owner's approval: the confirmation a step_up_required answer named, once they have approved it in the portal"
}
},
"required": [
"action"
],
"additionalProperties": false
}

Change the identity. Whether a contact at a new address is re-pinned without asking; an integration’s exposure, sign-in and disconnection; install a wallet’s chain, move, import, delete the identity, or take back a grant. The last five wait for the owner’s approval in the portal.

readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: true

Action What it does Arguments Scope /v1 operation
exposure Replace which of an integration’s tools contacts may reach integration, entries integrations:write setExposure
settings Your status, which decides what contacts read; whether a contact at a new address is re-pinned without asking (auto) or held (ask); or, alone, moved_away (no renewal reminders) accept_new_hosts?, status?, moved_away? identity:manage updateIdentitySettings
revoke_grant Take back an owner’s access to this identity; the owner approves it in the portal owner_id identity:share revokeIdentityGrant
install_leaf Install the chain the wallet issued; the identity answers with the new key chain, credential_id?, backup_verified? identity:lifecycle installLeaf
move_address Switch to the address the current leaf names; contacts are told address identity:lifecycle moveIdentityAddress
cancel_import Close an open review of an export zip by its digest: the uploaded file goes, and nothing else changes digest identity:lifecycle cancelImportReview
import_archive Take in the export zip a review holds, named by its digest; the owner approves it in the portal, shown the rows digest identity:lifecycle importArchive
delete_identity Erase this identity, its messages and its address, at once; the owner approves it in the portal — identity:lifecycle deleteIdentity
authorize_integration Start an integration’s OAuth sign-in; answers the URL the person opens integration, scope? integrations:write authorizeIntegration
disconnect Disconnect an integration and forget its credential integration integrations:write deleteIntegration
batondeck_identity_change input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"exposure",
"settings",
"revoke_grant",
"install_leaf",
"move_address",
"cancel_import",
"import_archive",
"delete_identity",
"authorize_integration",
"disconnect"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "exposure",
"description": "Replace which of an integration's tools contacts may reach",
"type": "object",
"properties": {
"integration": {
"type": "string",
"description": "the name this acts on"
},
"entries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"tool": {
"type": "string"
},
"mode": {
"type": "string",
"enum": [
"passthrough",
"mapped",
"agent"
]
}
},
"required": [
"tool",
"mode"
],
"additionalProperties": {}
}
}
},
"required": [
"integration",
"entries"
],
"additionalProperties": false,
"examples": [
{
"integration": "calendar",
"entries": [
{
"tool": "list_events",
"mode": "passthrough",
"exposed_name": "calendar_events"
}
]
}
]
},
{
"title": "settings",
"description": "Your status, which decides what contacts read; whether a contact at a new address is re-pinned without asking (auto) or held (ask); or, alone, moved_away (no renewal reminders)",
"type": "object",
"properties": {
"accept_new_hosts": {
"type": "string",
"enum": [
"auto",
"ask"
]
},
"status": {
"type": "string",
"enum": [
"auto",
"available",
"not_available",
"disabled"
]
},
"moved_away": {
"type": "boolean"
}
},
"additionalProperties": false,
"examples": [
{
"accept_new_hosts": "ask"
}
]
},
{
"title": "revoke_grant",
"description": "Take back an owner's access to this identity; the owner approves it in the portal",
"type": "object",
"properties": {
"owner_id": {
"type": "string",
"description": "the ownerId this acts on"
}
},
"required": [
"owner_id"
],
"additionalProperties": false,
"examples": [
{
"owner_id": "U-colleague"
}
]
},
{
"title": "install_leaf",
"description": "Install the chain the wallet issued; the identity answers with the new key",
"type": "object",
"properties": {
"chain": {
"minItems": 2,
"maxItems": 2,
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"credential_id": {
"anyOf": [
{
"type": "string",
"minLength": 1,
"maxLength": 512
},
{
"type": "null"
}
]
},
"backup_verified": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
]
}
},
"required": [
"chain"
],
"additionalProperties": false,
"examples": [
{
"chain": [
"MIIB…leaf",
"MIIB…root"
]
}
]
},
{
"title": "move_address",
"description": "Switch to the address the current leaf names; contacts are told",
"type": "object",
"properties": {
"address": {
"type": "string",
"minLength": 3,
"maxLength": 300
}
},
"required": [
"address"
],
"additionalProperties": false,
"examples": [
{
"address": "alex.batondeck.com"
}
]
},
{
"title": "cancel_import",
"description": "Close an open review of an export zip by its digest: the uploaded file goes, and nothing else changes",
"type": "object",
"properties": {
"digest": {
"type": "string",
"description": "the digest this acts on"
}
},
"required": [
"digest"
],
"additionalProperties": false,
"examples": [
{
"digest": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
}
]
},
{
"title": "import_archive",
"description": "Take in the export zip a review holds, named by its digest; the owner approves it in the portal, shown the rows",
"type": "object",
"properties": {
"digest": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"required": [
"digest"
],
"additionalProperties": false,
"examples": [
{
"digest": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
}
]
},
{
"title": "delete_identity",
"description": "Erase this identity, its messages and its address, at once; the owner approves it in the portal",
"type": "object",
"additionalProperties": false
},
{
"title": "authorize_integration",
"description": "Start an integration's OAuth sign-in; answers the URL the person opens",
"type": "object",
"properties": {
"integration": {
"type": "string",
"description": "the name this acts on"
},
"scope": {
"type": "string",
"maxLength": 512
}
},
"required": [
"integration"
],
"additionalProperties": false,
"examples": [
{
"integration": "calendar"
}
]
},
{
"title": "disconnect",
"description": "Disconnect an integration and forget its credential",
"type": "object",
"properties": {
"integration": {
"type": "string",
"description": "the name this acts on"
}
},
"required": [
"integration"
],
"additionalProperties": false,
"examples": [
{
"integration": "calendar"
}
]
}
]
},
"confirmation": {
"type": "string",
"description": "for an act that needs the owner's approval: the confirmation a step_up_required answer named, once they have approved it in the portal"
}
},
"required": [
"action"
],
"additionalProperties": false
}

Connect, share or open a wallet request. Connect an upstream MCP server; let another owner act as this identity; open a request for your wallet to sign, or mint a signing request. Sharing and signing wait for the owner’s approval in the portal.

readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Action What it does Arguments Scope /v1 operation
grant Let another owner of the workspace act as this identity; the owner approves it in the portal owner_id identity:share grantIdentity
open_wallet_request Open a request for your wallet to sign a new key (signup, renew, move, or return: a renewal that also hands back your wallet’s contact book); answers the page you sign on purpose, endpoint? identity:lifecycle openWalletRequest
csr Mint a key and a signing request for a wallet you run yourself purpose, endpoint? identity:lifecycle issueCsr
review_import Review an export zip (base64url): its contacts and what an import would do with each, and its digest; nothing is written archive identity:lifecycle reviewImportArchive
connect Connect an MCP server (a catalogue id, or an endpoint); answers the sign-in URL when it needs one catalogue?, slug?, endpoint?, transport?, auth? integrations:write createIntegration
batondeck_identity_write input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"grant",
"open_wallet_request",
"csr",
"review_import",
"connect"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "grant",
"description": "Let another owner of the workspace act as this identity; the owner approves it in the portal",
"type": "object",
"properties": {
"owner_id": {
"type": "string",
"minLength": 1
}
},
"required": [
"owner_id"
],
"additionalProperties": false,
"examples": [
{
"owner_id": "U-colleague"
}
]
},
{
"title": "open_wallet_request",
"description": "Open a request for your wallet to sign a new key (signup, renew, move, or return: a renewal that also hands back your wallet's contact book); answers the page you sign on",
"type": "object",
"properties": {
"purpose": {
"type": "string",
"enum": [
"signup",
"renew",
"move"
]
},
"endpoint": {
"type": "string",
"minLength": 1,
"maxLength": 512
}
},
"required": [
"purpose"
],
"additionalProperties": false,
"examples": [
{
"purpose": "renew"
}
]
},
{
"title": "csr",
"description": "Mint a key and a signing request for a wallet you run yourself",
"type": "object",
"properties": {
"purpose": {
"type": "string",
"enum": [
"signup",
"renew",
"move"
]
},
"endpoint": {
"type": "string",
"minLength": 1,
"maxLength": 512
}
},
"required": [
"purpose"
],
"additionalProperties": false,
"examples": [
{
"purpose": "renew"
}
]
},
{
"title": "review_import",
"description": "Review an export zip (base64url): its contacts and what an import would do with each, and its digest; nothing is written",
"type": "object",
"properties": {
"archive": {
"type": "string",
"minLength": 1
}
},
"required": [
"archive"
],
"additionalProperties": false,
"examples": [
{
"archive": "UEsDBBQ…"
}
]
},
{
"title": "connect",
"description": "Connect an MCP server (a catalogue id, or an endpoint); answers the sign-in URL when it needs one",
"type": "object",
"properties": {
"catalogue": {
"type": "string",
"maxLength": 64
},
"slug": {
"type": "string",
"minLength": 2,
"maxLength": 32
},
"endpoint": {
"type": "string",
"format": "uri"
},
"transport": {
"type": "string",
"enum": [
"streamable-http",
"sse"
]
},
"auth": {
"anyOf": [
{
"type": "object",
"properties": {
"header": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"value": {
"type": "string",
"minLength": 1,
"maxLength": 4096
}
},
"required": [
"header",
"value"
]
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"examples": [
{
"catalogue": "linear"
}
]
}
]
},
"confirmation": {
"type": "string",
"description": "for an act that needs the owner's approval: the confirmation a step_up_required answer named, once they have approved it in the portal"
}
},
"required": [
"action"
],
"additionalProperties": false
}

Read the workspace. The workspace, its settings, residency, single sign-on, plan, billing, usage, members, audit, hostnames and a custom domain, agent keys, webhooks and their deliveries, exports, and an export’s archive (which waits for the owner’s approval in the portal).

readOnlyHint: true · openWorldHint: true

Action What it does Arguments Scope /v1 operation
settings The workspace’s settings, and why the platform fixes the ones it fixes — workspace:read listSettings
workspace The workspace: name, status, plan, jurisdiction, any pause or deletion hold — workspace:read getWorkspace
plan The plan and every entitlement in force, with where each comes from — billing:read getWorkspacePlan
billing The subscription as billing knows it — billing:read getBilling
usage Metered usage by day limit? billing:read listUsage
members The owners in the workspace and which of them administer it — members:read listMembers
audit The workspace’s audit: its chain and its events limit? audit:read listWorkspaceAudit
domains The hostnames the workspace answers on — workspace:read listDomains
keys Agent keys: name, prefix, scopes, who made it, last use; never a key. The owner’s own, or every key for an admin — keys:read listApiKeys
webhooks Webhook endpoints and their state; never a secret — credentials:read listWebhooks
webhook_deliveries An endpoint’s delivery log, newest first webhook_id, limit? credentials:read listWebhookDeliveries
domain One custom domain: its status, the DNS record to create and what is still needed, read live hostname workspace:read getCustomDomain
residency Where the workspace’s data is held, and whether the residency guarantee is in effect — workspace:read getResidency
sso Whether the workspace requires single sign-on, its connections and its domains — workspace:read getSso
download_export The workspace export zip, unencrypted, base64, up to 5 MiB; send acknowledge: “unencrypted”; the owner approves it in the portal acknowledge? export:read exportWorkspace
batondeck_workspace_read input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"settings",
"workspace",
"plan",
"billing",
"usage",
"members",
"audit",
"domains",
"keys",
"webhooks",
"webhook_deliveries",
"domain",
"residency",
"sso",
"download_export"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "settings",
"description": "The workspace's settings, and why the platform fixes the ones it fixes",
"type": "object",
"additionalProperties": false
},
{
"title": "workspace",
"description": "The workspace: name, status, plan, jurisdiction, any pause or deletion hold",
"type": "object",
"additionalProperties": false
},
{
"title": "plan",
"description": "The plan and every entitlement in force, with where each comes from",
"type": "object",
"additionalProperties": false
},
{
"title": "billing",
"description": "The subscription as billing knows it",
"type": "object",
"additionalProperties": false
},
{
"title": "usage",
"description": "Metered usage by day",
"type": "object",
"properties": {
"limit": {
"default": 200,
"type": "integer",
"minimum": 1,
"maximum": 1000
}
},
"additionalProperties": false,
"examples": [
{
"limit": 30
}
]
},
{
"title": "members",
"description": "The owners in the workspace and which of them administer it",
"type": "object",
"additionalProperties": false
},
{
"title": "audit",
"description": "The workspace's audit: its chain and its events",
"type": "object",
"properties": {
"limit": {
"default": 100,
"type": "integer",
"minimum": 1,
"maximum": 500
}
},
"additionalProperties": false,
"examples": [
{
"limit": 50
}
]
},
{
"title": "domains",
"description": "The hostnames the workspace answers on",
"type": "object",
"additionalProperties": false
},
{
"title": "keys",
"description": "Agent keys: name, prefix, scopes, who made it, last use; never a key. The owner's own, or every key for an admin",
"type": "object",
"additionalProperties": false
},
{
"title": "webhooks",
"description": "Webhook endpoints and their state; never a secret",
"type": "object",
"additionalProperties": false
},
{
"title": "webhook_deliveries",
"description": "An endpoint's delivery log, newest first",
"type": "object",
"properties": {
"webhook_id": {
"type": "string",
"description": "the id this acts on"
},
"limit": {
"default": 50,
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"required": [
"webhook_id"
],
"additionalProperties": false,
"examples": [
{
"webhook_id": "whe_1",
"limit": 20
}
]
},
{
"title": "domain",
"description": "One custom domain: its status, the DNS record to create and what is still needed, read live",
"type": "object",
"properties": {
"hostname": {
"type": "string",
"description": "the hostname this acts on"
}
},
"required": [
"hostname"
],
"additionalProperties": false,
"examples": [
{
"hostname": "batondeck.example.com"
}
]
},
{
"title": "residency",
"description": "Where the workspace's data is held, and whether the residency guarantee is in effect",
"type": "object",
"additionalProperties": false
},
{
"title": "sso",
"description": "Whether the workspace requires single sign-on, its connections and its domains",
"type": "object",
"additionalProperties": false
},
{
"title": "download_export",
"description": "The workspace export zip, unencrypted, base64, up to 5 MiB; send acknowledge: \"unencrypted\"; the owner approves it in the portal",
"type": "object",
"properties": {
"acknowledge": {
"description": "Must be \"unencrypted\": This file is not encrypted. Anyone who gets it can read your contact list and all your conversations and files. It holds no keys, so it cannot be used to speak as you. Keep it where you keep private documents, and delete it once it has been imported.",
"type": "string"
}
},
"additionalProperties": false,
"examples": [
{
"acknowledge": "unencrypted"
}
]
}
]
},
"confirmation": {
"type": "string",
"description": "for an act that needs the owner's approval: the confirmation a step_up_required answer named, once they have approved it in the portal"
}
},
"required": [
"action"
],
"additionalProperties": false
}

Change the workspace. Change a setting or its name; pause, resume, schedule or cancel its deletion; require single sign-on; check or remove a custom domain; revoke a key; rotate, pause or remove a webhook. Pausing, deleting and single sign-on wait for the owner’s approval in the portal.

readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: true

Action What it does Arguments Scope /v1 operation
update Rename the workspace, or set how long a sign-in lasts name?, session_max_age_hours? workspace:manage updateWorkspace
pause Pause the workspace (restriction of processing); the owner approves it in the portal reason? workspace:admin pauseWorkspace
resume Lift your own pause — workspace:admin resumeWorkspace
request_deletion Schedule the workspace for deletion after a seven-day hold; the owner approves it in the portal reason? workspace:admin requestWorkspaceDeletion
cancel_deletion Cancel a scheduled deletion inside its seven days — workspace:admin cancelWorkspaceDeletion
revoke_key Revoke an agent key: the owner’s own, or any for an admin; it stops working at once key_id keys:manage revokeApiKey
rotate_webhook_secret Rotate an endpoint’s signing secret; the new one is in the answer once webhook_id credentials:manage rotateWebhookSecret
set_webhook_status Pause an endpoint, or resume one webhook_id, status credentials:manage setWebhookStatus
delete_webhook Remove a webhook endpoint; its delivery log stays webhook_id credentials:manage deleteWebhook
check_domain Check a custom domain now, and record the result hostname workspace:manage checkCustomDomain
remove_domain Remove a custom domain no identity lives at hostname workspace:manage removeCustomDomain
set_sso_required Require single sign-on, or stop requiring it; the owner approves it in the portal required workspace:admin setSsoRequired
batondeck_workspace_change input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"update",
"pause",
"resume",
"request_deletion",
"cancel_deletion",
"revoke_key",
"rotate_webhook_secret",
"set_webhook_status",
"delete_webhook",
"check_domain",
"remove_domain",
"set_sso_required"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "update",
"description": "Rename the workspace, or set how long a sign-in lasts",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"session_max_age_hours": {
"anyOf": [
{
"type": "integer",
"minimum": 1,
"maximum": 168
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"examples": [
{
"name": "Pune Studio"
}
]
},
{
"title": "pause",
"description": "Pause the workspace (restriction of processing); the owner approves it in the portal",
"type": "object",
"properties": {
"reason": {
"type": "string",
"maxLength": 500
}
},
"additionalProperties": false,
"examples": [
{
"reason": "a dispute with a contact"
}
]
},
{
"title": "resume",
"description": "Lift your own pause",
"type": "object",
"additionalProperties": false
},
{
"title": "request_deletion",
"description": "Schedule the workspace for deletion after a seven-day hold; the owner approves it in the portal",
"type": "object",
"properties": {
"reason": {
"type": "string",
"maxLength": 500
}
},
"additionalProperties": false,
"examples": [
{
"reason": "closing the studio"
}
]
},
{
"title": "cancel_deletion",
"description": "Cancel a scheduled deletion inside its seven days",
"type": "object",
"additionalProperties": false
},
{
"title": "revoke_key",
"description": "Revoke an agent key: the owner's own, or any for an admin; it stops working at once",
"type": "object",
"properties": {
"key_id": {
"type": "string",
"description": "the id this acts on"
}
},
"required": [
"key_id"
],
"additionalProperties": false,
"examples": [
{
"key_id": "key_1"
}
]
},
{
"title": "rotate_webhook_secret",
"description": "Rotate an endpoint's signing secret; the new one is in the answer once",
"type": "object",
"properties": {
"webhook_id": {
"type": "string",
"description": "the id this acts on"
}
},
"required": [
"webhook_id"
],
"additionalProperties": false,
"examples": [
{
"webhook_id": "whe_1"
}
]
},
{
"title": "set_webhook_status",
"description": "Pause an endpoint, or resume one",
"type": "object",
"properties": {
"webhook_id": {
"type": "string",
"description": "the id this acts on"
},
"status": {
"type": "string",
"enum": [
"active",
"paused"
]
}
},
"required": [
"webhook_id",
"status"
],
"additionalProperties": false,
"examples": [
{
"webhook_id": "whe_1",
"status": "paused"
}
]
},
{
"title": "delete_webhook",
"description": "Remove a webhook endpoint; its delivery log stays",
"type": "object",
"properties": {
"webhook_id": {
"type": "string",
"description": "the id this acts on"
}
},
"required": [
"webhook_id"
],
"additionalProperties": false,
"examples": [
{
"webhook_id": "whe_1"
}
]
},
{
"title": "check_domain",
"description": "Check a custom domain now, and record the result",
"type": "object",
"properties": {
"hostname": {
"type": "string",
"description": "the hostname this acts on"
}
},
"required": [
"hostname"
],
"additionalProperties": false,
"examples": [
{
"hostname": "batondeck.example.com"
}
]
},
{
"title": "remove_domain",
"description": "Remove a custom domain no identity lives at",
"type": "object",
"properties": {
"hostname": {
"type": "string",
"description": "the hostname this acts on"
}
},
"required": [
"hostname"
],
"additionalProperties": false,
"examples": [
{
"hostname": "batondeck.example.com"
}
]
},
{
"title": "set_sso_required",
"description": "Require single sign-on, or stop requiring it; the owner approves it in the portal",
"type": "object",
"properties": {
"required": {
"type": "boolean"
}
},
"required": [
"required"
],
"additionalProperties": false,
"examples": [
{
"required": true
}
]
}
]
},
"confirmation": {
"type": "string",
"description": "for an act that needs the owner's approval: the confirmation a step_up_required answer named, once they have approved it in the portal"
}
},
"required": [
"action"
],
"additionalProperties": false
}

Create in the workspace. Mint an agent key, register a webhook, start an export, or open a plan checkout, billing or single sign-on link — each waiting for the owner’s approval in the portal — or add a custom domain.

readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Action What it does Arguments Scope /v1 operation
checkout A Stripe Checkout link for a paid plan; the owner approves it in the portal first plan billing:manage openCheckout
billing_portal A link to Stripe’s customer portal; the owner approves it in the portal first — billing:manage openBillingPortal
mint_key Mint an agent key; the owner approves it in the portal, and the key is in the answer once name, scopes?, everything?, identity_ids?, expires_in_days? keys:manage mintApiKey
create_webhook Register a webhook endpoint; the owner approves it in the portal, and the secret is in the answer once url, events? credentials:manage createWebhook
add_domain Add a custom domain; answers the DNS records to create hostname workspace:manage addCustomDomain
sso_portal_link A short-lived link to set up single sign-on or verify a domain; the owner approves it in the portal intent workspace:admin createSsoPortalLink
batondeck_workspace_write input schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"checkout",
"billing_portal",
"mint_key",
"create_webhook",
"add_domain",
"sso_portal_link"
]
},
"arguments": {
"type": "object",
"description": "the arguments of the action named by `action`",
"anyOf": [
{
"title": "checkout",
"description": "A Stripe Checkout link for a paid plan; the owner approves it in the portal first",
"type": "object",
"properties": {
"plan": {
"type": "string",
"enum": [
"pro",
"team",
"enterprise"
]
}
},
"required": [
"plan"
],
"additionalProperties": false,
"examples": [
{
"plan": "team"
}
]
},
{
"title": "billing_portal",
"description": "A link to Stripe's customer portal; the owner approves it in the portal first",
"type": "object",
"additionalProperties": false
},
{
"title": "mint_key",
"description": "Mint an agent key; the owner approves it in the portal, and the key is in the answer once",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"scopes": {
"minItems": 1,
"type": "array",
"items": {
"type": "string"
}
},
"everything": {
"type": "boolean"
},
"identity_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"expires_in_days": {
"type": "integer",
"minimum": 1,
"maximum": 365
}
},
"required": [
"name"
],
"additionalProperties": false,
"examples": [
{
"name": "nightly export",
"scopes": [
"batondeck:workspace:read"
]
}
]
},
{
"title": "create_webhook",
"description": "Register a webhook endpoint; the owner approves it in the portal, and the secret is in the answer once",
"type": "object",
"properties": {
"url": {
"type": "string",
"minLength": 1
},
"events": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"url"
],
"additionalProperties": false,
"examples": [
{
"url": "https://hooks.example.com/hdtp",
"events": [
"message.received"
]
}
]
},
{
"title": "add_domain",
"description": "Add a custom domain; answers the DNS records to create",
"type": "object",
"properties": {
"hostname": {
"type": "string",
"minLength": 3,
"maxLength": 253
}
},
"required": [
"hostname"
],
"additionalProperties": false,
"examples": [
{
"hostname": "batondeck.example.com"
}
]
},
{
"title": "sso_portal_link",
"description": "A short-lived link to set up single sign-on or verify a domain; the owner approves it in the portal",
"type": "object",
"properties": {
"intent": {
"type": "string",
"enum": [
"sso",
"domain_verification"
]
}
},
"required": [
"intent"
],
"additionalProperties": false,
"examples": [
{
"intent": "sso"
}
]
}
]
},
"confirmation": {
"type": "string",
"description": "for an act that needs the owner's approval: the confirmation a step_up_required answer named, once they have approved it in the portal"
}
},
"required": [
"action"
],
"additionalProperties": false
}
URI Name What it holds
hdtp://inbox inbox Unread counts per thread, for a badge that costs no tool call
hdtp://requests contact requests Contacts waiting for the owner to approve them
hdtp://pending pending agent-answered requests Calls a contact made that this agent is expected to answer
hdtp://thread/{id} thread One conversation’s state: unread count and when it last moved