MCP Plugins
List MCP plugin providers, manage workspace connections, select plugins for assistants, and retrieve available tools through the Talkturo API.
curl --request GET \
--url "https://app.talkturo.com/api/mcp/providers" \
--header "Cookie: sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token"
const response = await fetch("https://app.talkturo.com/api/mcp/providers", {
method: "GET",
headers: {
Cookie: "sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token"
}
})
const data = await response.json()
console.log(data)
{
"providers": [
{
"id": "google-drive",
"name": "Google Drive",
"description": "Search and retrieve files from Google Drive",
"brandColor": "#0F9D58",
"iconUrl": "https://app.talkturo.com/images/mcp/google-drive.png"
},
{
"id": "notion",
"name": "Notion",
"description": "Search pages and databases from connected Notion workspaces",
"brandColor": "#111111",
"iconUrl": "https://app.talkturo.com/images/mcp/notion.png"
}
]
}
{
"error": "Unauthorized"
}
curl --request GET \
--url "https://app.talkturo.com/api/mcp/plugins?accountSlug=acme&assistantId=1d9d4e3c-5296-4f9b-a6b7-4f0f2f5851d4" \
--header "Cookie: sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token"
const url = new URL("https://app.talkturo.com/api/mcp/plugins")
url.searchParams.set("accountSlug", "acme")
url.searchParams.set("assistantId", "1d9d4e3c-5296-4f9b-a6b7-4f0f2f5851d4")
const response = await fetch(url, {
method: "GET",
headers: {
Cookie: "sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token"
}
})
const data = await response.json()
console.log(data)
{
"plugins": [
{
"id": "google-drive",
"name": "Google Drive",
"description": "Search and retrieve files from Google Drive",
"brandColor": "#0F9D58",
"iconUrl": "https://app.talkturo.com/images/mcp/google-drive.png",
"connections": [
{
"id": "8f2546ec-2f4f-4e1d-8f39-654f7f2bbf2d",
"label": "Operations workspace",
"expiresAt": "2026-01-15T18:25:43.511Z",
"needsReauth": false
}
],
"connectionId": "8f2546ec-2f4f-4e1d-8f39-654f7f2bbf2d",
"enabledTools": [
"drive.search",
"drive.get_file"
],
"defaultTools": [
"drive.search"
]
}
]
}
{
"error": "accountSlug is required"
}
{
"error": "Forbidden"
}
{
"error": "Assistant not found"
}
curl --request POST \
--url "https://app.talkturo.com/api/mcp/plugins/select" \
--header "Content-Type: application/json" \
--header "Cookie: sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token" \
--data '{
"assistantId": "1d9d4e3c-5296-4f9b-a6b7-4f0f2f5851d4",
"accountSlug": "acme",
"provider": "google-drive",
"connectionId": "8f2546ec-2f4f-4e1d-8f39-654f7f2bbf2d",
"tools": ["drive.search", "drive.get_file"]
}'
const response = await fetch("https://app.talkturo.com/api/mcp/plugins/select", {
method: "POST",
headers: {
"Content-Type": "application/json",
Cookie: "sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token"
},
body: JSON.stringify({
assistantId: "1d9d4e3c-5296-4f9b-a6b7-4f0f2f5851d4",
accountSlug: "acme",
provider: "google-drive",
connectionId: "8f2546ec-2f4f-4e1d-8f39-654f7f2bbf2d",
tools: ["drive.search", "drive.get_file"]
})
})
const data = await response.json()
console.log(data)
{
"ok": true,
"attached": true
}
{
"error": "tools must contain at most 100 items"
}
{
"error": "Connection not found"
}
curl --request GET \
--url "https://app.talkturo.com/api/mcp/plugins/tools?accountSlug=acme&connectionId=8f2546ec-2f4f-4e1d-8f39-654f7f2bbf2d" \
--header "Cookie: sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token"
const url = new URL("https://app.talkturo.com/api/mcp/plugins/tools")
url.searchParams.set("accountSlug", "acme")
url.searchParams.set("connectionId", "8f2546ec-2f4f-4e1d-8f39-654f7f2bbf2d")
const response = await fetch(url, {
method: "GET",
headers: {
Cookie: "sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token"
}
})
const data = await response.json()
console.log(data)
{
"tools": [
{
"name": "drive.search",
"description": "Search files and folders by name and content"
},
{
"name": "drive.get_file",
"description": "Fetch file metadata and downloadable content"
}
],
"defaultTools": [
"drive.search"
],
"capabilities": {
"plan": "tool_selection_required",
"stage": "production",
"blockedTools": [],
"warning": null
}
}
{
"error": "reauth_required",
"tools": []
}
{
"error": "connectionId is required"
}
{
"error": "Connection not found"
}
curl --request POST \
--url "https://app.talkturo.com/api/mcp/plugins/connect-key" \
--header "Content-Type: application/json" \
--header "Cookie: sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token" \
--data '{
"accountSlug": "acme",
"provider": "close",
"apiKey": "sk_live_example_key",
"label": "Sales Close"
}'
const response = await fetch("https://app.talkturo.com/api/mcp/plugins/connect-key", {
method: "POST",
headers: {
"Content-Type": "application/json",
Cookie: "sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token"
},
body: JSON.stringify({
accountSlug: "acme",
provider: "close",
apiKey: "sk_live_example_key",
label: "Sales Close"
})
})
const data = await response.json()
console.log(data)
{
"ok": true,
"connectionId": "8f2546ec-2f4f-4e1d-8f39-654f7f2bbf2d",
"label": "Sales Close"
}
{
"error": "missing_params"
}
{
"error": "unauthorized"
}
{
"error": "forbidden"
}
{
"error": "unknown_provider"
}
{
"error": "invalid_key"
}
{
"error": "save_failed"
}
curl --request POST \
--url "https://app.talkturo.com/api/mcp/oauth/authorize" \
--header "Content-Type: application/json" \
--header "Cookie: sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token" \
--data '{
"provider": "calendly",
"accountSlug": "acme",
"label": "Calendly Sales"
}'
const response = await fetch("https://app.talkturo.com/api/mcp/oauth/authorize", {
method: "POST",
headers: {
"Content-Type": "application/json",
Cookie: "sb-access-token=sb_example_access_token; sb-refresh-token=sb_example_refresh_token"
},
body: JSON.stringify({
provider: "calendly",
accountSlug: "acme",
label: "Calendly Sales"
})
})
const data = await response.json()
console.log(data)
{
"url": "https://auth.calendly.com/oauth/authorize?response_type=code&client_id=example&redirect_uri=https%3A%2F%2Fapp.talkturo.com%2Fapi%2Fmcp%2Foauth%2Fcallback&state=example_state&code_challenge=example_challenge&code_challenge_method=S256"
}
{
"error": "invalid_body"
}
{
"error": "unauthorized"
}
{
"error": "forbidden"
}
{
"error": "unknown_provider"
}
{
"error": "authorize_failed",
"detail": "Failed to generate authorization URL"
}
Endpoint summary
| Method | Path | Purpose | Auth |
|---|---|---|---|
GET | /api/mcp/providers | List available MCP providers | Session cookie |
GET | /api/mcp/plugins | List plugins, connections, and assistant selections | Session cookie |
POST | /api/mcp/plugins/select | Attach or detach a plugin for an assistant | Session cookie |
GET | /api/mcp/plugins/tools | List tools available for a workspace connection | Session cookie |
POST | /api/mcp/plugins/connect-key | Connect a provider using an API key | Session cookie |
POST | /api/mcp/oauth/authorize | Generate an OAuth authorization URL for a provider | Session cookie |
GET | /api/mcp/oauth/callback | Handle the OAuth callback from a provider | None (redirect target) |
All MCP plugin endpoints use the Talkturo web session for authentication. Send the authenticated Supabase session cookie with each request. These endpoints do not accept API keys.
GET /api/mcp/providers
Returns the MCP providers that Talkturo can connect to.
Parameters
This endpoint does not accept path, query, or request body parameters.
Response fields
Available MCP providers.
Provider identifier used when selecting a plugin for an assistant.
Human-readable provider name.
Short description of the provider and its integration.
Provider brand color value.
Absolute URL for the provider icon.
GET /api/mcp/plugins
Returns MCP plugins for the workspace, including available connections and the current selection for an assistant when assistantId is provided.
Query parameters
Workspace account slug.
Assistant UUID. When provided, the response includes the current plugin selection for that assistant in connectionId and enabledTools.
Response fields
Plugins available to the workspace.
Plugin or provider identifier.
Human-readable plugin name.
Short description of the plugin.
Brand color associated with the plugin.
Absolute URL for the plugin icon.
Authentication method used by the provider, such as oauth or api_key.
URL to documentation on how to obtain an API key for providers that use API key authentication. Absent for OAuth-only providers.
Workspace connections for this plugin provider.
Connection UUID.
Display label for the connection.
Connection expiration timestamp in ISO 8601 format when the provider issues expiring credentials.
Whether the connection requires reauthorization before tools can be used.
Currently selected connection UUID for the assistant and provider.
Tool names currently enabled for the assistant on this plugin.
Default tool names suggested for this plugin.
POST /api/mcp/plugins/select
Attaches a provider connection to an assistant and stores the selected tool list. If tools is an empty array, Talkturo detaches the plugin from the assistant and deletes the saved configuration.
Body parameters
Assistant UUID that will receive the plugin selection.
Workspace account slug.
Provider identifier returned by GET /api/mcp/providers.
Connection UUID for the selected provider.
List of tool names to enable for the assistant. Each item can contain up to 200 characters, and the array can contain up to 100 items. Send an empty array to detach the plugin from the assistant.
Response fields
Whether the request completed successfully.
Whether a plugin configuration is attached after the request completes. false indicates the plugin was detached because tools was empty.
GET /api/mcp/plugins/tools
Returns the tools exposed by a specific workspace connection. Use this endpoint before saving a plugin selection so you can present the current tool list to the user.
Query parameters
Workspace account slug.
Connection UUID.
Response fields
Tools available through the selected connection. When reauthorization is required, this array is returned empty.
Tool identifier.
Human-readable description of the tool.
Default tool names recommended for the connection.
Capability metadata for the connection, or null when no capability metadata is available.
Capability plan identifier.
Capability stage for the tool set.
Tool names that are blocked for the current connection or plan.
Warning message to display alongside the tool list.
Returned with the value reauth_required when the connection must be reauthorized before tools can be listed.
POST /api/mcp/plugins/connect-key
Connect a provider that uses API key authentication by submitting the key directly. This creates a workspace connection without an OAuth flow.
Body parameters
Workspace account slug.
Provider identifier returned by GET /api/mcp/providers.
API key for the provider. The key is not returned in the response.
Display label for the connection. When omitted, a default label is generated.
Response fields
Whether the connection was created successfully.
UUID of the newly created connection.
Display label for the connection.
Error responses
| Status | Error value | Meaning |
|---|---|---|
400 | missing_params | Missing accountSlug, provider, or apiKey |
401 | unauthorized | Missing or invalid session |
403 | forbidden | Not allowed to access the workspace |
404 | unknown_provider | Provider not recognized |
404 | account_not_found | Workspace not found |
422 | no_tools | Provider has no tools available |
422 | invalid_key | API key was rejected by the provider |
502 | provider_unreachable | Provider could not be contacted |
500 | save_failed | Connection could not be saved |
500 | connect_failed | Connection attempt failed |
POST /api/mcp/oauth/authorize
Generate an OAuth authorization URL for a provider that uses OAuth. Redirect the user to the returned URL to begin the authorization flow.
Body parameters
Provider identifier returned by GET /api/mcp/providers.
Workspace account slug.
Display label for the connection. Must be between 1 and 80 characters.
Response fields
OAuth authorization URL. Redirect the user to this URL to begin the OAuth flow. The URL includes response_type, client_id, redirect_uri, state, code_challenge, and code_challenge_method parameters.
Error responses
| Status | Error value | Meaning |
|---|---|---|
400 | invalid_body | Request body failed validation |
401 | unauthorized | Missing or invalid session |
403 | forbidden | Not allowed to access the workspace |
404 | unknown_provider | Provider not recognized |
404 | account_not_found | Workspace not found |
500 | authorize_failed | Failed to generate the authorization URL. A detail field may provide additional context. |
GET /api/mcp/oauth/callback
Handle the OAuth callback from a provider. After the user authorizes the connection at the provider's site, the provider redirects back to this endpoint with an authorization code.
This endpoint does not return JSON. It returns an HTML popup page that communicates the result to the opener window using postMessage, BroadcastChannel, and localStorage. The published payload has the shape { type: "mcp_oauth_result", ok: boolean, provider: string, connectionId?: string, error?: string, at: number }.
Query parameters
Authorization code returned by the provider. Required unless the provider returns an error.
State value returned by the provider. Required unless the provider returns an error.
OAuth error returned by the provider when authorization fails.
Published payload
The HTML page publishes the following JSON payload to the opener window:
Always mcp_oauth_result.
Whether the OAuth connection succeeded.
Provider identifier.
Connection UUID. Present only when ok is true.
Error identifier. Present only when ok is false.
Timestamp when the payload was generated.
Possible error values
| Error value | Meaning |
|---|---|
missing_code_or_state | The provider did not return code or state |
state_missing | State cookie was not found |
state_mismatch | State hash did not match the expected value |
bad_context | OAuth context could not be deserialized |
unknown_provider | Provider not recognized |
client_secret_missing | Provider client secret is not configured |
token_exchange_failed | Token exchange with the provider failed |
save_failed | Connection could not be saved |
callback_failed | Unexpected error during callback processing |
Error behavior
All endpoints require an authenticated Talkturo session. Beyond 401 Unauthorized, MCP plugin endpoints can return the following status codes depending on the route and workspace state:
| Status | Meaning |
|---|---|
400 | Missing or invalid query or body parameters |
401 | Missing or invalid session |
403 | Authenticated, but not allowed to access the workspace or assistant |
404 | Requested assistant or connection was not found |
500 | Unexpected server error |