PRD-35: Technical Specification

Version: 1.0 Status: 🟡 Design Phase Parent: PRD-35 (Tool Catalog & Registry Architecture) Last Updated: 2026-01-17


Part 1: API Contracts

1.1 Automatos Credential Resolution API

This API is called by the Unified Adapter to resolve credentials for hosted mode executions.

Endpoint: POST /api/credentials/resolve

Purpose: Resolve and return decrypted credentials for a tool execution.

Authentication: Service token (Bearer token issued to Adapter)

Request:

{
    "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
    "tool_name": "github",
    "credential_type": "github_api",  // Optional, can resolve by tool_name
    "service_name": "unified-adapter",
    "environment": "production"  // Optional, defaults to "production"
}

Response (Success):

Response (Not Found):

Response (Unauthorized):

Implementation Notes:

  • Lookup order: tenant_tool_config.credential_idcredential_types fallback

  • Credentials are decrypted server-side and returned

  • Audit log entry created for each resolution

  • Rate limiting: 100 req/min per service_name


1.2 Automatos Tool Enablement APIs

Endpoint: GET /api/tools/available

Purpose: List all tools available from Adapter (for enablement UI).

Authentication: User JWT (tenant context)

Response:


Endpoint: POST /api/tools/enable

Purpose: Enable a tool for the tenant with credentials.

Authentication: User JWT (tenant context, admin role)

Request:

Response:

Logic:

  1. Validate adapter_tool_id exists in Adapter

  2. Create or update credential in credentials table

  3. Create or update tenant_tool_config with credential_id

  4. Return success


Endpoint: DELETE /api/tools/{adapter_tool_id}/disable

Purpose: Disable a tool for the tenant.

Authentication: User JWT (tenant context, admin role)

Response:

Logic:

  1. Set tenant_tool_config.enabled = false

  2. Optionally: Remove agent assignments (or leave orphaned)

  3. Do NOT delete credentials (user may re-enable)


1.3 Agent Tool Assignment APIs

Endpoint: GET /api/agents/{agent_id}/tools

Purpose: Get all tools assigned to an agent.

Authentication: User JWT (tenant context)

Response:


Endpoint: POST /api/agents/{agent_id}/tools

Purpose: Assign a tool to an agent.

Authentication: User JWT (tenant context)

Request:

Response:

Validation:

  1. Tool must be enabled for tenant (tenant_tool_config.enabled = true)

  2. Agent must belong to same tenant

  3. Idempotent: update if assignment exists


Endpoint: DELETE /api/agents/{agent_id}/tools/{adapter_tool_id}

Purpose: Remove a tool assignment from an agent.

Authentication: User JWT (tenant context)

Response:


Endpoint: PUT /api/agents/{agent_id}/tools/batch

Purpose: Batch update tool assignments (for UI toggles).

Authentication: User JWT (tenant context)

Request:

Response:


1.4 Adapter MCP Execution API

Endpoint: POST /mcp (on Adapter, via Context Forge)

Purpose: Execute a tool via MCP protocol.

Request (Hosted Mode):

Request (BYO Mode):

Response (Success):

Response (Error):


Part 2: Agent-Tool Assignment Flow

2.1 UI Flow: Tools Settings Page

Location: Settings > Tools (existing page, enhanced)

User Journey:

Enable Tool Modal:


2.2 UI Flow: Agent Configuration

Location: Agent modal > Tools tab (new section, similar to Skills)

User Journey:


2.3 Runtime Flow: Tool Execution


2.4 Integration with UnifiedToolExecutor


2.5 Updated ToolRegistry


Part 3: Database Migrations

Migration: Add Tool Assignment Tables


Part 4: Summary Checklist

API Implementation

Database

Backend Services

Frontend

Adapter Updates

Testing


Part 5: Next Steps - Bulk Tool Registration

Phase 1: Tool Catalog Population (Priority: HIGH)

Goal: Register 50+ tools in the catalog with proper metadata and credential mappings.

1.1 Tool Categories to Add:

Category
Example Tools
Credential Type

Communication

Slack, Discord, Telegram, Twilio

OAuth/API Key

DevOps

GitHub, GitLab, Jira, Linear

OAuth/PAT

CRM

Salesforce, HubSpot, Pipedrive

OAuth

Productivity

Notion, Google Docs, Airtable

OAuth

Database

PostgreSQL, MongoDB, Supabase

Connection String

AI/ML

OpenAI, Anthropic, HuggingFace

API Key

Analytics

Google Analytics, Mixpanel

OAuth/API Key

Storage

S3, GCS, Cloudflare R2

Access Key

1.2 Bulk Registration Script

1.3 Registration Data Structure

Phase 2: Credential Type Expansion

Current: 400+ credential types seeded (most are placeholders)

Action Items:

  1. Verify schema_definition for top 20 tools

  2. Add OAuth flow support for tools requiring it

  3. Add validation patterns (e.g., GitHub PAT format: ghp_*)

  4. Add test_endpoint configurations for credential testing

Phase 3: Hosted Credential Mode

Goal: Enable Automatos to store credentials and resolve them on demand.

Implementation:

  1. Add credential_mode parameter to tool execution

  2. Implement callback API from Adapter → Automatos

  3. Add tenant_tool_config for multi-tenant credential isolation

  4. Add credential rotation and expiry handling

Phase 4: Tool Discovery & Recommendation

Goal: Smart tool suggestions based on agent type and task.

Features:

  • "You might also need" suggestions

  • Tool bundles (e.g., "DevOps Bundle" = GitHub + Jira + Slack)

  • Usage analytics for tool recommendations


Appendix: Bugs Fixed in This Iteration

Bug 1: Operation Parameter Not Passed to Adapter

File: unified_executor.py Issue: _execute_mcp_tool was looking for method key, but tool calls used operation Fix: Support both method and operation keys, with fallback logic

Bug 2: POST Parameters Sent as Query String

File: executors.py (Unified Adapter) Issue: RestExecutor sent all params as query params, but Slack API requires body Fix: Detect POST/PUT/PATCH and send remaining params in request body (form-urlencoded)

Bug 3: Slack API Errors Not Detected

File: executors.py (Unified Adapter) Issue: Slack returns 200 OK with ok: false in body for errors Fix: Check for ok: false in JSON response and log warning

Bug 4: Credential Update Creating Duplicates

File: tool-config-modal.tsx Issue: Config modal always called create API, not update Fix: Look up existing credentials by type and pass credentialId for updates

Bug 5: Query Params Not Sent to Credentials API

File: credentials.ts Issue: listCredentials passed query in options, but apiClient ignored it Fix: Build query params directly into URL string

Last updated