[{"data":1,"prerenderedAt":1031},["ShallowReactive",2],{"doc:\u002Fv\u002F2026.3\u002Fbuild-with-ai\u002Fcall-workspace369-from-your-app-over-https":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"section":10,"version":11,"lastUpdated":12,"body":13,"_type":1025,"_id":1026,"_source":1027,"_file":1028,"_stem":1029,"_extension":1030},"\u002Fv\u002F2026.3\u002Fbuild-with-ai\u002Fcall-workspace369-from-your-app-over-https","build-with-ai",false,"","Call Workspace369 from your app over HTTPS","Send JSON-RPC tools\u002Flist and tools\u002Fcall requests to the Workspace369 MCP endpoint from your own server code with a personal access token, and handle every error.","Build with AI","2026.3","2026-10-18",{"type":14,"children":15,"toc":1009},"root",[16,24,29,36,80,86,197,203,214,226,270,276,302,311,316,327,348,355,360,371,377,387,393,406,722,734,740,745,754,759,880,892,898,925,938,944],{"type":17,"tag":18,"props":19,"children":20},"element","p",{},[21],{"type":22,"value":23},"text","Your own server code can call the same tools an AI app uses. You send an HTTPS POST to the Workspace369 MCP endpoint with a personal access token, and get one JSON answer back. This is the Model Context Protocol over HTTP, not a REST API: there is one URL, and the tool name goes in the request body.",{"type":17,"tag":18,"props":25,"children":26},{},[27],{"type":22,"value":28},"Use this from a backend, a scheduled job, or a script. Do not call it from browser code.",{"type":17,"tag":30,"props":31,"children":33},"h2",{"id":32},"before-you-begin",[34],{"type":22,"value":35},"Before you begin",{"type":17,"tag":37,"props":38,"children":39},"ol",{},[40,55,67],{"type":17,"tag":41,"props":42,"children":43},"li",{},[44,46,53],{"type":22,"value":45},"A workspace admin has turned MCP on. See ",{"type":17,"tag":47,"props":48,"children":50},"a",{"href":49},"\u002Fv\u002F2026.3\u002Fai-connections\u002Fenable-mcp-and-manage-connected-apps\u002F",[51],{"type":22,"value":52},"Enable MCP and manage connected apps",{"type":22,"value":54},".",{"type":17,"tag":41,"props":56,"children":57},{},[58,60,66],{"type":22,"value":59},"You have a personal access token with the scopes your calls need. See ",{"type":17,"tag":47,"props":61,"children":63},{"href":62},"\u002Fv\u002F2026.3\u002Fai-connections\u002Fpersonal-access-tokens\u002F",[64],{"type":22,"value":65},"Personal access tokens for scripts and agents",{"type":22,"value":54},{"type":17,"tag":41,"props":68,"children":69},{},[70,72,79],{"type":22,"value":71},"The token is in an environment variable on your server, here called ",{"type":17,"tag":73,"props":74,"children":76},"code",{"className":75},[],[77],{"type":22,"value":78},"WORKSPACE369_TOKEN",{"type":22,"value":54},{"type":17,"tag":30,"props":81,"children":83},{"id":82},"how-the-endpoint-works",[84],{"type":22,"value":85},"How the endpoint works",{"type":17,"tag":87,"props":88,"children":89},"ul",{},[90,117,127,137,170,180],{"type":17,"tag":41,"props":91,"children":92},{},[93,99,101,107,109,115],{"type":17,"tag":94,"props":95,"children":96},"strong",{},[97],{"type":22,"value":98},"URL:",{"type":22,"value":100}," ",{"type":17,"tag":73,"props":102,"children":104},{"className":103},[],[105],{"type":22,"value":106},"https:\u002F\u002Fmcp.workspace369.com\u002Fmcp",{"type":22,"value":108},". To pin requests to one workspace, use ",{"type":17,"tag":73,"props":110,"children":112},{"className":111},[],[113],{"type":22,"value":114},"https:\u002F\u002Fmcp.workspace369.com\u002Fw\u002F\u003CworkspaceId>\u002Fmcp",{"type":22,"value":116},". A token for a different workspace is refused with a 403.",{"type":17,"tag":41,"props":118,"children":119},{},[120,125],{"type":17,"tag":94,"props":121,"children":122},{},[123],{"type":22,"value":124},"Method:",{"type":22,"value":126}," POST only. Any other method returns 405.",{"type":17,"tag":41,"props":128,"children":129},{},[130,135],{"type":17,"tag":94,"props":131,"children":132},{},[133],{"type":22,"value":134},"Stateless:",{"type":22,"value":136}," every request stands alone. There is no session to open or close, and each answer is a single JSON body.",{"type":17,"tag":41,"props":138,"children":139},{},[140,145,146,152,154,160,162,168],{"type":17,"tag":94,"props":141,"children":142},{},[143],{"type":22,"value":144},"Headers:",{"type":22,"value":100},{"type":17,"tag":73,"props":147,"children":149},{"className":148},[],[150],{"type":22,"value":151},"Authorization: Bearer \u003Ctoken>",{"type":22,"value":153},", ",{"type":17,"tag":73,"props":155,"children":157},{"className":156},[],[158],{"type":22,"value":159},"Content-Type: application\u002Fjson",{"type":22,"value":161},", and ",{"type":17,"tag":73,"props":163,"children":165},{"className":164},[],[166],{"type":22,"value":167},"Accept: application\u002Fjson, text\u002Fevent-stream",{"type":22,"value":169},". The Accept header must list both types.",{"type":17,"tag":41,"props":171,"children":172},{},[173,178],{"type":17,"tag":94,"props":174,"children":175},{},[176],{"type":22,"value":177},"Body:",{"type":22,"value":179}," a JSON-RPC 2.0 message, up to 1 MB.",{"type":17,"tag":41,"props":181,"children":182},{},[183,188,190,196],{"type":17,"tag":94,"props":184,"children":185},{},[186],{"type":22,"value":187},"Token:",{"type":22,"value":189}," a personal access token starts with ",{"type":17,"tag":73,"props":191,"children":193},{"className":192},[],[194],{"type":22,"value":195},"mcp_pat_",{"type":22,"value":54},{"type":17,"tag":30,"props":198,"children":200},{"id":199},"list-the-tools",[201],{"type":22,"value":202},"List the tools",{"type":17,"tag":18,"props":204,"children":205},{},[206,212],{"type":17,"tag":73,"props":207,"children":209},{"className":208},[],[210],{"type":22,"value":211},"tools\u002Flist",{"type":22,"value":213}," returns every tool you can call, with its description and input schema.",{"type":17,"tag":215,"props":216,"children":221},"pre",{"className":217,"code":219,"language":220,"meta":7},[218],"language-bash","curl -s https:\u002F\u002Fmcp.workspace369.com\u002Fmcp \\\n  -H \"Authorization: Bearer $WORKSPACE369_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Accept: application\u002Fjson, text\u002Fevent-stream\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools\u002Flist\",\"params\":{}}'\n","bash",[222],{"type":17,"tag":73,"props":223,"children":224},{"__ignoreMap":7},[225],{"type":22,"value":219},{"type":17,"tag":18,"props":227,"children":228},{},[229,231,237,239,245,247,253,255,261,263,269],{"type":22,"value":230},"The answer has the form ",{"type":17,"tag":73,"props":232,"children":234},{"className":233},[],[235],{"type":22,"value":236},"{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"tools\":[ ... ]}}",{"type":22,"value":238},". Each tool has a ",{"type":17,"tag":73,"props":240,"children":242},{"className":241},[],[243],{"type":22,"value":244},"name",{"type":22,"value":246},", a ",{"type":17,"tag":73,"props":248,"children":250},{"className":249},[],[251],{"type":22,"value":252},"description",{"type":22,"value":254},", and an ",{"type":17,"tag":73,"props":256,"children":258},{"className":257},[],[259],{"type":22,"value":260},"inputSchema",{"type":22,"value":262}," that tells you which arguments it accepts. Read the schema before you call a tool. The same list is in the ",{"type":17,"tag":47,"props":264,"children":266},{"href":265},"\u002Fv\u002F2026.3\u002Fai-connections\u002Fmcp-tools-reference\u002F",[267],{"type":22,"value":268},"MCP tools reference",{"type":22,"value":54},{"type":17,"tag":30,"props":271,"children":273},{"id":272},"call-a-tool",[274],{"type":22,"value":275},"Call a tool",{"type":17,"tag":18,"props":277,"children":278},{},[279,285,287,292,294,300],{"type":17,"tag":73,"props":280,"children":282},{"className":281},[],[283],{"type":22,"value":284},"tools\u002Fcall",{"type":22,"value":286}," takes the tool ",{"type":17,"tag":73,"props":288,"children":290},{"className":289},[],[291],{"type":22,"value":244},{"type":22,"value":293}," and its ",{"type":17,"tag":73,"props":295,"children":297},{"className":296},[],[298],{"type":22,"value":299},"arguments",{"type":22,"value":301},". This call searches clients:",{"type":17,"tag":215,"props":303,"children":306},{"className":304,"code":305,"language":220,"meta":7},[218],"curl -s https:\u002F\u002Fmcp.workspace369.com\u002Fmcp \\\n  -H \"Authorization: Bearer $WORKSPACE369_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Accept: application\u002Fjson, text\u002Fevent-stream\" \\\n  -d '{\n    \"jsonrpc\": \"2.0\",\n    \"id\": 2,\n    \"method\": \"tools\u002Fcall\",\n    \"params\": {\n      \"name\": \"clients_search\",\n      \"arguments\": { \"query\": \"Acme\", \"limit\": 10 }\n    }\n  }'\n",[307],{"type":17,"tag":73,"props":308,"children":309},{"__ignoreMap":7},[310],{"type":22,"value":305},{"type":17,"tag":18,"props":312,"children":313},{},[314],{"type":22,"value":315},"A successful answer looks like this:",{"type":17,"tag":215,"props":317,"children":322},{"className":318,"code":320,"language":321,"meta":7},[319],"language-json","{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 2,\n  \"result\": {\n    \"content\": [{ \"type\": \"text\", \"text\": \"Found 1 client ...\" }],\n    \"structuredContent\": { \"clients\": [ ... ], \"nextCursor\": \"...\" }\n  }\n}\n","json",[323],{"type":17,"tag":73,"props":324,"children":325},{"__ignoreMap":7},[326],{"type":22,"value":320},{"type":17,"tag":18,"props":328,"children":329},{},[330,332,338,340,346],{"type":22,"value":331},"Read ",{"type":17,"tag":73,"props":333,"children":335},{"className":334},[],[336],{"type":22,"value":337},"result.structuredContent",{"type":22,"value":339}," in code. ",{"type":17,"tag":73,"props":341,"children":343},{"className":342},[],[344],{"type":22,"value":345},"result.content",{"type":22,"value":347}," is the same information as text for a person or model to read.",{"type":17,"tag":349,"props":350,"children":352},"h3",{"id":351},"nodejs",[353],{"type":22,"value":354},"Node.js",{"type":17,"tag":18,"props":356,"children":357},{},[358],{"type":22,"value":359},"This helper works in Node 18 and later. It retries once after a rate limit and returns the structured result.",{"type":17,"tag":215,"props":361,"children":366},{"className":362,"code":364,"language":365,"meta":7},[363],"language-js","const ENDPOINT = \"https:\u002F\u002Fmcp.workspace369.com\u002Fmcp\";\n\nlet nextId = 1;\n\nexport async function callTool(name, args = {}) {\n  for (let attempt = 0; attempt \u003C 2; attempt++) {\n    const res = await fetch(ENDPOINT, {\n      method: \"POST\",\n      headers: {\n        Authorization: `Bearer ${process.env.WORKSPACE369_TOKEN}`,\n        \"Content-Type\": \"application\u002Fjson\",\n        Accept: \"application\u002Fjson, text\u002Fevent-stream\",\n      },\n      body: JSON.stringify({\n        jsonrpc: \"2.0\",\n        id: nextId++,\n        method: \"tools\u002Fcall\",\n        params: { name, arguments: args },\n      }),\n    });\n\n    if (res.status === 429) {\n      const wait = Number(res.headers.get(\"Retry-After\") ?? \"5\");\n      await new Promise((r) => setTimeout(r, wait * 1000));\n      continue;\n    }\n    if (res.status === 401) throw new Error(\"Token is invalid, revoked, or expired.\");\n    if (!res.ok) throw new Error(`Workspace369 returned HTTP ${res.status}`);\n\n    const body = await res.json();\n    if (body.error) throw new Error(`JSON-RPC error ${body.error.code}: ${body.error.message}`);\n\n    const result = body.result;\n    if (result.isError) {\n      throw new Error(result.content?.[0]?.text ?? \"The tool refused the call.\");\n    }\n    if (result.structuredContent?.held_for_approval) {\n      return { held: true, ...result.structuredContent };\n    }\n    return result.structuredContent;\n  }\n  throw new Error(\"Rate limited twice in a row.\");\n}\n","js",[367],{"type":17,"tag":73,"props":368,"children":369},{"__ignoreMap":7},[370],{"type":22,"value":364},{"type":17,"tag":349,"props":372,"children":374},{"id":373},"python",[375],{"type":22,"value":376},"Python",{"type":17,"tag":215,"props":378,"children":382},{"className":379,"code":381,"language":373,"meta":7},[380],"language-python","import os\nimport time\nimport requests\n\nENDPOINT = \"https:\u002F\u002Fmcp.workspace369.com\u002Fmcp\"\n_next_id = 0\n\n\ndef call_tool(name, arguments=None):\n    global _next_id\n    for _ in range(2):\n        _next_id += 1\n        res = requests.post(\n            ENDPOINT,\n            headers={\n                \"Authorization\": f\"Bearer {os.environ['WORKSPACE369_TOKEN']}\",\n                \"Content-Type\": \"application\u002Fjson\",\n                \"Accept\": \"application\u002Fjson, text\u002Fevent-stream\",\n            },\n            json={\n                \"jsonrpc\": \"2.0\",\n                \"id\": _next_id,\n                \"method\": \"tools\u002Fcall\",\n                \"params\": {\"name\": name, \"arguments\": arguments or {}},\n            },\n            timeout=60,\n        )\n        if res.status_code == 429:\n            time.sleep(int(res.headers.get(\"Retry-After\", \"5\")))\n            continue\n        if res.status_code == 401:\n            raise RuntimeError(\"Token is invalid, revoked, or expired.\")\n        res.raise_for_status()\n\n        body = res.json()\n        if \"error\" in body:\n            raise RuntimeError(f\"JSON-RPC error: {body['error']}\")\n        result = body[\"result\"]\n        if result.get(\"isError\"):\n            raise RuntimeError(result[\"content\"][0][\"text\"])\n        structured = result.get(\"structuredContent\") or {}\n        if structured.get(\"held_for_approval\"):\n            return {\"held\": True, **structured}\n        return structured\n    raise RuntimeError(\"Rate limited twice in a row.\")\n",[383],{"type":17,"tag":73,"props":384,"children":385},{"__ignoreMap":7},[386],{"type":22,"value":381},{"type":17,"tag":30,"props":388,"children":390},{"id":389},"handle-errors",[391],{"type":22,"value":392},"Handle errors",{"type":17,"tag":18,"props":394,"children":395},{},[396,398,404],{"type":22,"value":397},"There are two layers of errors. HTTP status codes describe the request. The ",{"type":17,"tag":73,"props":399,"children":401},{"className":400},[],[402],{"type":22,"value":403},"isError",{"type":22,"value":405}," flag on a result describes the tool call.",{"type":17,"tag":407,"props":408,"children":409},"table",{},[410,434],{"type":17,"tag":411,"props":412,"children":413},"thead",{},[414],{"type":17,"tag":415,"props":416,"children":417},"tr",{},[418,424,429],{"type":17,"tag":419,"props":420,"children":421},"th",{},[422],{"type":22,"value":423},"What you see",{"type":17,"tag":419,"props":425,"children":426},{},[427],{"type":22,"value":428},"What it means",{"type":17,"tag":419,"props":430,"children":431},{},[432],{"type":22,"value":433},"What to do",{"type":17,"tag":435,"props":436,"children":437},"tbody",{},[438,463,487,518,536,568,592,616,654,693],{"type":17,"tag":415,"props":439,"children":440},{},[441,453,458],{"type":17,"tag":442,"props":443,"children":444},"td",{},[445,447],{"type":22,"value":446},"HTTP 401, ",{"type":17,"tag":73,"props":448,"children":450},{"className":449},[],[451],{"type":22,"value":452},"{\"error\":\"unauthorized\"}",{"type":17,"tag":442,"props":454,"children":455},{},[456],{"type":22,"value":457},"The token is missing, invalid, revoked, or expired.",{"type":17,"tag":442,"props":459,"children":460},{},[461],{"type":22,"value":462},"Create a new token. Do not retry.",{"type":17,"tag":415,"props":464,"children":465},{},[466,477,482],{"type":17,"tag":442,"props":467,"children":468},{},[469,471],{"type":22,"value":470},"HTTP 403, ",{"type":17,"tag":73,"props":472,"children":474},{"className":473},[],[475],{"type":22,"value":476},"{\"error\":\"forbidden_origin\"}",{"type":17,"tag":442,"props":478,"children":479},{},[480],{"type":22,"value":481},"The request came from a browser page on a website that is not allowed.",{"type":17,"tag":442,"props":483,"children":484},{},[485],{"type":22,"value":486},"Call from server code instead.",{"type":17,"tag":415,"props":488,"children":489},{},[490,500,513],{"type":17,"tag":442,"props":491,"children":492},{},[493,494],{"type":22,"value":470},{"type":17,"tag":73,"props":495,"children":497},{"className":496},[],[498],{"type":22,"value":499},"{\"error\":\"workspace_mismatch\"}",{"type":17,"tag":442,"props":501,"children":502},{},[503,505,511],{"type":22,"value":504},"You used a ",{"type":17,"tag":73,"props":506,"children":508},{"className":507},[],[509],{"type":22,"value":510},"\u002Fw\u002F\u003CworkspaceId>\u002Fmcp",{"type":22,"value":512}," URL for a different workspace than the token.",{"type":17,"tag":442,"props":514,"children":515},{},[516],{"type":22,"value":517},"Use the URL of the token's own workspace.",{"type":17,"tag":415,"props":519,"children":520},{},[521,526,531],{"type":17,"tag":442,"props":522,"children":523},{},[524],{"type":22,"value":525},"HTTP 405",{"type":17,"tag":442,"props":527,"children":528},{},[529],{"type":22,"value":530},"The request was not a POST.",{"type":17,"tag":442,"props":532,"children":533},{},[534],{"type":22,"value":535},"Use POST.",{"type":17,"tag":415,"props":537,"children":538},{},[539,550,555],{"type":17,"tag":442,"props":540,"children":541},{},[542,544],{"type":22,"value":543},"HTTP 429, ",{"type":17,"tag":73,"props":545,"children":547},{"className":546},[],[548],{"type":22,"value":549},"{\"error\":\"rate_limited\"}",{"type":17,"tag":442,"props":551,"children":552},{},[553],{"type":22,"value":554},"You went over the rate limit.",{"type":17,"tag":442,"props":556,"children":557},{},[558,560,566],{"type":22,"value":559},"Wait for the number of seconds in the ",{"type":17,"tag":73,"props":561,"children":563},{"className":562},[],[564],{"type":22,"value":565},"Retry-After",{"type":22,"value":567}," header, then retry.",{"type":17,"tag":415,"props":569,"children":570},{},[571,582,587],{"type":17,"tag":442,"props":572,"children":573},{},[574,576],{"type":22,"value":575},"HTTP 503, ",{"type":17,"tag":73,"props":577,"children":579},{"className":578},[],[580],{"type":22,"value":581},"{\"error\":\"service_unavailable\"}",{"type":17,"tag":442,"props":583,"children":584},{},[585],{"type":22,"value":586},"MCP is switched off for the whole service.",{"type":17,"tag":442,"props":588,"children":589},{},[590],{"type":22,"value":591},"Retry later.",{"type":17,"tag":415,"props":593,"children":594},{},[595,606,611],{"type":17,"tag":442,"props":596,"children":597},{},[598,600],{"type":22,"value":599},"HTTP 400 with a JSON-RPC ",{"type":17,"tag":73,"props":601,"children":603},{"className":602},[],[604],{"type":22,"value":605},"error",{"type":17,"tag":442,"props":607,"children":608},{},[609],{"type":22,"value":610},"The body is not valid JSON.",{"type":17,"tag":442,"props":612,"children":613},{},[614],{"type":22,"value":615},"Fix the request.",{"type":17,"tag":415,"props":617,"children":618},{},[619,629,649],{"type":17,"tag":442,"props":620,"children":621},{},[622,624],{"type":22,"value":623},"HTTP 406 with a JSON-RPC ",{"type":17,"tag":73,"props":625,"children":627},{"className":626},[],[628],{"type":22,"value":605},{"type":17,"tag":442,"props":630,"children":631},{},[632,634,640,642,648],{"type":22,"value":633},"The Accept header does not list both ",{"type":17,"tag":73,"props":635,"children":637},{"className":636},[],[638],{"type":22,"value":639},"application\u002Fjson",{"type":22,"value":641}," and ",{"type":17,"tag":73,"props":643,"children":645},{"className":644},[],[646],{"type":22,"value":647},"text\u002Fevent-stream",{"type":22,"value":54},{"type":17,"tag":442,"props":650,"children":651},{},[652],{"type":22,"value":653},"Send both.",{"type":17,"tag":415,"props":655,"children":656},{},[657,676,688],{"type":17,"tag":442,"props":658,"children":659},{},[660,662,668,670],{"type":22,"value":661},"HTTP 200, ",{"type":17,"tag":73,"props":663,"children":665},{"className":664},[],[666],{"type":22,"value":667},"result.isError",{"type":22,"value":669}," is ",{"type":17,"tag":73,"props":671,"children":673},{"className":672},[],[674],{"type":22,"value":675},"true",{"type":17,"tag":442,"props":677,"children":678},{},[679,681,687],{"type":22,"value":680},"The tool refused or failed. The reason is in ",{"type":17,"tag":73,"props":682,"children":684},{"className":683},[],[685],{"type":22,"value":686},"result.content[0].text",{"type":22,"value":54},{"type":17,"tag":442,"props":689,"children":690},{},[691],{"type":22,"value":692},"Show or log the reason. Do not retry unchanged.",{"type":17,"tag":415,"props":694,"children":695},{},[696,712,717],{"type":17,"tag":442,"props":697,"children":698},{},[699,700,706,707],{"type":22,"value":661},{"type":17,"tag":73,"props":701,"children":703},{"className":702},[],[704],{"type":22,"value":705},"held_for_approval",{"type":22,"value":669},{"type":17,"tag":73,"props":708,"children":710},{"className":709},[],[711],{"type":22,"value":675},{"type":17,"tag":442,"props":713,"children":714},{},[715],{"type":22,"value":716},"The call is waiting for a person to approve it.",{"type":17,"tag":442,"props":718,"children":719},{},[720],{"type":22,"value":721},"See the next section.",{"type":17,"tag":18,"props":723,"children":724},{},[725,727,732],{"type":22,"value":726},"Typical ",{"type":17,"tag":73,"props":728,"children":730},{"className":729},[],[731],{"type":22,"value":403},{"type":22,"value":733}," reasons are \"MCP is not enabled for this workspace\", \"Insufficient scope\", a missing permission, a record that was not found, an opted-out client, and an out-of-allowance message when the workspace cannot pay for the call. A refused or failed call is not charged.",{"type":17,"tag":349,"props":735,"children":737},{"id":736},"calls-held-for-approval",[738],{"type":22,"value":739},"Calls held for approval",{"type":17,"tag":18,"props":741,"children":742},{},[743],{"type":22,"value":744},"Tools that send something to a person are held until someone approves them in the Workspace369 app. A held call is not an error. The result looks like this:",{"type":17,"tag":215,"props":746,"children":749},{"className":747,"code":748,"language":321,"meta":7},[319],"{\n  \"structuredContent\": {\n    \"held_for_approval\": true,\n    \"approval_id\": \"...\",\n    \"approval_url\": \"https:\u002F\u002Fapp.workspace369.com\u002Fsettings\u002Fapprovals\u002F...\",\n    \"approval_expires_at\": \"2026-10-18T15:00:00.000Z\"\n  }\n}\n",[750],{"type":17,"tag":73,"props":751,"children":752},{"__ignoreMap":7},[753],{"type":22,"value":748},{"type":17,"tag":18,"props":755,"children":756},{},[757],{"type":22,"value":758},"Nothing has been sent. Do not call the tool again for the same request, because a second call would create a second request. Instead:",{"type":17,"tag":37,"props":760,"children":761},{},[762,782,868],{"type":17,"tag":41,"props":763,"children":764},{},[765,767,773,775,780],{"type":22,"value":766},"Show the person the ",{"type":17,"tag":73,"props":768,"children":770},{"className":769},[],[771],{"type":22,"value":772},"approval_url",{"type":22,"value":774},", or tell them to open ",{"type":17,"tag":94,"props":776,"children":777},{},[778],{"type":22,"value":779},"Approvals",{"type":22,"value":781}," in Workspace369.",{"type":17,"tag":41,"props":783,"children":784},{},[785,787,793,795,801,803,809,810,816,817,823,824,830,831,837,838,844,845,851,853,859,860,866],{"type":22,"value":786},"Poll ",{"type":17,"tag":73,"props":788,"children":790},{"className":789},[],[791],{"type":22,"value":792},"approvals_get",{"type":22,"value":794}," with ",{"type":17,"tag":73,"props":796,"children":798},{"className":797},[],[799],{"type":22,"value":800},"{ \"approval_id\": \"...\" }",{"type":22,"value":802},". It is free. Its ",{"type":17,"tag":73,"props":804,"children":806},{"className":805},[],[807],{"type":22,"value":808},"status",{"type":22,"value":669},{"type":17,"tag":73,"props":811,"children":813},{"className":812},[],[814],{"type":22,"value":815},"pending",{"type":22,"value":153},{"type":17,"tag":73,"props":818,"children":820},{"className":819},[],[821],{"type":22,"value":822},"executing",{"type":22,"value":153},{"type":17,"tag":73,"props":825,"children":827},{"className":826},[],[828],{"type":22,"value":829},"approved_done",{"type":22,"value":153},{"type":17,"tag":73,"props":832,"children":834},{"className":833},[],[835],{"type":22,"value":836},"declined",{"type":22,"value":153},{"type":17,"tag":73,"props":839,"children":841},{"className":840},[],[842],{"type":22,"value":843},"expired",{"type":22,"value":153},{"type":17,"tag":73,"props":846,"children":848},{"className":847},[],[849],{"type":22,"value":850},"failed",{"type":22,"value":852},", or ",{"type":17,"tag":73,"props":854,"children":856},{"className":855},[],[857],{"type":22,"value":858},"interrupted",{"type":22,"value":161},{"type":17,"tag":73,"props":861,"children":863},{"className":862},[],[864],{"type":22,"value":865},"outcome",{"type":22,"value":867}," holds the result once the call has run.",{"type":17,"tag":41,"props":869,"children":870},{},[871,873,878],{"type":22,"value":872},"If the status is ",{"type":17,"tag":73,"props":874,"children":876},{"className":875},[],[877],{"type":22,"value":858},{"type":22,"value":879},", do not repeat the call. It may already have gone out. Ask the person to check the app.",{"type":17,"tag":18,"props":881,"children":882},{},[883,885,891],{"type":22,"value":884},"A request expires after 1 hour. The full list of tools that are held is in ",{"type":17,"tag":47,"props":886,"children":888},{"href":887},"\u002Fv\u002F2026.3\u002Fai-connections\u002Fmcp-permissions-tokens-and-audit\u002F#sends-and-approval",[889],{"type":22,"value":890},"How MCP access is controlled and billed",{"type":22,"value":54},{"type":17,"tag":30,"props":893,"children":895},{"id":894},"rate-limits",[896],{"type":22,"value":897},"Rate limits",{"type":17,"tag":18,"props":899,"children":900},{},[901,903,908,910,916,917,923],{"type":22,"value":902},"One connection may make 120 calls per minute. The whole workspace may make 600 calls per minute. A call over the limit gets a 429 with ",{"type":17,"tag":73,"props":904,"children":906},{"className":905},[],[907],{"type":22,"value":565},{"type":22,"value":909}," and is not counted against the next minute. If you need many records, ask for larger pages with the tool's ",{"type":17,"tag":73,"props":911,"children":913},{"className":912},[],[914],{"type":22,"value":915},"limit",{"type":22,"value":641},{"type":17,"tag":73,"props":918,"children":920},{"className":919},[],[921],{"type":22,"value":922},"cursor",{"type":22,"value":924}," arguments instead of many small calls.",{"type":17,"tag":18,"props":926,"children":927},{},[928,930,936],{"type":22,"value":929},"Write tools accept an optional ",{"type":17,"tag":73,"props":931,"children":933},{"className":932},[],[934],{"type":22,"value":935},"idempotency_key",{"type":22,"value":937},". Send the same key again to avoid doing the same thing twice after a network error.",{"type":17,"tag":30,"props":939,"children":941},{"id":940},"check-your-result",[942],{"type":22,"value":943},"Check your result",{"type":17,"tag":37,"props":945,"children":946},{},[947,959,986,991],{"type":17,"tag":41,"props":948,"children":949},{},[950,952,957],{"type":22,"value":951},"Run the ",{"type":17,"tag":73,"props":953,"children":955},{"className":954},[],[956],{"type":22,"value":211},{"type":22,"value":958}," request. You should see a list of tools.",{"type":17,"tag":41,"props":960,"children":961},{},[962,964,969,971,977,979,985],{"type":22,"value":963},"Run a read-only ",{"type":17,"tag":73,"props":965,"children":967},{"className":966},[],[968],{"type":22,"value":284},{"type":22,"value":970},", such as ",{"type":17,"tag":73,"props":972,"children":974},{"className":973},[],[975],{"type":22,"value":976},"clients_search",{"type":22,"value":978},". You should see ",{"type":17,"tag":73,"props":980,"children":982},{"className":981},[],[983],{"type":22,"value":984},"structuredContent",{"type":22,"value":54},{"type":17,"tag":41,"props":987,"children":988},{},[989],{"type":22,"value":990},"Revoke the token and run the request again. You should get a 401.",{"type":17,"tag":41,"props":992,"children":993},{},[994,996,1001,1003,1008],{"type":22,"value":995},"Open ",{"type":17,"tag":94,"props":997,"children":998},{},[999],{"type":22,"value":1000},"AI Connections (MCP)",{"type":22,"value":1002}," in Settings and find your calls in the ",{"type":17,"tag":94,"props":1004,"children":1005},{},[1006],{"type":22,"value":1007},"Activity Log",{"type":22,"value":54},{"title":7,"searchDepth":1010,"depth":1010,"links":1011},2,[1012,1013,1014,1015,1020,1023,1024],{"id":32,"depth":1010,"text":35},{"id":82,"depth":1010,"text":85},{"id":199,"depth":1010,"text":202},{"id":272,"depth":1010,"text":275,"children":1016},[1017,1019],{"id":351,"depth":1018,"text":354},3,{"id":373,"depth":1018,"text":376},{"id":389,"depth":1010,"text":392,"children":1021},[1022],{"id":736,"depth":1018,"text":739},{"id":894,"depth":1010,"text":897},{"id":940,"depth":1010,"text":943},"markdown","content:v:2026.3:build-with-ai:call-workspace369-from-your-app-over-https.md","content","v\u002F2026.3\u002Fbuild-with-ai\u002Fcall-workspace369-from-your-app-over-https.md","v\u002F2026.3\u002Fbuild-with-ai\u002Fcall-workspace369-from-your-app-over-https","md",1792310456113]