| list_projectsA | List Polarion projects the authenticated user can access. Use this to discover project IDs for other tools. Polarion's Lucene
supports trailing wildcards (name:ILCU*) but rejects leading
wildcards (*foo*) with HTTP 400. |
| list_documentsA | List all documents in a Polarion project. Returns (space_id, document_name) pairs that other document
tools accept. First call per project performs a full discovery scan
and caches the result for 60 seconds, so subsequent paginated calls
are cheap. |
| get_documentA | Get a document's metadata (and optionally its raw body source). Returns title, type, status, and custom fields. With
include_homepage_content_html=True the content_html field
carries homePageContent as raw Polarion HTML — the exact shape
that round-trips through update_document(home_page_content_html=...)
losslessly (no Markdown conversion, no sanitization). homePageContent is the inline prose only — heading text and
embedded work-item bodies live in separate work items. For end-to-end
reading use read_document; for structural metadata
use read_document_parts. Only feed content_html back to
update_document when the read flag was True (a False read blanks
the field, and the empty string is rejected at the write side).
|
| list_document_enum_optionsA | List valid enum options for a document field of the given document type. Call this before update_document when you need to pick a value
for a document's status / type / custom enum field. Polarion
does NOT validate these values on write -- unknown ids are stored
verbatim as ghost values -- so resolve them first. This tool covers
DOCUMENT fields only; work-item fields are surfaced via
list_work_item_enum_options. Returns the FULL enum set for the field on the given document type.
Workflow transitions are NOT filtered by the document's current
state; that is a separate Polarion endpoint not exposed here.
document_type='~' returns the type-agnostic option set. An unknown
document_type is silently treated as ~ by Polarion with no error,
so verify the type id (e.g. via get_document) before trusting
the result. |
| list_work_item_enum_optionsA | List valid enum options for a work item field of the given type. Call this before create_work_item / update_work_item when you
need to pick a value for a work item's type / status /
severity / priority / custom enum field. Polarion does NOT
validate these values on write -- unknown ids are stored verbatim as
ghost values (priority only coerces non-numeric inputs to the
project default) -- so resolve them first. This tool covers WORK
ITEM fields only; document fields are surfaced via
list_document_enum_options. Returns the FULL enum set for the field on the given work item type.
Workflow transitions are NOT filtered by the work item's current
state; that is a separate Polarion endpoint not exposed here.
work_item_type='~' returns the type-agnostic option set. An
unknown work_item_type is silently treated as ~ by Polarion
with no error, so verify the type id (e.g. via get_work_item)
before trusting the result. |
| read_document_partsA | List the structural parts of a document in order. Use this when you need part IDs for move_work_item_to_document,
heading levels, or per-work-item type/status. Each workitem part
already carries its description as Markdown, so a follow-up
get_work_item is unnecessary when scanning bodies. For plain
reading prefer read_document. If you only need work items filtered by type/status/title/custom-field
or a subset of the document (e.g. "non-heading work items only"),
prefer list_work_items with a SQL:(...) query — see that
tool's docstring for a recipe gallery. Smaller payload than this
tool, no per-part pagination. |
| read_documentA | Render a Polarion document end-to-end as flowing Markdown. Paginates read_document_parts internally and interleaves heading
titles, embedded work-item descriptions, and inline prose into a
single Markdown stream — the canonical way to read a document body.
Empty placeholder paragraphs are skipped. Output is read-only synthesis: do NOT feed it back to update_document
(the rendered Markdown collapses Polarion's ID-anchored placeholder
structure and the round-trip would orphan headings). Use
get_document(include_homepage_content_html=True) for round-trip
editing of the raw HTML source. For metadata-only extraction (work item IDs / types / statuses /
custom fields) prefer list_work_items with a SQL:(...) query
— this tool always materializes the full body Markdown for every
part, which is wasteful when the caller only wants a filtered list. |
| list_work_itemsA | List and search work items in a Polarion project. Pass a Lucene query (type:requirement, status:approved AND
type:requirement, title:SRS*) or omit it for all work items. Leading
wildcards (*foo*) return HTTP 400. module is not indexed — see
SQL prefix below for the workaround. Description body text is NOT indexed — for content search, scan
read_document_parts (each workitem part already carries its
description) or use read_document for end-to-end reading. SQL prefix. A query starting with SQL:( runs as native
SQL, unlocking patterns Lucene cannot express: module-scoped lookup,
leading-wildcard LIKE, custom-field joins, and role-preserving
traceability. Escape ' as '' in string literals; Polarion's
REST query does not support bind parameters, so any user-supplied
value substituted into a recipe must be escaped before sending.
C_DESCRIPTION LIKE does NOT match (CLOB stored elsewhere; use
read_document_parts for body search). On this server LIKE is
rejected inside EXISTS (SELECT ...) ("Restricted SQL commands:
LIKE") — keep LIKE in the top-level WHERE by using
INNER JOIN as the recipes below do (works everywhere). Schema (tables are POLARION.<name>; columns shown are the ones
used for JOINs and filtering):: WORKITEM c_uri, c_id, c_type, c_title, c_status,
fk_uri_module, fk_uri_project
MODULE c_uri, c_id, c_modulefolder, fk_uri_project
PROJECT c_uri, c_id
REL_MODULE_WORKITEM fk_uri_module, fk_uri_workitem
CF_WORKITEM fk_uri_workitem, c_name,
c_string_value | c_boolean_value |
c_durationtime_value | ...
STRUCT_WORKITEM_LINKEDWORKITEMS
fk_uri_p_workitem (source / role-holder),
fk_uri_workitem (target), c_role
Recipe 1 — work items belonging to a document (excludes Recycle Bin
and Referenced Work Items, matches read_document_parts scope):: SQL:(SELECT item.* FROM POLARION.MODULE doc
INNER JOIN POLARION.PROJECT proj ON doc.FK_URI_PROJECT = proj.C_URI
INNER JOIN POLARION.REL_MODULE_WORKITEM rel
ON rel.FK_URI_MODULE = doc.C_URI
INNER JOIN POLARION.WORKITEM item
ON item.C_URI = rel.FK_URI_WORKITEM
WHERE proj.C_ID = '<project>' AND doc.C_MODULEFOLDER = '<space>'
AND doc.C_ID = '<document>'
AND item.FK_URI_MODULE = doc.C_URI)
The trailing item.FK_URI_MODULE = doc.C_URI predicate is what
excludes Referenced Work Items and Recycle Bin entries; drop it to
include them. Common adjustments on Recipe 1: exclude headings with
AND item.C_TYPE != 'heading' (read_document_parts returns
all parts including headings), filter type with
AND item.C_TYPE IN ('requirement','testcase'), or substring-match
the title with AND LOWER(item.C_TITLE) LIKE '%foo%' (Lucene
rejects leading *). Recipe 2 — custom-field value search (= or LIKE):: SQL:(SELECT item.* FROM POLARION.WORKITEM item
INNER JOIN POLARION.CF_WORKITEM cf ON cf.FK_URI_WORKITEM = item.C_URI
WHERE cf.C_NAME = '<field>'
AND cf.C_STRING_VALUE LIKE '%<value>%')
Use c_boolean_value / c_durationtime_value (etc.) for non-string
customs. Rich text customs ({type: "text/plain", value: ...}) are
CLOB-stored — read them via get_work_item instead. Recipe 3 — back-traceability (work items whose role link points to
<target-id>, e.g. all children of a given parent):: SQL:(SELECT DISTINCT item.* FROM POLARION.WORKITEM item
INNER JOIN POLARION.STRUCT_WORKITEM_LINKEDWORKITEMS link
ON link.FK_URI_P_WORKITEM = item.C_URI
INNER JOIN POLARION.WORKITEM target
ON target.C_URI = link.FK_URI_WORKITEM
WHERE target.C_ID = '<target-id>' AND link.C_ROLE = '<role>')
fk_uri_p_workitem is the source (role-holder), fk_uri_workitem
is the target. Unlike list_work_item_links(direction='back')
(Lucene fallback, drops the role), this preserves c_role.
Recipe 4 — forward-traceability (work items linked from
<source-id>, e.g. testcases a requirement verifies):: SQL:(SELECT DISTINCT item.* FROM POLARION.WORKITEM item
INNER JOIN POLARION.STRUCT_WORKITEM_LINKEDWORKITEMS link
ON link.FK_URI_WORKITEM = item.C_URI
INNER JOIN POLARION.WORKITEM source
ON source.C_URI = link.FK_URI_P_WORKITEM
WHERE source.C_ID = '<source-id>' AND link.C_ROLE = '<role>')
Mirror of Recipe 3 with the two FK_*_WORKITEM columns swapped
in both JOIN conditions. Other patterns (testrun / timepoint / assignee joins, the
LUCENE_QUERY table function) live in the Polarion SDK at
polarion/sdk/doc/database/SQLQueryExamples.pdf. |
| get_work_itemA | Get full details of a single Polarion work item. With include_description_html=True the description_html field
carries the raw Polarion HTML body — the exact shape that round-trips
through update_work_item(description_html=...) losslessly. Only
feed it back when this flag was True (a False read blanks the field,
and the update tool treats "" as leave unchanged). |
| read_work_itemA | Read a Polarion work item with its body rendered as Markdown. Synthesis variant of get_work_item: returns the same metadata
fields plus description as Markdown (converted from Polarion
HTML via html_to_markdown()) instead of description_html.
Use this when an LLM needs to read or summarise the body. The
converter collapses Polarion-specific spans and ID anchors, so the
Markdown is read-only — do NOT feed it back to update_work_item.
For round-trip editing, pair
get_work_item(include_description_html=True) with
update_work_item(description_html=...). |
| list_work_item_linksA | List a work item's outgoing or incoming links. A single call returns one direction; call twice (direction="forward"
then direction="back") when both sides of the traceability graph are
needed. Forward links use the /linkedworkitems endpoint and expose
the originating role (e.g. parent, relates_to, verifies).
Back links fall back to a linkedWorkItems: Lucene query that does
not surface the originating role on this server, so role is None
for every back-direction item — recover it by calling forward on the
source work item. The suspect flag marks links whose target has changed since the
link was last reviewed; it is only meaningful in the forward direction. |
| list_document_commentsA | List comments attached to a Polarion document. Comments come back as a flat page; reconstruct threads on the client
side via parent_comment_id (set on replies) and child_comment_ids
(direct replies). Top-level comments have parent_comment_id of
None. text is returned verbatim, with text_format indicating
'text/html' or 'text/plain'. HTML is NOT sanitized so the body
round-trips losslessly; treat it as untrusted input if rendering.
|
| create_work_itemA | Create a new Polarion work item in a project. The work item is created free-floating — to place it inside a
document at a specific outline position, follow up with
move_work_item_to_document. Direct creation into a document via
the module relationship is intentionally NOT exposed: per the
Polarion API, such work items land in the document's recycle bin
until a separate Document Part is created, leaving them invisible
in the document body. Always pair create + move for a single,
visible result. Format asymmetry: description here is Markdown (converted to
sanitized HTML on write) because greenfield authoring is natural for
LLMs. After creation the round-trip pair is
get_work_item(include_description_html=True) ↔
update_work_item(description_html=...) which speaks raw HTML
verbatim. The two formats never mix. Polarion does NOT validate enum membership server-side. Unknown
type / status / severity ids are stored verbatim as
ghost values that look real on later reads but never match Lucene
queries. priority is the only partial exception: a non-numeric
string coerces to the project default, but a numeric string outside
the enum set (e.g. "999.0") also persists verbatim. Resolve valid
ids first via list_work_item_enum_options(project_id, field_id,
work_item_type). custom_fields is the same story: unknown
field IDs — including brand-new IDs that no work item of this type
has ever used — silently persist as ghost attributes. Pass keys
taken from a prior get_work_item. |
| update_work_itemA | Update an existing Polarion work item. PATCHes the supplied fields and follows up with a GET so the caller
can confirm the change in current. None / empty string /
empty list all mean leave unchanged — this tool exposes no path
to clear a field. description_html is RAW Polarion HTML, sent verbatim with no
sanitization, so XSS/script filtering is delegated to Polarion's
renderer — NEVER pass untrusted input. Pair with
get_work_item(include_description_html=True) for the round-trip.
For greenfield authoring use create_work_item(description=...)
(Markdown) — the two format paths never mix.
hyperlinks and assignee_ids REPLACE the existing lists (pass
the full list, not a delta). custom_fields is partial — omitted
keys are preserved. Unknown custom-field IDs silently persist as
ghost attributes; pass keys from a prior read to avoid creating them.
The module relationship is NOT exposed here: Polarion rejects
PATCHes that attempt to modify it. To attach, detach, or move a
work item between documents, use move_work_item_to_document /
move_work_item_from_document. Prefer workflow_action over a raw status edit so the project's
transition rules run. workflow_action and change_type_to MUST
be paired with at least one body field — Polarion rejects empty PATCH
bodies (HTTP 400 "At least one of the members is required"). Direct
status / severity / resolution writes are NOT validated
server-side: unknown ids are stored verbatim as ghost values.
priority only coerces non-numeric inputs to the project default;
numeric strings outside the enum set also persist verbatim. Resolve
valid ids first via list_work_item_enum_options(project_id,
field_id, work_item_type). |
| move_work_item_to_documentA | Move a work item into a Polarion document at a specific position. Calls the moveToDocument action endpoint, which updates the work item's
module relationship, inserts a document part at the specified
position, and assigns a proper outline_number — atomically. This
is the ONLY supported way to attach a work item body to a document; editing
homePageContent directly to inject a macro reference leaves the
module relationship unset and produces an inconsistent state. Heading-type work items are rejected (HTTP 400 "Cannot move
headings"); headings must be created inside their target document.
If the work item is already in a different document, this detaches it from
the source — the operation is a move, not a copy. To detach a work
item back to free-floating (no document), use
move_work_item_from_document — the module relationship
cannot be cleared via PATCH. Provide AT MOST one of previous_part_id (insert AFTER) /
next_part_id (insert BEFORE); if both are omitted the work item
is appended at the end of the target document. Discover part IDs
with read_document_parts. Side effect: this server auto-creates an outgoing link from the
moved work item to its enclosing section heading. The role is
project-configurable (commonly parent or relates_to), so
discover it by inspecting forward links on a known-attached work
item in the same project. The auto-link appears in
list_work_item_links(direction="forward") after the move and is
silently removed by move_work_item_from_document. The role
collides with any same-role link created from the same source --
see the "phantom success" note on create_work_item_links. |
| move_work_item_from_documentA | Detach a work item from its document, returning it to free-floating state. Inverse of move_work_item_to_document. Calls the
moveFromDocument action endpoint, which clears the work item's
module relationship and removes the corresponding document part.
This is the ONLY supported detach path because Polarion rejects PATCH
attempts on the module relationship. The work item resource itself is preserved (with all history, links,
and attributes) and reappears as a free-floating work item visible to
list_work_items but not to any document. To re-attach, call
move_work_item_to_document. Calling this on a work item that is already free-floating returns
HTTP 400, surfaced here as RuntimeError — not idempotent.
Heading-type work items CAN be detached; the heading becomes a
free-floating work item with space_id="" and outline_number=""
(orphan-like state, but the work item is intact). |
| update_documentA | Update a Polarion document's metadata or body. PATCHes only the attributes you set; omitted fields are preserved
server-side. Unlike update_work_item this does NOT follow up
with a GET — call get_document if you need the refreshed state. home_page_content_html is the round-trip pair for
get_document(include_homepage_content_html=True). The HTML is
sent verbatim with no sanitization, so XSS/script filtering is
delegated to Polarion's renderer — NEVER pass untrusted input.
Empty string is rejected (would wipe the body and orphan every
heading); pass '<p></p>' for a near-empty body.
Body-write behaviour: Heading auto-create: inline <h1>..<h4> tags become heading
work items with module and outline_number set automatically.
A bare <hN>Title</hN> alone is safe. Orphan headings: removing an <hN> removes the part but
leaves the heading work item behind (still module-linked, no
outline_number). DO NOT inject anchorless <p> paragraphs: ``X DO NOT inject work item macro references: appending
<div id="polarion_wiki macro name=module-workitem;params=id=NEW">
creates a workitem_<NEW> part visible in
read_document_parts but leaves the work item's module relationship
unset (space_id="", outline_number="") — an inconsistent
half-attached state. Always attach via
move_work_item_to_document.
Workflow: prefer workflow_action over a raw status edit so
project rules run. workflow_action MUST be paired with at least
one attribute field — Polarion rejects empty PATCH bodies. Direct
status / type writes are NOT validated server-side: unknown
ids are stored verbatim as ghost values. Resolve valid ids first via
list_document_enum_options(project_id, field_id, document_type).
Unknown custom_fields IDs also become ghost attributes; pass
keys from a prior get_document. |
| create_documentA | Create a new Polarion document in a space. Greenfield document creation. The document starts empty (or with the
optional home_page_content body) and headings / work item parts
can be added later via update_document and
move_work_item_to_document. Format asymmetry: home_page_content here is Markdown (converted
to sanitized HTML on write) because greenfield authoring is natural
for LLMs. After creation the round-trip pair is
get_document(include_homepage_content_html=True) ↔
update_document(home_page_content_html=...) which speaks raw HTML
verbatim. The two formats never mix. When home_page_content is provided, every block-level element of
the rendered HTML (<p>, <ul>, <ol>, <table>, <div>,
<blockquote>, <pre>) is stamped with a unique
id="polarion_mcp_N" anchor. Without these ids the document saves
but the next read_document_parts returns HTTP 500. Headings
<h1>..<h4> are intentionally skipped — Polarion rewrites their
ids into a polarion_wiki macro name=module-workitem macro form on
save. module_name is Polarion's persistent identifier within the space
and is used in every subsequent URL (get_document,
update_document, etc.). It must be unique within space_id;
a duplicate name causes Polarion to return HTTP 409, surfaced here
as RuntimeError.
Polarion does NOT validate enum membership server-side. Unknown
type / status ids are stored verbatim as ghost values that
look real on later reads but never match Lucene queries. Resolve
valid ids first via list_document_enum_options(project_id,
field_id, document_type). custom_fields is the same story:
unknown field IDs silently persist as ghost attributes -- pass keys
taken from a prior get_document. |
| create_work_item_linksA | Create one or more outgoing links from a single source work item. All links share the same source (project_id / work_item_id)
and are sent as a single bulk JSON:API request. For each spec
target_project_id defaults to project_id for the common
same-project case; pass it explicitly only for cross-project links.
The orientation matches list_work_item_links(direction="forward")
on the source. Polarion does not validate link roles server-side: an unknown role
is stored verbatim and never matches subsequent queries. Resolve valid
roles by reading an existing link with
list_work_item_links(direction="forward") on a similar work item
in the same project. Each spec's revision pins the link to a specific Polarion revision
when set, otherwise the link targets the current HEAD. suspect
marks the link as needing re-review (usually False for new links). The returned link_ids are five-segment composites
<srcProj>/<srcWI>/<role>/<tgtProj>/<tgtWI> in input order, and
are the path identifiers for future delete/PATCH of the same links
via delete_work_item_links. Bulk semantics -- partial-failure hazard: behavior on mixed-success
(e.g. one duplicate among otherwise valid links) is not currently
characterised on this server. On any 4xx response, assume nothing was
committed and re-query with
list_work_item_links(direction="forward") before retrying. If you
need per-link diagnostics, send one spec per call. Phantom-success on same-role conflict: when the source work item is
attached to a document, move_work_item_to_document auto-creates
one outgoing link (role depends on project config -- see that
tool's docstring). Posting a NEW link with the SAME role from the
same source returns 201 and echoes the requested
link_id -- but the new link is NOT persisted. The pre-existing
auto-link remains the only forward link, with its original target.
There is no error to detect this client-side. After every create
on an in-document source, verify the actual stored state with
list_work_item_links(direction="forward") on the source AND
list_work_item_links(direction="back") on the intended target;
if your link is missing, detach via move_work_item_from_document,
create the link, then re-attach with move_work_item_to_document. |
| delete_work_item_linksA | Delete one or more outgoing links from a single source work item. Mirrors create_work_item_links: same source coordinates, structured
refs for each target. Only outgoing ("forward") links are removed
through this endpoint. Back links are removed by calling this tool on
the other work item (the one owning the outgoing side). External
hyperlinks live on hyperlinks and are managed via
update_work_item. How to identify links: From a prior create_work_item_links call: reuse the same specs
(drop suspect / revision -- delete needs only role + target). From list_work_item_links(direction="forward"): each item's
role and id (the target's short ID) form one ref;
target_project_id defaults to project_id for same-project.
Idempotent at the body level: Polarion silently ignores refs whose
composite id does not match an existing link, deletes any refs that
do match, and returns 204 either way. So re-deleting an
already-removed link is a no-op, and a mixed batch (some real,
some stale) succeeds for the real ones without surfacing the
stale ones. ValueError is reserved for path-level 404 -- the
source work item itself does not exist; the body-level "link not
found" case never reaches the tool layer. |
| update_work_item_linksA | Update suspect / revision on one existing outgoing work item link. Use this to clear a suspect flag after a reviewer signs off, or to
pin a link to a specific revision. Identify the link first with
list_work_item_links(direction="forward"): the role and target
work item ID together address one specific link. suspect and revision are tri-state: an explicit True /
False / string value updates that attribute, while None (the
default) leaves the existing server-side value alone. This differs
from create_work_item_links where suspect defaults to False
(a concrete value). At least one of suspect / revision must be
provided -- passing both as None is rejected because Polarion
would 400 on the resulting empty PATCH body.
To update multiple links, call this tool once per link. Unlike
create_work_item_links / delete_work_item_links, the PATCH
endpoint has no server-side bulk equivalent. Polarion does not validate link role ids server-side, so a typo in
role returns 404 -- the link simply does not exist under that role. |
| create_document_commentsA | Create one or more comments on a Polarion document in a single request. All comments in comments are sent in a single POST to
/projects/{p}/spaces/{s}/documents/{d}/comments. Polarion
returns a 201 with the IDs of all created comments. Thread model: a comment with parent_comment_id=None is a
top-level review comment. To reply to an existing comment, set
parent_comment_id to the short ID returned in
list_document_comments (e.g. 'c42'); the tool composes the
full four-segment path proj/space/doc/c42 that the Polarion API
requires. Text format: 'text/plain' (default) stores the body
verbatim. Use 'text/html' for HTML-formatted bodies — the HTML
is sent as-is, no sanitization. resolved: omitting the field (None) lets Polarion default to
False; pass True to create a pre-resolved comment. author_id: omit to have Polarion use the authenticated token's
user. This operation is NOT idempotent — retrying with the same input
creates duplicate comments. |
| update_document_commentA | Resolve or re-open a single document comment. Sends PATCH to
/projects/{p}/spaces/{s}/documents/{d}/comments/{commentId}
with {"resolved": <bool>} — the only patchable attribute on a
document comment. Use list_document_comments to discover the
short comment ID (last segment of the full 4-part path). Root comments only: Polarion accepts this PATCH only on top-level
comments (parent_comment_id is None in
list_document_comments). Calling it on a reply -- any comment
with a non-null parent_comment_id -- returns HTTP 400 "Resolved
field can be set only for root comments" and surfaces as
RuntimeError. Filter for parent_comment_id is None before
calling. There is no server-side workflow to resolve an individual
reply; resolving the root marks the entire thread resolved. This operation is idempotent: marking a comment resolved twice leaves
the same server state as marking it resolved once. |