Skip to main content
Glama

Add work package comment

add_work_package_comment

Posts a markdown comment on a work package to reply in a ticket thread, record a decision, or leave a handover note, and returns the created journal entry.

Instructions

Post a comment on a work package.

Use this to reply in a ticket's thread, record a decision, or leave a handover note. Returns the created journal entry (activity id, author, markdown text, internal flag, timestamps) — the same shape list_work_package_comments returns, so the id can be reused.

Pitfalls. Every call creates a new comment; it is not idempotent, so do not retry blindly after a timeout — read the thread first. internal=true is refused on OpenProject below 16.0 because those versions accept the flag and publish the comment anyway; upgrade or post publicly, deliberately. notify=false suppresses notifications only, the comment is still visible to everyone who can see the work package.

Cross-references: read the thread with list_work_package_comments; change fields (status, assignee, dates) with update_work_package rather than describing the change in prose; attach a file with upload_attachment.

Input Schema

NameRequiredDescriptionDefault
idYesWork package id to comment on. Get it from search_work_packages or list_work_packages.
notifyNoSend the usual watcher/assignee notifications. Set false for bulk or bookkeeping comments so inboxes stay quiet.
commentYesComment body in markdown. OpenProject renders it; @-mentions need the user's mention syntax, plain names do not notify anyone.
internalNoPost as an internal comment, visible only to project members with the internal-comments permission. Requires OpenProject >= 16; on older instances the call fails instead of posting publicly.

Output Schema

NameRequiredDescriptionDefault
idNo
kindYes
authorNo
commentNo
detailsNo
versionNo
internalNo
truncatedNo
created_atNo
updated_atNo
work_packageNo
comment_lengthNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed54 schema fields changedv0.4.0
    • removedOutput schema / description
      Removed value: -"One journal entry: a comment, a set of field changes, or both.\n\nOpenProject aggregates a comment and the edits saved with it into a single\njournal entry, so ``kind='comment'`` entries can still carry ``details``."
    • changedOutput schema / properties / author / 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 / author / default
      Removed value: -null
    • removedOutput schema / properties / author / description
      Removed value: -"User who wrote the entry."
    • 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: -"Comment body as markdown (raw); html is dropped. Cut to max_comment_chars when 'truncated' is true."
    • addedOutput schema / properties / comment / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / comment_length / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / comment_length / default
      Removed value: -null
    • removedOutput schema / properties / comment_length / description
      Removed value: -"Character length of the untruncated comment; set only when truncated."
    • addedOutput schema / properties / comment_length / type
      Added value: +[
      +  "integer",
      +  "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 / details / description
      Removed value: -"Field changes recorded with this entry; always a list, empty for a comment-only entry."
    • removedOutput schema / properties / details / items / description
      Removed value: -"One field change inside a journal entry, parsed into its parts."
    • removedOutput schema / properties / details / items / properties / field / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / details / items / properties / field / default
      Removed value: -null
    • removedOutput schema / properties / details / items / properties / field / description
      Removed value: -"Changed field as OpenProject labels it, e.g. 'Status', 'Start date'."
    • addedOutput schema / properties / details / items / properties / field / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / details / items / properties / from / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / details / items / properties / from / default
      Removed value: -null
    • removedOutput schema / properties / details / items / properties / from / description
      Removed value: -"Previous value; null when the field was set for the first time."
    • addedOutput schema / properties / details / items / properties / from / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / details / items / properties / text / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / details / items / properties / text / default
      Removed value: -null
    • removedOutput schema / properties / details / items / properties / text / description
      Removed value: -"The change as OpenProject phrases it, kept verbatim for anything the parser could not split (attachment adds, diff-only notes)."
    • addedOutput schema / properties / details / items / properties / text / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / details / items / properties / to / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / details / items / properties / to / default
      Removed value: -null
    • removedOutput schema / properties / details / items / properties / to / description
      Removed value: -"New value; null when the field was cleared."
    • addedOutput schema / properties / details / items / properties / to / type
      Added value: +[
      +  "string",
      +  "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: -"Activity id. Pass it back as list_work_package_comments(activity_id=...) to read a truncated comment in full."
    • addedOutput schema / properties / id / type
      Added value: +[
      +  "integer",
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / internal / default
      Removed value: -false
    • removedOutput schema / properties / internal / description
      Removed value: -"True for internal (project-member-only) comments; OpenProject >= 16."
    • removedOutput schema / properties / kind / description
      Removed value: -"'comment' when the entry carries comment text, 'field_change' otherwise."
    • removedOutput schema / properties / truncated / default
      Removed value: -false
    • removedOutput schema / properties / truncated / description
      Removed value: -"True when the comment was cut to max_comment_chars."
    • 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 of the last edit."
    • addedOutput schema / properties / updated_at / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / version / anyOf
      Removed value: -[
      -  {
      -    "type": "integer"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • removedOutput schema / properties / version / default
      Removed value: -null
    • removedOutput schema / properties / version / description
      Removed value: -"Journal version number of this entry within the work package."
    • addedOutput schema / properties / version / type
      Added value: +[
      +  "integer",
      +  "null"
      +]
    • 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 entry belongs to."
  2. First observedv0.1.0

TDQS

A4.7/5.0
Behavior5/5

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

The description adds substantial behavioral context beyond annotations: non-idempotency and retry risk, OpenProject <16.0 behavior for internal comments, and the distinction that notify=false only suppresses notifications while the comment remains visible. These are exactly the operational caveats an agent needs before invoking a write operation.

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

Conciseness5/5

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

The description is front-loaded with the core action and usage cases, then organized into pitfalls and cross-references. Despite covering several caveats, every section earns its place and remains easy to scan.

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?

The tool has an output schema and annotations, and the description still adds valuable return-shape context, retry guidance, version-specific caveats, and sibling routing. Nothing an agent needs to invoke it correctly appears to be missing.

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%, so parameter meanings are already fully documented in the input schema. The description reinforces important semantics for internal and notify, but it does not add substantial new syntax or format guidance beyond what the schema already provides.

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?

The description states a specific verb and resource: post a comment on a work package. It also distinguishes the tool from siblings by naming update_work_package, list_work_package_comments, and upload_attachment as alternatives for related tasks.

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?

It gives explicit when-to-use cases (reply in a thread, record a decision, leave a handover note) and routes other actions to the correct sibling tools. It also warns against blind retries and points to list_work_package_comments for reading the thread first.

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