待办事项API服务

一个基于JSON-RPC 2.0和PostgreSQL的待办事项CRUD API服务,适用于个人任务管理和小型团队协作。

  • by izaqyos
  • JavaScript
  • 本地部署
  • 更新于
在 GitHub 查看 izaqyos/toymcp

使用说明

toyMCP待办事项列表服务器

这是一个简单的示例服务器,使用模型上下文协议(MCP)概念,特别是使用HTTP上的JSON-RPC 2.0实现To-Do-list CRUD API。

它使用Node.js、Express和PostgreSQL(通过Docker)实现持久性。

设置

  1. 先决条件:

    • Node.js(推荐LTS版本)
    • npm(通常随Node.js一起提供)
    • Docker和Docker Compose
  2. 克隆存储库(如果适用):

    # git clone ...
    # cd toyMCP
    
  3. 安装依赖关系:

    npm install
    
  4. 启动PostgreSQL数据库: 确保Docker桌面(或Docker守护进程)正在运行。

    docker compose up -d db
    

    这将启动一个名为的PostgreSQL容器 toymcp_db 在后台,为其数据创建一个持久卷。

  5. 运行服务器:

    npm start
    

    如有必要,服务器将初始化数据库架构,并开始监听 http://localhost:3000 (或指定的端口 PORT 环境变量)。 JSON-RPC端点为 http://localhost:3000/rpc. Swagger API文档用户界面位于 http://localhost:3000/api-docs.

清理服务器启动

如果需要确保服务器以全新的数据库启动(例如,在运行手动端到端测试或重置状态之前),可以使用 clean_start.sh 脚本:

  1. 停止正在运行的服务器 (如有)按 Ctrl+C 在它运行的终端。
  2. 确保脚本可执行:
    chmod +x clean_start.sh
    
  3. 运行脚本:
    ./clean_start.sh
    
    此脚本将停止并删除数据库容器(docker compose down),重新启动它(docker compose up -d db),然后启动Node.js服务器(npm start).

运行测试

确保PostgreSQL容器正在运行(docker compose up -d db).

测试分为 tests/unit_tests 和 tests/integration_tests。以下命令运行所有测试:

npm test

运行覆盖报告

npm run coverage

这将向终端输出摘要,并在 coverage/lcov-report/ 目录,反映了单元和集成测试的覆盖范围。

运行端到端测试脚本

该项目包括一个编排脚本(run_full_test.sh)它使用以下命令执行完整的测试序列 curl 包括预先清理数据库并提供摘要报告。这是执行手动端到端检查的推荐方法。

先决条件: curl, jq

chmod +x run_full_test.sh test_server.sh # Ensure scripts are executable
./run_full_test.sh

API文档

交互式API文档可通过Swagger UI在本地(当服务器运行时)和通过GitHub Pages部署:

  • 本地Swagger用户界面: http://localhost:3000/api-docs
  • GitHub页面交换用户界面: https://izaqyos.github.io/toyMCP/swagger-ui/

文档是根据JSDoc注释自动生成的 src/swagger_definitions.js 使用 swagger-jsdoc.

API使用(通过HTTP POST的JSON-RPC 2.0)

向发送POST请求 http://localhost:3000/rpc 随着 Content-Type: application/json 以及体内的JSON-RPC 2.0有效载荷。

示例工具: curl

  • 添加项目(todo.add)

    curl -X POST -H "Content-Type: application/json" \
         -d '{"jsonrpc": "2.0", "method": "todo.add", "params": {"text": "Buy groceries"}, "id": 1}' \
         http://localhost:3000/rpc
    

    成功响应:

    {
        "jsonrpc": "2.0",
        "result": {
            "id": 1,
            "text": "Buy groceries",
            "created_at": "2025-04-07T16:15:00.123Z"
        },
        "id": 1
    }
    
  • 列出项目(todo.list)

    curl -X POST -H "Content-Type: application/json" \
         -d '{"jsonrpc": "2.0", "method": "todo.list", "id": 2}' \
         http://localhost:3000/rpc
    

    成功响应(示例):

    {
        "jsonrpc": "2.0",
        "result": [
            {
                "id": 1,
                "text": "Buy groceries",
                "created_at": "2025-04-07T16:15:00.123Z"
            }
            // ... other items
        ],
        "id": 2
    }
    
  • 删除项目(todo.remove) (假设ID为1的项目存在)

    curl -X POST -H "Content-Type: application/json" \
         -d '{"jsonrpc": "2.0", "method": "todo.remove", "params": {"id": 1}, "id": 3}' \
         http://localhost:3000/rpc
    

    成功响应:

    {
        "jsonrpc": "2.0",
        "result": {
            "id": 1,
            "text": "Buy groceries",
            "created_at": "2025-04-07T16:15:00.123Z"
        },
        "id": 3
    }
    
  • 错误响应示例(未找到项目)

    # Request to remove ID 999 which doesn't exist
    curl -X POST -H "Content-Type: application/json" \
         -d '{"jsonrpc": "2.0", "method": "todo.remove", "params": {"id": 999}, "id": 4}' \
         http://localhost:3000/rpc
    

    答复:

    {
        "jsonrpc": "2.0",
        "error": {
            "code": 1001,
            "message": "Todo item with ID 999 not found"
        },
        "id": 4
    }