Create New Module
Use this when adding a new integration like ClickHouse, Prometheus, Loki, Dora, or Ethnode.
The architecture is module + server operations, not plugins + bespoke proxy endpoints.
Files To Create
Create the module folder:
modules/{name}/
├── config.go
├── module.go
├── examples.go
├── examples.yaml
└── python/{name}.py
Add these when needed:
resources.go for custom MCP resources
- helper files for schemas, discovery, or API clients
pkg/proxy/handlers/{name}_operations.go
pkg/proxy/handlers/{name}_operations_test.go
Copy From
modules/prometheus/ or modules/loki/ for simple JSON passthrough APIs
modules/clickhouse/ for streamed table results and datasource discovery
modules/dora/ or modules/ethnode/ for external HTTP APIs with curated helpers
Required Wiring
pkg/app/app.go
Add reg.Add({name}module.New()) in buildModuleRegistry().
pkg/server/operations_<domain>.go
Add new server-owned operation handling for the module.
pkg/server/operations_dispatch.go
Wire the module's handler into dispatch.
pkg/proxy/server_config.go
Add proxy server config translation only if the module needs proxy-held credentials or typed proxy config.
sandbox/ethpandaops/ethpandaops/__init__.py
Add the lazy import if the module exposes a Python module.
sandbox/Dockerfile
Copy modules/{name}/python/{name}.py into the installed ethpandaops package.
Architecture Rules
- Do not add a new MCP tool. MCP stays limited to platform primitives.
- Module semantics live in Go.
- Python wrappers stay thin and go through
sandbox/ethpandaops/ethpandaops/_runtime.py.
- Default remote execution path is
POST /api/v1/operations/{module.operation}.
- Server operation handlers own validation, defaults, routing, and error mapping.
- Upstream-backed bulk data must stay passthrough when possible.
Do not materialize large tables into row-object JSON in the server.
- Small synthetic/object operations can still return the JSON envelope.
- Credentials never go into the sandbox. Only metadata and server runtime tokens do.
Module Contract
Implement module.Module from pkg/module/module.go and only the optional capability interfaces you need:
- base lifecycle:
Name, Init, ApplyDefaults, Validate, Start, Stop
- optional capabilities:
SandboxEnvProvider, DatasourceInfoProvider, ExamplesProvider, PythonAPIDocsProvider, ResourceProvider
Python Rules
- Keep Python ergonomic, not semantic.
clickhouse.query(...) style wrappers should call _runtime helpers and parse only at the edge.
- If the operation returns bulk tables, prefer streaming formats like TSV instead of normalized JSON rows.
- If the operation already returns useful upstream JSON, return that JSON rather than reshaping it in Python.
CLI Rules
- Module-specific CLI commands should be thin adapters over server operations.
- Do not duplicate validation/default logic already implemented in the server operation handler.
- Pretty-printing belongs in CLI; semantic behavior does not.
Checklist
1---2name: create-module3description: Add a new datasource module to ethpandaops/panda. Triggers on: add module, new module, create module, add plugin, new plugin, create plugin, add datasource.4---56# Create New Module78Use this when adding a new integration like ClickHouse, Prometheus, Loki, Dora, or Ethnode.9The architecture is **module + server operations**, not plugins + bespoke proxy endpoints.1011## Files To Create1213Create the module folder:1415```text16modules/{name}/17├── config.go18├── module.go19├── examples.go20├── examples.yaml21└── python/{name}.py22```2324Add these when needed:25- `resources.go` for custom MCP resources26- helper files for schemas, discovery, or API clients27- `pkg/proxy/handlers/{name}_operations.go`28- `pkg/proxy/handlers/{name}_operations_test.go`2930## Copy From3132- `modules/prometheus/` or `modules/loki/` for simple JSON passthrough APIs33- `modules/clickhouse/` for streamed table results and datasource discovery34- `modules/dora/` or `modules/ethnode/` for external HTTP APIs with curated helpers3536## Required Wiring37381. `pkg/app/app.go`39 Add `reg.Add({name}module.New())` in `buildModuleRegistry()`.402. `pkg/server/operations_<domain>.go`41 Add new server-owned operation handling for the module.423. `pkg/server/operations_dispatch.go`43 Wire the module's handler into dispatch.444. `pkg/proxy/server_config.go`45 Add proxy server config translation only if the module needs proxy-held credentials or typed proxy config.465. `sandbox/ethpandaops/ethpandaops/__init__.py`47 Add the lazy import if the module exposes a Python module.486. `sandbox/Dockerfile`49 Copy `modules/{name}/python/{name}.py` into the installed `ethpandaops` package.5051## Architecture Rules5253- Do **not** add a new MCP tool. MCP stays limited to platform primitives.54- Module semantics live in Go.55- Python wrappers stay thin and go through `sandbox/ethpandaops/ethpandaops/_runtime.py`.56- Default remote execution path is `POST /api/v1/operations/{module.operation}`.57- Server operation handlers own validation, defaults, routing, and error mapping.58- Upstream-backed bulk data must stay passthrough when possible.59 Do not materialize large tables into row-object JSON in the server.60- Small synthetic/object operations can still return the JSON envelope.61- Credentials never go into the sandbox. Only metadata and server runtime tokens do.6263## Module Contract6465Implement `module.Module` from `pkg/module/module.go` and only the optional capability interfaces you need:66- base lifecycle: `Name`, `Init`, `ApplyDefaults`, `Validate`, `Start`, `Stop`67- optional capabilities: `SandboxEnvProvider`, `DatasourceInfoProvider`, `ExamplesProvider`, `PythonAPIDocsProvider`, `ResourceProvider`6869## Python Rules7071- Keep Python ergonomic, not semantic.72- `clickhouse.query(...)` style wrappers should call `_runtime` helpers and parse only at the edge.73- If the operation returns bulk tables, prefer streaming formats like TSV instead of normalized JSON rows.74- If the operation already returns useful upstream JSON, return that JSON rather than reshaping it in Python.7576## CLI Rules7778- Module-specific CLI commands should be thin adapters over server operations.79- Do not duplicate validation/default logic already implemented in the server operation handler.80- Pretty-printing belongs in CLI; semantic behavior does not.8182## Checklist8384- [ ] New module implements `module.Module`85- [ ] Examples and Python API docs are added86- [ ] Server operation handler is wired into `pkg/server/operations_dispatch.go`87- [ ] No new MCP tool was added88- [ ] Python module is thin and copied via `sandbox/Dockerfile`89- [ ] CLI, if added, calls operations instead of bespoke transport logic90- [ ] `go test ./...` passes91- [ ] `python3 -m py_compile ...` passes for touched Python files92- [ ] `make docker-sandbox` builds if sandbox files changed