Skip to main content
Glama

Log time

log_time

Book time against a work package or project with OpenProject validation, so invalid activities or permissions return errors instead of partial entries.

Instructions

Book time against a work package or a project.

Use it when the user says "log 2 hours on #1234" or "book half a day to project X". The call is validated through OpenProject's own form endpoint first, so an activity this project does not allow, a missing permission or a closed cost-reporting period comes back as a typed error listing what would be accepted — nothing half-written is left behind.

Returns the created entry: {id, hours, spent_on, comment, user, activity, work_package, project, created_at, updated_at, lock_version}. hours comes back as a float.

Pitfalls. This is not idempotent — calling it twice books the time twice, so never blind-retry after a timeout; list the day's entries first. The time is always booked for the token owner; you cannot log time on someone else's behalf through this tool. Logging time does not change the work package's status, estimate or progress — those are separate fields, and on instances that derive progress from work the percentage is read-only anyway. The work package's spent_hours reflects the new entry on the next read.

Cross-references: the activities and ids this project accepts come from get_project_metadata(project_id=...); review what is already booked with list_time_entries; fix a mistake with update_time_entry or delete_time_entry.

Input Schema

NameRequiredDescriptionDefault
hoursYesDuration in hours as a float: 1.5 is one and a half hours, 0.25 is fifteen minutes. Must be positive; OpenProject stores it to the minute.
commentNoWhat the time was spent on. Short and factual: it shows up in cost reports next to the hours.
activityNoActivity name ('Development') or numeric id. Omit to take the instance default from the form. Names are resolved against this project's allowed activities; an unknown name fails with the valid ones listed.
spent_onYesThe date the work was done, ISO YYYY-MM-DD. Required and never inferred — 'today' on the server may not be today for the user.
project_idNoProject to book the time on when the work belongs to no single ticket (numeric id or identifier). Required when work_package_id is omitted.
work_package_idNoWork package to book the time on. Ids come from search_work_packages or list_work_packages. Either this or project_id is required; passing both books on the work package inside that project.

Output Schema

NameRequiredDescriptionDefault
idNo
userNo
hoursNo
commentNo
projectNo
activityNo
spent_onNo
created_atNo
updated_atNo
lock_versionNo
work_packageNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed41 schema fields changedv0.4.0
    • removedOutput schema / description
      Removed value: -"A single time entry with the fields only a detail read carries."
    • changedOutput schema / properties / activity / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "description": "A reference to another resource. Canonical output shape.",
      -    "properties": {
      -      "id": {
      -        "anyOf": [
      -          {
      -            "type": "integer"
      -          },
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null,
      -        "description": "Resource id."
      -      },
      -      "name": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null,
      -        "description": "Human-readable name."
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "id": {
      +        "type": [
      +          "integer",
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "name": {
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / activity / default
      Removed value: -null
    • removedOutput schema / properties / activity / description
      Removed value: -"Time-entry activity (Development, Management, …); instance-defined."
    • removedOutput schema / properties / comment / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / comment / default
      Removed value: -null
    • removedOutput schema / properties / comment / description
      Removed value: -"Free-text comment as entered (raw); html is dropped."
    • addedOutput schema / properties / comment / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / created_at / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / created_at / default
      Removed value: -null
    • removedOutput schema / properties / created_at / description
      Removed value: -"ISO 8601 UTC timestamp."
    • addedOutput schema / properties / created_at / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / hours / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / hours / default
      Removed value: -null
    • removedOutput schema / properties / hours / description
      Removed value: -"Logged duration in hours as a float (1.5 = one and a half hours), converted from OpenProject's ISO 8601 duration."
    • addedOutput schema / properties / hours / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / id / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / id / default
      Removed value: -null
    • removedOutput schema / properties / id / description
      Removed value: -"Time entry id. Feed it to update_time_entry or delete_time_entry."
    • addedOutput schema / properties / id / type
      Added value: +[
      +  "integer",
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / lock_version / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / lock_version / default
      Removed value: -null
    • removedOutput schema / properties / lock_version / description
      Removed value: -"Optimistic-locking version, when this instance reports one for time entries; null means the resource is updated without a lock version."
    • addedOutput schema / properties / lock_version / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • changedOutput schema / properties / project / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "description": "A reference to another resource. Canonical output shape.",
      -    "properties": {
      -      "id": {
      -        "anyOf": [
      -          {
      -            "type": "integer"
      -          },
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null,
      -        "description": "Resource id."
      -      },
      -      "name": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null,
      -        "description": "Human-readable name."
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "id": {
      +        "type": [
      +          "integer",
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "name": {
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / project / default
      Removed value: -null
    • removedOutput schema / properties / project / description
      Removed value: -"Project the entry belongs to."
    • removedOutput schema / properties / spent_on / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / spent_on / default
      Removed value: -null
    • removedOutput schema / properties / spent_on / description
      Removed value: -"The date the work was done, ISO YYYY-MM-DD."
    • addedOutput schema / properties / spent_on / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / updated_at / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / updated_at / default
      Removed value: -null
    • removedOutput schema / properties / updated_at / description
      Removed value: -"ISO 8601 UTC timestamp."
    • addedOutput schema / properties / updated_at / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / user / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "description": "A reference to another resource. Canonical output shape.",
      -    "properties": {
      -      "id": {
      -        "anyOf": [
      -          {
      -            "type": "integer"
      -          },
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null,
      -        "description": "Resource id."
      -      },
      -      "name": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null,
      -        "description": "Human-readable name."
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "id": {
      +        "type": [
      +          "integer",
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "name": {
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / user / default
      Removed value: -null
    • removedOutput schema / properties / user / description
      Removed value: -"User the time is booked for."
    • changedOutput schema / properties / work_package / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "description": "A reference to another resource. Canonical output shape.",
      -    "properties": {
      -      "id": {
      -        "anyOf": [
      -          {
      -            "type": "integer"
      -          },
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null,
      -        "description": "Resource id."
      -      },
      -      "name": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null,
      -        "description": "Human-readable name."
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "id": {
      +        "type": [
      +          "integer",
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "name": {
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / work_package / default
      Removed value: -null
    • removedOutput schema / properties / work_package / description
      Removed value: -"Work package the time is booked on; null for project-level entries."
  2. First observedv0.1.0

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, idempotentHint=false, destructiveHint=false and openWorldHint=true, and the description largely restates the non-idempotency rather than extending it. It does add genuine context beyond annotations: server-side form validation yielding typed errors, no partial writes, token-owner-only attribution, and the fact that status/estimate/progress are untouched. Useful but partially overlapping with what the structured hints already say.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then structured into Pitfalls and Cross-references sections that make it scannable despite its length. The length is defensible for a non-idempotent mutation with six parameters, though the explicit return-field enumeration duplicates the output schema and could be dropped.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the mutation risks, the auth/attribution constraint, the validation-failure behavior, and the follow-up tool chain an agent needs. An output schema exists, so the return-value list is redundant rather than missing. Nothing required to call this correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each parameter already documents itself thoroughly (float hours, ISO date, activity name-or-id, project_id required when work_package_id is omitted). The description adds only the pointer to get_project_metadata for valid activity values and the token-owner booking constraint, which is modest incremental value over a schema that already does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Book time against a work package or a project') and immediately scopes it against the sibling family by naming update_time_entry, delete_time_entry and list_time_entries. An agent can distinguish this create operation from the time-entry CRUD siblings without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete triggering utterances ('log 2 hours on #1234', 'book half a day to project X') plus explicit routing: get_project_metadata for valid activities, list_time_entries to review before retrying, update_time_entry/delete_time_entry to correct mistakes. The 'never blind-retry after a timeout; list the day's entries first' line is an explicit when-not rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.