Skip to content

Building a Custom Integration

If the built-in integrations don't cover the system you need, you can build your own.


Architecture

Integrations in DMOps.ai follow the provider pattern:

  1. A Python class extending IntegrationProvider defines the tools the agent can call
  2. The provider is registered in the integration registry
  3. The acp-tools Hermes plugin auto-discovers registered providers and makes their tools available to agents at runtime

Creating a provider

Create a new file in src/api/integrations/<your_system>.py:

python
from integrations.base import IntegrationProvider, ToolDef, ToolResult

class MySystemProvider(IntegrationProvider):
    kind = "my_system"
    name = "My System"
    description = "Connect agents to My System for reading and writing records."

    def get_tools(self) -> list[ToolDef]:
        return [
            ToolDef(
                name="my_system_search",
                description=(
                    "Search My System records by keyword. "
                    "Returns a list of matching records with id, name, and status."
                ),
                parameters={
                    "type": "object",
                    "properties": {
                        "query": {
                            "type": "string",
                            "description": "Search keyword"
                        }
                    },
                    "required": ["query"]
                }
            )
        ]

    def call_tool(self, tool_name: str, args: dict, credentials: dict) -> ToolResult:
        if tool_name == "my_system_search":
            # Use credentials["api_key"] to authenticate
            # Call the external API
            results = self._search(credentials["api_key"], args["query"])
            return ToolResult(content=str(results))
        raise ValueError(f"Unknown tool: {tool_name}")

Registering the provider

Add your provider to src/api/integrations/registry.py:

python
from integrations.my_system import MySystemProvider
register_provider(MySystemProvider.kind, MySystemProvider)

Adding the seed function

Add a seed function in src/api/acp_integrations.py that creates the integration record in the database on startup:

python
def seed_my_system_integration(conn) -> None:
    conn.execute("""
        INSERT OR IGNORE INTO integrations (kind, name, description, credential_schema)
        VALUES (?, ?, ?, ?)
    """, (
        "my_system",
        "My System",
        "Connect agents to My System.",
        json.dumps({"api_key": {"type": "string", "label": "API Key", "secret": True}})
    ))

Call it from the api_server.py lifespan.


Credential schema

The credential_schema JSON tells the admin UI what fields to show when configuring the integration. Supported field types: string, password (hidden), url, boolean.


Testing your integration

  1. Restart the API server to pick up the new provider
  2. Navigate to Settings → Integrations — your new integration should appear
  3. Enter test credentials and click Test Connection
  4. Grant the integration to a test agent and run a task that invokes the tool

Tool description guidelines

See docs/integration-tool-guidelines.md for the full ToolDef description rules. Key rules:

  • Every tool needs a description explaining what it does AND what it returns
  • Every argument needs a description
  • Tools that need schema discovery must include a SCHEMA RULE referencing the discovery tool