registry (docker v2): catalog/tags/delete tools, emits image.pushed (a build's image is now pullable). verdaccio (npm): list/info tools, emits package.published. portainer: endpoints/stacks/containers tools — tools-only, since its only events are the underlying containers' lifecycle, which the host owns. Typecheck; manifests parse.
51 lines
1.9 KiB
TypeScript
51 lines
1.9 KiB
TypeScript
// portainer's tools — its own code (novox/hq ADR 0044), importing portainer's own client. They
|
|
// return structured data; the mesh serves them through the sdk's tool harness. portainer is
|
|
// tools-only (no events entrypoint): a container starting or stopping is the host's signal to emit,
|
|
// not Portainer's to re-announce.
|
|
|
|
import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools";
|
|
import { PortainerClient } from "../client.js";
|
|
|
|
export function getPortainerTools(portainer: PortainerClient): ToolDefinition[] {
|
|
return [
|
|
{
|
|
name: "portainer_endpoints",
|
|
description: "List the environments (endpoints) Portainer manages — each a Docker host or cluster.",
|
|
input: {},
|
|
run: async () => {
|
|
const endpoints = await portainer.listEndpoints();
|
|
return { count: endpoints.length, endpoints };
|
|
},
|
|
},
|
|
{
|
|
name: "portainer_stacks",
|
|
description: "List the stacks (compose/swarm deployments) Portainer knows about.",
|
|
input: {},
|
|
run: async () => {
|
|
const stacks = await portainer.listStacks();
|
|
return { count: stacks.length, stacks };
|
|
},
|
|
},
|
|
{
|
|
name: "portainer_containers",
|
|
description: "List the containers on one Portainer endpoint, including stopped ones.",
|
|
input: { endpoint: { type: "number", description: "the endpoint id (see portainer_endpoints)" } },
|
|
run: async (args) => {
|
|
const endpointId = Number(args.endpoint);
|
|
const containers = await portainer.listContainers(endpointId);
|
|
return { endpointId, count: containers.length, containers };
|
|
},
|
|
},
|
|
];
|
|
}
|
|
|
|
// The tools exist only when a token is configured; without one, portainer contributes none rather
|
|
// than failing the whole runtime.
|
|
registerModuleTools("portainer", (env) => {
|
|
try {
|
|
return getPortainerTools(PortainerClient.fromEnv(env));
|
|
} catch {
|
|
return [];
|
|
}
|
|
});
|