mcpField
B
blink-connectors

blink-connectors

github.com/blink-newDevelopment438 installsUpdated 2w ago
Repository

About blink-connectors

blink-connectors is a Blink skill and usage guide for accessing third-party APIs through connected providers. It is for developers using the CLI, SDK, or MCP tools, and includes provider-specific request and troubleshooting guidance.

Key features

  1. 01Checks connector status
  2. 02Executes API calls through providers
  3. 03Lists linked OAuth providers
  4. 04Supports CLI and SDK usage
  5. 05Documents path rules and error handling

Use cases

  1. 01Reading Slack channels or Notion pages
  2. 02Retrieving Google Sheets data
  3. 03Running Google Ads reports
  4. 04Diagnosing authorization, scope, or quota errors

MCP support

The skill documents the MCP tools blink_connector_exec, blink_connector_linked, and blink_connector_status for API execution and connection checks.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/blink-new/blink-plugin --skill blink-connectors

After installing, type/blink-connectorsin Claude Code to confirm it loaded.

Details

From the project README

Getting Started

# List available providers
blink connector providers

# Check connection status
blink connector status slack

# Execute an API call
blink connector exec slack /conversations GET

MCP Tools

ToolDescription
blink_connector_execExecute API call through a connected provider
blink_connector_linkedList all OAuth providers currently connected for a project
blink_connector_statusCheck connection status for a specific provider

Prerequisites

Initial OAuth connection must be done in the browser at blink.new/settings?tab=connectors. Users authorize each provider once, then CLI/MCP/SDK can make API calls.

SDK Usage

// Check status
const status = await blink.connectors.status('slack')

// GET request
const channels = await blink.connectors.execute('slack', {
  method: '/conversations',
  http_method: 'GET',
  params: { types: 'public_channel,private_channel' }
})

// POST request
await blink.connectors.execute('slack', {
  method: '/chat/postMessage',
  http_method: 'POST',
  params: { channel: 'C1234', text: 'Hello from Blink!' }
})

Available Providers

ProviderIDCommon Endpoints
Slackslack/conversations, /chat/postMessage, /users
Discorddiscord/user, /guilds, /channels/{id}/messages
Notionnotion/search, /databases, /pages
Google Drivegoogle_drive/files
Google Calendargoogle_calendar/events
Google Sheetsgoogle_sheets/spreadsheets/{id}/values/{range}
Google Docsgoogle_docs/documents
Google Slidesgoogle_slides/presentations
LinkedInlinkedin/userinfo, /ugcPosts
HubSpothubspot/contacts, /companies, /deals
Salesforcesalesforce/query, /sobjects/{type}
GitHubgithub/user, /repos, /issues — see blink-github skill for clone/push/PR
Stripestripe/customers, /charges, /subscriptions
Jirajira/search, /issue, /project
Microsoftmicrosoft/me, /messages, /events
Airtableairtable/bases, /records

Plus 20+ more — run blink connector providers for the full list.

CLI Examples

# Slack: list channels
blink connector exec slack /conversations GET

# Notion: search pages
blink connector exec notion /search POST '{"query":"meeting notes"}'

# Google Sheets: read data
blink connector exec google_sheets "/spreadsheets/SHEET_ID/values/Sheet1!A1:D10" GET

# HubSpot: list contacts
blink connector exec hubspot /contacts GET '{"limit":50}'

# Salesforce: SOQL query
blink connector exec salesforce /query GET '{"q":"SELECT Id,Name FROM Account LIMIT 10"}'

CLI syntax: blink connector exec <provider> <endpoint> [method] [params]

Method Path Rules

  1. Paths start with / — /conversations not conversations
  2. Dynamic IDs go in the path — /channels/${channelId}/messages
  3. Provider IDs use underscores — google_drive, google_calendar, google_sheets
  4. GET params become query parameters; POST params become JSON body
  5. Invalid JSON in CLI params hard-fails (exit 1) — bad JSON used to silently send {}. If you see Invalid JSON for params: ..., fix the quoting (shell-escape inner double quotes or use --input @file.json).

Google Ads (composio_googleads) — reading data

Every path must start with the API version, and the customer id goes in the PATH, never in the body. There is no top-level /search resource — /search, /googleads/search and /searchStream all 404.

# Find the customer id
blink connector exec composio_googleads /v23/customers:listAccessibleCustomers GET

# Run a report (GAQL)
blink connector exec composio_googleads /v23/customers/CUSTOMER_ID/googleAds:search POST \
  '{"query":"SELECT campaign.name, metrics.clicks FROM campaign WHERE segments.date DURING LAST_14_DAYS"}'

googleAds:searchStream works the same way but returns its payload — errors included — wrapped in an array.

Quota (RESOURCE_EXHAUSTED, scope DEVELOPER)

A 429 with rateScope: DEVELOPER is a cap on Composio's shared developer token — pooled across tenants — not on the user's Google Ads account. Nothing the user does to their account fixes it. Honour the retryDelay (often 10h+) and surface it to the user rather than retrying into it.

rateScope: ACCOUNT means the opposite: that one is the user's own account rate limit, and the delay is usually short.

Google Ads (composio_googleads) — writing campaigns

The old falsy-stripping workarounds are retired. Composio's proxy used to drop false, 0, {} and [] from POST bodies (#3324). That was fixed upstream on 2026-07-24 and re-verified against the live proxy on 2026-07-29. Send falsy values normally. Do not build portfolio bidding strategies just to avoid manualCpc: {}, and do not omit a network setting you want off — omitting it means "use account defaults", which is not the same as false.

  1. Dry-run first with partialFailure: true + validateOnly: true. Google returns 200 with a partialFailureError carrying the full fieldPathElements list, so you see every bad field at once instead of one error per round trip. Flip validateOnly to false only once the dry-run is clean.

  2. Empty proto markers work inline. { "manualCpc": {} } satisfies campaign_bidding_strategy — verified. Portfolio strategies are still the right choice when you actually want shared bidding across campaigns, but they're no longer a workaround.

  3. finalUrls goes at the Asset top level, NOT inside sitelinkAsset. This one still holds, but it's plain Google schema, not a proxy quirk: SitelinkAsset has no finalUrls field, so nesting it returns Invalid JSON payload ... Unknown name "finalUrls".

  4. v23 requires containsEuPoliticalAdvertising on campaign create. Use the string enum: "containsEuPoliticalAdvertising": "DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING". Omitting it returns contains_eu_political_advertising: REQUIRED.

  5. networkSettings booleans are real booleans. Set them true or false as you mean them. Note Google rejects targetGoogleSearch: false on a Search campaign with OPERATION_NOT_PERMITTED_FOR_CONTEXT — that's Google's rule, not a stripped field.

Debugging recipe
# Dry-run and read the full error list
blink connector exec composio_googleads /v23/customers/CUSTOMER_ID/campaigns:mutate POST \
  '{"operations":[...],"partialFailure":true,"validateOnly":true}'

# Then: read partialFailureError.details[].errors[].location.fieldPathElements
# to see exactly which field Google rejected, fix it, re-run with validateOnly:false

Prefer connector exec (the proxy) over connector tool-execute (the native tool catalog) for Google Ads. The native path collapses Google's error into an opaque Error executing the tool GOOGLEADS_* with no field detail.

Error Codes

CodeMeaning
CONNECTOR_NOT_CONNECTEDUser hasn't authorized this provider
CONNECTOR_DISABLEDProvider disabled for this project
MISSING_SCOPEReconnect with additional permissions
*_API_ERRORUpstream API error (e.g. SLACK_API_ERROR)

Token refresh is handled automatically by Blink backend.

Comments

Markdown supported