书签管理服务器

Raindrop.io MCP服务器是一个模型上下文协议(MCP)服务器,通过OAuth或直接令牌认证,向MCP客户端暴露书签、集合、标签和高亮内容。

  • by Aarekaz
  • TypeScript
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 Aarekaz/raindrop-mcp

使用说明

Raindrop.io MCP服务器

Raindrop.io的模型上下文协议(MCP)服务器。它通过OAuth或直接令牌认证的Streamable HTTP向MCP客户端公开书签、集合、标签和突出显示。

特性

  • 收藏:列表、管理、合并、清理、重新排序、封面上传
  • 书签:搜索、创建/更新/删除、批量创建/删除、文件/封面上传
  • 标签:列表、重命名、合并、删除
  • 亮点:列表、创建、更新、删除
  • OAuth 2.0+PKCE或直接令牌认证
  • Cloudflare Workers部署,配备Workers KV支持的OAuth存储

需求

  • Bun 1.0+
  • 启用Workers的Cloudflare帐户
  • Raindrop.io帐户
  • 一种身份验证方法:
    • Raindrop OAuth应用程序+Workers KV,或
    • 雨滴API代币

设置

安装依赖项:

bun install

环境变量

OAuth(建议用于生产环境):

  • OAUTH_CLIENT_ID
  • OAUTH_CLIENT_SECRET
  • OAUTH_REDIRECT_URI (例如。 https://raindrop-mcp.anuragd.me/auth/callback)
  • OAUTH_ALLOWED_REDIRECT_URIS (逗号分隔)
  • TOKEN_ENCRYPTION_KEY (64个十六进制字符)
  • JWT_SIGNING_KEY
  • RAINDROP_AUTH_KV 配置了工人KV绑定 wrangler.jsonc

直接令牌回退(单用户):

  • RAINDROP_ACCESS_TOKEN
  • ALLOW_ENV_TOKEN_AUTH=true

部署范围广 RAINDROP_ACCESS_TOKEN 不建议将回退用于生产。它仅在以下情况下处于活动状态 ALLOW_ENV_TOKEN_AUTH 明确设置为 true;更喜欢OAuth或按请求 X-Raindrop-Token 用于生产用途的身份验证。

部署(Cloudflare Workers)

bunx wrangler login
bun run cf:kv:create
# copy the printed KV ids into wrangler.jsonc, then set secrets with wrangler
bun run deploy:cloudflare

看 文档/部署.md 用于完整的Cloudflare设置和烟雾测试。

托管服务器

使用生产MCP端点:

https://raindrop-mcp.anuragd.me/mcp

支持OAuth的MCP客户端将:

  1. 发现 /.well-known/oauth-protected-resource.
  2. 发现 /.well-known/oauth-authorization-server.
  3. 注册 /register.
  4. 打开 /authorize 使用PKC。
  5. 当不存在Raindrop会话时,通过Raindrop OAuth发送给您。
  6. 在以下位置交换授权码 /token.
  7. 呼叫 /mcp 持有已发行的不记名代币。

MCP客户端配置

{
  "mcpServers": {
    "raindrop": {
      "url": "https://raindrop-mcp.anuragd.me/mcp",
      "transport": "streamable-http"
    }
  }
}

如果使用直接令牌身份验证:

{
  "mcpServers": {
    "raindrop": {
      "url": "https://raindrop-mcp.anuragd.me/mcp",
      "transport": "streamable-http",
      "headers": {
        "X-Raindrop-Token": "your_token"
      }
    }
  }
}

端点

终点 目的
GET / 公共登录页面
GET /docs/ 静态设置/参考文档
GET /info 公共JSON功能摘要
POST /mcp MCP可流式HTTP端点
GET /.well-known/oauth-protected-resource 受保护的资源元数据
GET /.well-known/oauth-authorization-server 授权服务器元数据
POST /register 动态客户端注册
GET /authorize MCP OAuth授权条目
POST /authorize 同意批准/拒绝
POST /token 授权码和刷新令牌交换
GET /auth/init 内部Raindrop OAuth启动
GET /auth/callback 内部Raindrop OAuth回调

工具

收藏:

  • collection_list
  • collection_children_list
  • collection_manage
  • collection_bulk_delete
  • collection_reorder
  • collection_expand
  • collection_merge
  • collection_clean
  • collection_empty_trash
  • collection_cover_upload
  • user_stats

书签:

  • bookmark_search
  • bookmark_manage
  • bookmark_cache
  • bookmark_suggest_existing
  • bookmark_bulk_create
  • bookmark_bulk_delete
  • bookmark_file_upload
  • bookmark_cover_upload
  • bulk_edit_bookmarks
  • bookmark_statistics

标签:

  • tag_list
  • tag_manage

亮点:

  • highlight_manage

建筑

graph TB
    subgraph "Client Layer"
        Browser[Web Browser]
        MCPClient[MCP Client SDK]
    end

    subgraph "Transport Layer"
        Worker["Cloudflare Worker\nsrc/worker.ts"]
    end

    subgraph "Authentication Layer"
        OAuth["OAuth Service\nPKCE Flow"]
        TokenStorage["Token Storage\nAES-256 Encrypted"]
        WorkersKV["Workers KV\nRAINDROP_AUTH_KV"]

        OAuth --> TokenStorage
        TokenStorage --> WorkersKV
    end

    subgraph "MCP Protocol Layer"
        MCPService["MCP Server\nMCP SDK web transport"]
    end

    subgraph "Service Layer"
        RaindropService["RaindropService\nAPI Client\nopenapi-fetch"]
    end

    subgraph "External Services"
        RaindropAPI[Raindrop.io API]
    end

    MCPClient -->|HTTP| Worker

    Browser -->|HTTPS| Worker
    Worker -->|MCP auth wrapper| OAuth
    OAuth -->|Validated Token| MCPService
    MCPService -->|Per-User Token| RaindropService
    RaindropService -->|HTTP Requests| RaindropAPI

OAuth流

sequenceDiagram
    participant User
    participant Client as Client App
    participant Worker as Cloudflare Worker
    participant OAuth as OAuth Service
    participant KV as Workers KV
    participant Raindrop as Raindrop.io

    User->>Client: Add MCP endpoint
    Client->>Worker: GET /.well-known/oauth-protected-resource
    Worker->>Client: Protected resource metadata
    Client->>Worker: GET /.well-known/oauth-authorization-server
    Worker->>Client: Authorization metadata
    Client->>Worker: POST /register
    Worker->>KV: Store OAuth client
    Client->>Worker: GET /authorize with PKCE + resource
    Worker->>Client: Redirect to /auth/init when no Raindrop session exists
    Client->>Worker: GET /auth/init
    Worker->>Raindrop: Authorization request
    Raindrop->>User: Consent
    User->>Raindrop: Approve access
    Raindrop->>Worker: GET /auth/callback?code=XXX&state=YYY
    Worker->>KV: Store encrypted Raindrop token
    Worker->>Client: Continue /authorize consent
    User->>Worker: Approve MCP client
    Worker->>KV: Store authorization code
    Worker->>Client: Redirect with code
    Client->>Worker: POST /token
    Worker->>Client: JWT access token
    Client->>Worker: POST /mcp (Bearer JWT)
    Worker->>KV: Fetch encrypted Raindrop token
    Worker->>Raindrop: MCP operation with Raindrop token
    Raindrop->>Worker: Response
    Worker->>Client: MCP result

多租户模型

graph LR
    subgraph "Shared Server Instance"
        Endpoint["MCP Endpoint\n/mcp"]
        Auth[Auth Layer]

        subgraph "Request-Scoped Services"
            Service1["RaindropService\nUser 1 Token"]
            Service2["RaindropService\nUser 2 Token"]
            Service3["RaindropService\nUser 3 Token"]
        end
    end

    subgraph "Users"
        User1[User 1]
        User2[User 2]
        User3[User 3]
    end

    subgraph "Storage"
        KV["Workers KV"]
    end

    User1 -->|Bearer JWT| Endpoint
    User2 -->|X-Raindrop-Token| Endpoint
    User3 -->|Bearer JWT| Endpoint

    Endpoint --> Auth
    Auth --> KV

    Auth -->|Token A| Service1
    Auth -->|Token B| Service2
    Auth -->|Token C| Service3

    Service1 --> API[Raindrop.io API]
    Service2 --> API
    Service3 --> API

发展

bun run dev
bun run type-check
bun test

故障排除

  • 401:缺少身份验证(OAuth流未完成或没有X-Raindrop-Token)
  • 406:客户端必须发送 Accept: application/json, text/event-stream
  • 500:检查日志和令牌有效性

许可证

麻省理工学院