Files

81 lines
3.4 KiB
TypeScript

// minio's tools — ported here from the shared sdk (novox/hq ADR 0039), importing minio's own client.
// They return structured data; the mesh serves them through the sdk's tool harness. These are the
// read/inspect operations useful to an operator; creating storage for a consumer is the provisioner's
// job, not a tool's.
import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools";
import { MinioClient } from "../client.js";
export function getMinioTools(minio: MinioClient): ToolDefinition[] {
return [
{
name: "minio_list_buckets",
description: "List every S3 bucket in the object store, with creation dates.",
input: {},
run: async () => {
const buckets = await minio.listBuckets();
return {
count: buckets.length,
buckets: buckets.map((b) => ({ name: b.name, createdAt: b.creationDate?.toISOString() })),
};
},
},
{
name: "minio_list_objects",
description: "List objects in a bucket, optionally under a prefix.",
input: {
bucket: { type: "string", description: "the bucket name" },
prefix: { type: "string", description: "only keys under this prefix (e.g. 'photos/')" },
recursive: { type: "boolean", description: "descend into nested prefixes (default false)" },
limit: { type: "number", description: "max keys to return (default 100)" },
},
run: async (args) => {
const bucket = String(args.bucket);
const objects = await minio.listObjects(
bucket,
args.prefix ? String(args.prefix) : "",
Boolean(args.recursive),
args.limit ? Number(args.limit) : 100,
);
return {
bucket,
count: objects.length,
objects: objects.map((o) => ({ key: o.name, size: o.size, lastModified: o.lastModified.toISOString(), etag: o.etag })),
};
},
},
{
name: "minio_bucket_info",
description: "Summary of one bucket: whether it exists, its region, and a sampled object count and size.",
input: { bucket: { type: "string", description: "the bucket name" } },
run: async (args) => minio.bucketInfo(String(args.bucket)),
},
{
name: "minio_presigned_url",
description: "A time-limited URL to download (GET) or upload (PUT) one object without credentials.",
input: {
bucket: { type: "string", description: "the bucket name" },
object: { type: "string", description: "the object key" },
method: { type: "string", description: "'GET' to download (default) or 'PUT' to upload" },
expires: { type: "number", description: "seconds until the URL expires (default 86400 = 24h)" },
},
run: async (args) => {
const method = String(args.method ?? "GET").toUpperCase() === "PUT" ? "PUT" : "GET";
const expires = args.expires ? Number(args.expires) : 86400;
const url = minio.presignedUrl(method, String(args.bucket), String(args.object), expires);
return { method, bucket: String(args.bucket), object: String(args.object), expiresInSeconds: expires, url };
},
},
];
}
// The tools exist only when the object store is configured and reachable; without it minio
// contributes none rather than failing the whole tool runtime.
registerModuleTools("minio", (env) => {
try {
return getMinioTools(MinioClient.fromEnv(env));
} catch {
return [];
}
});