Execute Tool
The core AgentBridge endpoint. Send a provider slug, tool name, and parameters — AgentBridge retrieves the user's encrypted OAuth token, calls the upstream provider API, and returns a normalized response with latency tracking and execution logging.
Endpoint #
Authorization: Bearer ab_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
Requires a write or admin scoped API key. A read-scoped key will receive a 403 Forbidden response.
Request Body #
All fields must be JSON. The params object schema is specific to each provider and tool — consult the Integrations docs for per-provider tool schemas.
"notion", "slack", "github", "google-drive", "gmail".
"create_page", "send_message", "create_issue".
422 with the provider's validation error.
Shorthand Format #
Instead of specifying provider and tool separately, you can combine them into a single provider.tool string and omit the provider field entirely. This is especially useful when routing tool calls from an LLM — you can pass the string returned by GET /mcp/tools directly.
{
"tool": "github.create_issue",
"params": {
"repo": "acme/backend",
"title": "Fix memory leak in worker"
}
}
Both forms are fully equivalent. Use whichever fits your workflow:
{ "provider": "github", "tool": "create_issue", "params": {...} }
{ "tool": "github.create_issue", "params": {...} }
Use GET /mcp/tools to retrieve all available provider.tool strings in one request.
Response #
Successful executions return HTTP 200 with a consistent JSON envelope. The data field contains the normalized response from the upstream provider.
{
"status": "success",
"data": { /* provider-specific response */ },
"latencyMs": 312,
"executionId": "exec_01hxyz..."
}
"success" on 200 responses.
GET /logs/:id.
Examples #
Notion — Create Page #
Create a new page inside a Notion database or parent page.
{
"provider": "notion",
"tool": "create_page",
"params": {
"parent_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Meeting Notes — March 14",
"content": "Agenda: Q1 review, roadmap planning, hiring update."
}
}
{
"status": "success",
"data": {
"id": "page_789xyz",
"url": "https://notion.so/Meeting-Notes-March-14-789xyz",
"created_time": "2026-03-14T10:30:00.000Z"
},
"latencyMs": 312,
"executionId": "exec_01hxyz7a9b..."
}
Slack — Send Message #
Post a message to a Slack channel using its channel ID.
{
"provider": "slack",
"tool": "send_message",
"params": {
"channel": "C012AB3CD",
"text": "Deployment to production completed successfully."
}
}
{
"status": "success",
"data": {
"ok": true,
"ts": "1710432000.123456",
"channel": "C012AB3CD"
},
"latencyMs": 198,
"executionId": "exec_01hyza3b4c..."
}
GitHub — Create Issue #
Open a new issue in a GitHub repository with optional labels and body text.
{
"provider": "github",
"tool": "create_issue",
"params": {
"repo": "acme/backend",
"title": "Fix memory leak in worker process",
"body": "Worker process memory grows unbounded after 24h uptime. See #142.",
"labels": ["bug", "performance"]
}
}
{
"status": "success",
"data": {
"id": 2048319,
"number": 157,
"url": "https://github.com/acme/backend/issues/157",
"state": "open"
},
"latencyMs": 421,
"executionId": "exec_01hzab5d6e..."
}
Error Responses #
400 — Provider Not Connected #
The requested provider has no active integration for this user.
{
"statusCode": 400,
"message": "Integration not found for provider: notion",
"error": "Bad Request"
}
422 — Provider Returned Error #
AgentBridge successfully called the upstream API but the provider responded with an error.
{
"statusCode": 422,
"message": "Provider returned an error",
"error": "Unprocessable Entity",
"providerError": {
"object": "error",
"status": 403,
"code": "restricted_resource",
"message": "Insufficient permissions to access this resource."
}
}
The providerError field contains the raw error body from the upstream provider. Its shape varies by provider. Always check statusCode === 422 and inspect providerError for provider-specific error codes and messages.
404 — Tool Not Found #
The tool name does not exist for the given provider.
{
"statusCode": 404,
"message": "Tool 'create_pge' not found for provider: notion",
"error": "Not Found"
}
Check the Integrations docs for the exact list of tool names per provider. Tool names are case-sensitive and use snake_case.
Retries #
AgentBridge does not retry failed requests automatically. Implement client-side retry logic for transient errors:
429(rate limited): Wait until the Unix timestamp in theX-RateLimit-Resetheader, then retry once.500(server error): Retry with exponential backoff: 1s, 2s, 4s, then give up after 3 attempts.502(bad gateway): The upstream provider was unreachable. Retry after 5-10 seconds.
Do not retry the following status codes — they indicate a client or data problem that will not resolve on retry:
400— Fix the request (connect the integration or correct the body)401— Fix the API key403— Use a key with the correct scope404— Fix the tool name422— Fix the tool parameters or resolve the provider-side issue
Idempotency #
POST /api/mcp/execute is not idempotent. Each call creates a new execution log entry and may create side effects in the target system. For example:
- Calling
create_pagetwice creates two separate Notion pages - Calling
send_messagetwice sends two Slack messages - Calling
create_issuetwice opens two GitHub issues
AgentBridge does not currently support idempotency keys. To avoid duplicate side effects, implement idempotency checks in your agent logic. You can use GET /logs to verify whether a previous execution succeeded before retrying.
import { AgentBridge } from 'agentbridge-sdk';
const bridge = new AgentBridge(process.env.AGENTBRIDGE_API_KEY!);
// Check recent logs before retrying a create operation
const logs = await bridge.logs.list({ page: 1, limit: 5 });
const alreadyCreated = logs.data.some(
log => log.provider === 'notion'
&& log.tool === 'create_page'
&& log.status === 'success'
);
if (!alreadyCreated) {
await bridge.execute({
provider: 'notion',
tool: 'create_page',
params: { parent_id: 'abc', title: 'Report' },
});
}