Skip to main content
Glama
jais2402
by jais2402

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
EVERHOUR_API_KEYYesPersonal Everhour API key

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
everhour_get_current_userA

Returns the Everhour user account associated with the configured EVERHOUR_API_KEY.

Use this to discover the caller's user ID, which is required by some endpoints (e.g. when listing time records for "me") and to verify the API key is valid before logging time.

Args:

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns: JSON shape: { "id": number, "name": string, "email": string, "role": string, "status": string, "headline"?: string, "capacity"?: number // weekly capacity in seconds }

Examples:

  • "Who am I in Everhour?" → call with no args

  • "What is my Everhour user ID?" → call with response_format='json' and read .id

Error Handling:

  • 401 → API key missing or invalid; check EVERHOUR_API_KEY

everhour_list_usersA

List the workspace's team members with their Everhour user IDs. Admin access required.

Use this to resolve a person's name to their numeric Everhour user ID, which you then pass as 'user_id' to everhour_log_time / everhour_log_time_batch to log time on their behalf (admins only).

Args:

  • query (string, optional): case-insensitive filter on name or email. Omit to list everyone.

  • response_format ('markdown' | 'json')

Returns an array of user objects: { id, name, email, role, status, ... }.

Examples:

  • "What's Gayathri's Everhour user ID?" → query='gayathri', then read .id

  • "List all team members" → no args

Error Handling:

  • 403 → the API key is not an admin key; listing all users requires admin access.

everhour_list_projectsA

List or search Everhour projects, optionally filtered by source platform (e.g. Asana).

Useful for:

  • Discovering project IDs needed by other tools

  • Confirming an Asana project has been synced into Everhour

  • Browsing what work the user has access to

Args:

  • query (string, optional): Filter by name substring

  • platform ('asana' | 'trello' | 'jira' | 'github' | 'basecamp' | 'everhour', optional)

  • archived (boolean, optional): Include archived projects

  • limit, offset: Pagination (default limit=25, max 250)

  • response_format ('markdown' | 'json'): Output format (default 'markdown')

Returns: JSON shape: { "total": number, "count": number, "offset": number, "items": [{ "id": "as:...", "name": string, "platform": string, "status": string, "client"?: { "name": string }, ... }], "has_more": boolean, "next_offset"?: number }

Examples:

  • "List my Asana projects in Everhour" → platform='asana'

  • "Find the 'Lynx Dashboard' project" → query='Lynx Dashboard'

Error Handling:

  • 401 → check EVERHOUR_API_KEY

  • 429 → rate-limited, wait and retry

everhour_get_projectA

Fetch a single project by its Everhour project ID.

Args:

  • project_id (string): Everhour project ID (e.g. 'as:1208034567890123')

  • response_format ('markdown' | 'json'): Output format (default 'markdown')

Returns the full project record including name, platform, status, workspace, billing, budget, and members.

Examples:

  • "Show project as:1208012345678901" → project_id='as:1208012345678901'

Error Handling:

  • 404 → project not found / not visible to this API key

everhour_search_tasksA

Search tasks in Everhour by name, optionally scoped to a project.

This is the primary way to find an Everhour task that mirrors an Asana ticket when you only know the ticket name. Asana-synced tasks appear with IDs like 'as:'.

Args:

  • query (string): Search string, 1-200 chars

  • project_id (string, optional): Scope search to this Everhour project ID

  • limit, offset: Pagination (default limit=25, max 250)

  • response_format ('markdown' | 'json'): Output format

Returns: { "total": number, "count": number, "offset": number, "items": [{ "id": "as:...", "name": string, "url": string, "status"?: string, "projects"?: string[] }], "has_more": boolean, "next_offset"?: number }

Examples:

  • "Find Everhour task for 'Fix login bug'" → query='Fix login bug'

  • "Find all design review tasks in project as:120801..." → query='design review', project_id='as:120801...'

Error Handling:

  • 400 → query is empty

  • 429 → rate-limited

everhour_get_taskA

Fetch a single Everhour task by ID, including total tracked time, estimate, and per-user time breakdown.

Args:

  • task_id (string): Everhour task ID. For Asana tasks: 'as:'

  • response_format ('markdown' | 'json'): Output format

Returns the full task object with name, projects, status, estimate (seconds), time.total (seconds), URL, etc.

Examples:

  • "Show task as:1208034567890123" → task_id='as:1208034567890123'

Error Handling:

  • 404 → task not found / not synced into Everhour. Use everhour_find_task_by_asana_id to verify Asana mapping.

everhour_find_task_by_asana_idA

Look up an Everhour task by the underlying Asana task GID.

Everhour syncs Asana tasks with IDs of the form 'as:'. This tool builds that ID and fetches the task in one step. Use this before logging time when the user gives you an Asana ticket URL or GID.

Args:

Returns the full Everhour task record (same as everhour_get_task).

Examples:

Error Handling:

  • 404 → the Asana task is not synced into Everhour. The user must add the project to Everhour or open the task in Asana with the Everhour browser extension to trigger a sync.

everhour_log_timeA

Log (add) tracked time against an Everhour task. This is the primary tool for recording hours worked.

Args:

  • task_id (string): Everhour task ID. For Asana tasks: 'as:'.

  • duration ({ hours?: number } | { seconds?: number }): How long to log. Provide ONE of:

    • hours: decimal hours, 0-24 (e.g. 1.5 = 1h 30m)

    • seconds: integer seconds, 60-86400

  • date (string, optional): YYYY-MM-DD. Defaults to today.

  • comment (string, optional): Note describing the work.

  • user_id (number, optional): Defaults to the authenticated user (only admins can log for others).

  • response_format ('markdown' | 'json'): Output format

Returns the created time record: { "id": number, "date": "YYYY-MM-DD", "user": number, "time": number, // seconds "comment": string | null, "task": { "id": string, "name"?: string }, "createdAt": "ISO-8601" }

Examples:

  • "Log 2 hours on task as:1208... for today" → task_id='as:1208...', duration={ hours: 2 }

  • "Log 45 minutes on OPS-123 yesterday with comment 'fix flaky test'" → after resolving the task ID: duration={ seconds: 2700 }, date='YYYY-MM-DD', comment='fix flaky test'

  • For an Asana ticket where you only have the GID, prefer everhour_log_time_for_asana_task.

Error Handling:

  • 404 → task not synced; verify with everhour_find_task_by_asana_id

  • 409 → a time record already exists for that user/date — use everhour_update_time_record instead

  • 422 → validation error (duration too long, future date, etc.)

everhour_log_time_for_asana_taskA

Workflow tool: log time on the Everhour task that mirrors a given Asana task GID. Equivalent to calling everhour_log_time with task_id='as:', but spares you having to construct the ID.

Use this when the user gives you an Asana ticket URL/GID and asks to log hours.

Args:

  • asana_task_gid (string): Numeric Asana task GID

  • duration: same as everhour_log_time

  • date, comment, user_id: same as everhour_log_time

  • response_format ('markdown' | 'json')

Returns the created time record (same shape as everhour_log_time).

Examples:

  • User: "Log 1.5h on Asana ticket 1208034567890123 — implemented retry logic" → asana_task_gid='1208034567890123', duration={ hours: 1.5 }, comment='implemented retry logic'

Error Handling:

  • 404 → Asana task not synced into Everhour

  • 409 → a record already exists for that user/date (use everhour_update_time_record)

everhour_log_time_batchA

Log a batch of time records in a single call — one entry per (task, date). Built for the log-everhour daily/weekly/monthly workflow: pass already-resolved task IDs and already-rephrased comments.

Each entry is logged sequentially. A single row failing (404 not synced, 409 already exists, etc.) does NOT abort the batch unless stop_on_error is true — failures are reported per row.

Durations are normalized to increment_hours (default 30 min). Comments are checked against absolute rules; a forbidden word or empty comment rejects that row unless allow_rule_violations is true.

Args:

  • entries (array, 1-60): { task_id: 'as:' | native, duration: { hours } | { seconds }, date: 'YYYY-MM-DD', comment: string }

  • increment_hours (number, optional): rounding grid, default 0.5

  • stop_on_error (boolean, optional): default false

  • allow_rule_violations (boolean, optional): default false

  • user_id (number, optional): defaults to caller

  • response_format ('markdown' | 'json')

Returns: { "results": [{ "ok": boolean, "task_id": string, "date": string, "hours": number, "rounded"?: boolean, "warnings"?: string[], "record_id"?: number, "error"?: string }], "summary": { "logged": number, "failed": number, "totalHours": number } }

Examples:

  • Log a full day: entries=[{ task_id:'as:1208...', duration:{hours:3}, date:'2026-06-12', comment:'Reviewed and submitted changes for review.' }, ...]

Error Handling:

  • Per-row 404 → that Asana task is not synced; other rows still log.

  • Per-row 409 → a record already exists for that user/date; fix with everhour_update_time_record.

everhour_list_time_recordsA

List time records for a user across an optional date range, with optional project/task filters. Use this to review what's already been logged before adding more, or to build a timesheet.

Args:

  • from, to (string, optional): Date range, YYYY-MM-DD. If omitted, returns recent records.

  • user_id (number, optional): Defaults to the authenticated user.

  • project_id (string, optional): Restrict to one project.

  • task_id (string, optional): Restrict to one task.

  • limit, offset: Pagination (default limit=25, max 250)

  • response_format ('markdown' | 'json'): Output format

Returns: { "total": number, "count": number, "offset": number, "items": [{ "id": number, "date": string, "time": number, "comment": string|null, "task": { "id": string, "name"?: string } }], "has_more": boolean, "next_offset"?: number } Markdown output also shows a 'total tracked' summary.

Examples:

  • "Show what I logged this week" → from='YYYY-MM-DD' (Mon), to='YYYY-MM-DD' (Sun)

  • "How many hours have I logged on task as:1208...?" → task_id='as:1208...'

Error Handling:

  • 403 → not authorized to view that user's records

everhour_update_time_recordA

Modify an existing time record (change duration, date, or comment).

Args:

  • record_id (number): The time record ID returned by everhour_list_time_records or everhour_log_time.

  • duration ({ hours? } | { seconds? }, optional): New duration. Omit to keep existing.

  • date (string, optional): New date YYYY-MM-DD. Omit to keep existing.

  • comment (string, optional): New comment. Pass empty string to clear it. Omit to keep existing.

  • response_format ('markdown' | 'json')

Returns the updated time record.

Examples:

  • "Change record 12345 to 3 hours" → record_id=12345, duration={ hours: 3 }

  • "Update the comment on record 12345 to 'pair session with Alex'" → record_id=12345, comment='pair session with Alex'

Error Handling:

  • 404 → record not found

  • 403 → record locked (period closed) or not yours

everhour_delete_time_recordA

Permanently delete a time record. Cannot be undone.

Args:

  • record_id (number): ID of the time record to delete.

Returns a confirmation message on success.

Examples:

  • "Delete time record 12345" → record_id=12345

Error Handling:

  • 404 → record not found (may already have been deleted)

  • 403 → record locked or not yours

everhour_start_timerA

Start the active timer on an Everhour task. Only one timer can run at a time per user; starting a new one stops the previous.

Args:

  • task_id (string, optional): Everhour task ID. Use this OR asana_task_gid.

  • asana_task_gid (string, optional): Asana task GID. Will be resolved to 'as:'.

  • user_date (string, optional): YYYY-MM-DD, the user's local date. Defaults to today.

  • comment (string, optional): Note attached to the running timer.

  • response_format ('markdown' | 'json'): Output format

You must provide exactly one of task_id or asana_task_gid.

Returns the timer state (status='active', task, startedAt, today seconds, duration).

Examples:

  • "Start tracking Asana ticket 1208034567890123" → asana_task_gid='1208034567890123'

  • "Start a timer on task as:1208... with comment 'investigating bug'" → task_id='as:1208...', comment='investigating bug'

Error Handling:

  • 404 → task not found / not synced into Everhour

everhour_stop_timerA

Stop the currently running timer for the authenticated user. Everhour will commit the elapsed time as a time record on the task.

Args:

  • response_format ('markdown' | 'json'): Output format

Returns the timer state after stopping (status='stopped', today total seconds).

Examples:

  • "Stop my timer" → no args needed

Error Handling:

  • 404 → no timer is currently running

everhour_get_current_timerA

Return the state of the authenticated user's timer.

Args:

  • response_format ('markdown' | 'json'): Output format

Returns:

  • When running: { "status": "active", "duration": seconds, "today": seconds, "task": {...}, "startedAt": ISO-8601 }

  • When stopped: { "status": "stopped", "today": seconds }

Examples:

  • "Is my timer running?" → no args

  • "How long have I been working today?" → check .today (seconds)

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jais2402/ever-hour-mcp-for-jais'

If you have feedback or need assistance with the MCP directory API, please join our Discord server