Skip to main content
Glama
README.md
# Timesheet MCP Server

Simple timesheet automation server using Model Context Protocol (MCP) and NestJS.

## Features

- **Fresh Token on Every Tool Call** - Automatically refreshes authentication token on each request
- **Smart Authentication Handling** - Seamlessly handles token expiration and re-authenticates using MCP client credentials
- **No Token Storage** - Config file is deleted on server startup for security; fresh login on every session
- **Stateless Operation** - Each tool call is independent and self-authenticating
- **5 Essential Tools** organized by domain:
  - **Authentication**: `whoami` - Get current user info, assigned projects, and modules
  - **Timesheets**: `create_new_timesheet_entry`, `list_user_timesheet_entries`
  - **Activities**: `list_all_available_work_activities`
  - **Daily Updates**: `create_daily_scrum_standup_update`

## Quick Setup

### 1. Install Dependencies

```bash
npm install
```

### 2. Configure Environment

The server requires credentials to be configured in your MCP client's environment variables (not in a `.env` file on the server). This ensures credentials are never stored on the server.

**TIMESHEET_USERNAME** and **TIMESHEET_PASSWORD** must be configured in your MCP client configuration:
- For Claude Desktop: Configure in `claude_desktop_config.json` (see below)
- For OpenCode: Configure in the MCP environment variables
- For MCP Inspector: Set as environment variables before running

Optional server-side `.env` file:

```env
# Backend API (optional - defaults to https://timesheet.pinnacle.in:3000/api)
API_BASE_URL=https://timesheet.pinnacle.in:3000/api

# Node Environment
NODE_ENV=production
```

**Note**: SSL certificate verification is automatically disabled in the code for self-signed certificates.

### 3. Build and Run

```bash
npm run build
npm run start
```

## Authentication

The server implements **stateless, fresh authentication** for every tool call:

1. **On Server Startup**: Config file is deleted to ensure a clean state
2. **On Every Tool Call**:
   - Attempts to use existing cached token (if available)
   - Automatically refreshes token via `/auth/refresh` endpoint
   - If token is expired or invalid, re-authenticates using `TIMESHEET_USERNAME` and `TIMESHEET_PASSWORD` from MCP client environment
   - If login fails, returns a clear error message
3. **No Token Persistence**: Tokens are saved to config file temporarily but deleted on next server restart

This approach ensures:
- ✅ Fresh authentication on every server session
- ✅ Automatic token refresh without user intervention
- ✅ Graceful handling of expired credentials
- ✅ Clear error messages for troubleshooting
- ✅ No sensitive data stored on disk between sessions

## Available Tools

### Authentication Tools

#### `whoami`

Get current authenticated user information with automatically fetched projects and modules. This tool:
- Handles authentication automatically (refreshes token or logs in with MCP client credentials)
- Returns fresh user details, all assigned projects, and modules within those projects
- Provides clear error messages if credentials are missing or invalid
- This is the primary starting tool for verifying authentication

**Parameters**: None

**Response**:

```json
{
  "success": true,
  "message": "✓ User authenticated successfully!",
  "data": {
    "user": {
      "id": 41,
      "name": "John Doe",
      "username": "john.doe@company.com",
      "email": "john.doe@company.com",
      "roles": ["RESOURCE"],
      "managerId": 44
    },
    "projects": [
      {
        "id": 9,
        "name": "Project Name",
        "project_id": 9
      }
    ],
    "modules": [
      {
        "id": 41,
        "name": "Pyramid2.0_UI Gateway",
        "project_id": 9
      }
    ]
  }
}
```

### Timesheet Management Tools

#### `create_new_timesheet_entry`

Create a new daily timesheet entry with work details.

**Parameters**:

- `project_id` (number): Which project the work belongs to
- `module_id` (number): Which module/component within the project
- `activity_id` (number): The type of work (Development, Code Review, Testing, etc.)
- `start_time` (string): Start time in HH:MM:SS format
- `end_time` (string): End time in HH:MM:SS format
- `duration` (number): Duration in minutes
- `description` (string, min 10 chars): Detailed work description
- `date` (string): Date in YYYY-MM-DD format

**Example**:

```json
{
  "project_id": 9,
  "module_id": 41,
  "activity_id": 11,
  "start_time": "09:00:00",
  "end_time": "10:00:00",
  "duration": 60,
  "description": "Working on user authentication module implementation",
  "date": "2025-11-04"
}
```

#### `list_user_timesheet_entries`

Fetch and display user's timesheet entries with pagination.

**Parameters**:

- `page` (number, optional, default: 1): Page number for pagination
- `limit` (number, optional, default: 10, max: 100): Number of entries per page

**Example**:

```json
{
  "page": 1,
  "limit": 10
}
```

### Activity Management Tools

#### `list_all_available_work_activities`

Get all available work activity types/categories that can be used when creating timesheet entries.

**Parameters**: None

**Response**:

```json
{
  "success": true,
  "message": "✓ Available work activities fetched successfully!",
  "data": [
    {
      "id": 1,
      "name": "Development",
      "description": "Development work"
    },
    {
      "id": 11,
      "name": "Code Review",
      "description": "Code review activities"
    }
  ]
}
```

### Daily Updates Tools

#### `create_daily_scrum_standup_update`

Create a daily scrum standup update to report progress and blockers.

**Parameters**:

- `date` (string): Date in yyyy-MM-dd format
- `yesterdays_progress` (string): Summary of work completed yesterday
- `todays_priorities` (string): Main priorities and goals for today
- `task_blockers` (string): Any blockers or impediments (or "None" if no blockers)

**Example**:

```json
{
  "date": "2025-11-04",
  "yesterdays_progress": "Completed user authentication module with tests",
  "todays_priorities": "Implement profile page and integrate with API",
  "task_blockers": "Waiting for backend API documentation"
}
```

## MCP Client Configuration

### For Claude Desktop

Create/edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or appropriate config file for your OS:

```json
{
  "mcpServers": {
    "timesheet-mcp": {
      "command": "node",
      "args": ["/path/to/timesheet-mcp/dist/main.js"],
      "env": {
        "NODE_ENV": "production",
        "API_BASE_URL": "https://timesheet.pinnacle.in:3000/api",
        "TIMESHEET_USERNAME": "your.email@company.com",
        "TIMESHEET_PASSWORD": "your-password"
      }
    }
  }
}
```

**Windows Claude Desktop Path**: `%APPDATA%\Claude\claude_desktop_config.json`
**Linux Claude Desktop Path**: `~/.config/claude/claude_desktop_config.json`

### For OpenCode

Edit your OpenCode config file and add the MCP server configuration:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "timesheet-mcp": {
      "type": "local",
      "command": ["node", "/path/to/timesheet-mcp/dist/main.js"],
      "enabled": true,
      "environment": {
        "NODE_ENV": "production",
        "API_BASE_URL": "https://timesheet.pinnacle.in:3000/api",
        "TIMESHEET_USERNAME": "your.email@company.com",
        "TIMESHEET_PASSWORD": "your-password"
      }
    }
  }
}
```

**Note**: The `"type": "local"` field is required for OpenCode to recognize the MCP server.

### For MCP Inspector

```bash
npm run inspector
```

## Architecture

```
src/
├── common/                           # Shared utilities and DTOs
│   └── utils/
│       └── response.util.ts         # MCP response formatting utility
├── auth/                            # Authentication module
│   ├── auth.module.ts
│   ├── auth.service.ts
│   ├── auth.tools.ts               # whoami tool
│   ├── auto-login.service.ts
│   └── dto/
│       └── login.dto.ts
├── projects/                        # Project management module
│   ├── projects.module.ts
│   ├── projects.service.ts
│   └── projects.tools.ts           # Project-related tools
├── timesheets/                      # Timesheet module
│   ├── timesheets.module.ts
│   ├── timesheets.service.ts
│   ├── timesheets.tools.ts         # Timesheet creation and listing tools
│   └── dto/
│       └── create-timesheet.dto.ts
├── activities/                      # Activity management module
│   ├── activities.module.ts
│   ├── activities.service.ts
│   └── activities.tools.ts         # Activity listing tool
├── daily-updates/                   # Daily scrum module
│   ├── daily-updates.module.ts
│   ├── daily-updates.service.ts
│   ├── daily-updates.tools.ts      # Daily scrum tool
│   └── dto/
│       └── create-daily-scrum.dto.ts
├── config/                          # Configuration management
├── shared/                          # HTTP client & shared utilities
├── main.ts                          # Application entry point
└── app.module.ts                    # Main application module
```

## Design Principles

- **Modular Architecture**: Each domain (auth, projects, timesheets, etc.) is a separate module
- **Separation of Concerns**: Services handle business logic, tools handle MCP interface
- **Descriptive Tool Names**: Tool names clearly indicate what they do for LLM decision making
- **Response Utility**: Centralized MCP response formatting for consistency
- **DTOs**: Type-safe data transfer between layers

## Philosophy

This MCP server provides **simple API wrappers** - no AI, no smart parsing, no complex workflows.

The LLM (Claude, GPT, etc.) handles all natural language processing and intelligence. The server just provides CRUD operations for the timesheet API.

## API Endpoints Used

- `POST /api/auth/login` - User authentication
- `GET /api/projects/user/{userId}` - Get user projects
- `GET /api/modules/by-project?projectId={id}` - Get project modules
- `GET /api/activities` - Get all activities
- `POST /api/timesheets/create` - Create timesheet entry
- `GET /api/timesheets/list/{userId}` - Get user timesheets

## License

MIT