
QuickBooks Time
โ 11from aallsbury
Access all QuickBooks Time API functionality through a single MCP server interface.
QuickBooks Time MCP Server (V2 Update)
This is a combined MCP server that provides access to all QuickBooks Time API functionality through a single interface. It combines the functionality of four separate servers:
- JobCode Tools
- Reports & Core Tools
- Timesheet Tools
- User Tools
I would LOVE help improving this project! Just glad to be able to give something back finally!
This entire project was developed and published using artificial intelligence (Anthropic, OpenAI, Llama/META), as I personally cannot write much code without assistance. While every effort has been made to ensure quality and functionality, there may be imperfections or areas for improvement. I welcome any feedback, corrections, or suggestions from the community.
- Install dependencies:
pip install -r requirements.txt- Create a
.envfile with your QuickBooks Time access token:
QB_TIME_ACCESS_TOKEN=your_access_token_here
NODE_ENV=developmentAvailable Tools
JobCode Tools
-
get_jobcodes: Get jobcodes with advanced filtering options- Basic Filters:
ids: (array of numbers, optional) Comma separated list of jobcode IDsname: (string, optional) Filter by jobcode name, supports wildcard (*) matching from string startactive: (string, optional) Filter by status: "yes", "no", "both" (default: "yes")
- Type and Hierarchy Filters:
type: (string, optional) Filter by type: "regular", "pto", "paid_break", "unpaid_break", "all" (default: "regular")parent_ids: (array of numbers, optional) Filter by parent jobcode IDs. Special values: 0 (top-level only), -1 (all levels)
- Additional Filters:
customfields: (boolean, optional) Include custom fields in responsemodified_before: (string, optional) Filter by modification date (ISO 8601 format)modified_since: (string, optional) Filter by modification date (ISO 8601 format)page: (number) Page number for paginationlimit: (number) Results per page (max 200)
- Basic Filters:
-
get_jobcode: Get a specific jobcode by ID- Required Parameters:
id: (number) The ID of the jobcode to retrieve
- Required Parameters:
-
get_jobcode_hierarchy: Get complete jobcode hierarchy structure- Parameters:
parent_ids: (array of numbers, optional) Filter by parent IDs. Values: 0 (top-level), -1 (all), or specific IDsactive: (string, optional) Filter by status: "yes", "no", "both" (default: "yes")type: (string, optional) Filter by type: "regular", "pto", "paid_break", "unpaid_break", "all" (default: "regular")customfields: (boolean, optional) Include custom fields in response
- Parameters:
Timesheet Tools
-
get_timesheets: Get timesheets with filtering- Required Parameters (at least one):
ids: (array of numbers) Comma separated list of timesheet IDsstart_date: (string) Returns timesheets on or after this date (YYYY-MM-DD)modified_before: (string) Returns timesheets modified before this time (ISO 8601)modified_since: (string) Returns timesheets modified since this time (ISO 8601)
- Optional Parameters:
end_date: (string) Returns timesheets on or before this date (YYYY-MM-DD)user_ids: (array of numbers) Filter by specific user IDsgroup_ids: (array of numbers) Filter by specific group IDsjobcode_ids: (array of numbers) Filter by specific jobcode IDs (includes children)payroll_ids: (array of numbers) Filter by specific payroll IDson_the_clock: (string) Filter by current working status: "yes", "no", "both" (default: "no")jobcode_type: (string) Filter by type: "regular", "pto", "paid_break", "unpaid_break", "all" (default: "all")page: (number) Page numberlimit: (number) Results per page
- Required Parameters (at least one):
-
get_timesheet: Get a specific timesheet by ID- Required Parameters:
id: (number) The ID of the timesheet to retrieve
- Required Parameters:
-
get_current_timesheets: Get currently active timesheets- Required Parameters:
on_the_clock: (string) Must be set to "yes"
- Optional Parameters:
user_ids: (array of numbers) Filter active timesheets for specific usersgroup_ids: (array of numbers) Filter active timesheets for users in specific groupsjobcode_ids: (array of numbers) Filter active timesheets for specific jobcodessupplemental_data: (string) Include supplemental data: "yes", "no" (default: "yes")
- Required Parameters:
User Tools
-
get_users: Get all users with filtering- User Identification Filters:
ids: (array of numbers, optional) Filter by specific user IDsnot_ids: (array of numbers, optional) Exclude specific user IDsemployee_numbers: (array of numbers, optional) Filter by employee numbersusernames: (array of strings, optional) Filter by specific usernames
- Group Filters:
group_ids: (array of numbers, optional) Filter by group membershipnot_group_ids: (array of numbers, optional) Exclude users from specific groups
- Status and Identification Filters:
payroll_ids: (array of strings, optional) Filter by payroll identification numbersactive: (string, optional) Filter by status: "yes", "no", "both" (default: "yes")
- Name Filters:
first_name: (string, optional) Filter by first name (supports wildcards *)last_name: (string, optional) Filter by last name (supports wildcards *)
- Time-Based Filters:
modified_before: (string, optional) Filter by modification date (ISO 8601)modified_since: (string, optional) Filter by modification date (ISO 8601)
- Pagination:
page: (number, optional) Page number (default: 1)per_page: (number, optional) Results per page (default: 50, max: 50)
- User Identification Filters:
-
get_user: Get a specific user by ID- Required Parameters:
id: (number) The ID of the user to retrieve
- Required Parameters:
-
get_current_user: Get currently authenticated user- No parameters required
- Returns detailed user information including:
- Basic profile information
- Company details
- PTO balances
- Permissions
- Custom fields
-
get_groups: Get all groups from QuickBooks Time- Optional Parameters:
ids: (array of numbers) Filter by specific group IDsactive: (string) Filter by status: "yes", "no", "both" (default: "yes")manager_ids: (array of numbers) Filter groups by manager user IDssupplemental_data: (string) Include supplemental data: "yes", "no" (default: "yes")
- Returns group information including:
- Basic group details
- Manager assignments
- Timesheet settings
- Time entry settings
- Break settings
- Optional Parameters:
Project Management Tools
-
get_projects: Get projects with filtering- Optional Parameters:
ids: (array of numbers) Filter by specific project IDsactive: (string) Filter by status: "yes", "no", "both" (default: "yes")client_id: (number) Filter by client IDjobcode_id: (number) Filter by associated jobcode IDmodified_before: (string) Filter by modification date (ISO 8601)modified_since: (string) Filter by modification date (ISO 8601)page: (number) Page number (default: 1)per_page: (number) Results per page (default: 50, max: 50)
- Returns project information including:
- Basic project details
- Client and jobcode associations
- Budget information
- Dates and status
- Custom fields
- Optional Parameters:
-
get_project_activities: Get project activity logs- Optional Parameters:
project_ids: (array of numbers) Filter activities to specific projectsuser_ids: (array of numbers) Filter activities by specific usersactivity_types: (array of strings) Filter by activity types: "status_change", "note_added", "budget_change", "date_change", "custom_field_change"modified_before: (string) Filter by modification date (ISO 8601)modified_since: (string) Filter by modification date (ISO 8601)page: (number) Page number (default: 1)per_page: (number) Results per page (default: 50, max: 50)
- Returns activity information including:
- Activity type and details
- User who made the change
- Old and new values
- Timestamps
- Optional Parameters:
Reports Tools
-
get_current_totals: Get current totals snapshot including shift and day totals- Optional Parameters:
user_ids: (array of numbers) Filter totals to specific usersgroup_ids: (array of numbers) Filter totals for users in specific groupsjobcode_ids: (array of numbers) Filter totals for specific jobcodescustomfield_query: (string) Filter by custom field values in format: <customfield_id>||
- Returns:
- Real-time totals for active time entries
- Duration and start times
- Associated jobcode and user information
- Custom field values
- Optional Parameters:
-
get_payroll: Get payroll report- Required Parameters:
start_date: (string) Start of pay period (YYYY-MM-DD)end_date: (string) End of pay period (YYYY-MM-DD)
- Optional Parameters:
user_ids: (array of numbers) Filter payroll for specific usersgroup_ids: (array of numbers) Filter payroll for users in specific groupsinclude_zero_time: (boolean) Include users with no time entries (default: false)
- Returns:
- Total time by type (regular, overtime, double-time, PTO)
- Daily breakdowns per user
- Timesheet counts
- Required Parameters:
-
get_payroll_by_jobcode: Get payroll report grouped by jobcode- Required Parameters:
start_date: (string) Start of pay period (YYYY-MM-DD)end_date: (string) End of pay period (YYYY-MM-DD)
- Optional Parameters:
user_ids: (array of numbers) Filter payroll for specific usersgroup_ids: (array of numbers) Filter payroll for users in specific groupsjobcode_ids: (array of numbers) Filter payroll for specific jobcodesjobcode_type: (string) Filter by type: "regular", "pto", "paid_break", "unpaid_break"include_zero_time: (boolean) Include jobcodes with no time entries (default: false)
- Returns:
- Time totals by jobcode
- Breakdowns by user within each jobcode
- Daily totals per jobcode
- Required Parameters:
-
get_project_report: Get detailed project report with time entries- Required Parameters:
start_date: (string) Start date in YYYY-MM-DD formatend_date: (string) End date in YYYY-MM-DD format
- Optional Parameters:
user_ids: (array of numbers) Filter time entries by specific usersgroup_ids: (array of numbers) Filter time entries by specific groupsjobcode_ids: (array of numbers) Filter time entries by specific jobcodesjobcode_type: (string) Filter by type: "regular", "pto", "unpaid_break", "paid_break", "all" (default: "all")customfielditems: (object) Filter by custom field values in format: {"customfield_id": ["value1", "value2"]}
- Returns:
- Project time totals
- Breakdowns by user and group
- Filtered time entries based on criteria
- Required Parameters:
Additional Tools
-
get_custom_fields: Get custom tracking fields configured on timecards- Parameters:
ids: (array of numbers) Filter by specific custom field IDsactive: (string) Filter by status: "yes", "no", "both"applies_to: (string) Filter by application type: "timesheet", "jobcode", "user"value_type: (string) Filter by value type: "managed-list", "free-form"page: (number) Page numberlimit: (number) Results per page
- Parameters:
-
get_last_modified: Get last modified timestamps for objects- Parameters:
types: (array of strings) Types of objects to check (e.g., ["timesheets", "jobcodes", "users"])
- Parameters:
-
get_notifications: Get notifications- Parameters:
page: (number) Page numberlimit: (number) Results per page
- Parameters:
-
get_managed_clients: Get managed clients- Parameters:
page: (number) Page numberlimit: (number) Results per page
- Parameters:
Support
For issues and feature requests, please use the GitHub issues page or contact me directly at github.com/aallsbury.
pip install -r requirements.txtBefore it works, you'll need: QB_TIME_ACCESS_TOKEN
Claude Desktop Configuration
To use this server with Claude Desktop, you'll need to configure it in your Claude Desktop settings. Here's an example configuration:
{
"globalShortcut": "Ctrl+Q",
"mcpServers": {
"qb-time-tools": {
"command": "python",
"args": [
"./qb-time-mcp-server/main.py"
],
"env": {
"QB_TIME_ACCESS_TOKEN": "your_quickbooks_time_access_token_here"
}
}
}
}Running the Server
python main.pyThe server will start and listen for JSON-RPC requests on stdin/stdout.
No common issues documented yet. If you hit a problem, the repository's GitHub Issues page is the best place to look.
Licensed under MITโ you can use, modify, and redistribute it under that license's terms.
License
MIT License - See LICENSE file for details