Paymo MCP服务器
一种模型上下文协议(MCP)服务器 Paymo 时间跟踪和发票。使Claude Desktop能够管理时间条目、项目、任务并生成发票时间表。
特性
- ✅ 时间录入管理:通过自然语言创建和管理时间条目
- ✅ 项目和任务发现:按名称列出和搜索项目/任务
- ✅ 发票时间表导出:为特定发票生成CSV时间表
- ✅ 未填充时间分析:跟踪未计费的小时数和收入
- ✅ 批量操作:以YAML格式提交多个条目
- ✅ 智能过滤:按项目、日期范围、计费状态筛选条目
- ✅ 按时间顺序排序:所有导出都按日期自动排序
安装
git clone https://github.com/feamster/paymo-mcp.git
cd paymo-mcp
pip install -r requirements.txt需求
- Python 3.8+
- 具有API访问权限的Paymo帐户
- fastmcp 用于MCP服务器功能
配置
配置分为非敏感设置和身份验证:
~/.mcp-config/paymo/config.json (非敏感,可以在点文件中):
{
"timezone": "America/Chicago",
"projects": {
"Client Matter Name": {
"project_id": 12345,
"task_id": 67890
}
}
}~/.mcp-auth/paymo/auth.json (敏感,单独同步):
{
"api_key": "your-paymo-api-key-here"
}获取API密钥
- 登录Paymo
- 前往设置→ API
- 生成新的API密钥
- 将密钥复制到配置文件
用法
作为CLI工具
# List projects
python3 paymo_timesheet.py list-projects
# List tasks for a project
python3 paymo_timesheet.py list-tasks --project-id 12345
# Create a single entry
python3 paymo_timesheet.py create-entry \
--task-id 67890 \
--date 2025-12-10 \
--hours 3.5 \
--description "Document review and analysis"
# Export invoice timesheet by invoice number
python3 paymo_timesheet.py export-invoice-timesheets \
--invoice-number INV-20260331-241 \
--output-dir ./invoices
# List unbilled entries
python3 paymo_timesheet.py list-entries \
--start 2025-11-01 \
--end 2025-11-30 \
--unbilled作为MCP服务器
1.启动服务器
python3 paymo_timesheet.py mcp2.配置克劳德桌面
添加 ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"paymo": {
"command": "python3",
"args": ["/path/to/paymo-mcp/paymo_timesheet.py", "mcp"]
}
}
}3.重新启动克劳德桌面
Paymo工具现在将在Claude Desktop中提供。
MCP工具参考
项目与任务管理
list_paymo_projects()
列出所有活动的Paymo项目。
退货: 包含ID、名称和客户信息的项目列表。
list_paymo_tasks(project_id: int)
列出特定项目的所有任务。
Args:
project_id:Paymo项目ID
退货: 包含ID、名称和计费信息的任务列表。
时间录入管理
create_paymo_entry(task_id, date, duration_hours, description)
创建单个时间条目。
Args:
task_id(int):用于记录时间的任务IDdate(str):YYYY-MM-DD格式的日期duration_hours(浮动):工作时间(例如3.5小时)description(str):已完成工作的描述
退货: 已创建条目详细信息。
例子:
create_paymo_entry(
task_id=31450618,
date="2025-12-10",
duration_hours=6.0,
description="Expert report drafting and analysis"
)submit_paymo_timesheet(yaml_content: str)
从YAML格式提交多个条目。
Args:
yaml_content:带有时间表条目的YAML字符串
退货: 已创建条目的摘要。
YAML示例:
matter: "Patent Litigation Matter"
client: "Law Firm Client"
rate: 650
entries:
- date: "2025-12-02"
start_time: "09:00"
end_time: "12:30"
timezone: "America/Chicago"
task_id: 31450618
description: "Case strategy meeting"
- date: "2025-12-03"
duration_hours: 5.0
task_id: 31450740
description: "Expert witness report preparation"list_paymo_entries(start_date, end_date, project_id=None, billed=None)
列出带有可选过滤器的时间条目。
Args:
start_date(str):开始日期(YYYY-MM-DD)end_date(str):结束日期(YYYY-MM-DD)project_id(int,可选):按项目筛选billed(bool,可选):按计费状态过滤(True=已计费,False=未计费,None=全部)
退货: 包含任务名称、持续时间、描述和计费状态的条目列表。
发票管理
list_paymo_invoices(client_id=None, status=None)
列出带有可选过滤器的Paymo发票。
Args:
client_id(int,可选):按客户端筛选status(str,可选):按状态筛选(“草稿”、“已发送”、“查看”、“付费”)
退货: 包含编号、金额、日期和状态的发票列表。
get_outstanding_invoices_last_week()
获取过去7天的未付发票。
退货: 状态为“已发送”或“已查看”的最近发票列表。
export_invoice_timesheet(invoice_number: str, strict: bool = True)
为特定发票导出格式化的、可计费的CSV时间表。 这是生成发票时间表的主要工具。
Args:
invoice_number(str):发票上显示的发票号码(例如“INV-20260331-241”)strict(bool):如果为True(默认),则验证计算出的总额是否与发票匹配。如果为False,则跳过验证。
退货: 格式化CSV内容,包括:
- 页眉部分:事项名称、发票号码、期间、总小时数、费用、开支、应付总额
- 数据部分:日期、开始时间(HH:MM)、结束时间(HH:MM)、持续时间、任务、描述
- 页脚:费用汇总
特征:
- 严格匹配(默认):仅包括通过以下方式明确链接到该发票的条目
invoice_item_id,并验证计算出的费用与发票总额是否在5%以内 - 按日期按时间顺序排序(最早的第一个)
- 干净的HH:MM时间格式(不是原始ISO时间戳)
- 带有摘要标题的计费就绪格式
- 90天回顾,捕捉所有参赛作品
例子:
export_invoice_timesheet("INV-20260331-241") # strict validation (default)
export_invoice_timesheet("INV-20260331-241", False) # skip validation何时使用:
- 发票INV-20260331-241的出口时间表
- “为我的最新发票生成时间表”
- “获取发票X的计费准备时间表”
如果验证失败: 使用 export_paymo_timesheet(start_date, end_date, project_id) 改为按日期范围导出。
export_invoice_paymo_format(invoice_number: str, strict: bool = True)
导出时间表 精确的Paymo原生格式 所有标准列。当您需要导出与Paymo自己的导出格式完全匹配时,请使用此选项。
Args:
invoice_number(str):发票号码(例如“INV-20260331-241”)strict(bool):如果为True(默认),则验证总计是否与发票匹配
退货: CSV具有精确的Paymo列:
User, Internal User Id, Project, Internal Project Id, Project Description,
Tasklist, Internal Tasklist Id, Task, Internal Task Id, Start Time, End Time,
Worked Time, Decimal Hours, Time In Seconds何时使用:
- 需要精确的Paymo格式才能导入到另一个系统中
- 需要所有内部ID(用户、项目、任务、任务列表)
- 用户明确要求“Paymo格式”
例子:
export_invoice_paymo_format("INV-20260331-241")export_paymo_timesheet(start_date, end_date, project_id=None, format="csv")
导出日期范围的时间表。
Args:
start_date(str):开始日期(YYYY-MM-DD)end_date(str):结束日期(YYYY-MM-DD)project_id(int,可选):按项目筛选format(str):导出格式(“csv”或“xls”)
退货: 导出文件的路径。
示例查询(通过Claude Desktop)
时间条目创建
- *“为12月10日的专利诉讼项目创建一个3.5小时的条目,用于现有技术研究”*
- *“今天记录6个小时的知识产权案件专家报告起草情况”*
- *“在诉讼支持任务中添加昨天的2小时通话记录”*
项目和发票发现
- *“列出我的所有活动项目”*
- *“显示企业咨询项目的任务”*
- *“我上周有哪些未付发票?”*
- *“列出客户XYZ的所有未付发票”*
分析查询
- *“在过去的30天里,我有多少未开票的时间?”*
- *“上个月哪些项目没有发票?”*
- *“显示专利诉讼项目的未计费小时数”*
- *“我2025年11月的总收入是多少?”*
- *“按项目计算我第四季度的未开票收入”*
时间表导出
- *“导出发票INV-20260331-241的时间表”*
- *“为我的最新DivX发票生成时间表”*
- *“导出上周所有未付发票的时间表”*
- *“生成我12月时间条目的CSV”*
输出示例
发票时间表导出
当你奔跑时 export_invoice_timesheet("INV-20260331-241"),您将获得一个准备计费的CSV:
Matter,DivX vs. Netflix
Invoice,INV-20260331-241
Period,2026-03-04 to 2026-03-25
Total Hours,239.01
Fees,$143406.00
Expenses,$1016.95
Total Due,$144422.95
Date,Start Time,End Time,Duration (hours),Task,Description
2026-03-04,09:00,10:30,1.50,Trial Prep,Trial prep
2026-03-04,11:00,13:00,2.00,Trial Prep,"Post outline review session: incorporated feedback on outline flow"
2026-03-06,01:00,04:00,3.00,Trial Prep,"Solo trial prep: reviewing patent materials and invalidity case outline"
2026-03-06,16:00,17:30,1.50,Trial Prep,"Trial prep run-through with counsel re: patent technical benefits section"
Expenses,$1016.95主要特点:
- 标题包括事项、发票、期间、总小时数、费用、开支、应付总额
- 干净的HH:MM格式的时间(不是原始ISO时间戳)
- 按日期按时间顺序排序的条目
- 带费用的页脚
未填充时间分析
当你问的时候 *“我还有多少未开票的时间?”*,克劳德可能会回答:
You have 47.5 unbilled hours across 3 projects:
Patent Litigation Matter: 30.75 hours ($19,987.50)
Corporate Advisory: 12.00 hours ($7,800.00)
Expert Witness Case: 4.75 hours ($3,087.50)
Total unbilled: $30,875.00运作原理
API调用的自然语言
MCP服务器使Claude能够自动将自然语言翻译为Paymo API调用:
你说: *“为12月10日的诉讼项目创建一个6小时的条目”*
克劳德自动:
- 呼叫
list_paymo_projects()查找项目 - 在项目名称中搜索“诉讼”
- 呼叫
list_paymo_tasks(project_id)获取任务 - 使用以下内容创建条目
create_paymo_entry()
你说: *“哪些项目有未计费的时间?”*
克劳德自动:
- 呼叫
list_paymo_projects()获取所有项目 - 对于每个项目,呼叫
list_paymo_entries()和billed=False - 按项目汇总和报告未计费小时数
发票特定出口
这 export_invoice_timesheet() 功能提供计费就绪时间表 严格验证:
- 按编号查找发票(例如“INV-20260331-241”)
- 检索发票及其行项目
- 查找与这些发票项目链接的所有时间条目(通过
invoice_item_id) - 验证总计:检查(小时×费率)是否与发票总额在5%以内匹配
- 回溯90天以捕获所有条目(处理每月计费周期)
- 获取任务名称和项目/事项名称
- 按日期按时间顺序对条目排序(最早的第一个)
- 通过以下方式生成格式化的CSV:
- 标题:事项、发票、期间、总小时数、费用、开支、应付总额 - 数据:日期、开始时间(HH:MM)、结束时间(HH:MM)、持续时间、任务、描述 - 页脚:费用汇总
这可确保您获得 仅 实际在该特定发票上开票的条目,并验证总数是否匹配。
备选方案-日期范围导出: 如果您需要按日期范围输入,而不管发票链接如何(或者如果严格验证失败),请使用 export_paymo_timesheet(start_date, end_date, project_id) 相反。
速率限制
脚本自动处理Paymo的API费率限制:
- 监视器
X-Ratelimit-Remaining标头 - 在任务查找之间增加2秒的延迟
- 对429个指数回退错误的检索
- 接近极限时显示警告
故障排除
“未配置API密钥”
创建 ~/.mcp-auth/paymo/auth.json 使用API密钥(请参阅配置部分)。
“未安装fastmcp”
安装MCP服务器依赖关系:
pip install fastmcp“超出费率限制”
脚本将自动等待并重试。如果您经常看到这种情况,请减少批处理操作的规模。
空发票导出
某些发票可能没有时间条目(固定费用或仅含费用的发票)。验证发票是否包含Paymo中的时间条目。
发展
项目结构
paymo-mcp/
├── paymo_timesheet.py # Main script (CLI + MCP server)
├── requirements.txt # Python dependencies
└── README.md # This file关键类
PaymoClient:具有速率限制和重试逻辑的API包装TimesheetProcessor:YAML解析和批处理条目创建
添加新的MCP工具
- 添加
@mcp.tool()装饰器 - 使用arg描述定义清晰的文档字符串
- 加载配置并创建PaymoClient
- 返回结构化数据(字典/列表,而非字符串)
例子:
@mcp.tool()
def my_new_tool(arg1: str, arg2: int) -> Dict[str, Any]:
"""
Brief description of what this tool does
Args:
arg1: Description of first argument
arg2: Description of second argument
Returns:
Description of return value
"""
config = load_config()
api_key = config.get('api_key')
client = PaymoClient(api_key)
# Implementation here
return {"result": "data"}许可证
麻省理工学院
贡献
问题和拉取请求欢迎!请确保:
- 代码遵循现有样式
- 新功能包括文档
- MCP工具具有清晰的文档字符串
- 遵守速率限制
致谢
内置于 FastMCP 用于模型上下文协议支持。
