Plugin SDK

NeuralCleave plugins extend the agent with new tools and channel adapters. Plugins are standard Python packages discovered via PEP 451 entry-points in the neuralcleave.plugins group. They load at startup and hot-reload at runtime.

Concepts

ClassPurpose
ToolA callable the agent can invoke when the LLM decides to use it. Declares a JSON schema for parameters and returns a ToolResult.
PluginContainer that groups related tools. Provides metadata (name, version, description) and a setup() hook.
ChannelAdapterAn inbound+outbound message bridge to an external platform. Must produce InboundMessage objects and implement send().

Writing a Tool

python
from neuralcleave_sdk import Tool, ToolResult

class WeatherTool(Tool):
    name        = "get_weather"
    description = "Get current weather for a city."
    parameters  = {
        "type": "object",
        "properties": {
            "city": {"type": "string", "description": "City name"}
        },
        "required": ["city"],
    }

    async def execute(self, city: str) -> ToolResult:
        # real implementation would call a weather API
        return ToolResult(success=True, data={"temp": "22°C", "city": city})

execute() must be async. The gateway awaits it on the event loop. Blocking I/O belongs inside asyncio.to_thread().

Writing a Plugin

python
from neuralcleave_sdk import Plugin, PluginMetadata

class WeatherPlugin(Plugin):
    metadata = PluginMetadata(
        name        = "neuralcleave-weather",
        version     = "1.0.0",
        description = "Real-time weather data via OpenWeatherMap",
        author      = "Your Name",
        tags        = ["weather", "utility"],
    )

    def get_tools(self):
        return [WeatherTool()]

    async def setup(self, config: dict):
        # called once at load time; use config to read api keys, etc.
        self.api_key = config.get("openweathermap_api_key", "")

Package layout and entry-points

Plugins are standard Python packages. The minimal layout:

text
neuralcleave-weather/
├── pyproject.toml
└── src/
    └── neuralcleave_weather/
        ├── __init__.py
        ├── plugin.py      ← WeatherPlugin class
        └── tool.py        ← WeatherTool class
toml
# pyproject.toml
[build-system]
requires      = ["setuptools>=68"]
build-backend = "setuptools.backends.legacy:build"

[project]
name    = "neuralcleave-weather"
version = "1.0.0"
dependencies = ["neuralcleave-sdk>=2.1"]

[project.entry-points."neuralcleave.plugins"]
neuralcleave_weather = "neuralcleave_weather.plugin:WeatherPlugin"
💡

The entry-point key (left of =) is free-form but must be unique. The gateway loads all packages in the neuralcleave.plugins group automatically at startup.

Installing a plugin

bash
# From PyPI
pip install neuralcleave-weather

# From a local path (editable, great for development)
pip install -e ./neuralcleave-weather

# Via CLI (downloads from Hub registry)
neuralcleave plugins install neuralcleave-weather

Hot-reload

Reload all plugins without restarting the gateway:

bash
# CLI
neuralcleave plugins reload

# REST API
curl -X POST http://localhost:7432/api/v1/plugins/reload \
     -H "X-API-Key: $NC_API_KEY"

Writing a ChannelAdapter

python
from neuralcleave_sdk import ChannelAdapter
from neuralcleave.channels.models import InboundMessage
import asyncio

class MyChannelAdapter(ChannelAdapter):
    channel_name = "mychannel"

    async def start(self):
        # start polling / long-poll / webhook listener
        while True:
            raw = await self._poll()
            msg = InboundMessage(
                channel    = "mychannel",
                sender_id  = raw["from"],
                text       = raw["body"],
                session_id = raw["from"],
            )
            await self.on_message(msg)

    async def send(self, target: str, text: str) -> None:
        # send outbound reply
        await self._api_post(target, text)

Hub marketplace

The Hub is the curated registry for NeuralCleave plugins. Browse, install, and manage packages:

bash
# Browse available packages
neuralcleave hub list

# Search
neuralcleave hub search weather

# Install (downloads, installs pip package, and hot-reloads)
neuralcleave hub install neuralcleave-weather

# Enable / disable without uninstalling
neuralcleave hub toggle neuralcleave-weather

# Uninstall
neuralcleave hub uninstall neuralcleave-weather

PackageScanner

Before Hub installation, the PackageScanner performs a static safety scan on the package source. The scan flags known dangerous patterns (subprocess with user input, eval/exec, outbound connections to non-whitelisted hosts). Packages that fail the scan are rejected with a report. You can also invoke the scanner via the REST API:

bash
curl -X POST http://localhost:7432/api/v1/hub/scan \
  -H "Content-Type: application/json" \
  -d '{"code": "import subprocess; subprocess.run(input())"}'

Example plugins

Three reference implementations are in the repository under examples/plugins/:

PackageWhat it does
neuralcleave-githubTools for listing repos, creating issues, and reading PR diffs via GitHub REST API
neuralcleave-notionTools for searching Notion pages and creating new pages
neuralcleave-google-calendarTools for reading and creating Google Calendar events