From doover-development
Search and explore existing Doover apps for integration and functionality evaluation
npx claudepluginhub getdoover/doover-skills --plugin doover-developmentThis skill uses the workspace's default tool permissions.
This skill helps you search and explore existing Doover applications to evaluate functionality, find apps for integration, and understand available components.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
This skill helps you search and explore existing Doover applications to evaluate functionality, find apps for integration, and understand available components.
The App Explorer and public API only show public and Doover core apps. Your organization may have access to additional private apps that are not listed here. Private apps are shared directly between organizations and won't appear in public searches.
To see all apps available to you, check your organization's app library in the Doover admin panel.
Browse available apps visually at:
https://admin.doover.com/app-explorer
The web interface provides:
Query apps programmatically using the public API:
GET https://api.doover.com/public/applications/
| Parameter | Default | Description |
|---|---|---|
page | 1 | Page number |
per_page | 100 | Results per page (max 100) |
curl "https://api.doover.com/public/applications/?page=1&per_page=100"
{
"count": 33,
"next": null,
"previous": null,
"results": [
{
"id": "93956442461108741",
"name": "platform_interface",
"display_name": "Platform Interface",
"description": "Core hardware I/O interface",
"long_description": "Full markdown documentation...",
"type": "DEV",
"visibility": "COR",
"allow_many": false,
"config_schema": { ... },
"depends_on": [],
"image_name": "ghcr.io/getdoover/platform_interface",
"approx_installs": 150,
"stars": 5
}
]
}
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier |
name | string | Machine-readable name (snake_case) |
display_name | string | Human-readable title |
description | string | Brief summary |
long_description | string | Full markdown documentation |
type | enum | App type (see below) |
visibility | enum | Visibility level (see below) |
allow_many | boolean | Can run multiple instances |
config_schema | object | JSON Schema for configuration |
depends_on | array | IDs of required apps |
image_name | string | Docker image path |
approx_installs | integer | Approximate install count |
stars | integer | User rating |
Doover has three types of applications:
| Type | Name | Runs On | Purpose |
|---|---|---|---|
DEV | Device App | Docker on devices | Hardware control, local logic, device UI |
PRO | Processor | Cloud (serverless) | Cloud logic triggered by channels or schedules |
INT | Integration | Cloud (serverless) | Receive external data for an organization |
DEV)Run as Docker containers on field devices. They:
PRO)Cloud-based apps triggered by:
Installed per-device, can update device UI remotely.
INT)Cloud-based apps that:
See the doover-cloud-apps skill for detailed documentation on processors and integrations.
| Visibility | Description | In Public API |
|---|---|---|
PUB | Public - available to all users | Yes |
COR | Core - system infrastructure apps | Yes |
PRI | Private - shared between specific organizations | No |
Note: Private apps (PRI) are not visible in the public API or App Explorer. They are shared directly between organizations and only accessible to authorized users.
These are foundational apps that other apps depend on:
Search the API or UI for apps by their purpose:
# Fetch all apps and filter locally
curl "https://api.doover.com/public/applications/?per_page=100" | \
jq '.results[] | select(.description | test("modbus"; "i"))'
Find apps that depend on a specific app:
import requests
response = requests.get("https://api.doover.com/public/applications/?per_page=100")
apps = response.json()["results"]
# Find apps depending on platform_interface
platform_id = "93956442461108741"
dependent_apps = [
app for app in apps
if platform_id in app.get("depends_on", [])
]
Examine config schemas to understand integration points:
# Find apps that accept application references
apps_with_app_refs = [
app for app in apps
if "doover-application" in str(app.get("config_schema", {}))
]
Config schemas use JSON Schema with Doover extensions:
{
"config_schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"pump_pin": {
"title": "Pump Output Pin",
"type": "integer",
"default": 0,
"minimum": 0,
"maximum": 31
}
},
"required": ["pump_pin"]
}
}
| Extension | Description |
|---|---|
x-name | Property identifier in code |
x-hidden | Hide from UI (true/false) |
x-required | Conditional requirement |
format: "doover-application" | Reference to another app |
format: "doover-device" | Reference to a device |
format: "doover-schedule" | Schedule configuration |
Apps can reference other apps in their config:
{
"data_logger_app": {
"title": "Data Logger Application",
"type": "string",
"format": "doover-application",
"description": "App key of the data logger to send data to"
}
}
Controls engine ignition, starter, and emergency stop:
state, run_request_reason{
"name": "small_motor_control",
"display_name": "Small Motor Control",
"depends_on": ["93956442461108741"],
"config_schema": {
"properties": {
"starter_pin": { "type": "integer" },
"ignition_pin": { "type": "integer" },
"run_sense_pins": { "type": "array" }
}
}
}
Bridges Modbus devices to Doover channels:
Complex state machine for generator management:
class MyApp(Application):
async def main_loop(self):
# Get app key from config
motor_app_key = self.config.motor_control_app.value
# Read state from motor control app
motor_state = self.get_tag("state", app_key=motor_app_key)
run_reason = self.get_tag("run_request_reason", app_key=motor_app_key)
if motor_state == "running":
await self.process_motor_running()
class CoordinatorApp(Application):
async def main_loop(self):
# Read status from multiple apps
apps = [a.value for a in self.config.managed_apps.elements]
statuses = {}
for app_key in apps:
statuses[app_key] = self.get_tag("status", app_key=app_key)
# Coordinate based on aggregate status
all_ready = all(s == "ready" for s in statuses.values())
if all_ready:
await self.start_sequence()
from pydoover.config import Schema, Application
class MyConfig(Schema):
def __init__(self):
self.motor_control_app = Application(
"Motor Control App",
description="App key of the motor control instance"
)
self.data_logger_app = Application(
"Data Logger App",
description="App key for data logging"
)
When evaluating an app for use:
Look for apps depending on Platform Interface:
curl -s "https://api.doover.com/public/applications/?per_page=100" | \
jq '[.results[] | select(.depends_on | index("93956442461108741"))] |
.[] | {name, display_name, description}'
Search for "modbus", "mqtt", "relay", "bridge" in descriptions:
curl -s "https://api.doover.com/public/applications/?per_page=100" | \
jq '.results[] | select(.description | test("modbus|mqtt|bridge"; "i")) |
{name, display_name, description}'
# Apps accepting schedule configuration
curl -s "https://api.doover.com/public/applications/?per_page=100" | \
jq '.results[] | select(.config_schema | tostring | test("doover-schedule")) |
{name, display_name}'
get_tag() with the app key to read dataThe app explorer helps you understand: