81 lines
3.4 KiB
TypeScript
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 [];
|
|
}
|
|
});
|