npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pitra190/unit4-timesheet-mcp

v1.0.2

Published

MCP server for syncing absences to Unit4 timesheets via browser automation

Readme

@pitra190/unit4-timesheet-mcp

Automate filling timesheets in Unit4 Business World by chatting with AI. This MCP server works with Claude Desktop, Claude Code, Cursor, and other MCP-compatible clients.

Instead of manually filling timesheets every month, just say:

"Sync timesheets for March 2026"

And the tool will open a browser, log in, and fill everything in for you.

Quick Start

Step 1: Install Node.js

Download and install from nodejs.org (choose the LTS version).

Step 2: Run the setup wizard

Open your terminal (Terminal on Mac, Command Prompt on Windows) and run:

npx @pitra190/unit4-timesheet-mcp init

This will automatically:

  • Install the browser needed for automation
  • Create a ~/unit4-config/ folder with template config files
  • Print the MCP config block you'll need in Step 4

Step 3: Edit your config files

Open the ~/unit4-config/ folder and edit the three files inside. See Config Files Explained below for details on each file.

Step 4: Connect to your AI chat client

Copy the config block that was printed in Step 2 into your AI client's config file. Replace the placeholder values with your actual Unit4 credentials.

Where to paste it:

| Client | Config file location | |--------|---------------------| | Claude Desktop (Mac) | ~/Library/Application Support/Claude/claude_desktop_config.json | | Claude Desktop (Windows) | %APPDATA%\Claude\claude_desktop_config.json | | Claude Code | .mcp.json in your project folder | | Cursor | Settings > MCP Servers |

The config block looks like this — replace the YOUR_... values:

{
  "mcpServers": {
    "unit4-timesheet": {
      "command": "npx",
      "args": ["-y", "@pitra190/unit4-timesheet-mcp"],
      "env": {
        "UNIT4_LOGIN_URL": "https://ubw.unit4cloud.com/YOUR_INSTANCE/Login/Login.aspx",
        "UNIT4_USERNAME": "YOUR_USERNAME",
        "UNIT4_PASSWORD": "YOUR_PASSWORD",
        "UNIT4_BASE_PATH": "/Users/YOUR_NAME/unit4-config"
      }
    }
  }
}

Step 5: Restart your AI client and start chatting

Try these:

  • "Sync timesheets for March 2026"
  • "Preview timesheet entries for John Doe"
  • "Show the current sync status"

The tool will open a visible browser window so you can watch it fill in the timesheets.


Config Files Explained

All config files live in ~/unit4-config/. The setup wizard creates them with template values — you just need to fill in your actual data.

config.json

This controls what gets filled in the timesheets and when.

{
  "workOrder": "82010000100",
  "activities": {
    "regular": "078",
    "annual_leave": "611",
    "sick_leave": "820",
    "public_holiday": "611"
  },
  "leaveDescriptions": {
    "annual_leave": "annual leave",
    "sick_leave": "sick leave"
  },
  "hoursPerDay": 8,
  "setStatusReady": false,
  "dateRange": {
    "startDate": "2026-03-01",
    "endDate": "2026-03-31"
  },
  "holidays": [
    { "date": "2026-03-19", "description": "Nyepi Day" },
    { "date": "2026-04-03", "description": "Good Friday" }
  ]
}

| Field | What it means | |-------|---------------| | workOrder | Your Unit4 work order number | | activities.regular | Activity code for normal working hours | | activities.annual_leave | Activity code for annual leave | | activities.sick_leave | Activity code for sick leave | | activities.public_holiday | Activity code for public holidays | | leaveDescriptions | Text shown in the description column for each leave type | | hoursPerDay | Standard working hours per day (usually 8) | | setStatusReady | false = save as Draft, true = save as Ready | | dateRange | The month/period to process (update this each time you run) | | holidays | List of public holidays — employees get these days off automatically |

employee_mapping.json

This maps employee names to their Unit4 display names. Unit4 shows names in "Lastname, Firstname" format, which is different from how you normally refer to people.

{
  "John Doe": {
    "unit4Name": "Doe, John",
    "workDescription": "Frontend dev"
  },
  "Jane Smith": {
    "unit4Name": "Smith, Jane Marie",
    "workDescription": "Backend dev"
  }
}

| Field | What it means | |-------|---------------| | Key (e.g., "John Doe") | The name you use to refer to this person | | unit4Name | The exact name as it appears in Unit4 (must match exactly!) | | workDescription | Text shown in the description column for regular work hours |

To find someone's unit4Name, open Unit4 and look at how their name appears in the employee dropdown.

absence_data.json

This lists who is on leave and when. If nobody has any leave, just leave it as an empty array [].

[
  {
    "absence_id": "1",
    "employee_name": "John Doe",
    "leave_type": "annual_leave",
    "start_date": "2026-03-10",
    "end_date": "2026-03-12",
    "duration_days": 3,
    "notes": "Family vacation",
    "department": "Engineering"
  },
  {
    "absence_id": "2",
    "employee_name": "Jane Smith",
    "leave_type": "sick_leave",
    "start_date": "2026-03-05",
    "end_date": "2026-03-05",
    "duration_days": 1,
    "notes": "",
    "department": "Engineering"
  }
]

| Field | What it means | |-------|---------------| | absence_id | A unique ID (can be any string) | | employee_name | Must match a key in employee_mapping.json | | leave_type | Either "annual_leave" or "sick_leave" | | start_date | First day of leave (YYYY-MM-DD) | | end_date | Last day of leave (YYYY-MM-DD) | | duration_days | Number of working days (weekends don't count) | | notes | Optional notes | | department | Employee's department |


Environment Variables

| Variable | Required | Description | |----------|----------|-------------| | UNIT4_LOGIN_URL | Yes | Your Unit4 login page URL | | UNIT4_USERNAME | Yes | Unit4 username | | UNIT4_PASSWORD | Yes | Unit4 password | | UNIT4_BASE_PATH | Yes | Path to folder containing your config files | | UNIT4_ABSENCE_DATA_PATH | No | Path to absence data JSON (defaults to absence_data.json in UNIT4_BASE_PATH) |

Available Tools

| Tool | Description | |------|-------------| | sync_absences_to_unit4 | Run the full sync — opens a browser and fills timesheets for all employees | | get_unit4_sync_status | Check current configuration, mapped employees, and validate settings | | preview_timesheet_entries | Preview what entries would be created without actually submitting |

How It Works

The tool uses browser automation (Playwright) to:

  1. Log into Unit4 Business World
  2. Navigate to the timesheet form
  3. For each employee and each week in the date range:
    • Fill in regular work hours for weekdays
    • Fill in leave hours for any absences
    • Fill in public holidays
    • Skip days that already have the correct hours
  4. Save and take a screenshot for each employee/week

The browser window stays visible during the process so you can watch it work.