cnks 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
    
        cnks/server.py
    CHANGED
    
    | @@ -7,8 +7,10 @@ import subprocess | |
| 7 7 | 
             
            import sys
         | 
| 8 8 | 
             
            import time
         | 
| 9 9 | 
             
            import logging
         | 
| 10 | 
            +
            import webbrowser
         | 
| 10 11 | 
             
            from pathlib import Path
         | 
| 11 12 | 
             
            from urllib.parse import quote
         | 
| 13 | 
            +
            from typing import Dict, List, Any, Optional, Union
         | 
| 12 14 |  | 
| 13 15 | 
             
            from mcp.server.models import InitializationOptions
         | 
| 14 16 | 
             
            import mcp.types as types
         | 
| @@ -97,6 +99,8 @@ def open_chrome(url): | |
| 97 99 |  | 
| 98 100 | 
             
            async def search_with_playwright(keywords):
         | 
| 99 101 | 
             
                """使用playwright在知网搜索关键词"""
         | 
| 102 | 
            +
                global page_content
         | 
| 103 | 
            +
                
         | 
| 100 104 | 
             
                if not PLAYWRIGHT_AVAILABLE:
         | 
| 101 105 | 
             
                    return "需要安装playwright模块:uv add playwright"
         | 
| 102 106 |  | 
| @@ -216,7 +220,7 @@ async def search_with_playwright(keywords): | |
| 216 220 | 
             
                                                        # 查找所有包含"article/abstract?v="字样的链接
         | 
| 217 221 | 
             
                                                        links_count = await find_and_count_abstract_links(page)
         | 
| 218 222 |  | 
| 219 | 
            -
                                                        return  | 
| 223 | 
            +
                                                        return links_count
         | 
| 220 224 | 
             
                                                    else:
         | 
| 221 225 | 
             
                                                        logger.debug("[DEBUG] 在来源类别区域未找到CSSCI选项")
         | 
| 222 226 |  | 
| @@ -231,9 +235,11 @@ async def search_with_playwright(keywords): | |
| 231 235 | 
             
                                                            # 查找所有包含"article/abstract?v="字样的链接
         | 
| 232 236 | 
             
                                                            links_count = await find_and_count_abstract_links(page)
         | 
| 233 237 |  | 
| 234 | 
            -
                                                            return  | 
| 238 | 
            +
                                                            return links_count
         | 
| 235 239 | 
             
                                                        else:
         | 
| 236 | 
            -
                                                             | 
| 240 | 
            +
                                                            # 查找所有包含"article/abstract?v="字样的链接
         | 
| 241 | 
            +
                                                            links_count = await find_and_count_abstract_links(page)
         | 
| 242 | 
            +
                                                            return links_count
         | 
| 237 243 | 
             
                                                else:
         | 
| 238 244 | 
             
                                                    logger.debug("[DEBUG] 未找到来源类别区域")
         | 
| 239 245 |  | 
| @@ -248,61 +254,127 @@ async def search_with_playwright(keywords): | |
| 248 254 | 
             
                                                        # 查找所有包含"article/abstract?v="字样的链接
         | 
| 249 255 | 
             
                                                        links_count = await find_and_count_abstract_links(page)
         | 
| 250 256 |  | 
| 251 | 
            -
                                                        return  | 
| 257 | 
            +
                                                        return links_count
         | 
| 252 258 | 
             
                                                    else:
         | 
| 253 | 
            -
                                                         | 
| 259 | 
            +
                                                        # 查找所有包含"article/abstract?v="字样的链接
         | 
| 260 | 
            +
                                                        links_count = await find_and_count_abstract_links(page)
         | 
| 261 | 
            +
                                                        return links_count
         | 
| 254 262 | 
             
                                            except Exception as e:
         | 
| 255 263 | 
             
                                                logger.debug(f"[DEBUG] 勾选CSSCI选项时出错: {str(e)}")
         | 
| 256 | 
            -
                                                 | 
| 264 | 
            +
                                                # 查找所有包含"article/abstract?v="字样的链接
         | 
| 265 | 
            +
                                                links_count = await find_and_count_abstract_links(page)
         | 
| 266 | 
            +
                                                return links_count
         | 
| 257 267 |  | 
| 258 | 
            -
                                             | 
| 268 | 
            +
                                            # 查找所有包含"article/abstract?v="字样的链接
         | 
| 269 | 
            +
                                            links_count = await find_and_count_abstract_links(page)
         | 
| 270 | 
            +
                                            return links_count
         | 
| 259 271 | 
             
                                        else:
         | 
| 260 272 | 
             
                                            logger.debug("[DEBUG] 未找到'50'选项")
         | 
| 261 | 
            -
                                             | 
| 273 | 
            +
                                            page_content = {
         | 
| 274 | 
            +
                                                "count": 0,
         | 
| 275 | 
            +
                                                "links": [],
         | 
| 276 | 
            +
                                                "error": "已搜索并点击下拉框,但未找到'50'选项"
         | 
| 277 | 
            +
                                            }
         | 
| 278 | 
            +
                                            return 0
         | 
| 262 279 | 
             
                                    else:
         | 
| 263 280 | 
             
                                        logger.debug("[DEBUG] 未找到排序下拉框")
         | 
| 264 | 
            -
                                         | 
| 281 | 
            +
                                        page_content = {
         | 
| 282 | 
            +
                                            "count": 0,
         | 
| 283 | 
            +
                                            "links": [],
         | 
| 284 | 
            +
                                            "error": "已搜索,但未找到排序下拉框"
         | 
| 285 | 
            +
                                        }
         | 
| 286 | 
            +
                                        return 0
         | 
| 265 287 | 
             
                                except Exception as e:
         | 
| 266 288 | 
             
                                    logger.debug(f"[DEBUG] 点击下拉框或选项时出错: {str(e)}")
         | 
| 267 | 
            -
                                     | 
| 268 | 
            -
             | 
| 269 | 
            -
             | 
| 270 | 
            -
             | 
| 289 | 
            +
                                    page_content = {
         | 
| 290 | 
            +
                                        "count": 0,
         | 
| 291 | 
            +
                                        "links": [],
         | 
| 292 | 
            +
                                        "error": f"已搜索,但在点击下拉框或选项时出错: {str(e)}"
         | 
| 293 | 
            +
                                    }
         | 
| 294 | 
            +
                                    return 0
         | 
| 271 295 | 
             
                            else:
         | 
| 272 296 | 
             
                                # 不关闭浏览器
         | 
| 273 | 
            -
                                 | 
| 297 | 
            +
                                page_content = {
         | 
| 298 | 
            +
                                    "count": 0,
         | 
| 299 | 
            +
                                    "links": [],
         | 
| 300 | 
            +
                                    "error": f"已填写搜索关键词: {keywords},但未找到搜索按钮"
         | 
| 301 | 
            +
                                }
         | 
| 302 | 
            +
                                return 0
         | 
| 274 303 | 
             
                        else:
         | 
| 275 304 | 
             
                            # 不关闭浏览器
         | 
| 276 | 
            -
                             | 
| 305 | 
            +
                            page_content = {
         | 
| 306 | 
            +
                                "count": 0,
         | 
| 307 | 
            +
                                "links": [],
         | 
| 308 | 
            +
                                "error": f"未找到搜索框,无法搜索: {keywords}"
         | 
| 309 | 
            +
                            }
         | 
| 310 | 
            +
                            return 0
         | 
| 277 311 | 
             
                    except Exception as e:
         | 
| 278 312 | 
             
                        logger.debug(f"[DEBUG] 填写搜索框或点击搜索按钮时出错: {str(e)}")
         | 
| 279 313 | 
             
                        # 不关闭浏览器
         | 
| 280 | 
            -
                         | 
| 314 | 
            +
                        page_content = {
         | 
| 315 | 
            +
                            "count": 0,
         | 
| 316 | 
            +
                            "links": [],
         | 
| 317 | 
            +
                            "error": f"自动搜索过程中出错: {str(e)}"
         | 
| 318 | 
            +
                        }
         | 
| 319 | 
            +
                        return 0
         | 
| 281 320 | 
             
                except Exception as e:
         | 
| 282 321 | 
             
                    error_msg = str(e)
         | 
| 283 322 | 
             
                    logger.debug(f"[DEBUG] Playwright错误: {error_msg}")
         | 
| 284 323 |  | 
| 285 324 | 
             
                    # 如果是找不到Chrome的错误,提供更明确的指导
         | 
| 286 325 | 
             
                    if "Executable doesn't exist" in error_msg and "ms-playwright" in error_msg:
         | 
| 287 | 
            -
                         | 
| 288 | 
            -
                    
         | 
| 289 | 
            -
             | 
| 290 | 
            -
             | 
| 326 | 
            +
                        error_message = f"需要安装Playwright的浏览器: playwright install\n如果您想使用系统Chrome,请重新启动服务器。\n\n{error_msg}"
         | 
| 327 | 
            +
                    else:
         | 
| 328 | 
            +
                        error_message = f"使用Playwright启动Chrome失败: {error_msg}"
         | 
| 329 | 
            +
                        
         | 
| 330 | 
            +
                    page_content = {
         | 
| 331 | 
            +
                        "count": 0,
         | 
| 332 | 
            +
                        "links": [],
         | 
| 333 | 
            +
                        "error": error_message
         | 
| 334 | 
            +
                    }
         | 
| 335 | 
            +
                    return 0
         | 
| 291 336 |  | 
| 292 337 | 
             
            def search_with_direct_chrome(keywords):
         | 
| 293 338 | 
             
                """直接使用Chrome搜索,不使用playwright"""
         | 
| 294 | 
            -
                 | 
| 295 | 
            -
                
         | 
| 296 | 
            -
                # 构建知网搜索URL - 知网不支持URL参数搜索,所以只能打开页面
         | 
| 297 | 
            -
                url = "https://kns.cnki.net/kns8s/search"
         | 
| 339 | 
            +
                global page_content
         | 
| 298 340 |  | 
| 299 | 
            -
                 | 
| 300 | 
            -
                result = open_chrome(url)
         | 
| 341 | 
            +
                logger.debug("[DEBUG] 正在使用search_with_direct_chrome函数")
         | 
| 301 342 |  | 
| 302 | 
            -
                 | 
| 303 | 
            -
                     | 
| 304 | 
            -
             | 
| 305 | 
            -
                     | 
| 343 | 
            +
                try:
         | 
| 344 | 
            +
                    url = f"https://kns.cnki.net/kns8s/search?q={quote(keywords)}"
         | 
| 345 | 
            +
                    logger.debug(f"[DEBUG] 打开URL: {url}")
         | 
| 346 | 
            +
                    
         | 
| 347 | 
            +
                    result = open_chrome(url)
         | 
| 348 | 
            +
                    
         | 
| 349 | 
            +
                    if isinstance(result, str) and "打开Chrome" in result:
         | 
| 350 | 
            +
                        logger.debug(f"[DEBUG] 直接打开Chrome结果: {result}")
         | 
| 351 | 
            +
                        
         | 
| 352 | 
            +
                        page_content = {
         | 
| 353 | 
            +
                            "count": 0,
         | 
| 354 | 
            +
                            "links": [],
         | 
| 355 | 
            +
                            "error": f"直接打开Chrome搜索: {result}"
         | 
| 356 | 
            +
                        }
         | 
| 357 | 
            +
                        
         | 
| 358 | 
            +
                    else:
         | 
| 359 | 
            +
                        logger.debug("[DEBUG] 直接打开Chrome成功")
         | 
| 360 | 
            +
                        
         | 
| 361 | 
            +
                        page_content = {
         | 
| 362 | 
            +
                            "count": 0,
         | 
| 363 | 
            +
                            "links": [],
         | 
| 364 | 
            +
                            "message": "已打开Chrome并搜索关键词,但无法自动获取链接。请安装playwright以获取完整功能。"
         | 
| 365 | 
            +
                        }
         | 
| 366 | 
            +
                    
         | 
| 367 | 
            +
                    return page_content
         | 
| 368 | 
            +
                except Exception as e:
         | 
| 369 | 
            +
                    logger.debug(f"[DEBUG] search_with_direct_chrome出错: {str(e)}")
         | 
| 370 | 
            +
                    
         | 
| 371 | 
            +
                    page_content = {
         | 
| 372 | 
            +
                        "count": 0,
         | 
| 373 | 
            +
                        "links": [],
         | 
| 374 | 
            +
                        "error": f"使用Chrome搜索时出错: {str(e)}"
         | 
| 375 | 
            +
                    }
         | 
| 376 | 
            +
                    
         | 
| 377 | 
            +
                    return page_content
         | 
| 306 378 |  | 
| 307 379 | 
             
            def get_page_content():
         | 
| 308 380 | 
             
                """获取当前页面内容(简化模拟)"""
         | 
| @@ -515,15 +587,6 @@ async def handle_get_prompt( | |
| 515 587 | 
             
            async def handle_list_tools() -> list[types.Tool]:
         | 
| 516 588 | 
             
                """列出可用工具"""
         | 
| 517 589 | 
             
                return [
         | 
| 518 | 
            -
                    types.Tool(
         | 
| 519 | 
            -
                        name="open-cnki",
         | 
| 520 | 
            -
                        description="打开中国知网搜索页面",
         | 
| 521 | 
            -
                        inputSchema={
         | 
| 522 | 
            -
                            "type": "object",
         | 
| 523 | 
            -
                            "properties": {},
         | 
| 524 | 
            -
                            "required": [],
         | 
| 525 | 
            -
                        },
         | 
| 526 | 
            -
                    ),
         | 
| 527 590 | 
             
                    types.Tool(
         | 
| 528 591 | 
             
                        name="search-keywords",
         | 
| 529 592 | 
             
                        description="在知网搜索关键词",
         | 
| @@ -547,15 +610,6 @@ async def handle_list_tools() -> list[types.Tool]: | |
| 547 610 | 
             
                            "required": ["name", "content"],
         | 
| 548 611 | 
             
                        },
         | 
| 549 612 | 
             
                    ),
         | 
| 550 | 
            -
                    types.Tool(
         | 
| 551 | 
            -
                        name="get-abstract-links",
         | 
| 552 | 
            -
                        description="获取最近一次搜索找到的论文摘要链接",
         | 
| 553 | 
            -
                        inputSchema={
         | 
| 554 | 
            -
                            "type": "object",
         | 
| 555 | 
            -
                            "properties": {},
         | 
| 556 | 
            -
                            "required": [],
         | 
| 557 | 
            -
                        },
         | 
| 558 | 
            -
                    )
         | 
| 559 613 | 
             
                ]
         | 
| 560 614 |  | 
| 561 615 | 
             
            @server.call_tool()
         | 
| @@ -565,25 +619,7 @@ async def handle_call_tool( | |
| 565 619 | 
             
                """处理工具执行请求"""
         | 
| 566 620 | 
             
                global current_url, page_content
         | 
| 567 621 |  | 
| 568 | 
            -
                if name == " | 
| 569 | 
            -
                    current_url = "https://kns.cnki.net/kns8s/search"
         | 
| 570 | 
            -
                    result = open_chrome(current_url)
         | 
| 571 | 
            -
                    if result is True:
         | 
| 572 | 
            -
                        return [
         | 
| 573 | 
            -
                            types.TextContent(
         | 
| 574 | 
            -
                                type="text",
         | 
| 575 | 
            -
                                text="已打开中国知网搜索页面。"
         | 
| 576 | 
            -
                            )
         | 
| 577 | 
            -
                        ]
         | 
| 578 | 
            -
                    else:
         | 
| 579 | 
            -
                        return [
         | 
| 580 | 
            -
                            types.TextContent(
         | 
| 581 | 
            -
                                type="text",
         | 
| 582 | 
            -
                                text=f"打开中国知网时出错: {result}"
         | 
| 583 | 
            -
                            )
         | 
| 584 | 
            -
                        ]
         | 
| 585 | 
            -
                
         | 
| 586 | 
            -
                elif name == "search-keywords":
         | 
| 622 | 
            +
                if name == "search-keywords":
         | 
| 587 623 | 
             
                    if not arguments:
         | 
| 588 624 | 
             
                        raise ValueError("缺少参数")
         | 
| 589 625 |  | 
| @@ -593,24 +629,47 @@ async def handle_call_tool( | |
| 593 629 |  | 
| 594 630 | 
             
                    # 优先使用playwright进行搜索
         | 
| 595 631 | 
             
                    if PLAYWRIGHT_AVAILABLE:
         | 
| 596 | 
            -
                         | 
| 632 | 
            +
                        links_count = await search_with_playwright(keywords)
         | 
| 597 633 | 
             
                        current_url = "https://kns.cnki.net/kns8s/search"
         | 
| 598 634 |  | 
| 599 | 
            -
                         | 
| 600 | 
            -
             | 
| 601 | 
            -
             | 
| 602 | 
            -
                                 | 
| 603 | 
            -
             | 
| 604 | 
            -
             | 
| 635 | 
            +
                        # 返回结构化数据
         | 
| 636 | 
            +
                        if isinstance(page_content, dict):
         | 
| 637 | 
            +
                            return [
         | 
| 638 | 
            +
                                types.TextContent(
         | 
| 639 | 
            +
                                    type="text",
         | 
| 640 | 
            +
                                    text=json.dumps(page_content, ensure_ascii=False)
         | 
| 641 | 
            +
                                )
         | 
| 642 | 
            +
                            ]
         | 
| 643 | 
            +
                        else:
         | 
| 644 | 
            +
                            # 如果page_content不是字典,返回空结构
         | 
| 645 | 
            +
                            error_result = {
         | 
| 646 | 
            +
                                "count": 0,
         | 
| 647 | 
            +
                                "links": [],
         | 
| 648 | 
            +
                                "error": "搜索执行失败或结果格式异常"
         | 
| 649 | 
            +
                            }
         | 
| 650 | 
            +
                            return [
         | 
| 651 | 
            +
                                types.TextContent(
         | 
| 652 | 
            +
                                    type="text",
         | 
| 653 | 
            +
                                    text=json.dumps(error_result, ensure_ascii=False)
         | 
| 654 | 
            +
                                )
         | 
| 655 | 
            +
                            ]
         | 
| 605 656 | 
             
                    else:
         | 
| 606 657 | 
             
                        # 如果没有playwright,回退到传统方式
         | 
| 607 658 | 
             
                        result = search_with_direct_chrome(keywords)
         | 
| 608 659 | 
             
                        current_url = "https://kns.cnki.net/kns8s/search"
         | 
| 609 660 |  | 
| 661 | 
            +
                        # 确保结果是字典格式
         | 
| 662 | 
            +
                        if not isinstance(result, dict):
         | 
| 663 | 
            +
                            result = {
         | 
| 664 | 
            +
                                "count": 0,
         | 
| 665 | 
            +
                                "links": [],
         | 
| 666 | 
            +
                                "error": "需要安装playwright以获取链接: uv add playwright"
         | 
| 667 | 
            +
                            }
         | 
| 668 | 
            +
                            
         | 
| 610 669 | 
             
                        return [
         | 
| 611 670 | 
             
                            types.TextContent(
         | 
| 612 671 | 
             
                                type="text",
         | 
| 613 | 
            -
                                text= | 
| 672 | 
            +
                                text=json.dumps(result, ensure_ascii=False)
         | 
| 614 673 | 
             
                            )
         | 
| 615 674 | 
             
                        ]
         | 
| 616 675 |  | 
| @@ -637,26 +696,12 @@ async def handle_call_tool( | |
| 637 696 | 
             
                        )
         | 
| 638 697 | 
             
                    ]
         | 
| 639 698 |  | 
| 640 | 
            -
                elif name == "get-abstract-links":
         | 
| 641 | 
            -
                    if not page_content or "找到" not in page_content:
         | 
| 642 | 
            -
                        return [
         | 
| 643 | 
            -
                            types.TextContent(
         | 
| 644 | 
            -
                                type="text",
         | 
| 645 | 
            -
                                text="尚未执行搜索或未找到链接。请先使用search-keywords工具搜索。"
         | 
| 646 | 
            -
                            )
         | 
| 647 | 
            -
                        ]
         | 
| 648 | 
            -
                    
         | 
| 649 | 
            -
                    return [
         | 
| 650 | 
            -
                        types.TextContent(
         | 
| 651 | 
            -
                            type="text",
         | 
| 652 | 
            -
                            text=page_content
         | 
| 653 | 
            -
                        )
         | 
| 654 | 
            -
                    ]
         | 
| 655 | 
            -
                
         | 
| 656 699 | 
             
                raise ValueError(f"未知工具: {name}")
         | 
| 657 700 |  | 
| 658 701 | 
             
            async def find_and_count_abstract_links(page):
         | 
| 659 702 | 
             
                """查找并统计包含article/abstract?v=的链接"""
         | 
| 703 | 
            +
                global page_content
         | 
| 704 | 
            +
                
         | 
| 660 705 | 
             
                try:
         | 
| 661 706 | 
             
                    logger.debug("[DEBUG] 开始查找所有包含article/abstract?v=的链接")
         | 
| 662 707 |  | 
| @@ -690,11 +735,11 @@ async def find_and_count_abstract_links(page): | |
| 690 735 | 
             
                    else:
         | 
| 691 736 | 
             
                        logger.debug(f"[DEBUG] 链接数量为{links_count}条,多于预期的50条")
         | 
| 692 737 |  | 
| 693 | 
            -
                    # 存储结果 -  | 
| 694 | 
            -
                     | 
| 695 | 
            -
             | 
| 696 | 
            -
                         | 
| 697 | 
            -
                     | 
| 738 | 
            +
                    # 存储结果 - 使用字典结构而不是纯文本
         | 
| 739 | 
            +
                    page_content = {
         | 
| 740 | 
            +
                        "count": links_count,
         | 
| 741 | 
            +
                        "links": [{"index": link['index'], "url": link['href']} for link in links_info]
         | 
| 742 | 
            +
                    }
         | 
| 698 743 |  | 
| 699 744 | 
             
                    return links_count
         | 
| 700 745 | 
             
                except Exception as e:
         | 
| @@ -710,7 +755,7 @@ async def main(): | |
| 710 755 | 
             
                        write_stream,
         | 
| 711 756 | 
             
                        InitializationOptions(
         | 
| 712 757 | 
             
                            server_name="cnks",
         | 
| 713 | 
            -
                            server_version="0.1. | 
| 758 | 
            +
                            server_version="0.1.1",
         | 
| 714 759 | 
             
                            capabilities=server.get_capabilities(
         | 
| 715 760 | 
             
                                notification_options=NotificationOptions(),
         | 
| 716 761 | 
             
                                experimental_capabilities={},
         | 
| @@ -726,27 +771,28 @@ def create_fastmcp_server(): | |
| 726 771 | 
             
                    fast_mcp = FastMCP("知网搜索")
         | 
| 727 772 |  | 
| 728 773 | 
             
                    @fast_mcp.tool()
         | 
| 729 | 
            -
                    def  | 
| 730 | 
            -
                        """ | 
| 731 | 
            -
                        return open_chrome("https://kns.cnki.net/kns8s/search")
         | 
| 732 | 
            -
                    
         | 
| 733 | 
            -
                    @fast_mcp.tool()
         | 
| 734 | 
            -
                    async def search_keywords(keywords: str) -> str:
         | 
| 735 | 
            -
                        """在知网搜索关键词"""
         | 
| 774 | 
            +
                    async def search_keywords(keywords: str) -> dict:
         | 
| 775 | 
            +
                        """在知网搜索关键词并返回50个论文链接"""
         | 
| 736 776 | 
             
                        logger.debug("[DEBUG] 正在使用FastMCP的search_keywords函数")
         | 
| 737 777 | 
             
                        if PLAYWRIGHT_AVAILABLE:
         | 
| 738 | 
            -
                             | 
| 739 | 
            -
                             | 
| 778 | 
            +
                            result_count = await search_with_playwright(keywords)
         | 
| 779 | 
            +
                            # 返回结构化数据
         | 
| 780 | 
            +
                            if isinstance(page_content, dict):
         | 
| 781 | 
            +
                                return page_content
         | 
| 782 | 
            +
                            else:
         | 
| 783 | 
            +
                                # 如果page_content不是字典,返回空结构
         | 
| 784 | 
            +
                                return {
         | 
| 785 | 
            +
                                    "count": 0,
         | 
| 786 | 
            +
                                    "links": [],
         | 
| 787 | 
            +
                                    "error": "搜索执行失败或结果格式异常"
         | 
| 788 | 
            +
                                }
         | 
| 740 789 | 
             
                        else:
         | 
| 741 | 
            -
                             | 
| 742 | 
            -
                            return  | 
| 743 | 
            -
             | 
| 744 | 
            -
             | 
| 745 | 
            -
             | 
| 746 | 
            -
             | 
| 747 | 
            -
                        if not page_content or "找到" not in page_content:
         | 
| 748 | 
            -
                            return "尚未执行搜索或未找到链接。请先使用search_keywords工具搜索。"
         | 
| 749 | 
            -
                        return page_content
         | 
| 790 | 
            +
                            # 直接Chrome方式不会返回链接
         | 
| 791 | 
            +
                            return {
         | 
| 792 | 
            +
                                "count": 0,
         | 
| 793 | 
            +
                                "links": [],
         | 
| 794 | 
            +
                                "error": "需要安装playwright以获取链接: uv add playwright"
         | 
| 795 | 
            +
                            }
         | 
| 750 796 |  | 
| 751 797 | 
             
                    @fast_mcp.resource("webpage://current")
         | 
| 752 798 | 
             
                    def get_current_webpage() -> str:
         | 
| @@ -0,0 +1,6 @@ | |
| 1 | 
            +
            cnks/__init__.py,sha256=Sdhdrl3THgmQ5s_eMFKkggxDSrxP8HUN8dj63ddE6xQ,1266
         | 
| 2 | 
            +
            cnks/server.py,sha256=R3l0SUfajuUBU_cSrOpIDSlaVf2Z4MtXMEeHJewrkqU,32356
         | 
| 3 | 
            +
            cnks-0.1.1.dist-info/METADATA,sha256=4-9Nf2YNCZp7x8mWRMKf8ot41LehU2Vsxi_qLd6Tivk,22797
         | 
| 4 | 
            +
            cnks-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
         | 
| 5 | 
            +
            cnks-0.1.1.dist-info/entry_points.txt,sha256=OkIiD7Ctn1Fn5B5zY09ltFFjIA8mJd3lw5V20AGtyYg,35
         | 
| 6 | 
            +
            cnks-0.1.1.dist-info/RECORD,,
         | 
    
        cnks-0.1.0.dist-info/RECORD
    DELETED
    
    | @@ -1,6 +0,0 @@ | |
| 1 | 
            -
            cnks/__init__.py,sha256=Sdhdrl3THgmQ5s_eMFKkggxDSrxP8HUN8dj63ddE6xQ,1266
         | 
| 2 | 
            -
            cnks/server.py,sha256=m9jCDDBmjsYs9hE8okChGGyhkLC9k82njjHHaE-Jy7c,31534
         | 
| 3 | 
            -
            cnks-0.1.0.dist-info/METADATA,sha256=q-7GjkhKon6H_OPiilqBGkquGd3ZiYiyRZBYpep7S1I,22797
         | 
| 4 | 
            -
            cnks-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
         | 
| 5 | 
            -
            cnks-0.1.0.dist-info/entry_points.txt,sha256=OkIiD7Ctn1Fn5B5zY09ltFFjIA8mJd3lw5V20AGtyYg,35
         | 
| 6 | 
            -
            cnks-0.1.0.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         |