The mesh-mongodb container goes with its Dockerfile, build bases and bus credential. Its client shelled out to mongosh, which no machine's system carries, so it now speaks to the server through the official mongodb driver its package.json names, inlined into the bundle by the builder (ADR 0198 §4); the tools answer exactly as before (relaxed Extended JSON). The server is reached on loopback at the port the machine published (${port:27017}). The root secret was owned by the mongo image's user (secrets-owner 999:999), which the runtime's account cannot read; the module's own copy is now the runtime's, and the server is given its own 999-owned copy rendered from the same secret.
52 lines
2.2 KiB
TypeScript
52 lines
2.2 KiB
TypeScript
// mongodb's tools — mongodb's own code (novox/hq ADR 0039), importing mongodb's own client. They
|
|
// return structured data; the mesh serves them through the sdk's tool harness. Both call the server
|
|
// through MongoClient, the driver inside this bundle (see client.ts).
|
|
|
|
import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools";
|
|
import { MongoClient } from "../client.js";
|
|
|
|
export function getMongoTools(mongo: MongoClient): ToolDefinition[] {
|
|
return [
|
|
{
|
|
name: "mongodb_list_databases",
|
|
description: "List the databases on the mongodb server, with their on-disk size.",
|
|
input: {},
|
|
run: async () => ({ databases: await mongo.listDatabases() }),
|
|
},
|
|
{
|
|
name: "mongodb_query",
|
|
description: "Run a read-only find against a collection in a named database and return the matching documents.",
|
|
input: {
|
|
database: { type: "string", description: "the database to query" },
|
|
collection: { type: "string", description: "the collection to read from" },
|
|
filter: { type: "object", description: "the MongoDB query filter (defaults to {} — all documents)" },
|
|
limit: { type: "number", description: "maximum documents to return (default 100, capped at 1000)" },
|
|
},
|
|
run: async (args) => {
|
|
const database = String(args.database ?? "");
|
|
const collection = String(args.collection ?? "");
|
|
if (!database) throw new Error("mongodb_query: database is required");
|
|
if (!collection) throw new Error("mongodb_query: collection is required");
|
|
const filter = isObject(args.filter) ? args.filter : {};
|
|
const limit = Number(args.limit ?? 100) || 100;
|
|
const documents = await mongo.find(database, collection, filter, limit);
|
|
return { database, collection, documents };
|
|
},
|
|
},
|
|
];
|
|
}
|
|
|
|
function isObject(v: unknown): v is Record<string, unknown> {
|
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
}
|
|
|
|
// The tools exist only when the server can be reached from the environment; without it, mongodb
|
|
// contributes none rather than failing the whole tool runtime.
|
|
registerModuleTools("mongodb", (env) => {
|
|
try {
|
|
return getMongoTools(MongoClient.fromEnv(env));
|
|
} catch {
|
|
return [];
|
|
}
|
|
});
|