ReferenceWhat you can callRepliesmutate runreplies.draft

replies.draft

replies.draft is dispatched on 2 endpoints. Which one runs depends on the URL you post to, not on the name.

mutate replies.draft

Write a reply draft into a lead’s Sales Inbox thread. A person reviews and sends it in the app, this can send nothing.

EndpointPOST /mcp/mutate
Scopewrite
Sandbox keyallowed
Extra entitlementnone
MCP toolsselda_draft_reply
Convex functionmcpQueries:draftInboxReply

A free sandbox key may call it.

Arguments

ArgumentTypeRequiredNotes
leadIdstringrequired
bodystringrequired
instructionstringoptionalWhat the person asked for in their own words (“tee tästä lyhyempi”). Optional, kept only in the draft history beside the text, it changes nothing about what is stored in the composer. The selda_draft_reply tool schemas in api/mcp.ts and mcp-server/index.ts do not pass it yet, so this arrives empty on the tool path until they do.

What Selda fills in

You never send these. The HTTP layer overwrites them from the API key, which is what keeps one organisation’s data out of another’s reach.

ArgumentFilled in from
orgIdyour organisation, resolved from the API key

Example request

Required arguments only. Values in angle brackets are yours to fill in; the optional ones are in the table above.

curl -X POST https://api.selda.ai/mcp/mutate \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "fn": "replies.draft", "args": { "leadId": "<leadId>", "body": "<body>" } }'
{
  "fn": "replies.draft",
  "args": {
    "leadId": "<leadId>",
    "body": "<body>"
  }
}

Example response

Every endpoint answers in the same envelope.

{
  "value": <the function's return value>,
  "request_id": "req_..."
}

The shape of value is not documented here. mcpQueries:draftInboxReply declares no returns validator, so there is nothing to derive it from, and a shape written out by hand here is a shape that goes stale without anything noticing. Call it once against a test key and read what comes back.

On failure the body is { "error": { "type", "code", "message", "request_id" }, "request_id" } and request_id is echoed in the X-Request-Id header.

run replies.draft

Draft an answer to a reply.

EndpointPOST /mcp/run
Scopepipeline
Sandbox keyallowed
Extra entitlementnone
MCP toolsnone, HTTP only
Convex functionmcpQueries:draftReply

A free sandbox key may call it.

Arguments

ArgumentTypeRequiredNotes
threadIdstringrequired
intentstringoptional

What Selda fills in

You never send these. The HTTP layer overwrites them from the API key, which is what keeps one organisation’s data out of another’s reach.

ArgumentFilled in from
orgIdyour organisation, resolved from the API key

Example request

Required arguments only. Values in angle brackets are yours to fill in; the optional ones are in the table above.

curl -X POST https://api.selda.ai/mcp/run \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "fn": "replies.draft", "args": { "threadId": "<threadId>" } }'
{
  "fn": "replies.draft",
  "args": {
    "threadId": "<threadId>"
  }
}

Example response

Every endpoint answers in the same envelope.

{
  "value": <the function's return value>,
  "request_id": "req_..."
}

The shape of value is not documented here. mcpQueries:draftReply declares no returns validator, so there is nothing to derive it from, and a shape written out by hand here is a shape that goes stale without anything noticing. Call it once against a test key and read what comes back.

On failure the body is { "error": { "type", "code", "message", "request_id" }, "request_id" } and request_id is echoed in the X-Request-Id header.


Generated from convex/lib/mcpRegistry.ts. Nothing in this reference sends: launchRun is in no registry and never will be, so a script can prepare a campaign completely and a person still presses send in the app.