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
| Class | Purpose |
|---|---|
Tool | A callable the agent can invoke when the LLM decides to use it. Declares a JSON schema for parameters and returns a ToolResult. |
Plugin | Container that groups related tools. Provides metadata (name, version, description) and a setup() hook. |
ChannelAdapter | An inbound+outbound message bridge to an external platform. Must produce InboundMessage objects and implement send(). |
Writing a Tool
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
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:
neuralcleave-weather/
├── pyproject.toml
└── src/
└── neuralcleave_weather/
├── __init__.py
├── plugin.py ← WeatherPlugin class
└── tool.py ← WeatherTool class
# 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
# 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:
# 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
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:
# 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:
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/:
| Package | What it does |
|---|---|
neuralcleave-github | Tools for listing repos, creating issues, and reading PR diffs via GitHub REST API |
neuralcleave-notion | Tools for searching Notion pages and creating new pages |
neuralcleave-google-calendar | Tools for reading and creating Google Calendar events |