diff --git a/renderer/src/components/main-panel/prompt/index.vue b/renderer/src/components/main-panel/prompt/index.vue index 2c4962b..a680afd 100644 --- a/renderer/src/components/main-panel/prompt/index.vue +++ b/renderer/src/components/main-panel/prompt/index.vue @@ -1,27 +1,23 @@ diff --git a/servers/bing-picture.py b/servers/bing-picture.py new file mode 100644 index 0000000..cb858e2 --- /dev/null +++ b/servers/bing-picture.py @@ -0,0 +1,74 @@ +import requests +from pydantic import BaseModel +from typing import Optional, List +from mcp.server.fastmcp import FastMCP +from bs4 import BeautifulSoup +import json + + +from urllib import parse +import argparse +import os +import shutil +import uuid +import time +from threading import Thread +from typing import List + + +from bs4 import BeautifulSoup +import requests + +class ImageResult(BaseModel): + url: str + title: str + source: str + +class BingImage: + path = 'https://cn.bing.com/images/search' + block_num = 35 + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36" + } + +def bing_crawler(key_word: str, image_num: int) -> Optional[List[ImageResult]]: + query = { + 'q': key_word, + 'count': image_num + } + + url = BingImage.path + '?' + parse.urlencode(query) + res = requests.get(url, headers=BingImage.headers) + + soup = BeautifulSoup(res.content, "html.parser") + results = [] + for a in soup.select('.iusc'): + href = a.attrs['href'] + decode_href = parse.unquote(href) + media_url = decode_href.split('&')[4][9:] + title = a.get('alt', '') + + results.append(ImageResult( + url=media_url, + title=title, + source="bing" + )) + if len(results) >= image_num: + break + + return results if results else None + +mcp = FastMCP('image_crawler', version="0.0.1") + +@mcp.tool( + name='image_crawler', + description='根据关键词从指定搜索引擎爬取图片' +) +def image_crawler_tool(key_word: str, image_num: int) -> str: + """图片爬取工具,返回格式化字符串""" + images = bing_crawler(key_word, image_num) + return str(images) + +if __name__ == "__main__": + images = bing_crawler("明日方舟 m3", 5) + print(images) \ No newline at end of file diff --git a/servers/pyproject.toml b/servers/pyproject.toml index eb9d9aa..a0b504d 100644 --- a/servers/pyproject.toml +++ b/servers/pyproject.toml @@ -5,6 +5,7 @@ description = "Add your description here" readme = "README.md" requires-python = ">=3.11" dependencies = [ + "bs4>=0.0.2", "mcp[cli]>=1.5.0", "requests>=2.32.3", ] diff --git a/servers/uv.lock b/servers/uv.lock index e93bc3c..6c89493 100644 --- a/servers/uv.lock +++ b/servers/uv.lock @@ -25,6 +25,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916 }, ] +[[package]] +name = "beautifulsoup4" +version = "4.13.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285 }, +] + +[[package]] +name = "bs4" +version = "0.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/aa/4acaf814ff901145da37332e05bb510452ebed97bc9602695059dd46ef39/bs4-0.0.2.tar.gz", hash = "sha256:a48685c58f50fe127722417bae83fe6badf500d54b55f7e39ffe43b798653925", size = 698 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/bb/bf7aab772a159614954d84aa832c129624ba6c32faa559dfb200a534e50b/bs4-0.0.2-py2.py3-none-any.whl", hash = "sha256:abf8742c0805ef7f662dce4b51cca104cffe52b835238afc169142ab9b3fbccc", size = 1189 }, +] + [[package]] name = "certifi" version = "2025.1.31" @@ -335,12 +360,14 @@ name = "servers" version = "0.1.0" source = { virtual = "." } dependencies = [ + { name = "bs4" }, { name = "mcp", extra = ["cli"] }, { name = "requests" }, ] [package.metadata] requires-dist = [ + { name = "bs4", specifier = ">=0.0.2" }, { name = "mcp", extras = ["cli"], specifier = ">=1.5.0" }, { name = "requests", specifier = ">=2.32.3" }, ] @@ -363,6 +390,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] +[[package]] +name = "soupsieve" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, +] + [[package]] name = "sse-starlette" version = "2.2.1" diff --git a/service/src/controller/connect.ts b/service/src/controller/connect.ts index 0077bea..1e984a7 100644 --- a/service/src/controller/connect.ts +++ b/service/src/controller/connect.ts @@ -63,21 +63,9 @@ export class MCPClient { this.transport = new StdioClientTransport({ command: this.options.command || '', args: this.options.args || [], - cwd: this.options.cwd || process.cwd(), - // TODO - stderr: 'pipe' + cwd: this.options.cwd || process.cwd() }); - this.transport.onmessage = (message) => { - console.log('Received message from server:', message); - this.transportStdErr += message; - }; - - this.transport.onerror = (error) => { - console.log('Error from server:', error); - this.transportStdErr += error; - }; - break; case 'SSE': if (!this.options.url) { diff --git a/service/src/controller/index.ts b/service/src/controller/index.ts index ad8671d..ca2fc16 100644 --- a/service/src/controller/index.ts +++ b/service/src/controller/index.ts @@ -15,6 +15,9 @@ let client: MCPClient | undefined = undefined; function tryGetRunCommandError(command: string, args: string[] = [], cwd?: string): string | null { try { + console.log('current command', command); + console.log('current args', args); + const result = spawnSync(command, args, { cwd: cwd || process.cwd(), stdio: 'pipe', diff --git a/service/tabs.锦恢的 MCP Server.json b/service/tabs.锦恢的 MCP Server.json index d5e71b1..d5357c6 100644 --- a/service/tabs.锦恢的 MCP Server.json +++ b/service/tabs.锦恢的 MCP Server.json @@ -1,5 +1,5 @@ { - "currentIndex": 0, + "currentIndex": 2, "tabs": [ { "name": "交互测试", @@ -43,6 +43,24 @@ "systemPrompt": "" } } + }, + { + "name": "工具", + "icon": "icon-tool", + "type": "blank", + "componentIndex": 2, + "storage": { + "currentToolName": "add" + } + }, + { + "name": "资源", + "icon": "icon-file", + "type": "blank", + "componentIndex": 0, + "storage": { + "currentResourceName": "greeting" + } } ] } \ No newline at end of file