Skip to content

Commit 0aff2aa

Browse files
committed
refactor: optimize code generation logic
1 parent c4fa04a commit 0aff2aa

9 files changed

Lines changed: 626 additions & 575 deletions

File tree

packages/vue-generator/src/plugins/genMcpPlugin.js

Lines changed: 217 additions & 575 deletions
Large diffs are not rendered by default.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export default () => {
2+
return `import { TinyRemoter } from "@opentiny/next-remoter";
3+
import {
4+
WebMcpClient,
5+
createMessageChannelPairTransport,
6+
} from "@opentiny/next-sdk";
7+
import type { Transport } from "@opentiny/next-sdk";
8+
import { AGENT_ROOT, SESSION_ID } from "./base";
9+
import { mcpServerManager } from "./mcp/server";`
10+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export default () => {
2+
return ` createProxyTransport();
3+
initMcpServer();`
4+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
export default (schema, options) => {
2+
const { capabilities } = options
3+
4+
return `
5+
6+
const [serverTransport, clientTransport] = createMessageChannelPairTransport();
7+
8+
// 定义 MCP Server 的能力
9+
const capabilities = ${JSON.stringify(capabilities, null, 2)};
10+
11+
const mcpServer: {
12+
transport: Transport | null;
13+
capabilities: Record<string, any>;
14+
} = {
15+
transport: serverTransport,
16+
capabilities,
17+
};
18+
19+
provide("mcpServer", mcpServer);
20+
21+
serverTransport.onerror = (error) => {
22+
console.error(\`ServerTransport error:\`, error);
23+
};
24+
25+
const createProxyTransport = async () => {
26+
const client = new WebMcpClient(
27+
{ name: "mcp-web-client", version: "1.0.0" },
28+
{
29+
capabilities: {
30+
roots: { listChanged: true },
31+
sampling: {},
32+
elicitation: {},
33+
},
34+
}
35+
);
36+
// @ts-expect-error client
37+
window.client = client;
38+
await client.connect(clientTransport);
39+
40+
await client.connect({
41+
url: AGENT_ROOT + "mcp",
42+
sessionId: SESSION_ID,
43+
agent: true,
44+
onError: (error: Error) => {
45+
console.error("Connect proxy error:", error);
46+
},
47+
});
48+
49+
window.addEventListener("pagehide", client.onPagehide);
50+
};
51+
52+
// 初始化MCP服务器管理器
53+
const initMcpServer = async () => {
54+
try {
55+
// 初始化管理器
56+
mcpServerManager.init(router, mcpServer);
57+
// 连接所有服务器
58+
await mcpServerManager.connectAll(mcpServer.transport as Transport);
59+
console.log('MCP 服务器管理器初始化成功');
60+
} catch (error) {
61+
console.error('MCP 服务器管理器初始化失败:', error);
62+
}
63+
};`
64+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default () => {
2+
return `
3+
:deep(.next-sdk-trigger-btn) {
4+
font-size: 30px;
5+
}`
6+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default () => {
2+
return ` <TinyRemoter :sessionId="SESSION_ID" class="remoter" />`
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default (schema, options) => {
2+
const { agentRoot, sessionId } = options
3+
4+
return `export const AGENT_ROOT = '${agentRoot}'
5+
export const SESSION_ID = '${sessionId}'`
6+
}
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
export default (schema, options) => {
2+
const { enabledTools } = options
3+
4+
// 构建导入语句
5+
let toolImports = ''
6+
let registrations = ''
7+
8+
if (enabledTools.includes('navigation')) {
9+
toolImports += `
10+
import { registerNavigationTools } from './tools/navigationTools'`
11+
registrations += `
12+
registerNavigationTools(server, this.router!);`
13+
}
14+
15+
if (enabledTools.includes('application')) {
16+
toolImports += `
17+
import { registerApplicationTools } from './tools/applicationTools'`
18+
registrations += `
19+
registerApplicationTools(server);`
20+
}
21+
22+
return `import type { Router } from 'vue-router'
23+
import { WebMcpServer } from "@opentiny/next-sdk"
24+
import { registerMcpConfig } from '@opentiny/vue-common'
25+
import { createMcpTools, getTinyVueMcpConfig } from '@opentiny/tiny-vue-mcp'${toolImports}
26+
27+
// 配置接口
28+
interface PageServerConfig {
29+
name: string
30+
business: {
31+
id: string
32+
description: string
33+
}
34+
}
35+
36+
// MCP 服务器管理器
37+
export class McpServerManager {
38+
private servers = new Map<string, WebMcpServer>()
39+
private mainServer: WebMcpServer | null = null
40+
private router: Router | null = null
41+
private capabilities: any = null
42+
43+
/**
44+
* 注册服务器 tools
45+
* @param mode 模式:page 页面服务器,main 应用级别服务器
46+
* @param server 服务器实例
47+
*/
48+
registerServerToolsByMode(mode: 'page' | 'main', server: WebMcpServer) {
49+
const commonRegistrations = () => {${registrations}
50+
};
51+
52+
if (mode === 'main') {
53+
registerMcpConfig(getTinyVueMcpConfig(), createMcpTools);
54+
}
55+
56+
commonRegistrations();
57+
}
58+
59+
// 初始化管理器
60+
init(router: Router, config: any) {
61+
this.router = router
62+
this.capabilities = config.capabilities
63+
64+
// 创建主服务器
65+
this.mainServer = new WebMcpServer(
66+
{ name: "business-app", version: "1.0.0" },
67+
{ capabilities: this.capabilities }
68+
)
69+
70+
// 注册主服务器 tools
71+
this.registerServerToolsByMode('main', this.mainServer)
72+
}
73+
74+
// 获取或创建页面服务器
75+
getPageServer(pageId: string, config?: PageServerConfig): WebMcpServer {
76+
// 返回缓存的服务器
77+
if (this.servers.has(pageId)) {
78+
return this.servers.get(pageId)!
79+
}
80+
81+
// 创建新服务器
82+
const serverConfig = config || {
83+
name: pageId,
84+
business: { id: pageId, description: \`\${pageId} 页面\` }
85+
}
86+
87+
const server = new WebMcpServer(
88+
{ name: serverConfig.name, version: "1.0.0" },
89+
{ capabilities: this.capabilities }
90+
)
91+
92+
// 注册页面服务器 tools
93+
this.registerServerToolsByMode('page', server)
94+
95+
// 缓存并返回
96+
this.servers.set(pageId, server)
97+
console.log(\`页面服务器 \${pageId} 创建完成\`)
98+
99+
return server
100+
}
101+
102+
// 连接所有服务器
103+
async connectAll(transport: any) {
104+
const results = []
105+
106+
// 连接主服务器
107+
if (this.mainServer) {
108+
try {
109+
await this.mainServer.connect(transport)
110+
this.mainServer.transport = transport
111+
results.push({ name: 'main', success: true })
112+
} catch (error) {
113+
console.error('主服务器连接失败:', error)
114+
results.push({ name: 'main', success: false })
115+
}
116+
}
117+
118+
// 连接页面服务器
119+
for (const [pageId, server] of this.servers.entries()) {
120+
try {
121+
await server.connect(transport)
122+
server.transport = transport
123+
results.push({ name: pageId, success: true })
124+
} catch (error) {
125+
console.error(\`页面服务器 \${pageId} 连接失败:\`, error)
126+
results.push({ name: pageId, success: false })
127+
}
128+
}
129+
130+
console.log(\`服务器连接完成: \${results.filter(r => r.success).length}/\${results.length} 成功\`)
131+
return results
132+
}
133+
134+
// 获取主服务器
135+
getMainServer() {
136+
return this.mainServer
137+
}
138+
139+
// 清理页面服务器
140+
removePageServer(pageId: string) {
141+
const server = this.servers.get(pageId)
142+
if (server) {
143+
server.transport = null
144+
this.servers.delete(pageId)
145+
console.log(\`页面服务器 \${pageId} 已清理\`)
146+
}
147+
}
148+
149+
// 清理所有资源
150+
dispose() {
151+
// 清理所有服务器
152+
this.servers.forEach(server => {
153+
server.transport = null
154+
})
155+
this.servers.clear()
156+
157+
if (this.mainServer) {
158+
this.mainServer.transport = null
159+
}
160+
161+
this.mainServer = null
162+
this.router = null
163+
this.capabilities = null
164+
165+
console.log('所有服务器资源已清理')
166+
}
167+
}
168+
169+
// 全局实例
170+
export const mcpServerManager = new McpServerManager()
171+
172+
// 页面级服务器 composable
173+
export function usePageMcpServer(pageId: string, config?: PageServerConfig) {
174+
const server = mcpServerManager.getPageServer(pageId, config)
175+
176+
// 连接服务器
177+
const connect = async (): Promise<boolean> => {
178+
// 已连接直接返回
179+
if (server?.transport) {
180+
console.log(\`页面服务器 \${pageId} 已经连接\`)
181+
return true
182+
}
183+
184+
// 获取主服务器传输层并连接
185+
const transport = mcpServerManager.getMainServer()?.transport
186+
if (!transport) {
187+
console.warn(\`无法连接页面服务器 \${pageId}: 主服务器未连接\`)
188+
return false
189+
}
190+
191+
try {
192+
await server!.connect(transport)
193+
server!.transport = transport
194+
console.log(\`页面服务器 \${pageId} 已连接\`)
195+
return true
196+
} catch (error) {
197+
console.error(\`页面服务器 \${pageId} 连接失败:\`, error)
198+
return false
199+
}
200+
}
201+
202+
// 断开连接并清理页面服务器
203+
const disconnect = () => {
204+
if (server?.transport) {
205+
server.transport = null
206+
console.log(\`页面服务器 \${pageId} 已断开连接\`)
207+
}
208+
209+
mcpServerManager.removePageServer(pageId)
210+
}
211+
212+
return { server, connect, disconnect }
213+
}`
214+
}

0 commit comments

Comments
 (0)