mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-15 20:17:22 +00:00
auto generated tools docs, added stdio transport, added additional mcp config and permissions
This commit is contained in:
@@ -13,10 +13,12 @@ export default async function Page(props: {
|
||||
if (!page) notFound();
|
||||
|
||||
const MDXContent = page.data.body;
|
||||
// in case a page exports a custom toc
|
||||
const toc = (page.data as any).custom_toc ?? page.data.toc;
|
||||
|
||||
return (
|
||||
<DocsPage
|
||||
toc={page.data.toc}
|
||||
toc={toc}
|
||||
full={page.data.full}
|
||||
tableOfContent={{
|
||||
style: "clerk",
|
||||
|
||||
55
docs/components/McpTool.tsx
Normal file
55
docs/components/McpTool.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import type { Tool } from "jsonv-ts/mcp";
|
||||
import components from "fumadocs-ui/mdx";
|
||||
import { TypeTable } from "fumadocs-ui/components/type-table";
|
||||
import { DynamicCodeBlock } from "fumadocs-ui/components/dynamic-codeblock";
|
||||
|
||||
import type { JSONSchemaDefinition } from "jsonv-ts";
|
||||
|
||||
export const slugify = (s: string) => s.toLowerCase().replace(/ /g, "-");
|
||||
export const indent = (s: string, indent = 2) => s.replace(/^/gm, " ".repeat(indent));
|
||||
|
||||
export function McpTool({ tool }: { tool: ReturnType<Tool["toJSON"]> }) {
|
||||
return (
|
||||
<div>
|
||||
<components.h3 id={slugify(tool.name)}>
|
||||
<code>{tool.name}</code>
|
||||
</components.h3>
|
||||
<p>{tool.description}</p>
|
||||
|
||||
<JsonSchemaTypeTable schema={tool.inputSchema} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function JsonSchemaTypeTable({ schema }: { schema: JSONSchemaDefinition }) {
|
||||
const properties = schema.properties ?? {};
|
||||
const required = schema.required ?? [];
|
||||
const getTypeDescription = (value: any) =>
|
||||
JSON.stringify(
|
||||
{
|
||||
...value,
|
||||
$target: undefined,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
|
||||
return Object.keys(properties).length > 0 ? (
|
||||
<TypeTable
|
||||
type={Object.fromEntries(
|
||||
Object.entries(properties).map(([key, value]: [string, JSONSchemaDefinition]) => [
|
||||
key,
|
||||
{
|
||||
description: value.description,
|
||||
typeDescription: (
|
||||
<DynamicCodeBlock lang="json" code={indent(getTypeDescription(value), 1)} />
|
||||
),
|
||||
type: value.type,
|
||||
default: value.default ? JSON.stringify(value.default) : undefined,
|
||||
required: required.includes(key),
|
||||
},
|
||||
]),
|
||||
)}
|
||||
/>
|
||||
) : null;
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
"./integration/(runtimes)/",
|
||||
"---Modules---",
|
||||
"./modules/overview",
|
||||
"./modules/server",
|
||||
"./modules/server/",
|
||||
"./modules/data",
|
||||
"./modules/auth",
|
||||
"./modules/media",
|
||||
|
||||
361
docs/content/docs/(documentation)/modules/server/mcp.mdx
Normal file
361
docs/content/docs/(documentation)/modules/server/mcp.mdx
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"pages": ["overview", "mcp"]
|
||||
}
|
||||
3047
docs/mcp.json
Normal file
3047
docs/mcp.json
Normal file
File diff suppressed because it is too large
Load Diff
26
docs/package-lock.json
generated
26
docs/package-lock.json
generated
@@ -6,7 +6,6 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "bknd-docs",
|
||||
"version": "0.0.0",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@iconify/react": "^6.0.0",
|
||||
@@ -36,6 +35,7 @@
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "15.3.5",
|
||||
"fumadocs-docgen": "^2.1.0",
|
||||
"jsonv-ts": "^0.7.0",
|
||||
"postcss": "^8.5.6",
|
||||
"rimraf": "^6.0.1",
|
||||
"tailwindcss": "^4.1.11",
|
||||
@@ -6816,6 +6816,17 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/hono": {
|
||||
"version": "4.9.0",
|
||||
"resolved": "https://registry.npmjs.org/hono/-/hono-4.9.0.tgz",
|
||||
"integrity": "sha512-JAUc4Sqi3lhby2imRL/67LMcJFKiCu7ZKghM7iwvltVZzxEC5bVJCsAa4NTnSfmWGb+N2eOVtFE586R+K3fejA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/html-void-elements": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz",
|
||||
@@ -7525,6 +7536,19 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonv-ts": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonv-ts/-/jsonv-ts-0.7.0.tgz",
|
||||
"integrity": "sha512-zN5/KMs1WOs+0IbYiZF7mVku4dum8LKP9xv8VqgVm+PBz5VZuU1V8iLQhI991ogUbhGHHlOCwqxnxQUuvCPbQA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optionalDependencies": {
|
||||
"hono": "*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jsx-ast-utils": {
|
||||
"version": "3.3.5",
|
||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"dev:turbo": "next dev --turbo",
|
||||
"build": "bun generate:openapi && next build",
|
||||
"build": "bun generate:openapi && bun generate:mcp && next build",
|
||||
"start": "next start",
|
||||
"generate:openapi": "bun scripts/generate-openapi.mjs",
|
||||
"generate:mcp": "bun scripts/generate-mcp.ts",
|
||||
"postinstall": "fumadocs-mdx",
|
||||
"preview": "npm run build && wrangler dev",
|
||||
"cf:preview": "wrangler dev",
|
||||
@@ -42,6 +43,7 @@
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "15.3.5",
|
||||
"fumadocs-docgen": "^2.1.0",
|
||||
"jsonv-ts": "^0.7.0",
|
||||
"postcss": "^8.5.6",
|
||||
"rimraf": "^6.0.1",
|
||||
"tailwindcss": "^4.1.11",
|
||||
|
||||
65
docs/scripts/generate-mcp.ts
Normal file
65
docs/scripts/generate-mcp.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import type { Tool, Resource } from "jsonv-ts/mcp";
|
||||
import { rimraf } from "rimraf";
|
||||
|
||||
const config = {
|
||||
mcpConfig: "./mcp.json",
|
||||
outFile: "./content/docs/(documentation)/modules/server/mcp.mdx",
|
||||
};
|
||||
|
||||
async function generate() {
|
||||
console.info("Generating MCP documentation...");
|
||||
await cleanup();
|
||||
const mcpConfig = await Bun.file(config.mcpConfig).json();
|
||||
const document = await generateDocument(mcpConfig);
|
||||
await Bun.write(config.outFile, document);
|
||||
console.info("MCP documentation generated.");
|
||||
}
|
||||
|
||||
async function generateDocument({
|
||||
tools,
|
||||
resources,
|
||||
}: {
|
||||
tools: ReturnType<Tool["toJSON"]>[];
|
||||
resources: ReturnType<Resource["toJSON"]>[];
|
||||
}) {
|
||||
return `---
|
||||
title: "MCP"
|
||||
description: "Built-in full featured MCP server."
|
||||
tags: ["documentation"]
|
||||
---
|
||||
import { JsonSchemaTypeTable } from '@/components/McpTool';
|
||||
|
||||
## Tools
|
||||
|
||||
${tools
|
||||
.map(
|
||||
(t) => `
|
||||
### ${t.name}
|
||||
|
||||
${t.description ?? ""}
|
||||
|
||||
<JsonSchemaTypeTable schema={${JSON.stringify(t.inputSchema)}} key={"${String(t.name)}"} />`,
|
||||
)
|
||||
.join("\n")}
|
||||
|
||||
|
||||
## Resources
|
||||
|
||||
${resources
|
||||
.map(
|
||||
(r) => `
|
||||
|
||||
### ${r.name}
|
||||
|
||||
${r.description ?? ""}
|
||||
`,
|
||||
)
|
||||
.join("\n")}
|
||||
`;
|
||||
}
|
||||
|
||||
async function cleanup() {
|
||||
await rimraf(config.outFile);
|
||||
}
|
||||
|
||||
void generate();
|
||||
Reference in New Issue
Block a user