-
Notifications
You must be signed in to change notification settings - Fork 21
feat: add @opentiny/next-sdk #165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,14 +6,35 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <global-setting /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <tiny-remoter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| agent-root="https://agent.opentiny.design/api/v1/webmcp-trial/" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| :session-id="sessionId" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| :menuItems="[ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| action: 'qr-code', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| show: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| action: 'remote-control', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| show: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| action: 'remote-url', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| show: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </template> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <script lang="ts" setup> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { provide } from 'vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { onMounted, provide, ref } from 'vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { TinyConfigProvider } from '@opentiny/vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import GlobalSetting from '@/components/global-setting/index.vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { createMessageChannelPairTransport, WebMcpClient } from '@opentiny/next-sdk' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { TinyRemoter } from '@opentiny/next-remoter' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import TinyThemeTool from '@opentiny/vue-theme/theme-tool'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useTheme } from './hooks/useTheme'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import '@opentiny/next-remoter/dist/style.css' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const theme = new TinyThemeTool(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| useTheme(theme); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -30,6 +51,26 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const sessionId = ref('') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [serverTransport, clientTransport] = createMessageChannelPairTransport() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| provide('serverTransport', serverTransport) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onMounted(async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 创建 WebMcpClient ,并与 WebAgent 连接 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const client = new WebMcpClient() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await client.connect(clientTransport) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { sessionId: sessionID } = await client.connect({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+63
to
+64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: Summary of WebMcpClient.connect (from @opentiny/next-sdk):
Sources: Remove the duplicate The 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| agent: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // sessionId 为可选参数。若传入该参数,系统将使用指定值作为会话标识;若未传入,WebAgent 服务将自动生成一个随机的字符串作为 sessionId。为便于通过 MCP Inspector 工具进行调试,此处采用了固定的 sessionId。用户亦可通过浏览器原生提供的 crypto.randomUUID() 方法生成随机字符串作为会话标识。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sessionId: 'd299a869-c674-4125-a84b-bb4e24079b99', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url: 'https://agent.opentiny.design/api/v1/webmcp-trial/mcp' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+68
to
+70
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider removing hardcoded sessionId for production. The hardcoded Consider:
♻️ Proposed fix+ const MCP_URL = import.meta.env.VITE_MCP_URL || 'https://agent.opentiny.design/api/v1/webmcp-trial/mcp'
+ const DEBUG_SESSION_ID = import.meta.env.DEV ? 'd299a869-c674-4125-a84b-bb4e24079b99' : crypto.randomUUID()Then update the connect call: const { sessionId: sessionID } = await client.connect({
agent: true,
- // sessionId 为可选参数。若传入该参数,系统将使用指定值作为会话标识;若未传入,WebAgent 服务将自动生成一个随机的字符串作为 sessionId。为便于通过 MCP Inspector 工具进行调试,此处采用了固定的 sessionId。用户亦可通过浏览器原生提供的 crypto.randomUUID() 方法生成随机字符串作为会话标识。
- sessionId: 'd299a869-c674-4125-a84b-bb4e24079b99',
- url: 'https://agent.opentiny.design/api/v1/webmcp-trial/mcp'
+ sessionId: DEBUG_SESSION_ID,
+ url: MCP_URL
})
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sessionId.value = sessionID | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+59
to
+73
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for MCP connection failures. The 🛡️ Proposed fix with error handling onMounted(async () => {
+ try {
+ // 创建 WebMcpClient ,并与 WebAgent 连接
+ const client = new WebMcpClient()
+ await client.connect(clientTransport)
+ const { sessionId: sessionID } = await client.connect({
+ agent: true,
+ // sessionId 为可选参数。若传入该参数,系统将使用指定值作为会话标识;若未传入,WebAgent 服务将自动生成一个随机的字符串作为 sessionId。为便于通过 MCP Inspector 工具进行调试,此处采用了固定的 sessionId。用户亦可通过浏览器原生提供的 crypto.randomUUID() 方法生成随机字符串作为会话标识。
+ sessionId: 'd299a869-c674-4125-a84b-bb4e24079b99',
+ url: 'https://agent.opentiny.design/api/v1/webmcp-trial/mcp'
+ })
+ sessionId.value = sessionID
+ } catch (error) {
+ console.error('Failed to initialize MCP client:', error)
+ // Consider showing user-facing error notification
+ }
- // 创建 WebMcpClient ,并与 WebAgent 连接
- const client = new WebMcpClient()
- await client.connect(clientTransport)
- const { sessionId: sessionID } = await client.connect({
- agent: true,
-
- // sessionId 为可选参数。若传入该参数,系统将使用指定值作为会话标识;若未传入,WebAgent 服务将自动生成一个随机的字符串作为 sessionId。为便于通过 MCP Inspector 工具进行调试,此处采用了固定的 sessionId。用户亦可通过浏览器原生提供的 crypto.randomUUID() 方法生成随机字符串作为会话标识。
- sessionId: 'd299a869-c674-4125-a84b-bb4e24079b99',
-
- url: 'https://agent.opentiny.design/api/v1/webmcp-trial/mcp'
- })
- sessionId.value = sessionID
})📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <style lang="less" scoped> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,4 +38,8 @@ body { | |
|
|
||
| .tiny-button { | ||
| --tv-Button-min-width: unset; | ||
| } | ||
|
|
||
| .tr-container { | ||
| z-index: 999 !important; | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -101,8 +101,10 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Option as TinyOption, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Popover as TinyPopover, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from '@opentiny/vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { computed, reactive, ref, watch } from 'vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { WebMcpServer, z } from '@opentiny/next-sdk' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { computed, reactive, ref, watch, onMounted, inject } from 'vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useI18n } from 'vue-i18n'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { sleep } from '@/utils/base-utils'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import langTable from './lang-table.vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const emits = defineEmits<{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -216,6 +218,39 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setLangTableClose() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onMounted(async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const server = new WebMcpServer({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: 'i18n-management-mcp-server', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| version: '1.0.0' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const serverTransport = inject<any>('serverTransport') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| server.registerTool( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'add-i18n-entry', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title: '添加国际化词条', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: '添加国际化词条', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputSchema: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key: z.string().describe('词条关键字'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: z.string().describe('词条内容'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lang: z.union([z.literal(1), z.literal(2)]).describe('词条语言ID,英文 enUS 为:1,中文 zhCN 为:2'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async ({ key, content, lang }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onOpen() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await sleep(1000) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
kagol marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| locale.key = key | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| locale.content = content | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| locale.lang = lang | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await sleep(1000) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| addLocale() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { content: [{ type: 'text', text: `收到: ${key}` }] } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await server.connect(serverTransport) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+222
to
+253
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Check if Transport type is exported from @opentiny/next-sdk
rg -nP "export.*Transport" node_modules/@opentiny/next-sdk -A 2Repository: opentiny/tiny-pro Length of output: 132 🏁 Script executed: # Also check the actual file to verify it exists and code matches
if [ -f "template/tinyvue/src/views/locale/components/add-locale.vue" ]; then
echo "=== File exists. Checking lines 222-253 ==="
sed -n '222,253p' "template/tinyvue/src/views/locale/components/add-locale.vue"
else
echo "File not found at template/tinyvue/src/views/locale/components/add-locale.vue"
# Try to find it
find . -name "add-locale.vue" -type f 2>/dev/null
fiRepository: opentiny/tiny-pro Length of output: 994 🏁 Script executed: # Check if info-tab.vue exists and has similar MCP server setup pattern
find . -name "info-tab.vue" -type f 2>/dev/null | head -5Repository: opentiny/tiny-pro Length of output: 388 🏁 Script executed: # Check if @opentiny/next-sdk is in package.json
cat package.json | grep -A 5 -B 5 "@opentiny/next-sdk"Repository: opentiny/tiny-pro Length of output: 43 🏁 Script executed: # Check one info-tab.vue file to see similar MCP server pattern
head -n 400 "./template/tinyvue/src/views/menu/info/components/info-tab.vue" | grep -A 50 "onMounted"Repository: opentiny/tiny-pro Length of output: 3091 🏁 Script executed: # Check package.json file itself for @opentiny/next-sdk and dependencies section
head -n 100 package.json | tail -n 50Repository: opentiny/tiny-pro Length of output: 2327 🏁 Script executed: # Search for Transport type usage in the codebase
rg "Transport" --type vue --type ts --type js | head -20Repository: opentiny/tiny-pro Length of output: 88 🏁 Script executed: # Search for Transport type usage more broadly
rg "Transport" --type ts --type js | head -20Repository: opentiny/tiny-pro Length of output: 880 🏁 Script executed: # Check full package.json dependencies for @opentiny/next-sdk and related packages
rg "@opentiny" package.jsonRepository: opentiny/tiny-pro Length of output: 172 🏁 Script executed: # Look for WebMcpServer import to understand where Transport might come from
rg "WebMcpServer|import.*Transport" -A 2 -B 2 | head -30Repository: opentiny/tiny-pro Length of output: 2406 🏁 Script executed: # Check App.vue to see how serverTransport is typed and used
rg -A 10 "createMessageChannelPairTransport" "template/tinyvue/src/App.vue"Repository: opentiny/tiny-pro Length of output: 991 🏁 Script executed: # Look for type definitions or interfaces related to Transport in the codebase
rg "type.*Transport|interface.*Transport" --type ts -A 3Repository: opentiny/tiny-pro Length of output: 43 🏁 Script executed: # Check if there's a type definition file or declaration in node_modules or src
find . -name "*.d.ts" -o -name "*.ts" | xargs grep -l "Transport" 2>/dev/null | head -10Repository: opentiny/tiny-pro Length of output: 43 Add error handling and improve type safety. The MCP server setup mirrors the pattern in
These same issues appear in Proposed improvements+const MCP_UI_DELAY = 1000; // ms
+
onMounted(async () => {
+ try {
const server = new WebMcpServer({
name: 'i18n-management-mcp-server',
version: '1.0.0'
})
- const serverTransport = inject<any>('serverTransport')
+ const serverTransport = inject('serverTransport')
+ if (!serverTransport) {
+ console.error('serverTransport not provided')
+ return
+ }
server.registerTool(
'add-i18n-entry',
{
title: '添加国际化词条',
description: '添加国际化词条',
inputSchema: {
key: z.string().describe('词条关键字'),
content: z.string().describe('词条内容'),
lang: z.union([z.literal(1), z.literal(2)]).describe('词条语言ID,英文 enUS 为:1,中文 zhCN 为:2'),
}
},
async ({ key, content, lang }) => {
+ try {
onOpen()
- await sleep(1000)
+ await sleep(MCP_UI_DELAY)
locale.key = key
locale.content = content
locale.lang = lang
- await sleep(1000)
+ await sleep(MCP_UI_DELAY)
addLocale()
return { content: [{ type: 'text', text: `收到: ${key}` }] }
+ } catch (error) {
+ console.error('Failed to add i18n entry via MCP:', error)
+ return {
+ content: [{
+ type: 'text',
+ text: `添加词条失败: ${error instanceof Error ? error.message : String(error)}`
+ }],
+ isError: true
+ }
+ }
}
)
await server.connect(serverTransport)
+ console.log('i18n MCP server connected successfully')
+ } catch (error) {
+ console.error('Failed to initialize i18n MCP server:', error)
+ }
});📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <style scoped lang="less"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Modal as TinyModal, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Loading, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from '@opentiny/vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { WebMcpServer, z } from '@opentiny/next-sdk' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getAllLocalItems } from '@/api/local'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import useLoading from '@/hooks/loading'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -26,6 +27,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| import menuTree, { Node } from './menu-tree.vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import UpdateForm from './update-form.vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import AddMenu from './add-menu.vue'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { sleep } from '@/utils/base-utils'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { modalSize } = useResponsiveSize() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -241,10 +243,52 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetchLocalItems(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onMounted(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onMounted(async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Promise.all([fetchMenu(), fetchLocalItems()]).finally(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| treeLoading.value = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const server = new WebMcpServer({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: 'menu-management-mcp-server', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| version: '1.0.0' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const serverTransport = inject<any>('serverTransport') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+246
to
+255
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major 🧩 Analysis chain🏁 Script executed: # First, check if the file exists and view the relevant lines
if [ -f "template/tinyveo/src/views/menu/info/components/info-tab.vue" ]; then
sed -n '246,255p' "template/tinyveo/src/views/menu/info/components/info-tab.vue"
else
echo "Checking for correct file path..."
find . -name "info-tab.vue" -type f 2>/dev/null | head -5
fiRepository: opentiny/tiny-pro Length of output: 178 🏁 Script executed: # Check if @opentiny/next-sdk is in the project dependencies
find . -name "package.json" -type f | xargs grep -l "@opentiny/next-sdk" 2>/dev/null | head -5Repository: opentiny/tiny-pro Length of output: 92 🏁 Script executed: # Check the node_modules for Transport type export from @opentiny/next-sdk
if [ -d "node_modules/@opentiny/next-sdk" ]; then
echo "=== Checking for Transport type ==="
find node_modules/@opentiny/next-sdk -name "*.d.ts" -o -name "*.ts" | xargs grep -l "export.*Transport" 2>/dev/null | head -5
else
echo "@opentiny/next-sdk not found in node_modules"
fiRepository: opentiny/tiny-pro Length of output: 105 🏁 Script executed: # View the file content at the specified lines
sed -n '240,260p' template/tinyvue/src/views/menu/info/components/info-tab.vueRepository: opentiny/tiny-pro Length of output: 525 🏁 Script executed: # Search for Transport type definition in the codebase
rg "type.*Transport|export.*Transport" --type ts --type vue -iRepository: opentiny/tiny-pro Length of output: 88 🏁 Script executed: # Check imports in the info-tab.vue file to understand what's already imported
head -30 template/tinyvue/src/views/menu/info/components/info-tab.vueRepository: opentiny/tiny-pro Length of output: 1117 🏁 Script executed: # Check the package.json to see what version of @opentiny/next-sdk is used
rg "@opentiny/next-sdk" template/tinyvue/package.json -A 1 -B 1Repository: opentiny/tiny-pro Length of output: 170 🏁 Script executed: # Search for all imports from @opentiny/next-sdk to see what types are available
rg "from ['\"]@opentiny/next-sdk['\"]" -A 3 -B 1Repository: opentiny/tiny-pro Length of output: 1562 🏁 Script executed: # Search for Transport or transport-related types in the codebase
rg -i "transport" template/tinyvue/src/views/menu/info/components/info-tab.vue -B 2 -A 2Repository: opentiny/tiny-pro Length of output: 243 🏁 Script executed: # Check if there are any type definitions or .d.ts files in the repo that might define Transport
find . -name "*.d.ts" -type f | xargs grep -l "Transport" 2>/dev/null | head -10Repository: opentiny/tiny-pro Length of output: 43 🏁 Script executed: # Search for how serverTransport is actually used after injection
sed -n '255,280p' template/tinyvue/src/views/menu/info/components/info-tab.vueRepository: opentiny/tiny-pro Length of output: 880 🏁 Script executed: # Check how createMessageChannelPairTransport is used in App.vue to understand transport types
sed -n '1,50p' template/tinyvue/src/App.vue | grep -A 10 "createMessageChannelPairTransport"Repository: opentiny/tiny-pro Length of output: 469 🏁 Script executed: # Search for server.connect usage patterns
rg "server\.connect" -B 3 -A 3Repository: opentiny/tiny-pro Length of output: 1058 🏁 Script executed: # Search for any transport-related type definitions or interfaces in the codebase
rg "transport" template/tinyvue/src -i --type ts --type vue | head -30Repository: opentiny/tiny-pro Length of output: 88 🏁 Script executed: # Check if there's a web_search to verify what's exported from @opentiny/next-sdk
# We'll search the package documentationRepository: opentiny/tiny-pro Length of output: 43 🌐 Web query:
💡 Result: You can import the Transport type from the package. Example: import type { Transport } from '@opentiny/next-sdk' (See the WebMcpClient connect signature which uses Transport in the OpenTiny NEXT docs.) [1] Sources
Replace Line 255 uses Proposed fix+import type { Transport } from '@opentiny/next-sdk'
onMounted(async () => {
// ...
const server = new WebMcpServer({
name: 'menu-management-mcp-server',
version: '1.0.0'
})
- const serverTransport = inject<any>('serverTransport')
+ const serverTransport = inject<Transport>('serverTransport')
+ if (!serverTransport) {
+ console.error('serverTransport not provided')
+ return
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| server.registerTool( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'add-menu', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title: '添加菜单', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: '添加菜单', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputSchema: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: z.string().describe('名称'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| order: z.number().describe('优先级').default(0), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parentId: z.number().describe('父菜单ID').optional(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon: z.string().describe('图标').optional().default(''), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| component: z.string().describe('组件'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path: z.string().describe('路径'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| locale: z.string().describe('国际化'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async ({ name, order, parentId, icon, component, path, locale }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| handleAddMenu() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await sleep(1000) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| addMenu.value.setMenuInfo({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| order, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parentId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| component, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| menuType: "/", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| locale, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await sleep(1000) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClickAdd() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { content: [{ type: 'text', text: `收到: ${name}` }] } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+257
to
+289
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling and make delays configurable. The MCP tool registration has several concerns:
Proposed improvements+const MCP_UI_DELAY = 1000; // ms - delay for UI updates to be visible
+
onMounted(async () => {
// ... server setup ...
server.registerTool(
'add-menu',
{
title: '添加菜单',
description: '添加菜单',
inputSchema: {
name: z.string().describe('名称'),
order: z.number().describe('优先级').default(0),
parentId: z.number().describe('父菜单ID').optional(),
icon: z.string().describe('图标').optional().default(''),
component: z.string().describe('组件'),
path: z.string().describe('路径'),
locale: z.string().describe('国际化'),
}
},
async ({ name, order, parentId, icon, component, path, locale }) => {
+ try {
handleAddMenu()
- await sleep(1000)
+ await sleep(MCP_UI_DELAY)
addMenu.value.setMenuInfo({
name,
order,
parentId,
icon,
component,
menuType: "/",
path,
locale,
})
- await sleep(1000)
+ await sleep(MCP_UI_DELAY)
onClickAdd()
return { content: [{ type: 'text', text: `收到: ${name}` }] }
+ } catch (error) {
+ console.error('Failed to add menu via MCP:', error)
+ return {
+ content: [{
+ type: 'text',
+ text: `添加菜单失败: ${error instanceof Error ? error.message : String(error)}`
+ }],
+ isError: true
+ }
+ }
}
)
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await server.connect(serverTransport) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for server connection. The Add try-catch for server connection- await server.connect(serverTransport)
+ try {
+ await server.connect(serverTransport)
+ console.log('MCP server connected successfully')
+ } catch (error) {
+ console.error('Failed to connect MCP server:', error)
+ // Consider showing a user notification or disabling MCP features
+ }
});📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.