mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 12:37:20 +00:00
initialized mcp support
This commit is contained in:
@@ -6,3 +6,4 @@ export { user } from "./user";
|
||||
export { create } from "./create";
|
||||
export { copyAssets } from "./copy-assets";
|
||||
export { types } from "./types";
|
||||
export { mcp } from "./mcp/mcp";
|
||||
|
||||
97
app/src/cli/commands/mcp/mcp.ts
Normal file
97
app/src/cli/commands/mcp/mcp.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import type { CliCommand } from "cli/types";
|
||||
import { makeAppFromEnv } from "../run";
|
||||
import { s } from "bknd/utils";
|
||||
import { ObjectToolSchema } from "modules/mcp";
|
||||
import { serve } from "@hono/node-server";
|
||||
import { Hono } from "hono";
|
||||
import { mcp as mcpMiddleware, McpServer, Resource } from "jsonv-ts/mcp";
|
||||
import type { Module } from "modules/Module";
|
||||
|
||||
export const mcp: CliCommand = (program) =>
|
||||
program
|
||||
.command("mcp")
|
||||
.description("mcp server")
|
||||
.option("--port <port>", "port to listen on", "3000")
|
||||
.option("--path <path>", "path to listen on", "/mcp")
|
||||
.action(action);
|
||||
|
||||
async function action(options: { port: string; path: string }) {
|
||||
const app = await makeAppFromEnv({
|
||||
server: "node",
|
||||
});
|
||||
|
||||
const appConfig = app.modules.configs();
|
||||
const { version, ...appSchema } = app.getSchema();
|
||||
|
||||
const schema = s.strictObject(appSchema);
|
||||
|
||||
const nodes = [...schema.walk({ data: appConfig })].filter(
|
||||
(n) => n.schema instanceof ObjectToolSchema,
|
||||
) as s.Node<ObjectToolSchema>[];
|
||||
const tools = [...nodes.flatMap((n) => n.schema.getTools(n)), ...app.modules.ctx().mcp.tools];
|
||||
const resources = [...app.modules.ctx().mcp.resources];
|
||||
|
||||
const server = new McpServer(
|
||||
{
|
||||
name: "bknd",
|
||||
version: "0.0.1",
|
||||
},
|
||||
{ app, ctx: () => app.modules.ctx() },
|
||||
tools,
|
||||
resources,
|
||||
);
|
||||
server
|
||||
.resource("system_config", "bknd://system/config", (c) =>
|
||||
c.json(c.context.app.toJSON(), {
|
||||
title: "System Config",
|
||||
}),
|
||||
)
|
||||
.resource(
|
||||
"system_config_module",
|
||||
"bknd://system/config/{module}",
|
||||
(c, { module }) => {
|
||||
const m = c.context.app.modules.get(module as any) as Module;
|
||||
return c.json(m.toJSON(), {
|
||||
title: `Config for ${module}`,
|
||||
});
|
||||
},
|
||||
{
|
||||
list: Object.keys(appConfig),
|
||||
},
|
||||
)
|
||||
.resource("system_schema", "bknd://system/schema", (c) =>
|
||||
c.json(c.context.app.getSchema(), {
|
||||
title: "System Schema",
|
||||
}),
|
||||
)
|
||||
.resource(
|
||||
"system_schema_module",
|
||||
"bknd://system/schema/{module}",
|
||||
(c, { module }) => {
|
||||
const m = c.context.app.modules.get(module as any);
|
||||
return c.json(m.getSchema().toJSON(), {
|
||||
title: `Schema for ${module}`,
|
||||
});
|
||||
},
|
||||
{
|
||||
list: Object.keys(appSchema),
|
||||
},
|
||||
);
|
||||
|
||||
const hono = new Hono().use(
|
||||
mcpMiddleware({
|
||||
server,
|
||||
endpoint: {
|
||||
path: String(options.path) as any,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
serve({
|
||||
fetch: hono.fetch,
|
||||
port: Number(options.port) || 3000,
|
||||
});
|
||||
console.info(`Server is running on http://localhost:${options.port}${options.path}`);
|
||||
console.info(`⚙️ Tools:\n${server.tools.map((t) => `- ${t.name}`).join("\n")}\n`);
|
||||
console.info(`📚 Resources:\n${server.resources.map((r) => `- ${r.name}`).join("\n")}`);
|
||||
}
|
||||
Reference in New Issue
Block a user