.vscode — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited .vscode (MCP Server) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A Model Context Protocol (MCP) server that integrates with Harvest time tracking. This server allows AI assistants to interact with your Harvest account to log time, view projects, manage tasks, and track your work hours.
When combined with an Azure DevOps (ADO) MCP server and the included example skill, your AI assistant can automatically review ADO work items for effort-hours changes and log the corresponding time to Harvest.
The server expects your Harvest credentials to be available as OS-level environment variables. Set these in your system:
Windows (PowerShell — persistent for your user):
[System.Environment]::SetEnvironmentVariable("Harvest_ID", "your_account_id", "User")
[System.Environment]::SetEnvironmentVariable("Harvest_Token", "your_access_token", "User")macOS / Linux (add to `~/.bashrc`, `~/.zshrc`, or equivalent):
export Harvest_ID="your_account_id"
export Harvest_Token="your_access_token"After setting them, restart your terminal (and Cursor) so the new variables are picked up.
Clone this repo and build:
git clone <repo-url>
cd HarvestMCP
npm install
npm run buildIn your Cursor settings, open (or create) your MCP configuration file. On Windows this is typically at:
%USERPROFILE%\.cursor\mcp.jsonAdd the Harvest server entry. A sample is provided in examplemcp.json.md:
{
"mcpServers": {
"harvest": {
"type": "stdio",
"command": "node",
"args": [
"C:\\path\\to\\HarvestMCP\\build\\index.js"
],
"env": {
"HARVEST_ACCOUNT_ID": "${env:Harvest_ID}",
"HARVEST_ACCESS_TOKEN": "${env:Harvest_Token}"
}
}
}
}Important: Update the path inargsto the absolute path ofbuild/index.json your machine.
The ${env:...} syntax tells Cursor to read the values from your OS environment variables at runtime. This avoids committing secrets to your config files.
An example Cursor agent skill is provided in example-skill.md. This skill teaches the AI assistant how to review ADO work items for effort-hours changes and log the corresponding time to Harvest.
To use it:
example-skill.md to your Cursor skills directory (e.g. ~/.cursor/skills/log-harvest-time/SKILL.md)Note: This skill requires both the Harvest MCP server (this project) and an ADO MCP server to be configured in Cursor. Without the ADO MCP server, the skill cannot read work item effort-hours.
The example time-logging skill relies on an Azure DevOps MCP server to query work items and detect effort-hours changes. You need to have a separate ADO MCP server configured in your Cursor MCP settings alongside this Harvest server.
Your Cursor mcp.json should contain entries for both servers, for example:
{
"mcpServers": {
"harvest": {
// ... Harvest config as shown above ...
},
"ado": {
// ... your ADO MCP server config ...
}
}
}Refer to your ADO MCP server's documentation for its specific setup instructions and required environment variables (e.g. ADO PAT, organization URL, etc.).
| File | Description |
|---|---|
examplemcp.json.md | Sample Cursor MCP JSON configuration snippet for this server |
example-skill.md | Example Cursor agent skill for logging time from ADO work items |
This repo also includes a .vscode/mcp.json for running the server as a VS Code MCP server. The same environment variable approach applies — set Harvest_ID and Harvest_Token as OS environment variables, and VS Code will inject them at runtime via the ${env:...} syntax.
Install dependencies and build:
npm install
npm run buildRun the server directly (outside of an MCP client):
npm startIf you run it directly, you must provide HARVEST_ACCOUNT_ID and HARVEST_ACCESS_TOKEN in your shell environment.
Build and run with Docker Compose:
docker-compose up -dDocker Compose reads HARVEST_ACCOUNT_ID / HARVEST_ACCESS_TOKEN from your shell environment. It will also read a .env file next to docker-compose.yml if you choose to use one.
Or build manually:
docker build -t harvest-mcp-server .
docker run -e HARVEST_ACCOUNT_ID=your_id -e HARVEST_ACCESS_TOKEN=your_token harvest-mcp-serverThe server exposes the following tools to MCP clients:
list_projectsLists all active projects in your Harvest account.
Example: "Show me my active projects"
list_project_tasksLists all tasks for a specific project.
Parameters:
project_id (number): The ID of the projectExample: "What tasks are available for project 12345?"
log_timeLogs a time entry to Harvest.
Parameters:
project_id (number): The ID of the projecttask_id (number): The ID of the taskhours (number): Number of hours to logspent_date (string, optional): Date in YYYY-MM-DD format (defaults to today)notes (string, optional): Notes about the workExample: "Log 2.5 hours to project 12345, task 67890 with notes 'Developed new feature'"
get_todays_timeRetrieves all time entries for today with total hours.
Example: "How much time have I logged today?"
start_timerStarts a running timer for a project and task.
Parameters:
project_id (number): The ID of the projecttask_id (number): The ID of the tasknotes (string, optional): Notes about what you're working onExample: "Start a timer for project 12345, task 67890"
stop_timerStops a running timer.
Parameters:
time_entry_id (number): The ID of the time entry to stopExample: "Stop timer 98765"
update_time_entryUpdates an existing time entry (hours, notes, project, task, or date).
Parameters:
time_entry_id (number): The ID of the time entry to updatehours (number, optional): New number of hoursnotes (string, optional): Updated notesproject_id (number, optional): New project IDtask_id (number, optional): New task IDspent_date (string, optional): New date in YYYY-MM-DD formatExample: "Update time entry 98765 to 3 hours"
To use this MCP server with Claude Desktop, add it to your configuration file:
macOS/Linux: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"harvest": {
"command": "node",
"args": ["/absolute/path/to/HarvestMCP/build/index.js"],
"env": {
"HARVEST_ACCOUNT_ID": "your_account_id",
"HARVEST_ACCESS_TOKEN": "your_access_token"
}
}
}
}npm run buildnpm run watchMake sure the environment variables Harvest_ID and Harvest_Token are set at the OS level and that you have restarted Cursor / your terminal after setting them. The MCP config uses ${env:Harvest_ID} and ${env:Harvest_Token} to inject these at runtime.
Your access token may be invalid or expired. Generate a new one from the Harvest developers page.
Harvest returns 403 Forbidden when your token doesn't have permission for an endpoint. This server uses /v2/users/me/project_assignments to list projects and tasks you're assigned to, which works for normal member accounts. If you still get 403:
HARVEST_ACCOUNT_ID matches the account for your token.Check the logs:
docker-compose logs harvest-mcpEnsure HARVEST_ACCOUNT_ID / HARVEST_ACCESS_TOKEN are available to Docker Compose (either in your shell environment or via a .env file next to docker-compose.yml).
${env:...} syntax in MCP configs keeps secrets out of config filesHarvest API has rate limits:
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.