diff --git a/.vitepress/config.mts b/.vitepress/config.mts index 714c7ca..e56f9a2 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -1,4 +1,5 @@ import { defineConfig } from 'vitepress'; +import lightbox from "vitepress-plugin-lightbox"; export const customIcons = { share: { @@ -14,6 +15,12 @@ export default defineConfig({ base: baseUrl, ignoreDeadLinks: true, + markdown: { + config: (md) => { + md.use(lightbox, {}); + } + }, + head: [ ['link', { rel: 'icon', href: baseUrl + '/images/favicon.png' }] ], diff --git a/.vitepress/theme/Layout.vue b/.vitepress/theme/Layout.vue index f778585..f38cfcd 100644 --- a/.vitepress/theme/Layout.vue +++ b/.vitepress/theme/Layout.vue @@ -1,15 +1,30 @@ + + + + +}); - +const sameSource = (from: string, to: string) => { + return from.split('/').slice(0, 3).join('/') === to.split('/').slice(0, 3).join('/'); +} + +const handleRouteChangeStart = async (to: string) => { + const from = router.route.path; + + if (sameSource(from, to)) { + await animateIn('VPContent', { name: 'fade' }); + } else { + await animateIn('k-layout', { name: 'fade' }); + } +}; + + +const handleRouteChangeComplete = async (to: string) => { + await animateOut({ name: 'fade' }); + setupMediumZoom(); +}; + + +router.onBeforeRouteChange = handleRouteChangeStart; +router.onAfterRouteChange = handleRouteChangeComplete; + +onMounted(() => { + setupMediumZoom(); +}); + \ No newline at end of file diff --git a/.vitepress/theme/hook/animate.ts b/.vitepress/theme/hook/animate.ts new file mode 100644 index 0000000..5b1daa6 --- /dev/null +++ b/.vitepress/theme/hook/animate.ts @@ -0,0 +1,43 @@ + +export interface AnimationOption { + durationMs?: number; + name?: 'fade' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right'; + easing?: 'ease' | 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out'; +} + +function sleep(time: number) { + return new Promise((resolve) => { + setTimeout(resolve, time); + }); +} + +let lastAnimationId = ''; + +export async function animateIn(id: string, animationOption?: AnimationOption) { + const element = document.getElementById(id); + if (!element) { + return; + } + + lastAnimationId = id; + + const { durationMs = 150, name = 'fade', easing = 'ease-out' } = animationOption || {}; + element.style.transition = `opacity ${durationMs / 1000}s ${easing}`; + + element.classList.remove(name + '-in'); + element.classList.add(name + '-out'); + await sleep(durationMs); +} + +export async function animateOut(animationOption?: AnimationOption) { + const element = document.getElementById(lastAnimationId); + if (!element) { + return; + } + + const { durationMs = 150, name = 'fade', easing = 'ease-out' } = animationOption || {}; + element.style.transition = `opacity ${durationMs / 1000}s ${easing}`; + + element.classList.remove(name + '-out'); + element.classList.add(name + '-in'); +} \ No newline at end of file diff --git a/index.md b/index.md index 7d87e4b..dc6cf0f 100644 --- a/index.md +++ b/index.md @@ -98,7 +98,7 @@ features: 正如它的名字一样,OpenMCP 是一个面向开发者的 MCP 调试器和 SDK,致力于降低 AI Agent 的全链路开发成本和开发人员的心智负担。通过 OpenMCP 制作出可以在真实生活场景中解决问题,缩短工作时间的 mcp 工具,或是让工程师与研发科学家更快地交付 demo,并将这份愿景让公众看到,是我们的任务和使命。 - 是的,OpenMCP 完全开源,您不仅可以免费试用此产品,也可以一起加入我们,实现你的关于 Agent 的奇思妙想。OpenMCP 的任务是建立起关于 MCP 的生态圈。因为我们认为,MCP 的开发在未来一段时间内会是一项高度定制化的工作,所以当前的重点并不是赶紧出做一个看起来什么都能做的 Agent,而是步步为营做出相关的生态和基础设施。 + 是的,OpenMCP 完全开源,您不仅可以免费使用此产品,也可以一起加入我们,实现你的关于 Agent 的奇思妙想。OpenMCP 的任务是建立起关于 MCP 的生态圈。因为我们认为,MCP 的开发在未来一段时间内会是一项高度定制化的工作,所以当前的重点并不是赶紧出做一个看起来什么都能做的 Agent,而是步步为营做出相关的生态和基础设施。 如果你试图通过 OpenMCP 开发一款什么都能做的,通用的 AI Agent,你应该做的是把钱全部投资到量子计算机的研发,而不是点开这个网站。记住一句话,这个时代做全领域通用AI Agent,依概率收敛到电信诈骗。 diff --git a/package-lock.json b/package-lock.json index 3ff8771..73d2836 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,9 @@ "dependencies": { "element-plus": "^2.9.11", "vitepress": "^1.6.3" + }, + "devDependencies": { + "vitepress-plugin-lightbox": "^1.0.2" } }, "node_modules/@algolia/autocomplete-core": { @@ -1771,6 +1774,13 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/medium-zoom": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.1.0.tgz", + "integrity": "sha512-ewyDsp7k4InCUp3jRmwHBRFGyjBimKps/AJLjRSox+2q/2H4p/PNpQf+pwONWlJiOudkBXtbdmVbFjqyybfTmQ==", + "dev": true, + "license": "MIT" + }, "node_modules/memoize-one": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", @@ -1909,6 +1919,16 @@ "resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==" }, + "node_modules/photoswipe": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/photoswipe/-/photoswipe-5.4.4.tgz", + "integrity": "sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.12.0" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", @@ -2294,6 +2314,17 @@ } } }, + "node_modules/vitepress-plugin-lightbox": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vitepress-plugin-lightbox/-/vitepress-plugin-lightbox-1.0.2.tgz", + "integrity": "sha512-CLgz6iWzhTH/Buk0y/SPRy0Ukh+X9QPD1HMAlpVcBPPpENlKwtxKUrAzqwxgh/vOz+6Q+Kw5nKfPH1yL78Rlag==", + "dev": true, + "license": "MIT", + "dependencies": { + "medium-zoom": "^1.1.0", + "photoswipe": "^5.4.4" + } + }, "node_modules/vue": { "version": "3.5.14", "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.14.tgz", diff --git a/package.json b/package.json index a33aeb6..cfe4928 100644 --- a/package.json +++ b/package.json @@ -8,5 +8,8 @@ "dependencies": { "element-plus": "^2.9.11", "vitepress": "^1.6.3" + }, + "devDependencies": { + "vitepress-plugin-lightbox": "^1.0.2" } } diff --git a/plugin-tutorial/usage/connect-mcp.md b/plugin-tutorial/usage/connect-mcp.md index e69de29..b0fafc9 100644 --- a/plugin-tutorial/usage/connect-mcp.md +++ b/plugin-tutorial/usage/connect-mcp.md @@ -0,0 +1,9 @@ +# 连接 mcp 服务器 + +不同于 Claude Desktop 和其他的 MCP 客户端类产品,OpenMCP 进行 MCP 服务器连接的步骤是相当丝滑的。 + +:::info MCP客户端 +MCP 客户端是指能够通过 MCP 协议进行通信的大模型对话客户端,通常是一个运行在本地的应用程序(因为网页没有文件IO的权限)。它的产品形式目前几乎都是聊天机器人的形式,类似于你在网页使用的 chat.deepseek.com 或者 chat.openai.com +::: + +首先,打开你的 VLE,在 [获取 OpenMCP](https://kirigaya.cn/openmcp/plugin-tutorial/acquire-openmcp.html) 中完成 OpenMCP 的安装后, \ No newline at end of file