Assistiv Docs

MCP / Tools

Connect third-party apps (GitHub, Slack, Zoho Mail, Zendesk) via OAuth and expose their capabilities as tools to AI agents through the Model Context Protocol (MCP). Each connected app gets its own scoped URL — you choose which apps the model can see on each request.

Two base URLs:
  • https://api.assistiv.ai/v1 — inference, CRUD, mcp-config
  • https://mcp.assistiv.ai — tool execution, OAuth flows

Available Apps

GitHub

Issues, PRs, branches, workflow dispatch, gists, and more (10 tools).

Slack

Send messages, create channels, reactions, user lookup (10 tools).

Zoho Mail

Send emails, create tasks (2 tools).

Zendesk

Ticket CRUD, search, help center articles (10 tools).

Free tier

First 100 MCP tool calls per platform per calendar month are free. No wallet debit, no log row. After the 100th call, per-tool pricing applies. Counter resets on the 1st of each month.

How It Works

Phase 1

Platform admin activates apps(one-time, on the dashboard). Paste OAuth Client ID + Secret, your platform's base URL, and register https://mcp.assistiv.ai/oauth/callback in the provider's OAuth app settings.

Phase 2

End user connects apps (one-time per user per app). Your backend calls GET mcp.assistiv.ai/oauth/authorize?app=github, user approves, Assistiv stores the token encrypted.

Phase 3

Get per-app MCP URLs via GET /v1/me/mcp-config. Returns one scoped URL per connected app.

Phase 4

Use the URLs — pass them as tools in POST /v1/responses, or feed them into any MCP-compatible agent.

OAuth Connection Flow

1.

Platform admin activates the app: In the Assistiv dashboard (or via POST /v1/platforms/{id}/mcp/apps), provide your OAuth Client ID, Client Secret, and your platform's base URL. Paste https://mcp.assistiv.ai/oauth/callback as the Authorization callback URL in your provider's OAuth app.

2.

Get the authorization URL: Call GET mcp.assistiv.ai/oauth/authorize?app=github server-side with the end-user key. Returns a 302 redirect.

3.

Redirect the user: Send the browser to the authorization URL.

4.

Callback handled automatically: Provider redirects to mcp.assistiv.ai/oauth/callback. Assistiv exchanges the code for tokens, encrypts, and stores the connection.

5.

User lands back on your site: Redirected to {your_base_url}/mcp/oauth-callback?app=github&status=connected.

Why server-side? GET /oauth/authorize requires an Authorization header, which browser navigations cannot carry. Fetch server-side, read the 302 Location header, then redirect the browser.

End-User Endpoints

GETmcp.assistiv.ai/oauth/authorize

Returns a 302 redirect to the provider's OAuth consent page.

Auth: End-user key. Must be called server-side.

Query Parameters

NameTypeRequiredDescription
appstringRequiredApp slug (e.g. "github", "slack", "zoho_mail", "zendesk").
typescript
// Server action or backend route
const res = await fetch(
  "https://mcp.assistiv.ai/oauth/authorize?app=github",
  {
    headers: { Authorization: `Bearer ${endUserApiKey}` },
    redirect: "manual",
  }
);
const authorizeUrl = res.headers.get("location");
// Redirect the browser: window.location.href = authorizeUrl
GETmcp.assistiv.ai/apps

Lists MCP apps enabled for the authenticated user's platform.

Auth: End-user key.

bash
curl https://mcp.assistiv.ai/apps \
  -H "Authorization: Bearer sk-eu_your_key"
GETmcp.assistiv.ai/connections

Lists the authenticated end user's active app connections.

Auth: End-user key. OAuth tokens are never returned.

bash
curl https://mcp.assistiv.ai/connections \
  -H "Authorization: Bearer sk-eu_your_key"
json
{
  "data": [
    {
      "id": "uuid",
      "appSlug": "github",
      "createdAt": "2026-04-12T10:30:00Z"}
  ]
}
DELETEmcp.assistiv.ai/connections/:app

Disconnects an app by deactivating the stored OAuth credentials.

Auth: End-user key. Returns 204 No Content.

bash
curl -X DELETE https://mcp.assistiv.ai/connections/github \
  -H "Authorization: Bearer sk-eu_your_key"

Handling the OAuth Landing Page

After OAuth completes, the MCP service redirects the end user's browser to {base}/mcp/oauth-callback with query parameters describing the outcome.

GET{your_base_url}/mcp/oauth-callback

A route on YOUR website that handles the OAuth outcome. You implement this.

Query Parameters

NameTypeRequiredDescription
appstringOptionalApp slug (e.g. "github").
status"connected" | "error"OptionalOutcome of the OAuth flow.
errorstringOptionalError code when status is error.
error_descriptionstringOptionalHuman-readable error detail.
typescript
// e.g. app/mcp/oauth-callback/page.tsx (Next.js)
export default function OAuthCallback({
  searchParams,
}: {
  searchParams: { app?: string; status?: string; error?: string; error_description?: string };
}) {
  const { app, status, error, error_description } = searchParams;
  if (status === "connected") {
    return <p>{app} connected successfully. You can close this tab.</p>;
  }
  return (
    <div>
      <p>Failed to connect {app}: {error}</p>
      {error_description && <p>{error_description}</p>}
    </div>
  );
}

Per-App MCP URLs

Once an end user has connected apps, fetch their scoped MCP config. Each connected app gets its own URL — you choose which apps the model can see.

GET/v1/me/mcp-config

Returns per-app MCP URLs in both standard and OpenAI formats.

Auth: End-user key.

Use the openai format if you're calling /v1/responses — splice directly into your tools array.

Use the standard format for any MCP-compatible agent: Claude Desktop, OpenAI Codex, Cursor, LangChain MultiServerMCPClient, or your own harness.

json
// GET /v1/me/mcp-config
{
  "standard": {
    "github": {
      "transport": "streamable_http",
      "url": "https://mcp.assistiv.ai/mcp/github",
      "headers": { "Authorization": "Bearer sk-eu_..."}
    },
    "slack": {
      "transport": "streamable_http",
      "url": "https://mcp.assistiv.ai/mcp/slack",
      "headers": { "Authorization": "Bearer sk-eu_..."}
    }
  },
  "openai": [
    {
      "type": "mcp",
      "server_label": "github",
      "server_url": "https://mcp.assistiv.ai/mcp/github",
      "authorization": "Bearer sk-eu_..."},
    {
      "type": "mcp",
      "server_label": "slack",
      "server_url": "https://mcp.assistiv.ai/mcp/slack",
      "authorization": "Bearer sk-eu_..."}
  ]
}

Hosted MCP via Responses API

Pass per-app MCP tool items in your /v1/responses request. You pick which apps the model can see on each call.

Hosted MCP is only supported on /v1/responses. Sending type: "mcp" to /v1/chat/completions returns 422.

POST/v1/responses

Responses API with MCP tools. See Responses for full endpoint docs.

Auth: End-user key.

MCP Tool Item Fields

NameTypeRequiredDescription
typestringRequiredMust be "mcp".
server_labelstringRequiredApp slug: "github", "slack", "zoho_mail", "zendesk".
server_urlstring (URL)Requiredhttps://mcp.assistiv.ai/mcp/{app_slug}
authorizationstringRequired"Bearer sk-eu_..." — the end-user key.
require_approvalstringOptionalMust be "never" if set. "always" is not supported in v1.
bash
curl -X POST https://api.assistiv.ai/v1/responses \
  -H "Authorization: Bearer sk-eu_end_user_key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "input": "Create a GitHub issue in my-org/test-repo titled hello",
    "tools": [
      {
        "type": "mcp",
        "server_label": "github",
        "server_url": "https://mcp.assistiv.ai/mcp/github",
        "authorization": "Bearer sk-eu_end_user_key"
      }
    ]
  }'
typescript
// Include specific apps:
tools: config.openai.filter(t => ["github", "slack"].includes(t.server_label))

// Or include all connected apps:
tools: config.openai

Hybrid Execution Semantics

  • The model is invoked with both your function tools (if any) and the MCP tools.
  • Only MCP tool calls: backend executes them inline, re-invokes the model. Loop continues until a final answer.
  • Any function tool call: loop returns immediately so your platform can handle it. MCP calls in the same turn are NOT executed.
  • Maximum loop depth: 10 iterations. Each turn debits wallet/budget normally.

Response Output Items

json
{
  "id": "resp_abc",
  "object": "response",
  "status": "completed",
  "model": "gpt-4o",
  "output": [
    {
      "type": "mcp_call",
      "id": "mcp_xyz",
      "server_label": "github",
      "name": "github_create_issue",
      "arguments": "{\"owner\":\"my-org\",\"repo\":\"test-repo\",\"title\":\"hello\"}",
      "output": "Issue #42 created",
      "status": "completed"},
    {
      "type": "message",
      "id": "msg_abc",
      "role": "assistant",
      "content": [
        { "type": "output_text", "text": "Done — issue #42 is open."}
      ]
    }
  ],
  "usage": { "input_tokens": 120, "output_tokens": 35, "total_tokens": 155 }
}

Streaming Events

  • response.mcp_list_tools.in_progress / .completed — tool discovery
  • response.output_item.added (with item.type: "mcp_call")
  • response.mcp_call_arguments.delta / .done
  • response.mcp_call.in_progress / .completed
  • response.output_text.delta — final answer

Direct Protocol Access (Advanced)

POST mcp.assistiv.ai/mcp/{app_slug} is the raw JSON-RPC 2.0 endpoint over Streamable HTTP transport. Use it only if you're implementing your own MCP client. Requires the standard MCP session handshake (initialize notifications/initialized tools/list tools/call) and emits an mcp-session-id response header. Session TTL is 30 minutes. Tool names follow the pattern {app_slug}_{tool_name} (dashes converted to underscores).

Platform MCP Configuration

Manage which MCP apps are available to your platform's end users. These can be called with a platform key, or configured via the Assistiv dashboard. OAuth client secrets are encrypted at rest with AES-256-GCM.

POST/v1/platforms/{platformId}/mcp/apps

Activates an MCP app for your platform.

Auth: Platform key. Returns 201.

Request Body

NameTypeRequiredDescription
app_slugstringRequired"github", "slack", "zoho_mail", or "zendesk".
oauth_client_idstringRequiredYour OAuth app client ID.
oauth_client_secretstringRequiredYour OAuth app client secret. Encrypted at rest.
redirect_urlstring (URL)RequiredYour platform's base URL. End users land at {base}/mcp/oauth-callback after OAuth.
display_namestringOptionalHuman-readable name for dashboard display.
scopesstring[]OptionalOAuth scopes. Defaults to provider's built-in defaults.
Set the Authorization callback URL at your provider to https://mcp.assistiv.ai/oauth/callback.
bash
curl -X POST https://api.assistiv.ai/v1/platforms/{platformId}/mcp/apps \
  -H "Authorization: Bearer sk-plat_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "app_slug": "github",
    "display_name": "GitHub",
    "oauth_client_id": "Iv1.abc123",
    "oauth_client_secret": "secret_xyz",
    "redirect_url": "https://my-saas.com",
    "scopes": ["repo", "user"]
  }'
PATCH/v1/platforms/{platformId}/mcp/apps/{app_slug}

Updates an activated MCP app. All fields optional.

Auth: Platform key.

Request Body (all optional)

NameTypeRequiredDescription
display_namestringOptionalHuman-readable name.
oauth_client_idstringOptionalNew OAuth client ID.
oauth_client_secretstringOptionalNew OAuth client secret.
redirect_urlstring (URL)OptionalNew post-OAuth base URL.
scopesstring[]OptionalOAuth scopes to request.
is_activebooleanOptionalToggle the app on/off.
bash
curl -X PATCH https://api.assistiv.ai/v1/platforms/{platformId}/mcp/apps/github \
  -H "Authorization: Bearer sk-plat_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "redirect_url": "https://new-domain.com" }'
DELETE/v1/platforms/{platformId}/mcp/apps

Deactivates an MCP app. Soft delete — sets is_active=false.

Auth: Platform key. Returns 204.

Query Parameters

NameTypeRequiredDescription
app_slugstringRequiredApp slug to deactivate.
bash
curl -X DELETE "https://api.assistiv.ai/v1/platforms/{platformId}/mcp/apps?app_slug=github" \
  -H "Authorization: Bearer sk-plat_your_key"

Reference Endpoints

MethodEndpointAuthDescription
GETmcp.assistiv.ai/appssk-eu_*List available apps
GETmcp.assistiv.ai/connectionssk-eu_*List user's connections
DELETEmcp.assistiv.ai/connections/{app}sk-eu_*Disconnect an app
GETmcp.assistiv.ai/oauth/authorizesk-eu_*Start OAuth flow (302)
POSTmcp.assistiv.ai/mcp/{app_slug}sk-eu_*Per-app MCP endpoint
GET/v1/me/mcp-configsk-eu_*Get per-app MCP URLs
POST/v1/responsessk-eu_*Inference with MCP tools