Connectors and External Integrations Guide
This guide provides comprehensive documentation for integrating external services with Maitento. It covers Connectors (the foundation for external service definitions), External Operations (how agents invoke external tools), and Webhooks (event-driven callbacks).
Table of Contents
Overview
Maitento provides a layered architecture for integrating with external services:
+------------------------+
| AI Agents |
+------------------------+
|
v
+------------------------+
| External Operations | <-- Bindings + AI guidance
+------------------------+
|
v
+------------------------+
| Connectors | <-- Service definitions
+------------------------+
|
v
+------------------------+
| External Services | <-- REST APIs, MCP servers
+------------------------+
Connectors define the technical interface to external services (URLs, schemas, authentication).
External Operations add runtime bindings, AI guidance, and integration with agents.
Webhooks provide outbound event notifications when entities change in Maitento.
Connectors
What are Connectors?
Connectors are Maitento’s abstraction layer for integrating external services and APIs. They act as “device drivers” for external services, providing:
- Reusable service definitions that can be shared across multiple operations
- Schema validation for requests and responses using JSON Schema
- Authentication configuration for secure API access
- Namespace organization for managing multiple integrations
All connectors share common properties:
| Property | Description |
|---|---|
name | Unique identifier within namespace (max 150 chars) |
url | Endpoint URL for the external service |
description | Human-readable documentation (max 500 chars) |
requestSchema | JSON Schema for validating request structure |
responseSchema | JSON Schema for validating response structure |
authenticationType | How the connector authenticates (None, Header, Maitento) |
MCP Connectors
MCP (Model Context Protocol) connectors integrate with AI tool servers. They provide behavioral hints that help AI models understand the nature of operations:
| Hint | Description |
|---|---|
destructiveHint | When true, the operation may modify or delete data irreversibly |
idempotentHint | When true, multiple calls have the same effect as a single call |
openWorldHint | When true, the operation interacts with external systems beyond local context |
readOnlyHint | When true, the operation only reads data without modifying state |
Example MCP Connector:
{
"name": "weather-api",
"url": "https://api.weather.example.com/v1/current",
"description": "Gets current weather data for a specified location",
"requestSchemaJson": "{\"type\":\"object\",\"properties\":{\"location\":{\"type\":\"string\"}},\"required\":[\"location\"]}",
"responseSchemaJson": "{\"type\":\"object\",\"properties\":{\"temperature\":{\"type\":\"number\"},\"condition\":{\"type\":\"string\"}}}",
"authenticationType": "Header",
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true,
"readOnlyHint": true
}
OpenAPI Connectors
OpenAPI connectors integrate with standard REST APIs. They support HTTP methods and parameter definitions:
| Property | Description |
|---|---|
httpMethod | HTTP verb (GET, POST, PUT, DELETE, PATCH, etc.) |
pathParameters | Parameters embedded in URL path (e.g., /users/{userId}) |
queryParameters | Parameters passed as query strings |
Path and Query Parameter Definition:
{
"name": "userId",
"dataType": "String",
"isRequired": true,
"description": "The unique identifier of the user"
}
Supported Data Types: String, Number, Integer, Boolean
Example OpenAPI Connector:
{
"name": "user-service",
"url": "https://api.users.example.com/v2/users/{userId}",
"description": "Retrieves user information by ID",
"responseSchemaJson": "{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"email\":{\"type\":\"string\"}}}",
"authenticationType": "Header",
"httpMethod": "GET",
"pathParameters": [
{
"name": "userId",
"dataType": "String",
"isRequired": true,
"description": "The unique identifier of the user"
}
],
"queryParameters": [
{
"name": "includeProfile",
"dataType": "Boolean",
"isRequired": false,
"description": "Whether to include extended profile information"
}
]
}
Authentication Types
| Type | Description |
|---|---|
None | No authentication required |
Header | Authentication via HTTP headers (e.g., API key, Bearer token) |
Maitento | Uses Maitento’s internal secret management |
For Header authentication, you configure an authentication header that references a stored secret:
{
"headerName": "Authorization",
"secretId": "12345678-1234-1234-1234-123456789012"
}
External Operations
What are External Operations?
External Operations build on Connectors to enable AI agents to invoke external services. They provide:
- Parameter bindings that map data to connector inputs
- AI prompt guidance to help models understand when and how to use the operation
- Runtime value substitution using template placeholders
External Operations come in two types mirroring connectors:
| Type | Description |
|---|---|
McpExternalOperation | For MCP connector integrations (request bindings only) |
OpenApiExternalOperation | For REST API integrations (request, path, and query bindings) |
The 5-Level Binding Hierarchy
External Operations use a sophisticated binding hierarchy that allows values to be defined at multiple levels. When resolving a binding, the system checks each level in order (highest priority first):
| Priority | Level | Scope | Description |
|---|---|---|---|
| 1 | Session-level for single agent | Runtime, agent-scoped | Most specific runtime bindings |
| 2 | Session-level for entire interaction | Runtime, global | Runtime bindings for all agents |
| 3 | Interaction-level for single agent | Design-time, agent-scoped | Agent-specific design-time bindings |
| 4 | Interaction-level for entire interaction | Design-time, global | Shared design-time bindings |
| 5 | External operation level | Operation definition | Default values in the operation itself |
This hierarchy enables:
- Default values defined at the operation level
- Interaction-specific overrides at design time
- Session-specific values injected at runtime
- Agent-specific customization when needed
Three Sources of External Operations
External Operations can be attached to agents and interactions at three different points:
-
Agent-level (
AgentVersion.ExternalOperationReferences)- Operations defined directly on an agent
- Available whenever that agent is used
-
Interaction-Agent-level (
InteractionAgentBinding)- Operations attached when binding an agent to an interaction
- Specific to that agent within that interaction
-
Interaction-level (
InteractionVersion.ExternalOperations)- Operations defined on the interaction itself
- Available to all agents in the interaction
How Agents Use External Tools
When an AI agent needs external data or capabilities, Maitento converts External Operations into AI-compatible tool definitions:
-
Schema Reduction: The full JSON schema is reduced to only the parameters the AI needs to provide (unbound fields)
-
Tool Generation: Operations are converted to AI tool definitions with:
- Name and description
- Simplified parameter schema for unbound fields
- Proper JSON schema for AI invocation
-
Name Deduplication: If multiple operations have the same name, they are automatically disambiguated
Example: An operation with some pre-bound values:
{
"name": "get-weather",
"requestBindings": [
{ "target": "units", "value": "metric" }
]
}
The AI only sees the location parameter (the connector’s other required field), while units is automatically set to “metric”.
Execution Flow
When an AI model invokes an external tool:
AI Model invokes tool
|
v
CallToolHandler receives MCP call
|
v
CombinedExternalOperationBinder.CombineBindingsForInteraction()
|-- Gathers operations from 3 sources
|-- Applies 5-level binding hierarchy
+-- Returns BoundExternalOperation[]
|
v
Find matching BoundExternalOperation by name
|
v
OpenApiBoundExternalOperationExecutor.Execute()
|-- Validate request against reduced schema
|-- Build URL with path/query parameters
|-- Setup authentication headers
|-- Send HTTP request
|-- Validate response against schema
+-- Return BoundExternalOperationExecutionResult
|
v
AI receives structured response
Error Handling:
| Error Type | Description |
|---|---|
| Authentication Errors | Missing config, secret not found |
| Schema Validation Errors | Request or response doesn’t match schema |
| HTTP/Network Errors | Non-2xx responses, connection failures |
| Parameter Binding Errors | Duplicate targets, invalid bindings |
Webhooks
What are Webhooks?
Webhooks are HTTP callbacks triggered when entities are created or updated in Maitento. They enable real-time integration with external systems by pushing notifications when events occur.
Key Characteristics:
- Event-driven: Triggered automatically on entity changes
- Asynchronous: Uses a queue-based delivery system
- Reliable: Automatic retry with exponential backoff
- Secure: Shared secret for request verification
Webhook Types
| Type | Trigger Events |
|---|---|
AppProcess | App process created, started, paused, completed, or failed |
IngestedFile | File ingested or processing state changes (e.g., vector generation complete) |
CodeGenerationProcess | Code generation process created or status changes |
InteractionProcess | Interaction process created or status changes |
CapsuleProcess | Capsule process created or status changes |
Delivery Architecture
Maitento uses a two-phase delivery system:
Phase 1 (Synchronous): When an entity changes, a WebHookSendQueueItem is created in the database.
Phase 2 (Asynchronous): A background processor sends the webhook via HTTP.
Entity Created/Updated
|
v
TriggerWebHookIfRequired()
|
v
Create WebHookSendQueueItem
|
v
WebHookSendQueueProcessor (polls DB)
|
v
Enqueue to message bus
|
v
WebHookSenderBackgroundService
|
v
WebHookSender.ProcessItem()
|
v
HTTP PUT to registered URL
HTTP Request Format:
PUT <registered-url> HTTP/1.1
Content-Type: application/json
X-MT-WebHook-Type: AppProcess
X-MT-WebHook-Secret: <shared-secret>
X-MT-WebHook-AssociatedId: <entity-guid>
<custom headers from registration>
<JSON serialized entity>
Retry Policy
Webhooks automatically retry on failure using exponential backoff:
| Attempt | Wait Time | Cumulative Time |
|---|---|---|
| 1 | Immediate | - |
| 2 | 0.5 min | 0.5 min |
| 3 | 2 min | 2.5 min |
| 4 | 4.5 min | 7 min |
| 5 | 8 min | 15 min |
Formula: NextAttemptTime = Now + (attempt^2 / 2) minutes
Permanent Failure Conditions:
- Registration not found
- Associated entity not found
- Maximum attempts (5) exceeded
Cleanup: Successfully sent and permanently failed items are deleted after 6 hours.
API Reference Summary
Connectors API
| Method | Endpoint | Description |
|---|---|---|
| GET | /connectors | List all connectors |
| GET | /namespaces/{namespaceName}/connectors | List connectors in namespace |
| GET | /connectors/by-id/{id} | Get connector by ID |
| GET | /namespaces/{namespaceName}/connectors/by-name/{name} | Get connector by name |
| POST | /namespaces/{namespaceName}/connectors/mcp | Create MCP connector |
| POST | /namespaces/{namespaceName}/connectors/open-api | Create OpenAPI connector |
| DELETE | /connectors/by-id/{id} | Delete connector |
Required Roles: Tenant.Admin or Tenant.User
External Operations API
| Method | Endpoint | Description |
|---|---|---|
| GET | /external-operations | List all external operations |
| GET | /namespaces/{namespaceName}/external-operations | List in namespace |
| GET | /external-operations/by-id/{id} | Get by ID |
| GET | /namespaces/{namespaceName}/external-operations/by-name/{name} | Get by name |
| POST | /namespaces/{namespaceName}/external-operations/mcp | Create MCP operation |
| POST | /namespaces/{namespaceName}/external-operations/open-api | Create OpenAPI operation |
| DELETE | /external-operations/by-id/{id} | Delete operation |
Required Roles: Tenant.Admin or Tenant.User
Webhooks API
| Method | Endpoint | Description |
|---|---|---|
| GET | /web-hooks | List all webhook registrations |
| GET | /web-hooks/by-id/{id} | Get webhook by ID |
| POST | /web-hooks | Create webhook registration |
| PUT | /web-hooks/by-id/{id} | Update webhook registration |
| DELETE | /web-hooks/by-id/{id} | Delete webhook registration |
Required Roles: Tenant.Admin or Tenant.User
Configuration Examples
Example 1: Weather Service Integration
Step 1: Create the Connector
curl -X POST "https://api.maitento.com/namespaces/production/connectors/mcp" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "weather-api",
"url": "https://api.weather.example.com/v1/current",
"description": "Gets current weather data for a specified location",
"requestSchemaJson": "{\"type\":\"object\",\"properties\":{\"location\":{\"type\":\"string\"},\"units\":{\"type\":\"string\"}},\"required\":[\"location\"]}",
"responseSchemaJson": "{\"type\":\"object\",\"properties\":{\"temperature\":{\"type\":\"number\"},\"condition\":{\"type\":\"string\"}}}",
"authenticationType": "Header",
"readOnlyHint": true,
"idempotentHint": true
}'
Step 2: Create the External Operation
curl -X POST "https://api.maitento.com/namespaces/production/external-operations/mcp" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "get-current-weather",
"connectorId": "CONNECTOR_ID_FROM_STEP_1",
"requestBindings": [
{ "target": "units", "value": "metric" }
],
"authenticationHeader": {
"headerName": "X-Weather-API-Key",
"secretId": "YOUR_SECRET_ID"
},
"promptGuidance": "Use this operation to get current weather conditions. Provide a city name or coordinates as the location parameter. Returns temperature in Celsius and weather condition."
}'
Example 2: REST API with Path Parameters
Step 1: Create the Connector
curl -X POST "https://api.maitento.com/namespaces/production/connectors/open-api" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "customer-service",
"url": "https://api.crm.example.com/v2/customers/{customerId}",
"description": "Retrieves customer information by ID",
"responseSchemaJson": "{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"email\":{\"type\":\"string\"},\"tier\":{\"type\":\"string\"}}}",
"authenticationType": "Header",
"httpMethod": "GET",
"pathParameters": [
{
"name": "customerId",
"dataType": "String",
"isRequired": true,
"description": "The unique customer identifier"
}
],
"queryParameters": [
{
"name": "expand",
"dataType": "String",
"isRequired": false,
"description": "Comma-separated list of related resources to include"
}
]
}'
Step 2: Create the External Operation
curl -X POST "https://api.maitento.com/namespaces/production/external-operations/open-api" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "get-customer-details",
"connectorId": "CONNECTOR_ID_FROM_STEP_1",
"requestBindings": [],
"pathBindings": [
{ "target": "customerId", "value": "{{customer_id}}" }
],
"queryBindings": [
{ "target": "expand", "value": "orders,preferences" }
],
"authenticationHeader": {
"headerName": "Authorization",
"secretId": "YOUR_CRM_SECRET_ID"
},
"promptGuidance": "Retrieve detailed customer information including their orders and preferences. Requires the customer_id parameter."
}'
Example 3: Webhook for Process Monitoring
curl -X POST "https://api.maitento.com/web-hooks" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "AppProcess",
"url": "https://myapp.example.com/webhooks/process-updates",
"secret": "my-secure-webhook-secret-12345",
"headers": {
"X-Source": "maitento",
"X-Environment": "production"
}
}'
Webhook Handler Example (Node.js):
const express = require('express');
const app = express();
app.use(express.json());
app.put('/webhooks/process-updates', (req, res) => {
// Verify the webhook secret
const receivedSecret = req.headers['x-mt-webhook-secret'];
if (receivedSecret !== process.env.MAITENTO_WEBHOOK_SECRET) {
return res.status(401).send('Invalid secret');
}
const webhookType = req.headers['x-mt-webhook-type'];
const associatedId = req.headers['x-mt-webhook-associatedid'];
const payload = req.body;
console.log(`Received ${webhookType} webhook for ${associatedId}`);
console.log(`Status: ${payload.status}`);
// Handle different statuses
switch (payload.status) {
case 'Completed':
// Process completed successfully
notifyTeam(`Process ${associatedId} completed successfully`);
break;
case 'Failed':
// Process failed - alert team
alertTeam(`Process ${associatedId} failed: ${payload.failureDetails}`);
break;
case 'Running':
// Process started
logProgress(`Process ${associatedId} is now running`);
break;
}
// Always respond with 2xx to acknowledge receipt
res.status(200).send('OK');
});
app.listen(3000);
Example 4: Complete Integration Flow
This example shows how to set up an agent that can look up customer information and send notifications:
1. Create Secrets (via Secrets API)
# Store CRM API key
curl -X POST "https://api.maitento.com/namespaces/production/secrets" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "crm-api-key", "value": "sk_live_xxx..."}'
# Store notification service key
curl -X POST "https://api.maitento.com/namespaces/production/secrets" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "notification-api-key", "value": "ntfy_xxx..."}'
2. Create Connectors
# Customer lookup connector
curl -X POST "https://api.maitento.com/namespaces/production/connectors/open-api" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "crm-customer-lookup",
"url": "https://api.crm.example.com/customers/{id}",
"description": "Look up customer by ID",
"authenticationType": "Header",
"httpMethod": "GET",
"pathParameters": [{"name": "id", "dataType": "String", "isRequired": true, "description": "Customer ID"}],
"queryParameters": []
}'
# Notification connector
curl -X POST "https://api.maitento.com/namespaces/production/connectors/mcp" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "notification-service",
"url": "https://api.notifications.example.com/send",
"description": "Send notifications to users",
"requestSchemaJson": "{\"type\":\"object\",\"properties\":{\"recipient\":{\"type\":\"string\"},\"message\":{\"type\":\"string\"},\"channel\":{\"type\":\"string\"}},\"required\":[\"recipient\",\"message\"]}",
"authenticationType": "Header",
"destructiveHint": true
}'
3. Create External Operations
# Customer lookup operation
curl -X POST "https://api.maitento.com/namespaces/production/external-operations/open-api" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "lookup-customer",
"connectorId": "CRM_CONNECTOR_ID",
"requestBindings": [],
"pathBindings": [{"target": "id", "value": "{{customer_id}}"}],
"queryBindings": [],
"authenticationHeader": {"headerName": "X-API-Key", "secretId": "CRM_SECRET_ID"},
"promptGuidance": "Look up a customer by their ID. Returns customer name, email, and account status."
}'
# Notification operation with default channel
curl -X POST "https://api.maitento.com/namespaces/production/external-operations/mcp" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "send-notification",
"connectorId": "NOTIFICATION_CONNECTOR_ID",
"requestBindings": [{"target": "channel", "value": "email"}],
"authenticationHeader": {"headerName": "Authorization", "secretId": "NOTIFICATION_SECRET_ID"},
"promptGuidance": "Send a notification to a user. Provide recipient email and message content. Default channel is email."
}'
4. Register Webhooks for Monitoring
curl -X POST "https://api.maitento.com/web-hooks" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "InteractionProcess",
"url": "https://myapp.example.com/webhooks/interactions",
"secret": "my-interaction-webhook-secret",
"headers": {}
}'
Now your agent can use lookup-customer and send-notification tools, with the bindings automatically handling authentication and default values, while your webhook monitors process progress.
Best Practices
Connector Design
- Use descriptive names that clearly indicate the service and action
- Provide comprehensive schemas for request and response validation
- Set appropriate behavioral hints on MCP connectors to guide AI behavior
- Organize by namespace to keep related connectors together
External Operations
- Pre-bind static values like API versions, format preferences, and default settings
- Write clear prompt guidance explaining when and how to use each operation
- Leverage the binding hierarchy to set defaults at operation level and override at session level
- Use template placeholders (
{{variable}}) for values that should come from the AI or runtime
Webhooks
- Verify secrets on every webhook request
- Implement idempotent handlers since retries may deliver the same event multiple times
- Respond quickly with 2xx status codes; do heavy processing asynchronously
- Monitor for delivery failures and investigate permanent failures promptly
- Use custom headers to add routing or environment information
Security
- Store credentials as secrets using Maitento’s secret management
- Rotate webhook secrets periodically
- Use HTTPS endpoints for webhook receivers
- Validate all responses against schemas to catch unexpected data