Developer Dashboard

MCP and Connectors

Remote MCP servers and connector-style tools let a Responses model reach external systems when a prompt needs data or actions outside the model. In AvalAI, treat this as an advanced /v1/responses tool surface: use it only when the selected model, route, account, and external service are explicitly trusted and supported.

Adapted from the official OpenAI MCP and Connectors guide and Secure MCP Tunnel guide, with AvalAI endpoint, API key, model, and availability notes.

Warning

Hosted MCP and connector support is route-, model-, and account-dependent in AvalAI. If tools: [{"type": "mcp", ...}] is unavailable, keep the integration in your backend and expose a narrow function tool instead.

When to Use MCP

NeedPreferred pattern
Public current contextUse web search first
Your own database or APIUse a custom function tool
Official third-party MCP serverUse type: "mcp" only after support and trust checks
OAuth-backed SaaS connectorPass connector_id and per-request OAuth authorization only when enabled
Sensitive writes or paymentsRequire approval and set parallel_tool_calls: false

ChatGPT Developer Mode Lessons

OpenAI's ChatGPT Developer Mode is a ChatGPT app-building surface, not an AvalAI API route. It is still useful as a safety checklist because it exposes the full MCP tool surface, including read and write actions. When porting those ideas to AvalAI-compatible /v1/responses tools:

  • Treat any broad MCP server as high-risk until you have reviewed every imported tool, scope, and approval rule.
  • Prefer action-oriented tool names and descriptions that say "Use this when..." plus clear edge cases and parameter descriptions.
  • Put cross-tool guidance, shared rate limits, and required sequences in MCP server instructions or application policy, not in user-supplied text.
  • Ask prompts to name the desired server and tool when several tools overlap, and explicitly disallow unrelated tools for sensitive workflows.
  • Inspect the JSON payload for every write action before execution. If a tool is missing a reliable read-only annotation, treat it as write-capable.
  • Do not remember approvals across untrusted workflows. Approval caching is only safe when the user trusts the app to repeat similar actions.

Private Servers and Transport

Remote MCP servers must be reachable by the hosted tool runtime and should support Streamable HTTP or HTTP/SSE transport. If your MCP server is private, on-premises, or behind a firewall, OpenAI documents Secure MCP Tunnel as the pattern for reaching it without opening inbound firewall ports. In AvalAI, treat tunnel usage as an availability check: if the selected route does not expose hosted MCP tunneling, run the tunnel or service connector in your own backend and call it through a strict function tool.

Secure tunnel design checklist

Use this checklist before connecting any private MCP server through a hosted tunnel:

  • Outbound-only connection: the tunnel client should initiate the connection from inside your network; do not add public ingress to the MCP server just to make a model tool work.
  • Organization and workspace scope: associate the tunnel only with the Platform organization, workspace, or API surface that must call it. A tunnel visible in one workspace should not automatically become available everywhere.
  • Separate permissions: treat tunnel management, tunnel use, and connector/developer-mode permissions as separate access decisions. Give operators only the role they need.
  • Health and troubleshooting: expose admin or health endpoints only to trusted operators. Confirm the tunnel client is connected, ready, and polling before debugging model behavior.
  • OAuth through the tunnel: OAuth discovery and authorization metadata can be proxied through the tunnel, but user tokens still need normal secret-handling, scope minimization, and audit logging.
  • Logging boundaries: tunnel transport logs, product logs, and MCP server application logs are different evidence sources. Decide which logs your incident-response team will inspect and redact support exports.
  • AvalAI fallback: if hosted tunneling is not enabled for the selected AvalAI route, run the connector in your backend and expose one strict function tool instead of forwarding a broad private network surface.

Building a Data-Only MCP Server

OpenAI's MCP server guidance treats data-only connectors as read-only servers with a small, predictable tool surface. If you build a private knowledge connector for AvalAI-compatible Responses workflows, start with this shape:

ToolPurposeRequired output fields
searchReturn relevant records for a user queryresults[] with id, title, and canonical url
fetchReturn the full content for a selected recordid, title, text, canonical url, optional metadata

Implementation notes:

  • Declare JSON output schemas for every tool so the client can validate structuredContent.
  • Return the same JSON value in structuredContent and, for compatibility, as JSON text in the MCP content array.
  • Keep search and fetch read-only. Use a separate approval-gated tool for writes, tickets, payments, or account changes.
  • Make url a non-empty canonical URL when you want citation metadata. A title without a usable URL should be treated as ordinary tool output, not a citation.
  • Use stable document IDs that your backend can re-fetch; do not expose database primary keys if they reveal tenant or permission structure.
  • Validate permissions inside the MCP server on every call. The model's allowed_tools list is not an authorization system.

Remote MCP Request Shape

Remote MCP servers use server_url; connectors use connector_id. Both appear as mcp_list_tools, mcp_call, and optionally mcp_approval_request items in response.output.

python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["AVALAI_API_KEY"],
    base_url="https://api.avalai.ir/v1",
)

response = client.responses.create(
    model="gpt-5.5",
    input="Find the latest refund policy in the support knowledge base.",
    tools=[
        {
            "type": "mcp",
            "server_label": "support_kb",
            "server_url": "https://mcp.example.com/sse",
            "allowed_tools": ["search_docs"],
            "require_approval": "never",
        }
    ],
)

print(response.output_text)
javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.AVALAI_API_KEY,
  baseURL: "https://api.avalai.ir/v1",
});

const response = await client.responses.create({
  model: "gpt-5.5",
  input: "Find the latest refund policy in the support knowledge base.",
  tools: [
    {
      type: "mcp",
      server_label: "support_kb",
      server_url: "https://mcp.example.com/sse",
      allowed_tools: ["search_docs"],
      require_approval: "never",
    },
  ],
});

console.log(response.output_text);
bash
curl https://api.avalai.ir/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -d '{
    "model": "gpt-5.5",
    "input": "Find the latest refund policy in the support knowledge base.",
    "tools": [
      {
        "type": "mcp",
        "server_label": "support_kb",
        "server_url": "https://mcp.example.com/sse",
        "allowed_tools": ["search_docs"],
        "require_approval": "never"
      }
    ]
  }'

Connector Shape

For connector-style tools, your application handles OAuth and sends the short-lived access token in authorization on every request that needs it. Do not put access tokens in prompts, logs, or reusable prompt templates.

json
{
  "type": "mcp",
  "server_label": "google_calendar",
  "connector_id": "connector_googlecalendar",
  "authorization": "<oauth access token>",
  "allowed_tools": [
    "list_events"
  ],
  "require_approval": "never"
}

Common OpenAI connector IDs include connector_dropbox, connector_gmail, connector_googlecalendar, connector_googledrive, connector_microsoftteams, connector_outlookcalendar, connector_outlookemail, and connector_sharepoint. In AvalAI, document these as examples rather than guaranteed account features; verify connector availability, OAuth scopes, and model support before shipping.

Authentication and Scopes

Most useful MCP servers and all connector-style SaaS integrations need authentication. Treat authorization as a per-request secret, not durable conversation state:

  • Send the OAuth access token in the MCP tool's authorization field for every Responses request that needs it.
  • Do not expect the raw token to appear in returned Response objects or to be stored for later reuse by the hosted flow.
  • Request the minimum OAuth scopes needed for the specific tools you expose. Connector tool availability depends on the scopes attached to that token.
  • Prefer official MCP servers operated by the service provider. Be extra cautious with aggregators or proxy servers that receive your users' tokens and data.
  • Separate read-only and write-capable integrations so approval, logging, and incident response policies can be stricter for state-changing actions.

Tool Loading and Latency

When the model first sees an MCP tool, the Responses API may import the server catalog and emit an mcp_list_tools item. Keep that item in the conversation state when safe so later turns do not need to fetch the same tool list again. For large MCP servers, combine server_description, allowed_tools, and defer_loading: true so the model can decide when to load detailed tool schemas.

json
{
  "type": "mcp",
  "server_label": "support_kb",
  "server_description": "Search approved customer-support documentation.",
  "server_url": "https://mcp.example.com/sse",

  "allowed_tools": ["search_docs"],
  "defer_loading": true,
  "require_approval": "never"
}

Inspect Output Items

Your application should inspect MCP output items rather than relying only on output_text:

  • mcp_list_tools shows the imported tool catalog for a server_label, including names, descriptions, and JSON schemas. Keep it in state only after validating the server identity and schema.
  • mcp_call shows the tool name, JSON-string arguments, tool output, server_label, optional approval_request_id, and an error field for protocol, execution, or connectivity failures.
  • A single response can contain multiple MCP calls. If order or approval matters, use parallel_tool_calls: false and process the output array sequentially.
  • Treat URLs, file references, and rich content returned by MCP servers as third-party data. Validate domains and file types before embedding, downloading, or rendering them.

Failure Triage

Most MCP issues are configuration or readiness problems. Use this checklist before changing prompts:

SymptomWhat to check
mcp_list_tools.failedserver_url or connector_id, OAuth token, network reachability, and exact allowed_tools names.
mcp_call.error or failed call eventInspect the mcp_call item, server logs, tool arguments, and MCP protocol or execution errors.
Approval request stallsContinue with previous_response_id plus an mcp_approval_response; explicitly approve or reject.
No tool is called after enabling MCPWait until the tool list has completed, keep imported tool items in state, and avoid tool_choice: "required" until at least one tool is available.
Definition validation failsUse a unique server_label; set exactly one of server_url or connector_id; do not omit both.
Connector auth failsSend authorization in the MCP tool object on every request and do not also send headers.Authorization.

For AvalAI integrations, log the route, model, server_label, imported tool names, redacted auth state, and the typed output items. That evidence tells you whether the issue is model support, account availability, OAuth scope, server transport, or approval handling.

Approval Flow

Use approvals for writes, payments, email sends, account changes, data deletion, or any operation that crosses trust boundaries.

  1. Send the initial Responses request with require_approval: "always" or a selective policy.
  2. Inspect response.output for an mcp_approval_request item.
  3. Show the proposed tool name and arguments to a trusted user or policy engine.
  4. Continue the chain with previous_response_id and an mcp_approval_response item.
  5. Keep parallel_tool_calls: false when approval order matters.

OpenAI's default is approval-before-sharing for MCP tool calls. Use require_approval: "never" only after a trust review, or use an object policy to skip approval for a small set of safe tool names while requiring approval for everything else.

Fallback: App-Managed Function Tool

When hosted MCP is not enabled for your AvalAI route, proxy the external service in your application and expose only the safe operation as a strict function tool.

json
{
  "type": "function",
  "name": "search_support_docs",
  "description": "Search approved support documentation by query.",
  "parameters": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string"
      }
    },
    "required": [
      "query"
    ],
    "additionalProperties": false
  },
  "strict": true
}

In the Responses loop, execute this fallback only after validating the function_call.arguments, then return the service result in a function_call_output item with the same call_id. Keep the output narrow: include the answer, source IDs, permission decision, and any redacted error, not raw OAuth tokens, full third-party payloads, or hidden server logs.

Security Checklist

  • Connect only to trusted servers, preferably official servers run by the service provider.
  • Restrict imported tools with allowed_tools; do not expose a full server catalog by default.
  • Keep OAuth tokens in your secret store and send them through authorization, not prompt text.
  • Send authorization on every Responses request that needs it; hosted Responses flows do not return or persist the raw token for reuse.
  • Require approvals for sensitive reads and all state-changing actions.
  • Use require_approval: "never" only for trusted, read-only tools where your application can tolerate automatic data sharing.
  • Log the minimum useful audit trail: server label, tool name, redacted arguments, outcome, and approver.
  • Treat MCP output as third-party data; validate links, file IDs, and domains before rendering them.
  • Preserve or cache mcp_list_tools results only after validating the tool schema and server identity.
  • Review Zero Data Retention and data residency expectations separately for every third-party MCP server; external services apply their own retention and residency policies after data leaves AvalAI/OpenAI-hosted inference.