Tools API Reference
This page documents the REST API endpoints for tool management across the platform. These endpoints provide programmatic access to:
Composio App Marketplace: Browse and connect 880+ external apps (GitHub, Slack, Jira, etc.)
Agent Plugin Assignments: Assign marketplace plugins to agents for extended capabilities
Tool Configuration: Enable/disable specific actions per workspace
Metadata Synchronization: Sync app/action metadata from Composio API to local cache
For information about the Composio integration architecture and entity management, see Composio Integration. For the unified tool execution system, see Tool Router & Execution. For UI components and user workflows, see Connecting Apps.
Overview
The Tools API is composed of two main routers:
/api/tools/* - Composio Marketplace
/api/tools/* - Composio MarketplaceManages external app integrations via Composio:
Marketplace Browsing: List 880+ available apps from cached metadata
Connection Management: Initiate OAuth flows and manage connection states
Action Configuration: Enable/disable specific Composio actions per workspace
Metadata Synchronization: Sync app/action metadata from Composio API to local cache
Workspace Isolation: Scope tool assignments and configurations per workspace
/api/agents/{id}/plugins - Agent Plugin Assignments
/api/agents/{id}/plugins - Agent Plugin AssignmentsManages plugin assignments to individual agents:
Plugin Discovery: List plugins assigned to an agent
Assignment Management: Add/remove plugins from agents
Context Assembly: Get assembled agent context (persona + plugin skills + tools)
All endpoints require workspace context via hybrid authentication (see Authentication Flow).
Sources: orchestrator/api/tools.py:1-31, orchestrator/api/agent_plugins.py:1-28
Architecture Overview
The Tools API implements a cache-first architecture for Composio integrations and a registry-based architecture for plugin assignments.
Composio Marketplace Architecture
Title: Composio Marketplace Data Flow
Agent Plugin Assignment Architecture
Title: Agent Plugin Assignment Flow
Key Design Principles:
Cache-First Reads: All Composio listing endpoints (
/marketplace,/connected,/{app}/actions) read from database cache tables, not external APIsLazy Sync: Metadata syncing occurs only via explicit
POST /synccalls, not on page loadsWorkspace Isolation: Entity connections, tool configs, and plugin assignments are scoped per workspace via
workspace_idStatus Lifecycle: Connection status transitions:
added→pending→active(no deletion, only status updates)Plugin Validation: Plugins must be workspace-enabled before agent assignment (enforced via foreign key)
Sources: orchestrator/api/tools.py:77-171, orchestrator/api/tools.py:201-259, orchestrator/api/tools.py:606-619, orchestrator/api/agent_plugins.py:68-124
Data Models
Composio Tools API Models
Request Models
Response Models
Agent Plugin API Models
Request Models
Response Models
Sources: orchestrator/api/tools.py:41-69, orchestrator/api/agent_plugins.py:33-61
Composio Tools API Endpoints
GET /api/tools/marketplace
List available Composio apps from cached metadata. Supports category filtering, search, and pagination.
Query Parameters:
category
string
None
Filter by category (e.g., "CRM", "Communication")
search
string
None
Search by app name or description
limit
integer
100
Max results (1-1000)
offset
integer
0
Pagination offset
Response: MarketplaceOut
Flow Diagram:
Implementation Details:
PERFORMANCE FIX: This endpoint does NOT sync pending connections. Pending sync was removed to eliminate 48+ Composio API calls on page loads (see line 88-91 comment).
Internal tools (
RAG,MEMORY,NL2SQL,CODEGRAPH) are excluded via~ComposioAppCache.app_name.in_(INTERNAL_APP_NAMES)filter.Triggers are extracted from
app_metadataJSONB field, which is populated during sync.
Example Request:
Example Response:
Sources: orchestrator/api/tools.py:77-171
GET /api/tools/stats
Get aggregated statistics about tools, categories, and action counts.
Response: StatsOut
Implementation:
Reads from
composio_stats_cachetable (populated by/syncendpoint)Counts connected apps by querying
entity_connectionswherestatus = 'active'
Example Response:
Sources: orchestrator/api/tools.py:174-198
GET /api/tools/connected
Get all apps connected or added to the current workspace.
Response:
Status Values:
active: OAuth completed, fully connectedadded: Added to workspace but not authenticatedpending: OAuth in progress (awaiting callback)
PERFORMANCE NOTE: This endpoint reads connection status from database only. It does NOT call Composio API. Pending connections are synced via manual /refresh-connections endpoint (see line 214 comment).
Sources: orchestrator/api/tools.py:201-259
GET /api/tools/{app_name}/actions
Get available actions for a specific app, with enabled state for the current workspace.
Path Parameters:
app_name
string
Composio app name (e.g., "GITHUB")
Query Parameters:
search
string
None
Filter actions by name/description
limit
integer
5000
Max results (1-20000)
offset
integer
0
Pagination offset
Response:
Implementation Flow:
High Limit Rationale: Default limit is 5000 (not 500) because many apps like GitHub have 500+ actions. This avoids forcing frontend to implement pagination for "show all actions" use cases (see line 266-268 comment).
Sources: orchestrator/api/tools.py:262-309
GET /api/tools/{app_name}/triggers
Get available triggers (webhooks/events) for a specific app.
Path Parameters:
app_name
string
Composio app name
Response:
Implementation:
Reads from
composio_apps_cache.app_metadata["triggers"]JSONB fieldTriggers are synced during
POST /syncto avoid schema changesReturns empty array if app not found or triggers not synced
Sources: orchestrator/api/tools.py:312-329
POST /api/tools/{app_name}/actions
Save enabled actions for an app in the current workspace. This configures which actions agents can use when this tool is assigned.
Path Parameters:
app_name
string
Composio app name
Request Body:
Response:
Implementation:
Creates or updates
workspace_tool_configsrecordStores enabled actions in
configuration.enabled_actionsJSONB fieldTool ID is normalized to lowercase (e.g., "GITHUB" → "github")
Sources: orchestrator/api/tools.py:332-367
POST /api/tools/connect
Initiate OAuth connection flow for an app. Returns redirect URL for user authorization.
Request Body:
Response:
Flow Diagram:
Implementation Details:
Delegates OAuth flow to
ComposioClient.initiate_connection()Creates
entity_connectionsrecord withstatus="pending"Status transitions to
activeafter OAuth callback completes (see Composio Integration)
Sources: orchestrator/api/tools.py:370-393
GET /api/tools/workspace
Get ALL tools in workspace (both connected and added, but not yet connected).
Response:
Difference from /connected:
/connectedreturns only active connections/workspacereturns active, added, and pending (all workspace interactions)
Sources: orchestrator/api/tools.py:396-448
POST /api/tools/add-to-workspace
Add an app to workspace without OAuth. Creates added status connection record. User can later click "Connect" to initiate OAuth.
Request Body:
Response:
Status Transition Diagram:
Special Cases:
If connection with
status="pending"exists, it overwrites toadded(allows retry of failed OAuth)If
activeoraddedconnection exists, returnsalready_addedstatusCommits immediately to ensure database consistency
Sources: orchestrator/api/tools.py:451-528
DELETE /api/tools/remove-from-workspace/{app_name}
Remove an app from workspace. Deletes the connection record (works for any status).
Path Parameters:
app_name
string
App name to remove
Authentication:
Requires workspace admin/owner role (enforced by
_assert_workspace_admin())
Response:
Error Responses:
403 Forbidden: User lacks admin permissions404 Not Found: App not found in workspace or no entity exists
Implementation:
Calls
EntityManager.remove_connection(entity_id, app_name)Does NOT revoke OAuth tokens in Composio (connection can be re-added)
Sources: orchestrator/api/tools.py:566-595
POST /api/tools/sync
Synchronize app and action metadata from Composio API to local cache. Populates composio_apps_cache, composio_actions_cache, and composio_stats_cache tables.
Query Parameters:
sync_type
string
"full"
"full" or "incremental"
Authentication:
No admin check required (any authenticated workspace can sync)
Response:
Sync Types:
full
Fetch all apps and actions from Composio API, rebuild entire cache
incremental
Fetch only new/updated apps since last sync (based on updated_at)
Sync Architecture:
Performance Characteristics:
Full sync typically takes 10-15 seconds for 450 apps
Recommended frequency: Once per day or on-demand
Frontend should NOT call this on page loads (performance bottleneck)
Sources: orchestrator/api/tools.py:606-619
POST /api/tools/refresh-connections
Manually refresh pending connections from Composio API. Checks all workspace connections with status="pending" and updates to active if OAuth completed.
Response:
When to Use:
After OAuth callback completes
When UI shows stale pending status
NOT on every page load (see performance note in code)
Flow:
IMPORTANT: This endpoint makes external API calls and should be used sparingly. The marketplace and connected endpoints were optimized to NOT call this on page loads (removed in performance fix).
Sources: orchestrator/api/tools.py:622-685
Frontend Integration
MarketplaceToolsTab Component
The primary UI for browsing and adding Composio apps.
Key Features:
Category filtering via horizontal scroll buttons
Search by app name/description
Pagination (40 items per page)
Tool card display with connect/disconnect actions
Status badges (Connected, Added)
State Flow:
Component Hierarchy:
Performance Optimizations:
Category filter triggers new backend call with
categoryparam (server-side filtering)Search filter applies client-side for instant feedback
Apps are paginated to show 40 per page (prevents DOM overload)
Tool logos cached with
ToolLogocomponent
Sources: frontend/components/marketplace/marketplace-tools-tab.tsx:72-495
Database Schema
composio_apps_cache
Stores metadata for all available Composio apps.
id
integer
Primary key
app_name
string
Uppercase app identifier (e.g., "GITHUB")
app_slug
string
Lowercase slug for URLs
display_name
string
Human-readable name
description
text
App description
logo_url
string
URL to app logo
categories
jsonb
Array of category strings
auth_schemes
jsonb
Array of supported auth methods
action_count
integer
Total available actions
trigger_count
integer
Total available triggers
status
string
"ACTIVE", "DEPRECATED", etc.
app_metadata
jsonb
Additional metadata (includes triggers)
created_at
timestamp
Cache creation time
updated_at
timestamp
Last sync time
Indexes:
app_name(unique)statuscategories(GIN index for JSONB containment queries)
composio_actions_cache
Stores metadata for all actions across all apps.
id
integer
Primary key
app_name
string
Foreign key to apps (uppercase)
action_name
string
Unique action identifier
display_name
string
Human-readable name
description
text
Action description
parameters
jsonb
JSON Schema for action inputs
response_schema
jsonb
JSON Schema for action outputs
created_at
timestamp
Cache creation time
updated_at
timestamp
Last sync time
Indexes:
(app_name, action_name)(composite unique)action_name(for fast search)
composio_stats_cache
Stores aggregated statistics (total apps, actions, categories).
id
integer
Primary key
stat_key
string
Stat identifier (e.g., "total_apps", "categories")
stat_value
jsonb
Stat data (count, timestamp, breakdown)
updated_at
timestamp
Last update time
Example Rows:
entity_connections
Stores workspace-level app connections (managed by EntityManager).
id
integer
Primary key
entity_id
integer
Foreign key to entities table
app_name
string
Uppercase app name
status
string
"added", "pending", "active"
connection_id
string
Composio connection ID (null until active)
connected_at
timestamp
When OAuth completed
created_at
timestamp
When added to workspace
Status Lifecycle:
added- App added to workspace, not authenticatedpending- OAuth initiated, awaiting callbackactive- OAuth completed, connection established
Important: Connections are NEVER deleted, only status transitions. This prevents data loss from temporary OAuth failures.
workspace_tool_configs
Stores per-workspace configuration for tools (which actions are enabled).
id
integer
Primary key
workspace_id
uuid
Foreign key to workspaces
tool_id
string
Lowercase app name (e.g., "github")
display_name
string
Human-readable tool name
enabled
boolean
Whether tool is active
configuration
jsonb
Config data (includes enabled_actions)
created_at
timestamp
Creation time
updated_at
timestamp
Last modification time
Example Configuration:
marketplace_plugins
Stores plugins available in the marketplace (both global and workspace-scoped).
id
uuid
Primary key
slug
string
URL-friendly identifier (unique)
name
string
Human-readable name
version
string
Semantic version (e.g., "1.0.0")
description
text
Plugin description
author
string
Plugin author
source_type
string
"s3", "github", "local"
workspace_id
uuid
NULL for global, UUID for workspace-scoped
skills_count
integer
Number of skills in plugin
commands_count
integer
Number of commands in plugin
token_estimate
integer
Estimated token usage
content_metadata
jsonb
Skills, commands, dependencies
created_at
timestamp
Creation time
agent_assigned_plugins
Junction table mapping agents to their assigned plugins.
id
integer
Primary key
agent_id
integer
Foreign key to agents
plugin_id
uuid
Foreign key to marketplace_plugins
priority
integer
Load order (0 = highest priority)
assigned_at
timestamp
Assignment timestamp
Indexes:
(agent_id, plugin_id)(composite unique - prevents duplicate assignments)agent_id(for fast agent plugin lookups)
workspace_enabled_plugins
Tracks which plugins are enabled for a workspace (required before agent assignment).
id
integer
Primary key
workspace_id
uuid
Foreign key to workspaces
plugin_id
uuid
Foreign key to marketplace_plugins
enabled_at
timestamp
When enabled
enabled_by
string
User ID who enabled it
Constraint Enforcement:
Sources: orchestrator/core/models/composio_cache.py (referenced), orchestrator/core/models/tool_assignments.py (referenced), orchestrator/core/models/marketplace_plugins.py (referenced)
Error Handling
Common Error Responses
400 Bad Request
Invalid app_name format
{"detail": "Invalid app name"}
403 Forbidden
Non-admin tries admin endpoint
{"detail": "Insufficient permissions"}
404 Not Found
App not found in cache
{"detail": "App not found"}
503 Service Unavailable
Composio API unavailable
{"detail": "Failed to initiate OAuth: <error>"}
Rate Limiting
The API does NOT implement rate limiting at the endpoint level. However, Composio API has its own rate limits:
Free tier: 100 requests/minute
Paid tier: 1000 requests/minute
Exceeding these limits during /sync will result in 429 errors from Composio.
Retry Logic
/syncendpoint implements exponential backoff for failed API calls/refresh-connectionsretries pending connections up to 3 times/connectdoes NOT retry OAuth initiation (user must retry manually)
Sources: orchestrator/api/tools.py:370-393, orchestrator/api/tools.py:606-685
Authentication & Authorization
All endpoints use hybrid authentication (Clerk JWT or API keys). See Authentication Flow for details.
Workspace Context Resolution
Every request resolves workspace_id via:
x-workspace-idheader (priority 1)workspace_idquery param (priority 2)WORKSPACE_IDenv var (priority 3)Default tenant UUID (priority 4)
Connections and configurations are scoped per workspace, ensuring multi-tenant isolation.
Admin Endpoints
The following endpoints require workspace admin/owner role:
DELETE /api/tools/remove-from-workspace/{app_name}GET /api/tools/debug/connections(debug only)
Admin check enforced via _assert_workspace_admin(ctx: RequestContext) helper.
Sources: orchestrator/api/tools.py:32-36, orchestrator/api/tools.py:539-563
Testing & Debugging
Debug Endpoint
GET /api/tools/debug/connections (Admin only)
Shows all connection records for the current workspace, useful for diagnosing status issues.
Response:
Manual Testing Flow
Add app to workspace:
Initiate OAuth:
Complete OAuth in browser (use returned
redirect_url)Refresh connection status:
Verify connection:
Sources: orchestrator/api/tools.py:531-563
Agent Plugin Assignment Endpoints
GET /api/agents/{agent_id}/plugins
List all plugins assigned to an agent, with metadata from the marketplace.
Path Parameters:
agent_id
integer
Agent ID
Response:
Implementation Flow:
Title: Plugin Assignment Query
Authorization:
Validates agent exists in database
Enforces workspace isolation (agent.workspace_id must match ctx.workspace_id)
Returns 403 if workspace mismatch, 404 if agent not found
Sources: orchestrator/api/agent_plugins.py:68-124
PUT /api/agents/{agent_id}/plugins
Update plugin assignments for an agent. Replaces all existing assignments with the provided list.
Path Parameters:
agent_id
integer
Agent ID
Request Body:
Response:
Implementation Steps:
Validation:
Agent exists and belongs to current workspace
Deduplicate plugin_ids while preserving order
Each plugin_id resolves to a valid
marketplace_pluginsrecordEach plugin is workspace-enabled (exists in
workspace_enabled_plugins)
Assignment Update:
Delete all existing
agent_assigned_pluginsrecords for this agentInsert new records with priority based on list order (0, 1, 2, ...)
Commit transaction atomically
Error Handling:
403 if workspace mismatch
404 if agent not found
400 if plugin not found or not workspace-enabled
Key Constraint:
Plugins MUST be workspace-enabled before assignment. This prevents agents from accessing plugins that haven't been vetted by workspace admins.
Sources: orchestrator/api/agent_plugins.py:126-208
GET /api/agents/{agent_id}/context
Get the fully assembled agent context, including persona, plugin skills, and tools. Used by the Agent Factory when activating an agent.
Path Parameters:
agent_id
integer
Agent ID
Response:
Assembly Process:
Title: Agent Context Assembly
Token Estimation:
Base system prompt: ~500 tokens
Persona description: ~200 tokens per persona
Plugin skills: plugin.token_estimate (pre-calculated during scan)
Total = sum of all components
Use Case: This endpoint is called by the Agent Factory when activating an agent for execution. It provides all the context needed to construct the LLM system message, including persona voice and plugin-provided skills.
Sources: orchestrator/api/agent_plugins.py:211-281
Performance Considerations
Cache Hit Ratio
The cache-first architecture achieves near 100% cache hit ratio for listing endpoints:
/marketplace: Always reads from cache (no external calls)/connected: Reads from database only/{app}/actions: Reads from cache (no external calls)
Only /connect and /sync make external API calls.
Database Query Optimization
Indexes Used:
composio_apps_cache.app_name(unique, B-tree)composio_apps_cache.status(B-tree)composio_apps_cache.categories(GIN, for@>containment queries)composio_actions_cache(app_name, action_name)(composite unique)entity_connections(entity_id, app_name)(composite, for workspace lookups)
Query Patterns:
Frontend Pagination
The frontend uses client-side pagination after fetching filtered results:
40 items per page (hardcoded in
pageSizeconst)Resets to page 1 on filter/search change
Uses
EnhancedPaginationcomponent for UI
This avoids backend pagination complexity while maintaining performance (DB query still limited to 1000 apps).
Sources: frontend/components/marketplace/marketplace-tools-tab.tsx:82-248
Related Endpoints
Composio Integration Router
The /api/composio/* endpoints handle OAuth callbacks and entity management:
GET /api/composio/callback- OAuth callback handlerPOST /api/composio/disconnect- Revoke OAuth tokensGET /api/composio/entities- List Composio entities
See Composio Integration for details.
Agent Tool Assignments
The /api/agents/{id}/tools endpoints assign tools to specific agents:
GET /api/agents/{id}/tools- Get assigned tools for agentPUT /api/agents/{id}/tools- Update tool assignmentsPOST /api/agents/{id}/tools/bulk- Bulk assign/unassign
See Agent API Reference for details.
Sources: orchestrator/api/tools.py:1-700
Last updated

