{"versionId":"e7f13d9b-4c90-40ee-5ec1-08de8b9ac8a7","articleId":"29047bc1-90e5-4dcc-5732-08de8b941e33","title":"cURL Executor MCP Server | Admin Guide","tags":["MCP","System admin","All articles"],"content":"<html><head></head><body><div class=\"mce-toc\">\n<h2>Table of contents</h2>\n<ul>\n<li><a href=\"#mcetoc_1jktlfc7vbb\">What the cURL Executor does</a></li>\n<li><a href=\"#mcetoc_1jktlfc7vbc\">Enabling the&nbsp;cURL Executor</a></li>\n<li><a href=\"#3-adding-a-server-instance\">Add a server instance</a>\n<ul>\n<li><a href=\"#server-label-best-practice\">Server label best practice</a></li>\n</ul>\n</li>\n<li><a href=\"#4-access-restrictions\">Access restrictions</a></li>\n<li><a href=\"#mcetoc_1jktrv97qh3\">Set access restrictions</a>\n<ul>\n<li><a href=\"#allowed-http-verbs\">Allowed HTTP verbs</a></li>\n<li><a href=\"#allowed-domains\">Allowed domains</a></li>\n<li><a href=\"#allowed-urls\">Allowed URLs</a></li>\n<li><a href=\"#combining-domains-and-urls\">Combining domains and URLs</a></li>\n</ul>\n</li>\n<li><a href=\"#5-hiding-credentials-from-the-ai\">Hiding credentials from the AI</a>\n<ul>\n<li><a href=\"#additional-headers\">Additional Headers</a></li>\n<li><a href=\"#auth-config-oauth\">Auth Config (OAuth)</a></li>\n</ul>\n</li>\n<li><a href=\"#6-built-in-safety-always-enforced\">Built-in safety (always enforced)</a></li>\n<li><a href=\"#7-multiple-server-instances\">Multiple server instances</a></li>\n<li><a href=\"#8-use-cases\">Use cases</a>\n<ul>\n<li><a href=\"#outbound-webhook-with-a-static-api-key\">Outbound webhook with a static API key</a></li>\n<li><a href=\"#querying-a-rest-api-with-oauth\">Querying a REST API with OAuth</a></li>\n<li><a href=\"#multiple-integrations-via-separate-instances\">Multiple integrations via separate instances</a></li>\n<li><a href=\"#pushing-batch-processing-results-to-a-data-lake-or-storage-endpoint\">Pushing batch processing results to a data lake or storage endpoint</a></li>\n<li><a href=\"#development--exploration-instance\">Development / exploration instance</a></li>\n</ul>\n</li>\n</ul>\n</div>\n<h2 id=\"mcetoc_1jktlfc7vbb\">What the cURL Executor does</h2>\n<p>The cURL Executor is an MCP server with one tool,&nbsp;<code>ta_curl_execute</code>. It lets an assistant send HTTP requests to approved external endpoints.</p>\n<p>Use it for lightweight integrations such as:</p>\n<ul>\n<li>calling a webhook</li>\n<li>sending data to an external system</li>\n<li>querying a REST API</li>\n<li>triggering an automation flow</li>\n</ul>\n<p>Use a dedicated connector instead when one already exists and covers your use case.</p>\n<p>Administrators control:</p>\n<ul>\n<li>which HTTP methods are allowed</li>\n<li>which domains or URLs can be called</li>\n<li>which credentials are added server-side</li>\n</ul>\n<p>This helps you connect assistants to external services without exposing secrets in the conversation.</p>\n<hr dir=\"auto\" data-line=\"27\">\n<h2 id=\"mcetoc_1jktlfc7vbc\" dir=\"auto\" data-line=\"29\">Enabling the&nbsp;cURL Executor</h2>\n<h2 id=\"2-enabling-the-feature\" dir=\"auto\" data-line=\"29\"></h2>\n<p dir=\"auto\" data-line=\"31\">This is a beta feature. Contact the Theta Assist team to enable.</p>\n<hr dir=\"auto\" data-line=\"40\">\n<h2 id=\"3-adding-a-server-instance\" dir=\"auto\" data-line=\"42\">Add a server instance</h2>\n<ol dir=\"auto\" data-line=\"44\">\n<li dir=\"auto\" data-line=\"44\">Navigate to&nbsp;<strong>Admin &gt; Tools &gt; MCP Servers</strong>.</li>\n<li dir=\"auto\" data-line=\"45\">Click&nbsp;<strong>Add Theta Assist MCP Server</strong>&nbsp;and select&nbsp;<strong>cURL Executor</strong>.</li>\n<li>Enter:\n<ul>\n<li>a&nbsp;<strong>Label</strong>&nbsp;for internal use</li>\n<li>a&nbsp;<strong>Name</strong>&nbsp;for easier identification in admin settings</li>\n</ul>\n</li>\n</ol>\n<h3 id=\"server-label-best-practice\" dir=\"auto\" data-line=\"48\">Server label best practice</h3>\n<p dir=\"auto\" data-line=\"50\">The server label is an internal identifier (lowercase, alphanumeric, hyphens and underscores only). It appears in logs and configuration but is not directly shown to users. Use a label that describes the integration, not the technology — for example:</p>\n<table dir=\"auto\" style=\"border-collapse: collapse; border-spacing: 2px;\" border=\"1\" data-line=\"52\">\n<thead dir=\"auto\" data-line=\"52\">\n<tr dir=\"auto\" data-line=\"52\">\n<th>Label</th>\n<th>Name</th>\n</tr>\n</thead>\n<tbody dir=\"auto\" data-line=\"54\">\n<tr dir=\"auto\" data-line=\"54\">\n<td><code>crm-webhooks</code></td>\n<td>CRM Webhooks</td>\n</tr>\n<tr dir=\"auto\" data-line=\"55\">\n<td><code>reporting-api</code></td>\n<td>Reporting API</td>\n</tr>\n<tr dir=\"auto\" data-line=\"56\">\n<td><code>notification-service</code></td>\n<td>Notification Service</td>\n</tr>\n</tbody>\n</table>\n<p dir=\"auto\" data-line=\"58\">This makes it clear what each instance does when you have multiple cURL servers configured, and avoids exposing implementation details.</p>\n<blockquote dir=\"auto\" data-line=\"60\">\n<p dir=\"auto\" data-line=\"60\"><strong>Note:</strong>&nbsp;All cURL Executor instances point to the same MCP server URL — the label does not change the URL. You do not need to (and should not) modify the server URL when adding additional instances.</p>\n</blockquote>\n<hr dir=\"auto\" data-line=\"62\">\n<h2 id=\"4-access-restrictions\" dir=\"auto\" data-line=\"64\">Access restrictions</h2>\n<h2 id=\"mcetoc_1jktrv97qh3\">Set access restrictions</h2>\n<p>Use access restrictions to limit where the assistant can send requests.</p>\n<blockquote>\n<p><strong>Warning:</strong>&nbsp;If you leave all restriction fields empty, the cURL Executor can call any HTTPS URL allowed by the built-in safety rules. Do not use this setup in production.</p>\n</blockquote>\n<p>For production use, we recommend configuring:</p>\n<ul>\n<li>only the HTTP methods you need</li>\n<li>either a restricted domain list or an exact URL list</li>\n<li>credentials server-side only</li>\n</ul>\n<h3 id=\"allowed-http-verbs\" dir=\"auto\" data-line=\"70\">Allowed HTTP verbs</h3>\n<p dir=\"auto\" data-line=\"72\">Four checkboxes:&nbsp;<strong>GET</strong>,&nbsp;<strong>POST</strong>,&nbsp;<strong>PUT</strong>,&nbsp;<strong>DELETE</strong>. When one or more are checked, only those methods are permitted. All other methods return an error to the AI.</p>\n<p dir=\"auto\" data-line=\"74\">Leave all unchecked to allow any supported method.</p>\n<p dir=\"auto\" data-line=\"76\"><strong>Example error when blocked:</strong></p>\n<blockquote dir=\"auto\" data-line=\"77\">\n<p dir=\"auto\" data-line=\"77\"><code>HTTP verb 'GET' is not permitted by this server's configuration. Allowed: POST</code></p>\n</blockquote>\n<h3 id=\"allowed-domains\" dir=\"auto\" data-line=\"79\">Allowed domains</h3>\n<p dir=\"auto\" data-line=\"81\">A list of hostnames (e.g.&nbsp;<code>api.example.com</code>). Subdomains are automatically included — adding&nbsp;<code>example.com</code>&nbsp;also permits&nbsp;<code>api.example.com</code>&nbsp;and&nbsp;<code>subdomain.example.com</code>.</p>\n<p dir=\"auto\" data-line=\"83\">When set, any request to a domain not on the list is blocked.</p>\n<p dir=\"auto\" data-line=\"85\"><strong>Only applies when no Allowed URLs are configured.</strong>&nbsp;If URLs are set, the domain list is ignored — see below.</p>\n<p dir=\"auto\" data-line=\"87\"><strong>Example error when blocked:</strong></p>\n<blockquote dir=\"auto\" data-line=\"88\">\n<p dir=\"auto\" data-line=\"88\"><code>Domain 'unexpected.com' is not in the allowed domains list.</code></p>\n</blockquote>\n<h3 id=\"allowed-urls\" dir=\"auto\" data-line=\"90\">Allowed URLs</h3>\n<p dir=\"auto\" data-line=\"92\">A list of exact URL paths (e.g.&nbsp;<code>https://api.example.com/webhook)</code>. The query string is&nbsp;<strong>not</strong>&nbsp;matched — only the scheme, host, and path are compared. This means the AI can still append query parameters freely to a whitelisted path.</p>\n<p dir=\"auto\" data-line=\"94\">When set, Allowed URLs take&nbsp;<strong>precedence over Allowed Domains</strong>&nbsp;— the domain list is not evaluated.</p>\n<p dir=\"auto\" data-line=\"96\"><strong>Example error when blocked:</strong></p>\n<blockquote dir=\"auto\" data-line=\"97\">\n<p dir=\"auto\" data-line=\"97\"><code>URL 'https://api.example.com/other-path' is not in the allowed URLs list.</code></p>\n</blockquote>\n<h3 id=\"combining-domains-and-urls\" dir=\"auto\" data-line=\"99\">Combining domains and URLs</h3>\n<p dir=\"auto\" data-line=\"101\">You can configure both, but only one is active at a time:</p>\n<ul dir=\"auto\" data-line=\"102\">\n<li dir=\"auto\" data-line=\"102\">If&nbsp;<strong>Allowed URLs</strong>&nbsp;has entries → URLs are checked; domains are ignored.</li>\n<li dir=\"auto\" data-line=\"103\">If&nbsp;<strong>Allowed URLs</strong>&nbsp;is empty → Domains are checked (if configured).</li>\n</ul>\n<hr dir=\"auto\" data-line=\"105\">\n<h2 id=\"5-hiding-credentials-from-the-ai\" dir=\"auto\" data-line=\"107\">Hiding credentials from the AI</h2>\n<p dir=\"auto\" data-line=\"109\">Never ask the assistant to include API keys, bearer tokens, or other secrets in the prompt or tool call. Store credentials in&nbsp;<strong>Additional Headers</strong>&nbsp;or an attached&nbsp;<strong>Auth Config</strong>&nbsp;instead.</p>\n<h3 id=\"additional-headers\" dir=\"auto\" data-line=\"111\">Additional Headers</h3>\n<p dir=\"auto\" data-line=\"113\">The&nbsp;<strong>Additional Headers</strong>&nbsp;section lets you define key/value pairs that are injected into every request at execution time. The AI never sees these headers — they are not included in the tool's instructions and are applied server-side after the AI submits its curl command.</p>\n<p dir=\"auto\" data-line=\"115\">If the AI includes a header with the same name as an additional header, the configured value&nbsp;<strong>overrides</strong>&nbsp;what the AI provided.</p>\n<p dir=\"auto\" data-line=\"117\"><strong>Typical uses:</strong></p>\n<ul dir=\"auto\" data-line=\"118\">\n<li dir=\"auto\" data-line=\"118\"><code>x-api-key</code>&nbsp;→ static API key for the target service</li>\n<li dir=\"auto\" data-line=\"119\"><code>x-tenant-id</code>&nbsp;→ tenant identifier required by the API</li>\n<li dir=\"auto\" data-line=\"120\"><code>api-version</code>&nbsp;→ fixed API version header</li>\n</ul>\n<p dir=\"auto\" data-line=\"122\"><strong>Example:</strong></p>\n<table dir=\"auto\" style=\"border-collapse: collapse; border-spacing: 2px;\" border=\"1\" data-line=\"124\">\n<thead dir=\"auto\" data-line=\"124\">\n<tr dir=\"auto\" style=\"height: 32.78125px;\" data-line=\"124\">\n<th style=\"width: 32.489754%;\">Header Name</th>\n<th style=\"width: 58.03791%;\">Value</th>\n</tr>\n</thead>\n<tbody dir=\"auto\" data-line=\"126\">\n<tr dir=\"auto\" style=\"height: 32.78125px;\" data-line=\"126\">\n<td style=\"width: 32.489754%;\"><code>x-api-key</code></td>\n<td style=\"width: 58.03791%;\"><span style=\"font-family: monospace;\"><span style=\"background-color: #b4d7ff;\">example-api-key-value</span></span></td>\n</tr>\n<tr dir=\"auto\" style=\"height: 51.78125px;\" data-line=\"127\">\n<td style=\"width: 32.489754%;\"><code>x-tenant-id</code></td>\n<td style=\"width: 58.03791%;\"><code>my-org</code></td>\n</tr>\n</tbody>\n</table>\n<p dir=\"auto\" data-line=\"129\">The AI calls the API and these headers are silently included in every request.</p>\n<h3 id=\"auth-config-oauth\" dir=\"auto\" data-line=\"131\">Auth Config (OAuth)</h3>\n<p dir=\"auto\" data-line=\"133\">When an&nbsp;<strong>Auth Config</strong>&nbsp;is attached to the server instance, the server automatically:</p>\n<ol dir=\"auto\" data-line=\"135\">\n<li dir=\"auto\" data-line=\"135\">Obtains an OAuth access token using the configured app registration.</li>\n<li dir=\"auto\" data-line=\"136\">Injects it as&nbsp;<code>Authorization: Bearer &lt;token&gt;</code>&nbsp;into the request.</li>\n<li dir=\"auto\" data-line=\"137\">Overrides any&nbsp;<code>Authorization</code>&nbsp;header the AI may have included.</li>\n</ol>\n<p dir=\"auto\" data-line=\"139\">The AI is instructed not to include an&nbsp;<code>Authorization</code>&nbsp;header when an auth config is attached — the token is handled entirely server-side.</p>\n<p dir=\"auto\" data-line=\"141\"><strong>When to use each:</strong></p>\n<table dir=\"auto\" style=\"border-collapse: collapse; border-spacing: 2px;\" border=\"1\" data-line=\"143\">\n<thead dir=\"auto\" data-line=\"143\">\n<tr dir=\"auto\" data-line=\"143\">\n<th>Scenario</th>\n<th>Recommended approach</th>\n</tr>\n</thead>\n<tbody dir=\"auto\" data-line=\"145\">\n<tr dir=\"auto\" data-line=\"145\">\n<td>Static API key (<code>x-api-key</code>,&nbsp;<code>Authorization: ApiKey ...</code>)</td>\n<td>Additional Headers</td>\n</tr>\n<tr dir=\"auto\" data-line=\"146\">\n<td>OAuth / Azure AD-protected API</td>\n<td>Auth Config</td>\n</tr>\n<tr dir=\"auto\" data-line=\"147\">\n<td>OAuth token + additional non-auth headers (e.g. tenant ID)</td>\n<td>Auth Config + Additional Headers</td>\n</tr>\n</tbody>\n</table>\n<hr dir=\"auto\" data-line=\"149\">\n<h2 id=\"6-built-in-safety-always-enforced\" dir=\"auto\" data-line=\"151\">Built-in safety (always enforced)</h2>\n<p dir=\"auto\" data-line=\"153\">These rules always apply, even if you do not set access restrictions. They reduce the risk of unsafe or unintended requests.</p>\n<table dir=\"auto\" style=\"border-collapse: collapse; border-spacing: 2px;\" border=\"1\" data-line=\"155\">\n<thead dir=\"auto\" data-line=\"155\">\n<tr dir=\"auto\" data-line=\"155\">\n<th>Constraint</th>\n<th>Detail</th>\n</tr>\n</thead>\n<tbody dir=\"auto\" data-line=\"157\">\n<tr dir=\"auto\" data-line=\"157\">\n<td><strong>HTTPS only</strong></td>\n<td>Requests to&nbsp;<code>http://</code>&nbsp;URLs are rejected. This prevents the AI from probing internal services or making unencrypted calls.</td>\n</tr>\n<tr dir=\"auto\" data-line=\"158\">\n<td><strong>Supported methods</strong></td>\n<td>GET, POST, PUT, DELETE only. Other HTTP methods are not supported.</td>\n</tr>\n<tr dir=\"auto\" data-line=\"159\">\n<td><strong>Content-Type handling</strong></td>\n<td>Any Content-Type value is permitted.&nbsp;<code>application/x-www-form-urlencoded</code>&nbsp;receives special form-encoding handling; all other content types are passed through as-is.</td>\n</tr>\n</tbody>\n</table>\n<hr dir=\"auto\" data-line=\"161\">\n<h2 id=\"7-multiple-server-instances\" dir=\"auto\" data-line=\"163\">Multiple server instances</h2>\n<p dir=\"auto\" data-line=\"165\">The cURL Executor can be added as many times as needed. Create separate server instances when integrations use different destinations, credentials, or risk levels.</p>\n<p dir=\"auto\" data-line=\"167\"><strong>Example setup:</strong></p>\n<table dir=\"auto\" style=\"border-collapse: collapse; border-spacing: 2px;\" border=\"1\" data-line=\"169\">\n<thead dir=\"auto\" data-line=\"169\">\n<tr dir=\"auto\" data-line=\"169\">\n<th>Instance label</th>\n<th>Verbs</th>\n<th>Restriction</th>\n<th>Credentials</th>\n</tr>\n</thead>\n<tbody dir=\"auto\" data-line=\"171\">\n<tr dir=\"auto\" data-line=\"171\">\n<td><code>crm-webhooks</code></td>\n<td>POST</td>\n<td>Domain:&nbsp;<code>crm.example.com</code></td>\n<td>Additional header:&nbsp;<code>x-api-key</code></td>\n</tr>\n<tr dir=\"auto\" data-line=\"172\">\n<td><code>reporting-api</code></td>\n<td>GET, POST</td>\n<td>URLs:&nbsp;<code>https://reports.example.com/api/v2/query</code></td>\n<td>Auth Config (OAuth)</td>\n</tr>\n<tr dir=\"auto\" data-line=\"173\">\n<td><code>notification-service</code></td>\n<td>POST</td>\n<td>Domain:&nbsp;<code>notify.example.com</code></td>\n<td>Additional headers:&nbsp;<code>x-api-key</code>,&nbsp;<code>x-tenant-id</code></td>\n</tr>\n</tbody>\n</table>\n<p dir=\"auto\" data-line=\"175\">Each instance is independently available to assign to an assistant, and can be further restricted with an <a href=\"https://help.thetaassist.ai/article/access-profiles-admin-guide\" target=\"_blank\" rel=\"noopener\">Access Profile</a>.</p>\n<hr dir=\"auto\" data-line=\"177\">\n<h2 id=\"8-use-cases\" dir=\"auto\" data-line=\"179\">Use cases</h2>\n<h3 id=\"outbound-webhook-with-a-static-api-key\" dir=\"auto\" data-line=\"181\">Outbound webhook with a static API key</h3>\n<p dir=\"auto\" data-line=\"183\">An assistant submits structured data to an external ticketing or workflow system when triggered by the user.</p>\n<p dir=\"auto\" data-line=\"185\"><strong>Configuration:</strong></p>\n<ul dir=\"auto\" data-line=\"186\">\n<li dir=\"auto\" data-line=\"186\">Allowed Verbs:&nbsp;<code>POST</code>&nbsp;only</li>\n<li dir=\"auto\" data-line=\"187\">Allowed Domains:&nbsp;<code>hooks.ticketing-system.com</code></li>\n<li dir=\"auto\" data-line=\"188\">Additional Headers:&nbsp;<code>x-api-key</code>&nbsp;=&nbsp;<code>&lt;your key&gt;</code></li>\n</ul>\n<p dir=\"auto\" data-line=\"190\">The AI constructs the payload and POSTs it to the webhook URL. The API key is injected silently — the AI never handles it.</p>\n<hr dir=\"auto\" data-line=\"192\">\n<h3 id=\"querying-a-rest-api-with-oauth\" dir=\"auto\" data-line=\"194\">Querying a REST API with OAuth</h3>\n<p dir=\"auto\" data-line=\"196\">An assistant queries an internal reporting API protected by Azure AD, fetching data on demand during a conversation.</p>\n<p dir=\"auto\" data-line=\"198\"><strong>Configuration:</strong></p>\n<ul dir=\"auto\" data-line=\"199\">\n<li dir=\"auto\" data-line=\"199\">Allowed Verbs:&nbsp;<code>GET</code></li>\n<li dir=\"auto\" data-line=\"200\">Allowed URLs:&nbsp;<code>https://reports.internal.example.com/api/v2/results</code></li>\n<li dir=\"auto\" data-line=\"201\">Auth Config: OAuth app registration with appropriate scopes</li>\n</ul>\n<p dir=\"auto\" data-line=\"203\">The AI calls the endpoint and the access token is fetched and injected automatically. The querystring is not matched, so the AI can freely append filters and pagination parameters.</p>\n<hr dir=\"auto\" data-line=\"205\">\n<h3 id=\"multiple-integrations-via-separate-instances\" dir=\"auto\" data-line=\"207\">Multiple integrations via separate instances</h3>\n<p dir=\"auto\" data-line=\"209\">A single assistant needs to submit support tickets to one system and log activity to another, using different credentials for each.</p>\n<p dir=\"auto\" data-line=\"211\"><strong>Configuration:</strong></p>\n<ul dir=\"auto\" data-line=\"212\">\n<li dir=\"auto\" data-line=\"212\">Instance&nbsp;<code>support-tickets</code>: POST only, domain&nbsp;<code>api.helpdesk.com</code>,&nbsp;<code>x-api-key</code>&nbsp;header for helpdesk</li>\n<li dir=\"auto\" data-line=\"213\">Instance&nbsp;<code>activity-log</code>: POST only, URL&nbsp;<code>https://log.internal.example.com/api/events</code>, OAuth auth config for internal API</li>\n</ul>\n<p dir=\"auto\" data-line=\"215\">Both instances are enabled on the same assistant. The AI calls&nbsp;<code>ta_curl_execute</code>&nbsp;for each integration — the server enforces the restrictions per-instance, and credentials remain hidden.</p>\n<hr dir=\"auto\" data-line=\"217\">\n<h3 id=\"pushing-batch-processing-results-to-a-data-lake-or-storage-endpoint\" dir=\"auto\" data-line=\"219\">Pushing batch processing results to a data lake or storage endpoint</h3>\n<p dir=\"auto\" data-line=\"221\">After a batch processing job completes, an assistant can POST the results to a Power Automate endpoint (or similar HTTP trigger) for ingestion into a data lake, blob storage, or downstream system — without requiring the user to manually export and upload the file.</p>\n<p dir=\"auto\" data-line=\"223\"><strong>Configuration:</strong></p>\n<ul dir=\"auto\" data-line=\"224\">\n<li dir=\"auto\" data-line=\"224\">Allowed Verbs:&nbsp;<code>POST</code>&nbsp;only</li>\n<li dir=\"auto\" data-line=\"225\">Allowed URLs:&nbsp;<code>https://prod-xx.westeurope.logic.azure.com/workflows/...</code>&nbsp;(your Power Automate HTTP trigger URL)</li>\n<li dir=\"auto\" data-line=\"226\">Additional Headers: any static headers required by the trigger (e.g.&nbsp;<code>x-functions-key</code>&nbsp;for Azure Functions, or a shared secret)</li>\n</ul>\n<p dir=\"auto\" data-line=\"228\"><strong>Typical flow:</strong></p>\n<ol dir=\"auto\" data-line=\"230\">\n<li dir=\"auto\" data-line=\"230\">The assistant runs a batch processing job (e.g.&nbsp;<code>async_start_process_files</code>) and the results file is attached to the thread.</li>\n<li dir=\"auto\" data-line=\"231\">The user (or the assistant proactively) calls&nbsp;<code>ta_curl_execute</code>&nbsp;to POST the results JSON to the Power Automate trigger URL.</li>\n<li dir=\"auto\" data-line=\"232\">Power Automate receives the payload and routes it into storage, a database, or a downstream pipeline.</li>\n</ol>\n<p dir=\"auto\" data-line=\"234\">This pattern works well for scheduled or recurring extractions where the output needs to land in a centralised store rather than staying in the conversation.</p>\n<hr dir=\"auto\" data-line=\"236\">\n<h3 id=\"development--exploration-instance\" dir=\"auto\" data-line=\"238\">Development / exploration instance</h3>\n<p dir=\"auto\" data-line=\"240\">During assistant development, you may want an unrestricted instance to test against various endpoints before locking down the configuration for production.</p>\n<p dir=\"auto\" data-line=\"242\"><strong>Configuration:</strong></p>\n<ul dir=\"auto\" data-line=\"243\">\n<li dir=\"auto\" data-line=\"243\">No verb restrictions</li>\n<li dir=\"auto\" data-line=\"244\">No domain or URL restrictions</li>\n<li dir=\"auto\" data-line=\"245\">No credentials (or a non-production API key in additional headers)</li>\n</ul>\n<p><strong>⚠️ Do not assign unrestricted instances to production assistants or broad user&nbsp;groups. </strong>After testing, replace them with a restricted production instance before rollout.</p></body></html>","description":"This guide explains how to set up the cURL Executor MCP server in Theta Assist. Use it when you want an assistant to send controlled HTTP requests to external APIs, webhooks, or automation endpoints without exposing credentials in the conversation.","isMarkdown":false,"publishedOnUtc":"2026-03-29T22:38:45.9375417","modifiedOnUtc":"2026-03-27T02:34:56.88479"}