feat(mcp): mcp setting add service description page

This commit is contained in:
寇佳龙 2025-04-24 15:32:01 +08:00 committed by 亢奋猫
parent 317d452498
commit 696bf2dc79
12 changed files with 118 additions and 2 deletions

View File

@ -72,6 +72,7 @@
"@langchain/community": "^0.3.36",
"@mozilla/readability": "^0.6.0",
"@notionhq/client": "^2.2.15",
"@shikijs/markdown-it": "^3.2.2",
"@strongtz/win32-arm64-msvc": "^0.4.7",
"@tryfabric/martian": "^1.2.4",
"@types/react-infinite-scroll-component": "^5.0.0",

View File

@ -1121,6 +1121,7 @@
"installHelp": "Get Installation Help",
"tabs": {
"general": "General",
"description": "Description",
"tools": "Tools",
"prompts": "Prompts",
"resources": "Resources"

View File

@ -1120,6 +1120,7 @@
"installHelp": "インストールヘルプを取得",
"tabs": {
"general": "一般",
"description": "説明",
"tools": "ツール",
"prompts": "プロンプト",
"resources": "リソース"

View File

@ -1120,6 +1120,7 @@
"installHelp": "Получить помощь по установке",
"tabs": {
"general": "Общие",
"description": "Описание",
"tools": "Инструменты",
"prompts": "Подсказки",
"resources": "Ресурсы"

View File

@ -1121,6 +1121,7 @@
"installHelp": "获取安装帮助",
"tabs": {
"general": "通用",
"description": "描述",
"tools": "工具",
"prompts": "提示",
"resources": "资源"

View File

@ -1120,6 +1120,7 @@
"installHelp": "獲取安裝幫助",
"tabs": {
"general": "通用",
"description": "描述",
"tools": "工具",
"prompts": "提示",
"resources": "資源"

View File

@ -0,0 +1,50 @@
import { useTheme } from '@renderer/context/ThemeProvider'
import { getShikiInstance } from '@renderer/utils/shiki'
import { Card } from 'antd'
import MarkdownIt from 'markdown-it'
import { npxFinder } from 'npx-scope-finder'
import { useEffect, useRef, useState } from 'react'
import styled from 'styled-components'
interface McpDescriptionProps {
searchKey: string
}
const MCPDescription = ({ searchKey }: McpDescriptionProps) => {
const [renderedMarkdown, setRenderedMarkdown] = useState('')
const [loading, setLoading] = useState(false)
const md = useRef<MarkdownIt>(
new MarkdownIt({
linkify: true, // 自动转换 URL 为链接
typographer: true // 启用印刷格式优化
})
)
const { theme } = useTheme()
useEffect(() => {
const sk = getShikiInstance(theme)
md.current.use(sk)
getMcpInfo()
}, [theme, searchKey])
const getMcpInfo = async () => {
setLoading(true)
const packages = await npxFinder(searchKey).finally(() => setLoading(false))
const readme = packages[0]?.original?.readme ?? '暂无描述'
setRenderedMarkdown(md.current.render(readme))
}
return (
<Section>
<Card loading={loading}>
<div className="markdown" dangerouslySetInnerHTML={{ __html: renderedMarkdown }} />
</Card>
</Section>
)
}
const Section = styled.div`
padding-top: 8px;
`
export default MCPDescription

View File

@ -1,6 +1,7 @@
import { DeleteOutlined, SaveOutlined } from '@ant-design/icons'
import { useTheme } from '@renderer/context/ThemeProvider'
import { useMCPServers } from '@renderer/hooks/useMCPServers'
import MCPDescription from '@renderer/pages/settings/MCPSettings/McpDescription'
import { MCPPrompt, MCPResource, MCPServer, MCPTool } from '@renderer/types'
import { Button, Flex, Form, Input, Radio, Switch, Tabs } from 'antd'
import TextArea from 'antd/es/input/TextArea'
@ -516,6 +517,13 @@ const McpSettings: React.FC = () => {
)
}
]
if (server.searchKey) {
tabs.push({
key: 'description',
label: t('settings.mcp.tabs.description'),
children: <MCPDescription searchKey={server.searchKey} />
})
}
if (server.isActive) {
tabs.push(

View File

@ -206,7 +206,8 @@ const NpxSearch: FC = () => {
args: record.configSample?.args ?? ['-y', record.fullName],
env: record.configSample?.env,
isActive: false,
type: record.type
type: record.type,
searchKey: record.fullName
}
addMCPServer(newServer)

View File

@ -403,6 +403,7 @@ export interface MCPServer {
disabledTools?: string[] // List of tool names that are disabled for this server
configSample?: MCPConfigSample
headers?: Record<string, string> // Custom headers to be sent with requests to this server
searchKey?: string
}
export interface MCPToolInputSchema {

View File

@ -0,0 +1,34 @@
import { ThemeMode } from '@renderer/types'
import { MarkdownItShikiOptions, setupMarkdownIt } from '@shikijs/markdown-it'
import MarkdownIt from 'markdown-it'
import { BuiltinLanguage, BuiltinTheme, bundledLanguages, createHighlighter } from 'shiki'
const defaultOptions = {
themes: {
light: 'one-light',
dark: 'material-theme-darker'
},
defaultColor: 'light'
}
const initHighlighter = async (options: MarkdownItShikiOptions) => {
const themeNames = ('themes' in options ? Object.values(options.themes) : [options.theme]).filter(
Boolean
) as BuiltinTheme[]
return await createHighlighter({
themes: themeNames,
langs: options.langs || (Object.keys(bundledLanguages) as BuiltinLanguage[])
})
}
const highlighter = await initHighlighter(defaultOptions)
export function getShikiInstance(theme: ThemeMode) {
const options = {
...defaultOptions,
defaultColor: theme
}
return function (markdownit: MarkdownIt) {
setupMarkdownIt(markdownit, highlighter, options)
}
}

View File

@ -3268,6 +3268,21 @@ __metadata:
languageName: node
linkType: hard
"@shikijs/markdown-it@npm:^3.2.2":
version: 3.2.2
resolution: "@shikijs/markdown-it@npm:3.2.2"
dependencies:
markdown-it: "npm:^14.1.0"
shiki: "npm:3.2.2"
peerDependencies:
markdown-it-async: ^2.2.0
peerDependenciesMeta:
markdown-it-async:
optional: true
checksum: 10c0/37c98e45a0905ea58f605c7cd341c83f3289b6a37093862535c59f7cc178fe9bfb13413fea68d4d923341e51b2e5718fc5172147d15e07457a76aceed2ac1f95
languageName: node
linkType: hard
"@shikijs/themes@npm:3.2.2":
version: 3.2.2
resolution: "@shikijs/themes@npm:3.2.2"
@ -4315,6 +4330,7 @@ __metadata:
"@mozilla/readability": "npm:^0.6.0"
"@notionhq/client": "npm:^2.2.15"
"@reduxjs/toolkit": "npm:^2.2.5"
"@shikijs/markdown-it": "npm:^3.2.2"
"@strongtz/win32-arm64-msvc": "npm:^0.4.7"
"@swc/plugin-styled-components": "npm:^7.1.3"
"@tavily/core": "patch:@tavily/core@npm%3A0.3.1#~/.yarn/patches/@tavily-core-npm-0.3.1-fe69bf2bea.patch"
@ -15553,7 +15569,7 @@ __metadata:
languageName: node
linkType: hard
"shiki@npm:^3.2.1":
"shiki@npm:3.2.2, shiki@npm:^3.2.1":
version: 3.2.2
resolution: "shiki@npm:3.2.2"
dependencies: