Assistiv Docs

[ STEP 06 / INTEGRATION ]

MCP / Tools

apiv0.1.0sdk@assistiv/sdk@0.2.0

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 1,000 MCP tool calls per platform per calendar month are free. No wallet debit, no log row. After 1k, per-call pricing applies ($0.001 / call by default — see the pricing page). Counter resets on the 1st of each month.

Looking for Skills MCP tools?

The skills tool family (find_skill, fetch_skill, create_skill, delete_skill, submit_skill_review) auto-registers on the same MCP URL when platform.skills_enabled = true. Full reference and the three-call agent quickstart (curl) live on the Skills MCP page.

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).

Activating MCP apps for your platform

Decide which MCP apps (GitHub, Slack, Zoho Mail, Zendesk, …) your end users can connect, supply your OAuth Client ID and Secret, and set your platform's OAuth landing URL. This is a one-time setup per app, handled in the dashboard so the OAuth secret never round-trips through your own code.

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