Developers
Manifest Reference
Define plugin identity, tools, configuration, authentication, and safe execution contracts.
Overview
The manifest is the public contract for your plugin. It tells KasiLabs what the plugin is, where it is hosted, what tools it exposes, how those tools should be called, and what configuration the installer must provide.
Think of the manifest as both:
- A product listing for admins deciding whether to install the plugin.
- A tool contract for the agent deciding when and how to call your endpoint.
Full structure
{
"slug": "MY_PLUGIN",
"version": "1.0.0",
"name": "My Plugin",
"description": "Short customer-facing explanation of what this plugin does.",
"author": {
"name": "Your Company",
"email": "support@example.com",
"url": "https://example.com"
},
"tags": ["support", "crm"],
"homepage": "https://example.com/plugin-docs",
"baseUrl": "https://plugins.example.com/my-plugin",
"auth": {
"type": "secret"
},
"permissions": [
{
"key": "support:tickets:create",
"label": "Create support tickets",
"description": "Allows the agent to create customer support tickets.",
"default": true
}
],
"configurationSchema": {
"type": "object",
"properties": {
"workspaceId": {
"type": "string",
"description": "Workspace to connect this plugin to."
}
},
"required": ["workspaceId"]
},
"tools": []
}Required fields
| Field | Type | Description |
|---|---|---|
slug | string | Unique uppercase identifier such as ACME_CRM |
version | string | Version number such as 1.0.0 |
name | string | Human-readable plugin name |
baseUrl | string | HTTPS base URL for tool calls |
auth | object | Authentication mode |
tools | array | Tools exposed to the agent |
Optional fields
| Field | Type | Description |
|---|---|---|
description | string | Short explanation shown during installation |
author | object | Plugin author or company details |
tags | string[] | Discovery tags such as support, orders, crm |
homepage | string | Documentation or product page |
configurationSchema | object | Installation-time configuration fields |
permissions | array | Permission requests and disclosures for the actions your plugin can perform |
Tool definition
Each tool is one specific action the AI agent can ask your plugin to perform.
For example, if a customer asks, "Where is my delivery?", the agent might call a lookup_delivery tool. If the customer says, "My order arrived damaged", the agent might call a create_support_ticket tool. The tool name, description, and input schema tell the agent when that action is appropriate and what information it must provide.
{
"name": "lookup_delivery",
"description": "Look up delivery status by order number. Use this when a customer asks where their order is, asks for delivery ETA, or provides an order reference.",
"inputSchema": {
"type": "object",
"properties": {
"orderNumber": {
"type": "string",
"description": "Customer-facing order number."
}
},
"required": ["orderNumber"]
},
"outputSchema": {
"type": "object",
"properties": {
"status": { "type": "string" },
"eta": { "type": "string" }
}
},
"endpoint": {
"method": "POST",
"path": "/execute"
}
}Permission requests
Use the top-level permissions array to declare what your plugin is asking to do. These are shown during review and installation so admins understand the authority they are giving the plugin.
There are two categories:
| Category | Example | Runtime effect |
|---|---|---|
| Plugin-owned permission | support:tickets:create | Disclosure and admin review by default; your plugin should enforce it if the external action is sensitive |
| Platform bridge permission | plugin:payments:initiate:current_chat | Enforced by KasiLabs before the platform action runs |
This means removing support:tickets:create from the manifest may not stop the create_support_ticket endpoint from running. It mainly removes the explicit declaration shown to the merchant. Removing plugin:payments:initiate:current_chat is different: the payment bridge will reject payment requests from that plugin.
{
"permissions": [
{
"key": "support:tickets:create",
"label": "Create support tickets",
"description": "Allows the agent to create customer support tickets in the connected support desk.",
"default": true
},
{
"key": "delivery:jobs:create",
"label": "Create delivery jobs",
"description": "Allows the agent to create delivery jobs after an order is confirmed paid."
}
]
}Permission keys should be namespaced to your plugin or business domain:
| Pattern | Example |
|---|---|
{domain}:{resource}:read | support:tickets:read |
{domain}:{resource}:create | support:tickets:create |
{domain}:{resource}:update | delivery:jobs:update |
{domain}:{sensitive_action}:manage | accounting:invoices:manage |
Use default: true only for permissions that are safe for most installs. Leave sensitive actions off by default so admins must deliberately grant or approve them.
Permission requests versus dependency-only platform capabilities
Plugin permissions describe what your plugin can do or request. Platform capabilities such as Payments, M-Pesa, E-Commerce, Scheduling, and Escalations are owned by KasiLabs.
For plugin-owned workflows, do not ask the merchant to expose raw platform tools to the AI just so your plugin can use them. Declare the bridge permissions your plugin needs, then call the platform bridges from your plugin backend. The platform capability acts as a dependency-only service: it is available to your plugin through signed bridge calls, but it is not necessarily visible as an agent-facing tool.
This keeps the mother app business-agnostic. A gas plugin can expose gas tools, a legal plugin can expose consultation tools, and a salon plugin can expose booking tools. The platform only enforces generic effects: catalog sync, order creation, checkout, payment, receipts, messaging, scheduling, escalation, and refunds.
If a plugin is granted E-Commerce bridge permissions for a WhatsApp number instance, raw platform commerce_* tools are hidden from that AI agent for the same instance. The agent should use the plugin's domain tools, and the plugin should use the E-Commerce bridge for durable order persistence.
Recommended pattern:
- Declare plugin-owned permissions for your own domain actions.
- Declare platform bridge permissions for platform-owned side effects.
- Make your domain plugin tools agent-facing.
- Use bridge calls for dependency-only platform actions.
- Keep payment and order state transitions idempotent and bridge-backed.
Example: a delivery plugin that should only create delivery jobs for paid orders.
{
"permissions": [
{
"key": "delivery:jobs:create",
"label": "Create delivery jobs",
"description": "Allows delivery job creation after payment is confirmed."
}
],
"tools": [
{
"name": "create_delivery_job",
"description": "Create a delivery job for a paid order. Use this only after the Payments or E-Commerce order status confirms that the order is paid.",
"inputSchema": {
"type": "object",
"properties": {
"orderNumber": {
"type": "string",
"description": "Paid customer order number."
},
"deliveryAddress": {
"type": "string",
"description": "Customer delivery address."
}
},
"required": ["orderNumber", "deliveryAddress"]
}
}
]
}The merchant grants the plugin to the WhatsApp number instance and approves the plugin permissions. Platform bridge permissions are enforced by KasiLabs when your plugin calls a bridge.
Plugins that need Payments
Plugins cannot bypass Payments permissions. If your plugin workflow collects or verifies money, request a bridge permission such as plugin:payments:initiate:current_chat or plugin:payments:status:own.
For customer-initiated WhatsApp flows, prefer current_chat. The plugin receives a short-lived current-chat token when the agent calls the plugin tool, and sends that token to the payment bridge. The plugin should not ask for or accept a typed payer phone number unless it has a separate external-recipient permission.
Example tool description:
Create an external invoice record after payment succeeds. Use this only when the payment status is successful and a payment reference is available. Do not use this to request payment or verify payment.The bridge-backed flow should be:
- The agent calls your plugin's domain tool.
- Your plugin calls the Payments bridge with the current-chat token.
- The platform creates the payment request using the active provider.
- When payment succeeds, the platform sends a payment event back to your plugin if you configured an event tool.
- The platform generates the standard receipt PDF and sends one WhatsApp document message with the receipt summary as the caption.
Plugins that need Scheduling
Plugins should not secretly schedule platform messages. If the workflow needs reminders, request plugin:messages:schedule:<scope> and use the scheduling bridge.
Example tool description:
Create an appointment record and return the appointment time. If the customer also needs a reminder, use the Scheduling toolkit after this tool returns a confirmed appointment.The bridge-backed flow should be:
- Call your plugin to book the appointment.
- Your plugin uses the Scheduling bridge to create the reminder.
- The customer receives the confirmation from the agent or from the bridge, depending on the workflow.
Plugins that need E-Commerce
If your plugin depends on order state, request E-Commerce bridge permissions. Use plugin:ecommerce:catalog:sync to let merchants import your plugin's products or services into the platform catalog, then use plugin:ecommerce:orders:create:<scope> to create durable orders from those synced items.
For delivery flows, preserve the customer address exactly. If the customer says Beth House, Kasarani, House 16, send that full string as the delivery address. Do not normalize it to only the neighborhood.
Example:
Send a paid order to the warehouse system. Use this only after the platform order/payment event shows the order is paid and ready for fulfillment.Plugins that need platform bridges
If your plugin needs KasiLabs to act outside the immediate agent conversation, use a documented platform bridge. Bridges are narrow, permission-gated endpoints for specific platform-owned actions.
Current bridge families:
| Bridge family | Use it for |
|---|---|
| Payments | Initiate payment, check payment status, request refunds |
| E-Commerce | Create durable orders, read orders, create after-sale requests |
| Messaging | Send or schedule text messages |
| Escalations | Create or assign human escalations |
| Obligations | Request reminders or escalations for external obligations |
Declare the bridge permissions your plugin needs:
{
"permissions": [
{
"key": "plugin:payments:initiate:current_chat",
"label": "Request payment from the current customer",
"description": "Allows this plugin to ask KasiLabs to create payment requests for the customer currently chatting with the granted WhatsApp number instance."
},
{
"key": "plugin:ecommerce:orders:create:current_chat",
"label": "Create orders for the current customer",
"description": "Allows this plugin to create durable orders for the customer currently chatting with the granted WhatsApp number instance."
},
{
"key": "plugin:ecommerce:checkout:initiate",
"label": "Start commerce checkout",
"description": "Allows this plugin to start checkout for an order through KasiLabs payments."
},
{
"key": "plugin:obligations:request",
"label": "Request obligation reminders",
"description": "Allows this plugin to request reminder or escalation processing for obligations it owns."
},
{
"key": "plugin:messages:send:current_chat",
"label": "Send current-customer messages",
"description": "Allows this plugin to send text messages to the customer currently chatting with the WhatsApp number instance."
},
{
"key": "plugin:messages:schedule:current_chat",
"label": "Schedule current-customer messages",
"description": "Allows this plugin to schedule text messages to the customer currently chatting with the WhatsApp number instance."
}
]
}Add only the platform permissions the plugin actually needs. See Plugin Permissions for the complete permission list.
Add only the scope the plugin needs. For example, use plugin:messages:send:known_contact if the plugin can message existing chats outside the current conversation, and plugin:messages:send:external_recipient only if it must target brand-new recipients. Use plugin:payments:refund:execute:own for refunds limited to payments created by this plugin, and plugin:payments:refund:execute:any only for broader finance workflows.
These are platform bridge permissions, not your external system permissions. They must be granted on the plugin's WhatsApp number instance grant before the bridge request will work.
You can also expose obligation tools that KasiLabs polls periodically.
{
"tools": [
{
"name": "list_due_obligations",
"description": "List due or overdue obligations that need reminder or escalation handling.",
"metadata": {
"capability": "obligations.list_due"
},
"inputSchema": {
"type": "object",
"properties": {
"now": { "type": "number" },
"limit": { "type": "number" }
}
}
},
{
"name": "record_obligation_event",
"description": "Record the result of a reminder or escalation handled by KasiLabs.",
"metadata": {
"capability": "obligations.record_event"
},
"inputSchema": {
"type": "object",
"properties": {
"obligationId": { "type": "string" },
"eventType": { "type": "string" },
"occurredAt": { "type": "number" }
},
"required": ["obligationId", "eventType"]
}
}
]
}The obligations.list_due tool lets KasiLabs ask your plugin for due work. The optional obligations.record_event tool lets KasiLabs report whether a reminder or escalation was sent, blocked, or failed.
Polling does not bypass permissions. The WhatsApp number instance grant still needs message and recipient permissions before KasiLabs sends anything.
Tool fields
| Field | Required | Description |
|---|---|---|
name | Yes | Unique tool name within the plugin |
description | Yes | Clear instruction telling the agent when to use the tool |
inputSchema | Yes | JSON Schema for tool input |
outputSchema | No | Expected response shape |
endpoint.method | No | HTTP method, normally POST |
endpoint.path | No | Path appended to baseUrl; defaults to /execute |
metadata | No | Extra plugin-owned metadata |
Writing strong tool descriptions
The description is the most important part of tool authoring. It should answer:
- What does this tool do?
- When should the agent call it?
- What customer wording should trigger it?
- What should the agent not use it for?
Good:
Create a delivery booking for a paid order. Use this only after the order is confirmed paid and the customer has provided a delivery address.Weak:
Book delivery.Do not expose internal implementation details in the description. Write for the agent and the business process.
Input schemas
Use strict inputs. The more specific the schema, the less likely the agent is to send incomplete data.
Recommended:
- Use
requiredfor fields your endpoint cannot operate without. - Add descriptions for every field.
- Use enums for controlled choices.
- Prefer customer-facing references such as order number, ticket ID, or booking ID.
- Avoid asking the agent to invent values your system should generate.
Example:
{
"type": "object",
"properties": {
"orderNumber": {
"type": "string",
"description": "Customer-facing order number."
},
"priority": {
"type": "string",
"enum": ["low", "normal", "high"]
}
},
"required": ["orderNumber"]
}Output schemas
Output schemas help document what your endpoint returns. The agent can still work with normal JSON, but consistent output improves reliability.
Return:
- Status.
- Customer-safe message.
- External reference IDs.
- Next action where helpful.
Avoid:
- Raw logs.
- Secrets.
- Stack traces.
- Large unrelated payloads.
- Internal-only configuration.
Configuration schema
Use configurationSchema when each installing organization needs its own setup.
Examples:
- Workspace ID.
- Default support queue.
- Store branch.
- Region.
- API key.
- Default delivery zone.
Example:
{
"configurationSchema": {
"type": "object",
"properties": {
"defaultQueue": {
"type": "string",
"description": "Default queue for new customer tickets."
},
"region": {
"type": "string",
"enum": ["ke", "ug", "tz"]
}
},
"required": ["defaultQueue"]
}
}Configuration values are included in the tool call context. Treat them as sensitive where appropriate.
Authentication modes
No delegated account access
Use this when your plugin only needs the installation secret and configuration.
{
"auth": {
"type": "secret"
}
}Your endpoint should verify the signed platform token on every request.
No plugin auth
Use only for harmless demos.
{
"auth": {
"type": "none"
}
}Even then, you should still inspect and verify incoming requests before taking action.
Delegated account access
Use delegated access when the customer or organization must connect an external account.
{
"auth": {
"type": "oauth2",
"authorizationUrl": "https://provider.example.com/authorize",
"tokenUrl": "https://provider.example.com/token",
"scope": ["read:tickets", "write:tickets"]
}
}The platform handles the authorization flow and includes the resulting access token in tool calls after authorization succeeds.
Request format
Tool calls are sent to:
{baseUrl}{endpoint.path}Default:
{baseUrl}/executeHeaders include:
Authorizationwith a signed platform token.Content-Type: application/json.- Optional user authorization header when delegated access is configured.
Body:
{
"tool": "lookup_delivery",
"input": {
"orderNumber": "MAT-2026-0510-0041"
},
"context": {
"organizationId": "org_123",
"instanceId": "inst_456",
"user": {
"id": "customer_hash",
"hashVersion": 1
},
"config": {
"defaultQueue": "support"
}
}
}Response format
Return JSON.
{
"status": "out_for_delivery",
"eta": "Today between 3:00 PM and 5:00 PM",
"message": "The order is out for delivery."
}For errors, use clear, safe messages:
{
"error": "not_found",
"message": "No delivery was found for that order number."
}Permissions and sensitive tools
Manifest tools can create real business side effects. Mark and design them carefully.
Sensitive examples:
- Create payout.
- Issue refund.
- Cancel order.
- Mark delivered.
- Update invoice.
- Delete customer data.
For sensitive tools:
- Use narrow descriptions.
- Require references such as paid order number or approved request ID.
- Validate business state inside your endpoint.
- Return refusal messages when policy is not met.
- Prefer dashboard approval for money movement.
Next steps
- Plugin Permissions - Declare plugin-owned and platform bridge permissions
- Platform Bridges - Use signed bridge endpoints
- Authentication - Verify platform requests and delegated access
- Testing & Debugging - Test tool calls safely
- Permissions & RBAC - Understand plugin grants and toolkit boundaries