Tool reference · LinkedIn

propose_message

Propose a LinkedIn message to a 1st-degree connection. It is NOT sent: it waits in Approvals until a person approves (and may edit) it.

writesreaches LinkedInrate limited

Updated 2026-09-18 · Server 2.0.0

What it does

Draft a message for a person to approve. The approver can edit the text before it goes out; the agent sees the outcome with get_approval.

This tool drives a real LinkedIn account

It runs through a connected sender account in your workspace — not through a scraper and not through your own profile. Call list_sender_accounts first to see which identities are connected and healthy. If the workspace has none, this tool returns an error telling you so; accounts for agents covers how teams get one without risking their own profile.

Arguments

NameTypeRequiredMeaning
profilestringyesProfile URL, public identifier or provider id of the recipient
textstringyesThe message text
reasonstringnoWhy this message, shown to the approver
accountstringnoSender account id or name to send from.
dry_runbooleannoCheck everything (target, do-not-contact, duplicates, text, limits) and return the verdict without proposing anything

This table is generated from the literal inputSchema that tools/list returns, so what your client sees and what this page says are the same object:

inputSchema
{
  "type": "object",
  "properties": {
    "profile": {
      "type": "string",
      "description": "Profile URL, public identifier or provider id of the recipient"
    },
    "text": {
      "type": "string",
      "description": "The message text"
    },
    "reason": {
      "type": "string",
      "description": "Why this message, shown to the approver"
    },
    "account": {
      "type": "string",
      "description": "Sender account id or name to send from."
    },
    "dry_run": {
      "type": "boolean",
      "description": "Check everything (target, do-not-contact, duplicates, text, limits) and return the verdict without proposing anything"
    }
  },
  "required": [
    "profile",
    "text"
  ]
}

Request

Paste this, swap the key, and you have called the tool.

curl
curl -s https://topclozer.com/api/mcp \
  -H "Authorization: Bearer tcz_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "propose_message",
      "arguments": {
        "profile": "dana-whitfield",
        "text": "Thanks for connecting, Dana — would a 15-minute call next week be useful?",
        "reason": "Accepted our request yesterday."
      }
    }
  }'

Returns

{ approval_id, status, duplicate, target, account, next } — the same envelope as propose_connection_request.

The payload arrives inside an MCP content block — one text block whose body is this JSON, pretty-printed. Parse the string; there is no structured-content field.

payload
{ "approval_id": "apr_mf3k4c1z0", "status": "pending", "duplicate": false, "target": { "name": "Dana Whitfield", "headline": "CTO at Northbeam", "providerId": "ACoAAB1x…", "profileUrl": "https://www.linkedin.com/in/dana-whitfield" }, "account": "Marcus Feld", "next": "Waiting for a person in the TopClozer console → Approvals. Poll get_approval." }

Worth knowing

Needs the linkedin:propose scope. Messages reach 1st-degree connections; to anyone else the approved send fails with the reason recorded on the approval.

Rate limit

30 LinkedIn tool calls per 5 minutes, per workspace. Exceeding it returns HTTP 429 with JSON-RPC error -32002 and a Retry-After header. The budget is shared by every LinkedIn tool and counted per workspace, so minting a second key does not buy a second allowance.

The limit exists because an agent retrying in a loop is the request pattern that gets a LinkedIn account restricted, and a restricted account is a much worse outcome for you than a 429. Workspace tools do not spend this budget.

Related tools

All 65 tools are listed on the tool index. Connecting a client is on the Claude setup page, and the protocol details are on the server page.