@faapi/schema 0.0.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +18 -0
- package/dist/index.js +180 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PluginContext } from '@faapi/faapi';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* faapi 插件入口
|
|
5
|
+
*
|
|
6
|
+
* 在 faapi.config.ts 中声明:
|
|
7
|
+
* ```ts
|
|
8
|
+
* export default {
|
|
9
|
+
* plugins: ['@faapi/schema'],
|
|
10
|
+
* } satisfies FaapiConfig;
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
declare const _default: {
|
|
14
|
+
name: string;
|
|
15
|
+
setup(ctx: PluginContext): void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { _default as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// src/schemaServer.ts
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
// src/routeSchema.ts
|
|
7
|
+
import path from "path";
|
|
8
|
+
import {
|
|
9
|
+
getSchemaProperties,
|
|
10
|
+
getInputTypeForMethod
|
|
11
|
+
} from "@faapi/faapi";
|
|
12
|
+
function buildRouteSchemas(routes, rootDir) {
|
|
13
|
+
return routes.map((route) => {
|
|
14
|
+
const absoluteFilePath = path.resolve(rootDir, route.filePath);
|
|
15
|
+
const inputs = extractInputSchemas(absoluteFilePath, route.method, route);
|
|
16
|
+
return {
|
|
17
|
+
method: route.method,
|
|
18
|
+
path: route.urlPath,
|
|
19
|
+
filePath: route.filePath,
|
|
20
|
+
isDynamic: route.isDynamic,
|
|
21
|
+
inputs
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function extractInputSchemas(filePath, method, route) {
|
|
26
|
+
const inputs = [];
|
|
27
|
+
const inputType = getInputTypeForMethod(method);
|
|
28
|
+
const schema = getSchemaProperties(filePath, method, inputType);
|
|
29
|
+
if (schema) {
|
|
30
|
+
inputs.push({
|
|
31
|
+
source: inputType,
|
|
32
|
+
schemaName: schema.schemaName,
|
|
33
|
+
properties: schema.properties
|
|
34
|
+
});
|
|
35
|
+
} else {
|
|
36
|
+
inputs.push({
|
|
37
|
+
source: inputType,
|
|
38
|
+
schemaName: null,
|
|
39
|
+
properties: []
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (route.isDynamic && route.paramNames.length > 0) {
|
|
43
|
+
const paramsSchema = getSchemaProperties(filePath, method, "params");
|
|
44
|
+
const paramsProps = paramsSchema && paramsSchema.schemaName ? paramsSchema.properties : route.paramNames.map((name) => ({
|
|
45
|
+
name,
|
|
46
|
+
type: "string",
|
|
47
|
+
required: true
|
|
48
|
+
}));
|
|
49
|
+
inputs.push({
|
|
50
|
+
source: "params",
|
|
51
|
+
schemaName: paramsSchema?.schemaName ?? null,
|
|
52
|
+
properties: paramsProps
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return inputs;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/schemaServer.ts
|
|
59
|
+
function isSchemaEnabled() {
|
|
60
|
+
const envValue = process.env.FAAPI_SCHEMA;
|
|
61
|
+
if (envValue === "1" || envValue === "true") return true;
|
|
62
|
+
if (envValue === "0" || envValue === "false") return false;
|
|
63
|
+
return process.env.NODE_ENV !== "production";
|
|
64
|
+
}
|
|
65
|
+
function createSchemaServer(routes, rootDir) {
|
|
66
|
+
const server = new McpServer({
|
|
67
|
+
name: "faapi-schema",
|
|
68
|
+
version: "0.0.1"
|
|
69
|
+
});
|
|
70
|
+
let cachedSchemas = null;
|
|
71
|
+
function getSchemas() {
|
|
72
|
+
if (!cachedSchemas) {
|
|
73
|
+
cachedSchemas = buildRouteSchemas(routes, rootDir);
|
|
74
|
+
}
|
|
75
|
+
return cachedSchemas;
|
|
76
|
+
}
|
|
77
|
+
server.tool(
|
|
78
|
+
"list_routes",
|
|
79
|
+
"\u5217\u51FA\u5F53\u524D faapi \u5E94\u7528\u7684\u6240\u6709 API \u8DEF\u7531\uFF0C\u5305\u62EC\u65B9\u6CD5\u3001\u8DEF\u5F84\u3001\u662F\u5426\u52A8\u6001\u8DEF\u7531",
|
|
80
|
+
{},
|
|
81
|
+
() => {
|
|
82
|
+
const schemas = getSchemas();
|
|
83
|
+
const routesList = schemas.map((r) => ({
|
|
84
|
+
method: r.method,
|
|
85
|
+
path: r.path,
|
|
86
|
+
isDynamic: r.isDynamic,
|
|
87
|
+
filePath: r.filePath
|
|
88
|
+
}));
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
{
|
|
92
|
+
type: "text",
|
|
93
|
+
text: JSON.stringify(routesList, null, 2)
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
server.tool(
|
|
100
|
+
"get_route_schema",
|
|
101
|
+
"\u83B7\u53D6\u6307\u5B9A\u8DEF\u7531\u7684\u8BE6\u7EC6\u63A5\u53E3\u4FE1\u606F\uFF0C\u5305\u62EC\u8F93\u5165\u53C2\u6570\u7684\u540D\u79F0\u3001\u7C7B\u578B\u3001\u662F\u5426\u5FC5\u586B",
|
|
102
|
+
{
|
|
103
|
+
method: z.string().describe("HTTP \u65B9\u6CD5\uFF0C\u5982 GET\u3001POST"),
|
|
104
|
+
path: z.string().describe("\u8DEF\u7531\u8DEF\u5F84\uFF0C\u5982 /auth/login")
|
|
105
|
+
},
|
|
106
|
+
({ method, path: path2 }) => {
|
|
107
|
+
const schemas = getSchemas();
|
|
108
|
+
const route = schemas.find((r) => r.method === method.toUpperCase() && r.path === path2);
|
|
109
|
+
if (!route) {
|
|
110
|
+
return {
|
|
111
|
+
content: [
|
|
112
|
+
{
|
|
113
|
+
type: "text",
|
|
114
|
+
text: JSON.stringify({ error: `\u672A\u627E\u5230\u8DEF\u7531 ${method.toUpperCase()} ${path2}` })
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
content: [
|
|
121
|
+
{
|
|
122
|
+
type: "text",
|
|
123
|
+
text: JSON.stringify(route, null, 2)
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
server.tool(
|
|
130
|
+
"get_api_schema",
|
|
131
|
+
"\u83B7\u53D6\u5F53\u524D\u5E94\u7528\u6240\u6709\u63A5\u53E3\u7684\u5B8C\u6574 schema\uFF0C\u7C7B\u4F3C OpenAPI \u89C4\u8303\uFF0C\u5305\u542B\u6BCF\u4E2A\u8DEF\u7531\u7684\u8F93\u5165\u53C2\u6570\u5B9A\u4E49",
|
|
132
|
+
{},
|
|
133
|
+
() => {
|
|
134
|
+
const schemas = getSchemas();
|
|
135
|
+
const apiSchema = {};
|
|
136
|
+
for (const route of schemas) {
|
|
137
|
+
const key = `${route.method} ${route.path}`;
|
|
138
|
+
apiSchema[key] = {
|
|
139
|
+
method: route.method,
|
|
140
|
+
path: route.path,
|
|
141
|
+
isDynamic: route.isDynamic,
|
|
142
|
+
inputs: route.inputs.map((input) => ({
|
|
143
|
+
source: input.source,
|
|
144
|
+
schemaName: input.schemaName,
|
|
145
|
+
properties: input.properties
|
|
146
|
+
}))
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
content: [
|
|
151
|
+
{
|
|
152
|
+
type: "text",
|
|
153
|
+
text: JSON.stringify(apiSchema, null, 2)
|
|
154
|
+
}
|
|
155
|
+
]
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
);
|
|
159
|
+
return server;
|
|
160
|
+
}
|
|
161
|
+
async function startSchemaServer(routes, rootDir) {
|
|
162
|
+
const server = createSchemaServer(routes, rootDir);
|
|
163
|
+
const transport = new StdioServerTransport();
|
|
164
|
+
await server.connect(transport);
|
|
165
|
+
}
|
|
166
|
+
var schemaServer_default = {
|
|
167
|
+
name: "@faapi/schema",
|
|
168
|
+
setup(ctx) {
|
|
169
|
+
if (!isSchemaEnabled()) {
|
|
170
|
+
console.log("- Schema server disabled (FAAPI_SCHEMA=0 or production mode)");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
console.log("- Schema server enabled (stdio)");
|
|
174
|
+
void startSchemaServer(ctx.routes, ctx.rootDir);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
export {
|
|
178
|
+
schemaServer_default as default
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemaServer.ts","../src/routeSchema.ts"],"sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport type { RouteManifest, RouteInfo, FaapiPlugin, PluginContext } from '@faapi/faapi';\nimport { buildRouteSchemas } from './routeSchema.js';\n\n/**\n * 判断 schema server 是否应该启用\n * - FAAPI_SCHEMA=1 强制开启\n * - FAAPI_SCHEMA=0 强制关闭\n * - 未设置时:开发环境默认开启,生产环境默认关闭\n */\nexport function isSchemaEnabled(): boolean {\n const envValue = process.env.FAAPI_SCHEMA;\n if (envValue === '1' || envValue === 'true') return true;\n if (envValue === '0' || envValue === 'false') return false;\n // 未设置时根据 NODE_ENV 判断\n return process.env.NODE_ENV !== 'production';\n}\n\n/**\n * 创建 faapi Schema Server\n * 通过 MCP 协议暴露路由信息供 LLM 查询\n */\nexport function createSchemaServer(routes: RouteManifest, rootDir: string): McpServer {\n const server = new McpServer({\n name: 'faapi-schema',\n version: '0.0.1',\n });\n\n // 缓存 route schemas\n let cachedSchemas: RouteInfo[] | null = null;\n\n function getSchemas(): RouteInfo[] {\n if (!cachedSchemas) {\n cachedSchemas = buildRouteSchemas(routes, rootDir);\n }\n return cachedSchemas;\n }\n\n // Tool: 列出所有路由\n server.tool(\n 'list_routes',\n '列出当前 faapi 应用的所有 API 路由,包括方法、路径、是否动态路由',\n {},\n () => {\n const schemas = getSchemas();\n const routesList = schemas.map((r) => ({\n method: r.method,\n path: r.path,\n isDynamic: r.isDynamic,\n filePath: r.filePath,\n }));\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(routesList, null, 2),\n },\n ],\n };\n },\n );\n\n // Tool: 获取单个路由的详细 schema\n server.tool(\n 'get_route_schema',\n '获取指定路由的详细接口信息,包括输入参数的名称、类型、是否必填',\n {\n method: z.string().describe('HTTP 方法,如 GET、POST'),\n path: z.string().describe('路由路径,如 /auth/login'),\n },\n ({ method, path }) => {\n const schemas = getSchemas();\n const route = schemas.find((r) => r.method === method.toUpperCase() && r.path === path);\n\n if (!route) {\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({ error: `未找到路由 ${method.toUpperCase()} ${path}` }),\n },\n ],\n };\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(route, null, 2),\n },\n ],\n };\n },\n );\n\n // Tool: 获取所有路由的完整 schema(类似 OpenAPI)\n server.tool(\n 'get_api_schema',\n '获取当前应用所有接口的完整 schema,类似 OpenAPI 规范,包含每个路由的输入参数定义',\n {},\n () => {\n const schemas = getSchemas();\n const apiSchema: Record<string, unknown> = {};\n\n for (const route of schemas) {\n const key = `${route.method} ${route.path}`;\n apiSchema[key] = {\n method: route.method,\n path: route.path,\n isDynamic: route.isDynamic,\n inputs: route.inputs.map((input) => ({\n source: input.source,\n schemaName: input.schemaName,\n properties: input.properties,\n })),\n };\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(apiSchema, null, 2),\n },\n ],\n };\n },\n );\n\n return server;\n}\n\n/**\n * 启动 Schema Server(stdio 模式)\n */\nexport async function startSchemaServer(routes: RouteManifest, rootDir: string): Promise<void> {\n const server = createSchemaServer(routes, rootDir);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\n/**\n * faapi 插件入口\n *\n * 在 faapi.config.ts 中声明:\n * ```ts\n * export default {\n * plugins: ['@faapi/schema'],\n * } satisfies FaapiConfig;\n * ```\n */\nexport default {\n name: '@faapi/schema',\n setup(ctx: PluginContext) {\n if (!isSchemaEnabled()) {\n console.log('- Schema server disabled (FAAPI_SCHEMA=0 or production mode)');\n return;\n }\n console.log('- Schema server enabled (stdio)');\n // startSchemaServer 是异步的,但不阻塞启动流程\n void startSchemaServer(ctx.routes, ctx.rootDir);\n },\n} satisfies FaapiPlugin;\n","import path from 'node:path';\nimport {\n getSchemaProperties,\n getInputTypeForMethod,\n type RouteManifest,\n type RouteInfo,\n type RouteInputSchema,\n} from '@faapi/faapi';\n\n/**\n * 从路由清单生成接口描述信息\n *\n * 复用主包 schemaRegistry 已有的类型提取结果,避免重复 AST 分析。\n *\n * @param routes 路由清单\n * @param rootDir 根目录\n */\nexport function buildRouteSchemas(routes: RouteManifest, rootDir: string): RouteInfo[] {\n return routes.map((route) => {\n const absoluteFilePath = path.resolve(rootDir, route.filePath);\n const inputs = extractInputSchemas(absoluteFilePath, route.method, route);\n\n return {\n method: route.method,\n path: route.urlPath,\n filePath: route.filePath,\n isDynamic: route.isDynamic,\n inputs,\n };\n });\n}\n\n/**\n * 提取一个路由文件的所有输入 schema\n *\n * 直接查询 schemaRegistry,复用参数校验已提取的 PropertyType,\n * 不再重复执行 AST 分析。\n */\nfunction extractInputSchemas(\n filePath: string,\n method: string,\n route: { isDynamic: boolean; paramNames: string[] },\n): RouteInputSchema[] {\n const inputs: RouteInputSchema[] = [];\n\n // 主输入(query 或 body):从 registry 查询\n const inputType = getInputTypeForMethod(method);\n const schema = getSchemaProperties(filePath, method, inputType);\n\n if (schema) {\n inputs.push({\n source: inputType,\n schemaName: schema.schemaName,\n properties: schema.properties,\n });\n } else {\n // registry 无数据(不应发生,插件 setup 时 registry 已加载)\n inputs.push({\n source: inputType,\n schemaName: null,\n properties: [],\n });\n }\n\n // 动态路由参数\n if (route.isDynamic && route.paramNames.length > 0) {\n const paramsSchema = getSchemaProperties(filePath, method, 'params');\n\n // params 有类型声明时用类型信息,否则用 paramNames 兜底\n const paramsProps = (paramsSchema && paramsSchema.schemaName)\n ? paramsSchema.properties\n : route.paramNames.map((name) => ({\n name,\n type: 'string',\n required: true,\n }));\n\n inputs.push({\n source: 'params',\n schemaName: paramsSchema?.schemaName ?? null,\n properties: paramsProps,\n });\n }\n\n return inputs;\n}\n"],"mappings":"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","names":["path"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@faapi/schema",
|
|
3
|
+
"version": "0.0.0-canary.0",
|
|
4
|
+
"description": "Schema introspection for faapi — expose API schema to AI assistants via MCP",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=22"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsup",
|
|
22
|
+
"prepublishOnly": "pnpm build",
|
|
23
|
+
"test": "vitest run --passWithNoTests",
|
|
24
|
+
"typecheck": "tsc --noEmit"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@faapi/faapi": "workspace:*",
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
29
|
+
"zod": "^4.4.3"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^22.15.0",
|
|
33
|
+
"@vitest/coverage-v8": "3",
|
|
34
|
+
"tsup": "^8.4.0",
|
|
35
|
+
"typescript": "^5.7.0",
|
|
36
|
+
"vitest": "^3.1.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"typescript": ">=5.7.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependenciesMeta": {
|
|
42
|
+
"typescript": {
|
|
43
|
+
"optional": true
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "https://github.com/faapi/faapi.git",
|
|
50
|
+
"directory": "packages/schema"
|
|
51
|
+
}
|
|
52
|
+
}
|