Asana双向同步服务器

提供Asana工作区与本地parquet数据之间的双向同步、导入、导出和元数据管理的MCP服务器。

  • by markmhendrickson
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 markmhendrickson/mcp-server-asana

使用说明

Asana MCP服务器

用于Asana集成的MCP服务器,提供Asana工作区和本地拼花地板数据之间的双向同步、导入、导出和元数据管理。

学分

此MCP服务器整合了个人工作流存储库中Asana集成脚本的功能,为AI助手提供了一个标准化的界面。

特性

  • 双向同步:Asana工作空间和当地拼花地板之间的三向融合同步
  • 任务导入:通过智能合并从Asana导入任务
  • 任务导出:通过重复检测将本地任务导出到Asana
  • 评论导入:导入任务注释和附件
  • 元数据导入:导入自定义字段、依赖项和故事
  • Webhook注册:注册webhooks进行实时同步
  • 实用工具:获取单个任务、列出项目、获取工作区信息
  • 镶木MCP集成:所有数据操作都通过镶木MCP服务器
  • 全面测试覆盖:所有功能覆盖率>90%

安装

cd execution/mcp-servers/asana
pip install -r requirements.txt

测试

看 测试.md 获取全面的测试指南。

快速入门:

# Install test dependencies
pip install -r requirements-test.txt

# Run unit tests (fast, no external dependencies)
pytest -m unit

# Run all tests
pytest

配置

认证

服务器支持多种身份验证方法(按优先级顺序检查):

  1. 环境变量 (推荐,最高优先级):

    export ASANA_SOURCE_PAT="your-source-pat"
    export ASANA_TARGET_PAT="your-target-pat"  # Optional, defaults to source
    export SOURCE_WORKSPACE_GID="source-workspace-gid"
    export TARGET_WORKSPACE_GID="target-workspace-gid"
    export FALLBACK_ASSIGNEE_EMAIL="your@email.com"  # Optional
    
  2. 配置目录 .env 文件 (便携式,用户特定):

    • 地点: ~/.config/asana-mcp/.env
    • 格式:
      ASANA_SOURCE_PAT=your-source-pat
      ASANA_TARGET_PAT=your-target-pat
      SOURCE_WORKSPACE_GID=source-workspace-gid
      TARGET_WORKSPACE_GID=target-workspace-gid
      FALLBACK_ASSIGNEE_EMAIL=your@email.com
      
    • 首次使用时会自动创建配置目录
  3. 1密码集成 (可选,为了向后兼容):

    • 仅当父存储库结构存在时才可用
    • 配置标题为“Asana”的1Password项目
    • 添加字段:“source_pat”、“target_pat”和“source_workspace_gid”

注: MCP服务器是独立的、可移植的。它不需要任何特定的存储库结构。

拼花MCP服务器

此服务器需要配置和访问镶木地板MCP服务器。服务器会自动检测拼花地板服务器的位置,或者您可以设置:

export PARQUET_MCP_SERVER_PATH="/path/to/parquet_mcp_server.py"

光标配置

添加到光标MCP设置(通常 ~/.cursor/mcp.json 或光标设置):

{
  "mcpServers": {
    "asana": {
      "command": "python3",
      "args": [
        "/path/to/asana_mcp_server.py"
      ],
      "env": {
        "ASANA_SOURCE_PAT": "your-source-pat",
        "SOURCE_WORKSPACE_GID": "source-workspace-gid",
        "TARGET_WORKSPACE_GID": "target-workspace-gid"
      }
    }
  }
}

注: 替换 /path/to/asana_mcp_server.py 以及服务器文件的实际路径。

Claude桌面配置

增添 claude_desktop_config.json (通常 ~/Library/Application Support/Claude/claude_desktop_config.json 在macOS上):

{
  "mcpServers": {
    "asana": {
      "command": "python3",
      "args": [
        "/path/to/asana_mcp_server.py"
      ],
      "env": {
        "ASANA_SOURCE_PAT": "your-source-pat",
        "SOURCE_WORKSPACE_GID": "source-workspace-gid",
        "TARGET_WORKSPACE_GID": "target-workspace-gid"
      }
    }
  }
}

注: 替换 /path/to/asana_mcp_server.py 以及服务器文件的实际路径。

可用工具

import_asana_tasks

通过拼花地板MCP服务器将任务从Asana工作区导入本地拼花地板。

参数:

  • workspace (可选):要从中导入的工作区(“源”或“目标”,默认值:“源”)
  • only_incomplete (可选):仅获取未完成的任务(默认值:false)
  • assignee_gid (可选):按受让人GID筛选任务
  • max_tasks (可选):要导入的最大任务数
  • recalculate (可选):强制重新计算域(默认值:false)
  • include_archived (可选):包括存档项目中的任务(默认值:true)

退货:

  • success:布尔值表示成功
  • workspace:从导入的工作区
  • fetched:从Asana获取的任务数
  • updated:已更新的现有任务数
  • new:添加的新任务数
  • tasks:更新和新任务的详细清单

请求示例:

{
  "workspace": "source",
  "only_incomplete": true,
  "max_tasks": 50
}

示例响应:

{
  "success": true,
  "workspace": "source",
  "fetched": 45,
  "updated": 30,
  "new": 15,
  "tasks": {
    "updated": [...],
    "new": [...]
  }
}

export_asana_tasks

将本地任务导出到Asana工作区。

参数:

  • workspace (可选):要导出到的工作区(“目标”,默认值:“目标”)
  • task_ids (可选):要导出的特定任务ID(如果提供,则忽略限制和sync_log_filter)
  • limit (可选):要导出的最大任务数(默认值:10)
  • sync_log_filter (可选):按sync_log值筛选任务(例如,“pending_export”)

退货:

  • success:布尔值表示成功
  • workspace:工作区导出到
  • processed:已处理的任务数
  • created:在Asana中创建的任务数
  • updated:Asana中更新的任务数
  • failed:未能导出的任务数
  • tasks:创建、更新和失败任务的详细列表

请求示例:

{
  "workspace": "target",
  "task_ids": ["task_1", "task_2"],
  "limit": 20
}

示例响应:

{
  "success": true,
  "workspace": "target",
  "processed": 2,
  "created": 1,
  "updated": 1,
  "failed": 0,
  "tasks": {
    "created": [...],
    "updated": [...],
    "failed": []
  }
}

sync_asana_tasks

Asana工作空间和当地拼花地板之间的双向同步,使用三向合并进行现场级协调。

参数:

  • task_ids (可选):要同步的特定任务ID(如果提供,则仅同步这些任务)
  • sync_scope (可选):同步范围(“两者”、“源”或“目标”,默认值:“两者”)
  • dry_run (可选):预览更改而不应用它们(默认值:false)

退货:

  • success:布尔值表示成功
  • source_to_local:来源统计→ 本地同步
  • target_to_local:目标统计→ 本地同步
  • local_to_source:当地统计数据→ 源同步
  • local_to_target:当地统计数据→ 目标同步
  • sync_scope:执行的同步范围
  • dry_run:是否应用了更改
  • pending (当dry_run=true时):等待每个方向的更新/创建

请求示例:

{
  "task_ids": ["task_1", "task_2"],
  "sync_scope": "both",
  "dry_run": false
}

示例响应:

{
  "success": true,
  "source_to_local": {
    "updated": 5,
    "new": 2,
    "tasks": {...}
  },
  "target_to_local": {
    "updated": 3,
    "new": 1,
    "tasks": {...}
  },
  "local_to_source": {
    "updated": 2,
    "created": 0,
    "tasks": {...}
  },
  "local_to_target": {
    "updated": 4,
    "created": 1,
    "tasks": {...}
  },
  "sync_scope": "both"
}

import_asana_task_comments

为特定任务导入注释。

参数:

  • task_gids (必填):要导入注释的任务GID数组
  • workspace (可选):工作区(“源”或“目标”,默认:“源”)

退货:

  • success:布尔值表示成功
  • workspace:从导入的工作区
  • task_count:已处理的任务数
  • comments_imported:导入的评论数

import_asana_task_metadata

导入任务元数据:自定义字段、依赖关系和故事。

参数:

  • task_gids (必需):要导入元数据的任务GID数组
  • workspace (可选):工作区(“源”或“目标”,默认:“源”)
  • metadata_types (可选):要导入的元数据类型(数组,默认值:[“custom_fields”,“dependency”,“stories”])

退货:

  • success:布尔值表示成功
  • workspace:从导入的工作区
  • task_count:已处理的任务数
  • custom_fields:导入的自定义字段数
  • dependencies:导入的依赖项数量
  • stories:导入的故事数

register_asana_webhooks

为工作区中的项目注册Asana webhooks。

参数:

  • webhook_url (必需):公共webhook URL(必须是HTTPS)
  • workspace (可选):用于注册Webhook的工作区(“源”、“目标”或“两者”,默认值:“两者”)

退货:

  • 每个工作区的注册结果,包括计数和详细信息

get_asana_task

通过GID从Asana获取单个任务。

参数:

  • task_gid (必填):Asana任务GID
  • workspace (可选):工作区(“源”或“目标”,默认:“源”)

退货:

  • success:布尔值表示成功
  • workspace:从获取的工作区
  • task:任务数据对象

list_asana_projects

列出Asana工作区中的项目。

参数:

  • workspace (可选):工作区(“源”或“目标”,默认:“源”)
  • archived (可选):包括已存档的项目(true、false或全部为null)

退货:

  • success:布尔值表示成功
  • workspace:已查询工作区
  • workspace_gid:工作区GID
  • count:项目数量
  • projects:项目对象数组

get_asana_workspace_info

获取有关Asana工作区的信息。

参数:

  • workspace (可选):工作区(“源”或“目标”,默认:“源”)

退货:

  • success:布尔值表示成功
  • workspace:已查询工作区
  • workspace_data:工作区信息对象

错误处理

当操作失败时,服务器以JSON格式返回结构化错误消息。常见错误包括:

  • 身份验证错误:PAT缺失或无效
  • 工作区错误:工作区GID无效
  • API错误:Asana API错误,状态代码和消息
  • MCP错误:拼花MCP服务器连接或操作错误

错误响应示例:

{
  "error": "Missing required configuration values: ASANA_SOURCE_PAT, SOURCE_WORKSPACE_GID",
  "type": "RuntimeError",
  "context": "Tool: import_asana_tasks"
}

安全说明

  • API令牌从不记录或暴露在错误消息中
  • 令牌可以存储在环境变量中, ~/.config/asana-mcp/.env,或1Password
  • 所有API请求都使用HTTPS
  • 配置目录 .env 文件具有受限权限(仅限所有者读/写)
  • 环境变量是最安全的方法(不持久化到磁盘)
  • 所有数据操作都通过镶木MCP服务器(自动快照和审计日志)进行

故障排除

  1. 认证失败

    • 验证PAT是否正确且未过期
    • 从以下位置获取新的PAT:https://app.asana.com/0/my-apps
    • 确保工作区GID正确
    • 检查1Password集成是否配置正确(如果使用)
  2. 未找到工作区

    • 验证工作区GID是否正确
    • 检查PAT是否可以访问工作区
    • 确保工作区未被存档或删除
  3. 镶木MCP连接失败

    • 验证Cursor/Claude Desktop中是否配置了拼花地板MCP服务器
    • 检查 PARQUET_MCP_SERVER_PATH 环境变量
    • 确保拼花地板服务器可访问
  4. 任务不同步

    • 检查任务是否有必填字段(标题)
    • 验证工作区权限
    • 检查sync_log字段是否有错误代码
    • 审查Asana API费率限制
  5. 重复任务

    • 服务器在创建之前按标题检查重复项
    • 如果存在重复项,则更新现有任务
  6. 测试失败

    • 看 测试.md 故障排除指南
    • 确保安装了测试依赖项
    • 为集成测试配置测试工作区

计划限制

看 PLAN_LIMITATIONS.md 有关高级功能和计划特定限制的详细文档。

备注

  • 服务器使用拼花地板MCP服务器进行所有数据操作(从不直接访问拼花地板文件)
  • Webhook注册要求Webhook服务器正在运行且可访问
  • webhook服务器(asana_webhook_server.py)仍然是一个单独的后台服务
  • 三向合并在修改不同属性时保留两侧的更改
  • 所有日期字段都以ISO格式的字符串返回
  • 服务器以stdio模式运行,用于MCP通信
  • 监控脚本(monitor_asana_import.py, monitor_asana_export.py)保持分离

同步策略

双向同步使用三路合并方法:

  1. 上次同步状态:存储上次成功同步后的任务状态
  2. 三方比较:比较last_synced、current_local和current_asana
  3. 合并逻辑:
    • 如果只有Asana更改:使用Asana值
    • 如果仅本地更改:使用本地值
    • 如果两者都更改:使用较新的时间戳(冲突解决)
    • 如果两者都没有改变:保留现有值

这种方法在修改不同属性时保留了双方的更改,而不需要每个属性的时间戳。

建筑

Asana MCP Server
├── Asana API (read/write tasks, comments, metadata)
├── Parquet MCP Server (via MCP client)
│   ├── tasks.parquet
│   ├── task_comments.parquet
│   ├── task_custom_fields.parquet
│   ├── task_dependencies.parquet
│   ├── task_stories.parquet
│   └── task_attachments.parquet
└── Automatic snapshots & audit logging (via parquet MCP)

许可证

麻省理工学院

支持