Разделы

MCP-инструменты

Все инструменты MCP-сервера, сгруппированные по назначению.

Большинство инструментов принимают либо node_id, либо slug + project_id. Слаги читабельнее — используйте их.

Организации и проекты

05
create_organization

Create a new organization for the authenticated user.

name

create_project

Create a new project inside an organization. Returns the created project node with its ID and slug.

org_idnamekeyspec

ensure_project

Idempotent bootstrap: ensure an organization and project exist, creating them if absent. Use this at the start of an agent session to set up the workspace. Returns org_id, project_id, flags indicating whether each was newly created, and spec_mode — the project's spec policy (off|strict). In strict mode closing a task requires an applied spec delta or an explicit declare_spec_impact; write spec_mode into .flownix so later sessions know the rules before writing code.

org_nameproject_nameproject_keyproject_spec

list_organizations

List all organizations the authenticated user belongs to. Returns org IDs and names. Call this first to discover available org_ids.

list_projects

List all projects in an organization. Returns id, slug, name, and spec for each project.

org_id

Граф нод

10
create_node

Create epic/feature/plan/task under a parent node. On a project with spec_first on, creating a task or plan under a feature is REFUSED with FailedPrecondition (spec_first_not_approved) until that feature has an approved spec delta — tasks are cut from an accepted document, not before it. Features, epics and docs are never gated. If you hit that refusal, do not retry and do not work around it: read get_project_policy, drive the feature's delta to approval (propose_doc_delta → update_doc_delta → submit_doc_delta → ask the human), or declare_no_spec_impact on the feature if it changes no documented behaviour.

org_idproject_idparent_idparent_slugkindtitlecontenttagsai_modelagent_nameticket_refcomponents

delete_node

Permanently delete a node and all its children. This action is irreversible. Provide either node_id or slug+project_id.

node_idslugproject_id

get_node

Get a node by ID or slug. Returns full detail: title, content, status, progress, tags, comments, dependencies, references, and child_ids. Provide either node_id alone, or slug+project_id.

node_idslugproject_id

get_node_by_slug

Get a node by its slug. Returns full detail including child_ids. Equivalent to get_node with a slug.

slugproject_idnode_id

get_tree

Get the full hierarchy tree of a project: epics → features → plans → tasks. Use this to understand the overall project structure before drilling into nodes.

project_id

list_nodes

List nodes in a project. Filter by kind (epic/feature/plan/task/doc) and/or parent. Returns id, slug, title, kind, status, progress for each node.

project_idkindparent_idparent_slugticket_refcomponent

move_node

Move a node to a new parent. Provide node_id or slug, and new_parent_id or new_parent_slug. Nodes are sorted by creation time automatically. The spec_first decomposition gate applies here too: moving a task or plan under a feature that has no approved delta is refused exactly as creating one there would be. The gate stands on both paths on purpose — otherwise it would be bypassed in two calls.

node_idslugproject_idnew_parent_idnew_parent_slug

update_node_content

Update the title and/or Markdown body of an epic, feature, plan, or task node.

node_idslugproject_idtitlecontentcommit_hashticket_ref

update_node_progress

Update the completion percentage of a node. Progress is an integer from 0 (not started) to 100 (complete).

node_idslugproject_idprogress

update_node_status

Change the status of a node. Use this to mark tasks as in-progress, done, blocked, etc.

node_idslugproject_idstatus

Комментарии, теги, связи

10
add_comment

Post a Markdown comment to a node as an agent. Comments appear in the node's activity feed and are visible to the team.

node_idslugproject_idbody

add_dependency

Create a dependency edge: from_node depends on to_node. to_node is the blocker and must be completed before from_node can start. Read it as the sentence "from_node depends on to_node". Provide IDs or slugs for each node.

from_nodefrom_slugto_nodeto_slugproject_id

add_relation

Add a typed relation from one node to another. Directed types are stored once and appear as incoming on the target; related_to is symmetric and is visible from both nodes.

from_nodefrom_slugto_nodeto_slugproject_idrelation_type

add_tag

Add a label/tag to a node (e.g. 'backend', 'frontend', 'urgent', 'domain'). Tags are used for filtering and categorization.

node_idslugproject_idtag

get_dependencies

Get both sides of the dependency graph for a node: depends_on (blockers this node waits for) and blocks (nodes waiting for this one).

node_idslugproject_id

get_references

Get all cross-references for a node: nodes this node references (outgoing) and nodes that reference it (back-references).

node_idslugproject_id

get_relations

Get all typed semantic relations for a node (e.g. blocks, blocked_by, related_to, depends_on). Returns both outgoing and incoming relations.

node_idslugproject_id

remove_dependency

Remove the dependency edge "from_node depends on to_node". Same direction as add_dependency.

from_nodefrom_slugto_nodeto_slugproject_id

remove_relation

Remove the typed relation from one node to another. For related_to either endpoint order removes the symmetric relation; directed types retain their direction.

from_nodefrom_slugto_nodeto_slugproject_idrelation_type

set_references

Set cross-references on a node (overwrites existing). Identify the node by slug or node_id, and the references by ref_slugs (JSON array of slugs) and/or ref_ids (JSON array of node IDs). Slugs are enough on their own — project_id is optional, and a ref_slug may point at a node in another project.

node_idslugproject_idref_idsref_slugsnode_idslugproject_id

Документы

06
archive_doc

Archive a documentation node: it disappears from list_docs, from the node tree and from rag_query, but nothing is deleted — its revisions, comments, references and tags stay intact and restore_doc brings it all back. ARCHIVING IS CASCADING: the doc AND every doc below it in the tree go to the archive together, so check what is under a doc before archiving it. The response lists every archived doc by slug — read it, that is how you find out what else went with it. Only works on kind=doc nodes. Use this instead of delete_node for documents: delete_node is irreversible.

doc_iddoc_slugproject_id

create_doc_node

Create a documentation node (wiki page) inside a project. A doc that describes system behaviour is a spec: write it in the OpenSpec format — `## Purpose`, then `### Requirement: <name>` with a RFC 2119 keyword (SHALL/MUST/SHOULD/MAY), then `#### Scenario: <name>` with `- GIVEN` / `- WHEN` / `- THEN` steps. That format is the only accepted way to record behaviour: freeform prose describing a contract is a defect, validate_spec reports it, and in spec_mode=strict a delta that adds a new violation is refused.

org_idproject_idtitlecontentcomponentsspec_domain

list_archived_docs

List a project's archived documentation nodes, most recently archived first. This is the only place archived docs are visible: list_docs and get_tree do not show them. If a doc you expected is missing from list_docs, look here before concluding it was deleted.

project_id

list_docs

List all documentation nodes (wiki pages) in a project. Archived docs are NOT included — a doc missing from this list may be in the archive rather than deleted; use list_archived_docs to check.

project_idcomponent

restore_doc

Restore an archived documentation node: it returns to the tree, to list_docs and is queued for reindexing. Restores ONE doc, not a subtree — archiving cascades, restoring does not. If the doc's parent is still archived the doc moves to the project's docs root, and the response says so via reparented_to_root: tell the user, otherwise they will look for the doc where they left it. Use list_archived_docs to find what can be restored.

doc_iddoc_slugproject_id

update_doc_content

Update the title and/or Markdown content of a documentation node.

node_idslugproject_idtitlecontentspec_domain

Строгий spec-режим

16
apply_doc_delta

Apply a proposed delta: the doc body is replaced with the delta body and the doc version is bumped. Fails with a version conflict if the doc changed after the delta was proposed — reread the doc, rebuild your change on top of the current body and propose a new delta. In spec_mode=strict do this together with closing the task. Also fails when the delta introduces OpenSpec format issues the previous version of the document did not have (a requirement with no `#### Scenario:`, a requirement with no SHALL/MUST, a scenario missing GIVEN/WHEN/THEN); inherited issues come back in spec_issues as warnings and do not block. When the project has require_proposal_approval on, a delta whose review_status is not approved is refused: ask the user to approve it, do not propose it again.

revision_id

approve_doc_delta

HUMANS ONLY — you cannot call this. Approving a proposed spec delta is the user's decision, and a call from an agent session is refused with PermissionDenied. This tool is listed so you know the name of the step you are waiting on: when a delta is pending review, stop, tell the user the delta is waiting for approval, and name it. Do not re-propose the delta, do not apply it, do not move the task into in_progress — none of that will work until the user approves it in the web UI. Resume only after list_doc_deltas shows review_status: approved.

revision_idnote

declare_no_spec_impact

Declare that a node changes no documented behaviour, so no spec delta is needed. What it unblocks depends on the node kind, and these are NOT the same permission. On a task or plan it lifts the CLOSING gate: in spec_mode=strict this is the only way to reach done without an applied delta. On a feature it lifts the DECOMPOSITION gate: with spec_first on, you may create tasks under that feature without driving its document to approval. A declaration on a feature does NOT cascade down: every task under it still answers for its own spec, and closing each one still needs its own delta or its own declaration. Do not declare on the feature hoping to free the whole subtree — the closing gate reads the declaration of the node it is closing and nobody else's. reason must be a sentence naming what you changed and why it touches no documented behaviour — "n/a", "none" or a single word is rejected. If you cannot write that sentence, the change probably does affect the spec: propose a delta instead.

node_idslugproject_idreason

delete_doc_delta

Remove a delta from the doc's history entirely — no row is left behind. This is for garbage: a duplicate, a proposal made by mistake, a delta nobody will ever read. It is NOT the normal way to reject a delta: use discard_doc_delta for that, which records that the proposal was considered and rejected. Choose by intent, not by force: discard = "we decided against this", delete = "this should never have been here". Works only on proposed and discarded deltas. An applied delta cannot be deleted — it is spec history, and both the diff against the neighbouring version and reading the doc at that version rest on it; if an applied change is no longer right, propose a new delta instead.

revision_id

discard_doc_delta

Record the decision that a proposed delta will not be applied. The delta stays in the doc's history as discarded — anyone reading it later can see the proposal was considered and rejected. This is the normal way to say no to a delta. Use delete_doc_delta only when there should be no row at all (garbage, a duplicate, an accidental proposal). Only works on proposed deltas: an applied delta is history and is not rolled back — propose a new delta instead.

revision_idreason

export_openspec

Export the project as an OpenSpec directory tree and get back the list of files to write. Call this when the project's specs should live in the repository next to the code. Returns files[] with a path (starting with openspec/) and content for each — WRITE THEM YOURSELF with your file tools, relative to the repository root. This server does not touch your disk: it runs over HTTP for everyone at once, so a path it wrote to would be someone else's machine. The tree holds specs/<domain>/spec.md per document, changes/<slug>/ per open feature (proposal.md, design.md, tasks.md, delta specs) and changes/archive/<date>-<slug>/ per closed one.

project_id

get_doc_delta

Read one spec delta in full, including its round history: every review round with the action (submitted/approved/rejected/reopened), who did it, when, the reason, and the delta body AS IT WAS at that moment. That last part is the point — after a rejected draft has been reworked, the rejected text exists nowhere else, and "what did we throw away and why" is the question the history answers. list_doc_deltas does not return rounds: each round carries a whole document body, and in a list the history would outweigh the deltas themselves.

revision_id

get_project_policy

Read the project's spec policy before doing work. In spec_mode=strict, closing a task requires either an applied spec delta (propose_doc_delta then apply_doc_delta) or an explicit declaration that the spec did not change (declare_spec_impact: none) — otherwise the close is rejected. Call this when .flownix is missing or may be stale (the mode can be switched on after init). In strict mode a delta must also not make the document's OpenSpec format worse than it was: spec documents are written as `## Purpose` / `### Requirement: <name>` (SHALL/MUST) / `#### Scenario: <name>` (GIVEN/WHEN/THEN), and validate_spec tells you where you stand. The answer also carries spec_first and spec_first_requirement: with spec_first on the ORDER OF WORK is reversed — the feature's document is written and approved BEFORE any task is created under it, and creating one earlier is refused. Read that field before decomposing anything.

project_id

import_openspec

Load an OpenSpec directory tree into the project. Call this when a project is set up on top of a repository that already has openspec/. READ the tree yourself first with your file tools — every openspec/**/*.md — and pass the files here with their paths relative to the repository root. Idempotent by spec domain and by the changes/<name> directory: running it again on an unchanged tree creates nothing and proposes no deltas, so it is safe to call after every pull. Returns which nodes were created, updated and left alone, plus the ids of any deltas it proposed.

project_idfilesitemspropertiespathcontent

list_doc_deltas

List spec deltas: history of one doc (doc_id/doc_slug), deltas produced by one task (source_node_id/source_node_slug), or every delta still waiting to be applied in the project (project_id). Filter by state: proposed|applied|discarded. Each delta also carries review_status (draft|pending|approved|rejected) with reviewed_by/reviewed_at/review_note — that is the human decision on the proposal, separate from state. draft means nobody has been asked yet. On a project with require_proposal_approval this is how you check whether you may start: read it before moving a task into in_progress and before apply_doc_delta. Filter by review_status to find your own drafts. Round history is NOT returned here — use get_doc_delta for one delta when you need it.

doc_iddoc_slugproject_idsource_node_idsource_node_slugstatereview_status

propose_doc_delta

Propose a new state of a spec document (doc node) as a delta tied to the task that caused the change. body MUST be the FULL new document body — the complete Markdown of the doc after your change, not a patch, not a diff, not just the changed section. Applying a delta replaces the document body wholesale, so a fragment silently collapses the spec to that fragment. Read the doc first (get_node), edit the whole text, send it back. In spec_mode=strict this is how a task earns the right to be closed. A spec document is written in the OpenSpec format: `## Purpose`, then `## Requirements`, then one `### Requirement: <name>` per behaviour with a RFC 2119 keyword (SHALL/MUST/SHOULD/MAY) in its text, each followed by `#### Scenario: <name>` with `- GIVEN` / `- WHEN` / `- THEN` steps. The response carries spec_issues — what is still off about the format — and ops, the requirements this delta adds, changes, removes or renames. In spec_mode=strict a delta that introduces issues the previous version did not have is rejected; issues inherited from the previous version do not block. Run validate_spec on your draft first to avoid that round trip. The delta comes back with review_status: pending. On a project with require_proposal_approval this means STOP: tell the user the proposal is waiting for approval and name it, then wait. Until review_status is approved you may not apply the delta and may not move the covered task into in_progress — both calls are refused. EXCEPTION on a project with spec_first on: the delta is born review_status: draft, which asks nobody anything. A draft is your working copy — keep editing it with update_doc_delta, and it reaches the human only when you call submit_doc_delta. Do not tell the user a draft is waiting for their approval: it is not, and they will be waiting for each other.

doc_iddoc_slugproject_idsource_node_idsource_node_slugtitlebodyreason

reject_doc_delta

HUMANS ONLY — you cannot call this, same as approve_doc_delta. Rejecting a proposed spec delta is the user's decision and a call from an agent session is refused with PermissionDenied. If the user tells you a delta was rejected, read its review_note, rebuild the spec accordingly and propose a new delta — a rejected delta can be approved later, so do not delete it to start over.

revision_idreason

set_project_policy

Set the project's spec policy. spec_mode=strict makes every task close require either an applied spec delta (propose_doc_delta then apply_doc_delta) or an explicit declare_no_spec_impact — a project with no spec documents will have its very next task blocked by that gate, so bootstrap the spec first. spec_mode=off removes the requirement. Only a member of the project's organization may change this. Ask the user before switching the mode; never do it silently. require_proposal_approval adds the OpenSpec approval gate: a proposed delta must be approved by a human before the covered task may enter in_progress and before the delta may be applied. Omit the field to leave it as it is. spec_first reverses the order of work: the delta is born a draft, and creating a task or plan under a feature is refused until that feature has an approved delta. It only makes sense together with spec_mode=strict and require_proposal_approval — turning it on without them is refused with InvalidArgument, and so is turning either of them off while it is on. Enabling all three in one call is the normal way to switch a project over. Returns the settings as stored by the server — write those into .flownix, not what you asked for.

project_idspec_moderequire_proposal_approvalspec_first

submit_doc_delta

Send a draft delta to the human for review: review_status goes draft → pending. This is the only way a draft becomes a question addressed to somebody. What changes the moment you call it: the delta appears in the review queue, it starts holding the gates (the covered task can no longer enter in_progress, the delta can no longer be applied), and it can no longer be edited in place until a human decides. So after calling it, STOP. Tell the user which delta and which document are waiting for them, and wait — you cannot approve it yourself, and re-proposing, re-submitting or deleting it does not move anything forward. Refused with FailedPrecondition if the delta is not a draft, and refused if the draft made the document's OpenSpec format worse than its base — spending a review round on something the server already knows is wasteful.

revision_idnote

update_doc_delta

Edit a delta in place instead of proposing a new one. Works only on a delta whose review_status is draft or rejected; an approved one is refused, because approval refers to the text the human actually read — change that with a NEW delta, not by rewriting what they signed off. Editing a rejected delta returns it to draft and records a round, so the rejected body and the reason stay readable afterwards. body MUST be the FULL new document body, exactly as in propose_doc_delta — the complete Markdown after your change, not a patch and not just the paragraph you fixed. Applying a delta replaces the document wholesale, so a fragment silently collapses the spec to that fragment. The temptation is stronger here than when proposing, because "update" sounds like it should take a piece: it does not. Format issues come back in spec_issues but do NOT block the edit — a draft is written in passes, and a ratchet here would make it impossible to save a requirement before its scenario is written. The ratchet applies at submit_doc_delta.

revision_idtitlebodyreason

validate_spec

Check whether a spec document follows the format, and get back what to fix. Changes nothing. A spec document is written in the OpenSpec format: `## Purpose`, then `## Requirements`, then one `### Requirement: <name>` per behaviour with a RFC 2119 keyword (SHALL/MUST/SHOULD/MAY) in its text, each followed by `#### Scenario: <name>` with `- GIVEN` / `- WHEN` / `- THEN` steps. Pass doc_slug (or doc_id) to check a saved document, body to check raw text, or both to check the body while marking each issue as new or inherited from the saved document. Use body BEFORE propose_doc_delta so you learn about a problem while you still have the spec in your head. Each issue names a machine code, the place in the document, and what to do about it.

doc_slugdoc_idproject_idbody

Ревью кода

07
add_review_iteration

Add a new iteration to an existing review.

review_idcommit_hashcontent

create_review

Create a new code review with its first iteration. Returns the review with iterations.

project_idreviewerbranchcommit_hashcontentcomponents

get_node_reviews

Get all reviews that are linked to a specific node. Use this to see which code reviews reference a given task or feature. Returns {reviews: [...]}.

node_idslugproject_id

get_review

Get a review with all its iterations.

review_id

list_reviews

List all reviews for a project.

project_idcomponent

set_review_components

Replace the set of components a code review is linked to. The set is replaced whole; an empty list unlinks everything.

review_idproject_idcomponents

set_review_nodes

Link a review to one or more nodes (overwrites existing links). Creates a bidirectional navigable link: the review shows the nodes as chips, and each node shows the review as a backlink. Pass the full desired list of node_ids — this replaces all existing links.

review_idnode_ids

Компоненты системы

05
create_component

Create a system component — a service, app, library, infra or integration unit of the system being built (core-service, gateway, web, migrations). Components group work, docs and reviews; they are NOT units of planning and never move to done. Returns the component with its AF-COMP-N slug.

project_idtitledescriptioncomponent_kindrepo_pathlifecycletagsparent

get_component

Get one system component in full: description, progress, child components, and EVERYTHING linked to it — tasks and features, documents, and reviews. Do not collect those with separate calls; this one returns them.

componentproject_id

list_components

List the system components of a project, flat, with parent_id and PROGRESS for each: percent, total, done, a breakdown by status, and counts of linked docs and reviews. Progress covers work linked to the component or to any component below it in the tree — so this one call answers "how is gateway doing" without counting tasks by hand.

project_idcomponent_kindlifecycle

set_node_components

Replace the set of components a node (task, feature, doc, ...) is linked to. The set is replaced WHOLE: pass an empty list to unlink everything. A node can belong to several components.

nodeproject_idcomponents

update_component

Update a system component. Only the fields you pass are changed; omitted fields keep their current values.

componentproject_idtitledescriptioncomponent_kindrepo_pathlifecycleparent

Семантический поиск

03
rag_context

Get a ready-to-inject Markdown context block assembled from the most relevant indexed chunks for a query. Use this to pull project knowledge into an agent prompt in one call. Read-only semantic retrieval, distinct from get_node/get_tree structural reads.

project_idquerymax_charsmin_score

rag_query

Semantic (RAG) search over a project's indexed nodes and comments. Returns ranked chunks by meaning, not exact text — use this to find relevant tasks/docs by concept. This is distinct from list_nodes/get_tree, which browse the project structure by hierarchy and exact filters. Results below a relevance floor are dropped, so an EMPTY result with filtered_out > 0 means nothing in the project answers this query — treat that as a real answer, not as a reason to reason from weak matches. Content is returned as a snippet; open a hit with get_node before relying on its details. Read-only; does not modify the index.

project_idquerykkind_filterstatus_filteritemscomponentmin_scoremax_content_chars

rag_status

Report the RAG index status for a project: total indexed chunks, per-status node counts, vector dimension, and the sync-status breakdown (pending/in_progress/synced/failed). Use this to check whether the semantic index is up to date before relying on rag_query/rag_context. Read-only.

project_id

Скиллы

02
get_skill

Fetch the full Markdown content of a single Flownix skill by slug. Call this only for skills whose MD5 from list_skills differs from the local file — avoids downloading unchanged skills.

slug

list_skills

List all available Flownix agent skills with their slug, name, description, and MD5 hash. Does NOT return content — use get_skill to fetch content for a specific skill only when its MD5 differs from the local copy. Also returns `retired`: slugs that are no longer served (renamed or removed) and must be deleted locally.

Присутствие агентов

04
report_agent_usage

Optional. For the token reporter running alongside an agent, NOT for the agent itself: an agent that knows its own session must use session_report instead. Reports token usage for the agent working on this machine and directory — the server picks the session by host and cwd, because the reporter cannot see the agent's MCP session id. The caller gets no presence row of its own. Values are CUMULATIVE SINCE THE START OF THE SESSION, not deltas. Never send a made-up zero.

hostcwdgit_branchai_modelinput_tokensoutput_tokenscost_usd

session_announce

Optional. Tell Flownix who and where you are, so the agent presence panel can show your session properly. Call it ONCE at the start of your work; calling it again is harmless. Everything else about your session (that you are connected, which task you are on, how many calls you made) is already tracked automatically — this call only adds what the server cannot know. Omit any field you cannot determine; an omitted field never overwrites what is already known.

agent_nameai_modelhostoscwdgit_branch

session_end

Optional. Close your presence session immediately when you finish working. Without it the session is closed automatically once it stops making calls, so this only makes the presence panel accurate sooner.

reason

session_report

Optional. Report token usage and cost for this session. Values are CUMULATIVE SINCE THE START OF THE SESSION, not deltas since the last report: a skipped report must not make the total drift. Usually called by the optional statusLine reporter script rather than by the agent directly. When nothing reports usage, Flownix shows 'not reported' rather than zero — so never send a made-up zero.

input_tokensoutput_tokenscost_usd

Harness: конструктор

33
harness.add_role

Add an agent role to a draft harness version. A role is what an agent receives in work.claim and work.get_context: objective, system_instructions, responsibilities, prohibited_actions and output_schema. Workflow nodes address it by key in config.role_key. Published versions are refused with version.published_immutable. Returns the created role with its ID.

harness_version_idkeynamedescriptionobjectivesystem_instructionsresponsibilitiesprohibited_actionsoutput_schemamin_instancesmax_instances

harness.add_workflow_node

Add a node to the workflow graph of a draft version. Agent-executed types (agent_task, review, debate, vote, judge) need config.role_key naming a role of the version; human_gate waits for a human decision; condition, loop, create_flow_nodes and end run without an agent. Connect nodes with harness.connect_workflow_nodes. Invalid lease/retry/timeout values are refused with node.config_invalid; published versions with version.published_immutable. Returns the created node with its ID.

harness_version_idtypenameconfiginput_bindingsoutput_bindingstimeout_secondsretry_policy

harness.clone

Clone a harness under a new name. Copies one source version — the current published version, or the latest version if none is published — into version 1 of the new harness, including its roles, workflow nodes, edges, policies and default budget. The clone's version is a draft: validate and publish it. A source without versions gives a clone without versions.

harness_idnew_name

harness.connect_workflow_nodes

Connect two workflow nodes of a draft version with a directed edge: the target step starts after the source step completes and the edge's condition (if any) matches the source step's output. Every matching outgoing edge is taken, so several edges from one node give parallel fan-out or conditional branching. A loop node needs edges with condition outcome eq "continue" and outcome eq "exit" plus an edge back from its body. Published versions are refused with version.published_immutable.

harness_version_idfrom_node_idto_node_idconditionprioritymapping

harness.create

Create a new harness definition — a reusable multi-agent workflow template (e.g. council, review board, debate). The harness starts without versions: create one with harness.create_version, then add roles and workflow nodes to that version with harness.add_role and harness.add_workflow_node. Call harness.list first to reuse or clone an existing harness. Returns the created harness with its ID.

workspace_idnamedescriptiontype

harness.create_version

Create a new draft version of a harness definition. Version numbers are sequential (1, 2, 3…). Roles, workflow nodes, edges and policies are added to the draft afterwards with harness.add_role, harness.add_workflow_node, harness.connect_workflow_nodes and harness.set_policy; a new version does not copy them from an earlier one (use harness.clone for a copy). Validate with harness.validate, then make it the current version with harness.publish.

harness_idchangeloggraph_definitioninput_schemaoutput_schemadefault_budgetmax_run_duration_secondsmax_work_itemsmax_tokensmax_cost_usd

harness.export

Export a harness as a downloadable ZIP archive. The archive contains: harness.yaml (metadata), roles.md (all role descriptions), rules.yaml (policies), workflow.json (graph definition), system-prompts/*.md (per-role system prompts), and README.md (usage instructions). Returns a temporary download URL (expires in 1 hour).

harness_idversion_id

harness.get

Get a harness definition by ID. Returns the harness metadata (name, type, status, current_version_id — the latest published version, empty until the first publish) and all its versions. Reading never creates a version: a harness without versions comes back with an empty list — create one with harness.create_version. Use this to inspect a harness before editing or running it.

harness_id

harness.get_run

Read a harness run: status, title, input, source_node_ids (the Flownix nodes the run is about), result_node_ids (nodes created by create_flow_nodes), budget_snapshot, usage, work_items and remaining budget, and every step with its node name/type, iteration, status and output. Use it to see where a run stands and what previous steps produced.

run_id

harness.library_clone

Clone a library package version into a project you belong to. The clone is an independent draft harness with one unpublished version 1 authored by you: roles, steps, transitions, policies and schemas are copied as is, role links to project context/tool/model policies are empty and no participants are bound, and nothing links it back to the package or its source. Assign participants to roles, validate with harness.validate and publish with harness.publish before running. A project of an organization you are not a member of is refused.

package_idworkspace_idnumbername

harness.library_get

Read a library package card: title, author display name, clone count, every published version (number, date, summary) and the full composition of the selected version — roles with objectives, responsibilities, prohibited actions and instructions, steps in execution order with their config, transitions with conditions, policies, context policy and input/output schemas. This is exactly what a clone receives. Also returns your own rating (my_rating, 0 if none) and statistics: total clones, clones in the last 30 days, unique cloners, clones per version and unique viewers — the author's own clones and views are not counted, and opening the card counts as your view. Unpublished, hidden and unknown packages all answer not found.

package_idnumber

harness.library_link

Which library package a harness is linked to: a clone is linked to the package and version it came from, a published source to the package it was published into. Returns the matching package version (number), the latest one (latest_number), update_available, and own (you are the package author — publishing this harness then adds a new version of that same package; a copy of someone else's package cannot be published). linked:false — the harness is independent.

harness_id

harness.library_list

Browse the public harness template library: packages published by Flownix users from any organization, newest publication first. Each row has the title, author display name, latest version number, its summary and harness type, last publication date, clone count, average rating (rounded to 0.1, absent when unrated) and number of ratings. Sort by rating or clones to find popular packages. Search matches the title or the latest summary case-insensitively; type filters by the latest version's harness type. Before building a new harness with harness.create, look here for a package to clone with harness.library_clone. Paginate with next_page_token.

querytypesortpage_sizepage_token

harness.library_my_packages

List the library packages you authored, including packages with no published version left, each with all its versions and unpublished_at for unpublished ones. Packages you unpublished as a whole are not listed.

harness.library_preview

Show exactly what publishing a harness version to the library would expose to every Flownix user: the same composition harness.library_get shows and clones receive. Role instructions, step configs and schemas are copied as is — check them for internal paths, task slugs and other project data before publishing.

harness_version_id

harness.library_publish

Publish a published harness version to the public library, like publishing an npm package. Without package_id it creates a new package with an immutable title (defaults to the harness name, 1–120 characters) and version 1; with package_id it adds the next version to a package you authored — numbers never repeat, published versions never change. The whole content of the version (role instructions, step configs, schemas, policies) becomes visible to every Flownix user and is copied into clones: review it with harness.library_preview first and pass confirm_public: true to confirm, otherwise it is refused with library.confirmation_required. Draft versions are refused with library.version_not_published; summary must be 1–280 characters (library.summary_invalid); a different title for an existing package is refused with library.title_immutable; someone else's package with library.not_author. The package keeps no link to the source harness.

harness_version_idpackage_idtitlesummaryconfirm_public

harness.library_rate

Rate a library package from 1 to 5 as the current user. One rating per user and package — rating again replaces it; the rating applies to the whole package, not a version. Values outside 1–5 are refused with library.rating_invalid; the package author cannot rate their own package (library.self_rating); unpublished, hidden and unknown packages answer not found. Returns the package with its new average and number of ratings.

package_idvalue

harness.library_set_hidden

Platform administrators only: hide a library package with all its versions from everyone else, or return it to the catalog (hidden: false). Existing clones are not affected. Everyone else, including the package author, is refused with library.admin_required.

package_idhidden

harness.library_unlink

Unlink a harness from its library package. It stops receiving updates and becomes your own template: it can then be published as a new package of yours. Refused with library.not_linked when the harness is not linked.

harness_id

harness.library_unpublish

Unpublish one version of your library package (pass number) or the whole package (omit number). An unpublished version or package answers not found to everyone else and cannot be cloned; a package with no published versions leaves the catalog but stays in harness.library_my_packages, and you can publish a new version into it — unless you unpublished the whole package. Existing clones are never affected. Only the author may unpublish (library.not_author).

package_idnumber

harness.library_unrate

Remove your rating of a library package. Removing when you have not rated it changes nothing. Returns the package with its updated average and number of ratings.

package_id

harness.library_update

Update a linked harness to the latest version of its library package. The package content lands as a draft: an unpublished latest version is replaced, otherwise a new draft version is added; published versions keep serving runs — review the draft and publish it with harness.publish. Refused with library.up_to_date when there is nothing newer and library.not_linked for an independent harness.

harness_id

harness.list

List the harness definitions of a project, newest first: id, name, type, status and current_version — the number of the current published version (absent if the harness was never published). Call this before harness.create to reuse or clone an existing harness instead of creating a duplicate.

workspace_id

harness.list_pending_approvals

List open approvals a run (or every run of a project) is waiting for — from human_gate nodes and from require_approval policies on work.complete: type, title, description, options, step_run_id of the waiting step and created_at. Read-only — an agent cannot answer an approval: the decision is made by a human in the Flownix web app. Use it to tell the user exactly what the run needs from them.

run_idworkspace_id

harness.list_runs

List runs of a project, newest first, optionally filtered by harness, status and the Flownix node the run was started for. Use source_node to find the runs about a task or feature — pass its slug (AF-FEAT-10) or UUID.

workspace_idharness_idstatussource_node

harness.publish

Publish a harness version — makes it the current active version and sets the harness status to 'published'. The version is validated first (same rules as harness.validate): if there is any error, publishing is refused with FailedPrecondition 'version.invalid' and the error text lists every code, location and message. Publishing an already published version is refused with 'version.already_published'. A published version is immutable: add_role, update_role, add_workflow_node, connect_workflow_nodes and set_policy on it are refused with 'version.published_immutable' — create a new version instead. Returns the published version.

harness_version_id

harness.set_budget

Set the default run budget of a draft harness version. Every run started from the version snapshots it into budget_snapshot at harness.start_run; later changes never affect running runs. Limits: max_run_duration_seconds, max_work_items, max_tokens, max_cost_usd — 0 or omitted means no limit. Exceeding any limit fails the run with reason budget.exceeded. Tokens and cost count only what agents report in work.complete/work.fail usage. Published versions are refused.

harness_version_idbudgetmax_run_duration_secondsmax_work_itemsmax_tokensmax_cost_usd

harness.set_context_policy

Set the context policy of a draft harness version — what work.get_context returns to agents of every run of the version. include lists sections: run_input (run.input), role (the role block), predecessors (outputs of steps with an edge into the current node), all_steps (outputs of every completed step of the run, in completion order — useful for synthesis and triage). The node, work item, deliberation_id and a vote ballot are always returned. exclude lists top-level output keys removed from step outputs in the context (the stored outputs are unchanged), e.g. flow_nodes. max_tokens caps step outputs, estimated as JSON bytes / 4; the earliest completed outputs are dropped first and the response says context_truncated. 0 or omitted means no cap. Without a policy agents get run_input, role and predecessors. The whole policy is replaced. Unknown sections, an empty include or negative max_tokens are refused with InvalidArgument; published versions with version.published_immutable.

harness_version_idincludeexcludemax_tokens

harness.set_output_schema

Set the JSON Schema (draft 2020-12) of the final result of a draft harness version. Enforced on work.complete of every step whose node has an edge into an end node: a non-matching output is refused with output.schema_violation and the agent retries. Role output_schema (harness.add_role/update_role) still applies to every step of the role. An empty object {} removes the schema. An invalid schema is refused with output.schema_invalid; published versions with version.published_immutable.

harness_version_idoutput_schema

harness.set_policy

Set a policy on a draft harness version (published versions are refused with version.published_immutable). What the runtime enforces: category tools on work.* and council.* calls made by an agent holding a lease — subject.role_key (or role_keys) picks the role of that work item, action is a tool name or a prefix like council.*; deny beats allow and a denied call fails with PermissionDenied policy.denied. require_approval is accepted only with action work.complete: the step then waits for a human to approve the agent's result (the run goes waiting_for_user); any other require_approval is refused with policy.unsupported. Categories data_access, voting, budget, execution, approval, retention and privacy are stored but NOT enforced — the response carries a policy.not_enforced warning; set budgets with harness.set_budget. Calls an external agent makes outside Flownix (shell, files, other MCP servers) are never intercepted.

harness_version_idcategoryeffectsubjectactionresource_patterncondition

harness.start_run

Start a run of a published harness version. Drafts are refused with FailedPrecondition 'version.not_published' and no run is created; without harness_version_id the run uses the harness's current version (the latest published one). The budget is snapshotted into budget_snapshot. Creates the run and immediately advances it: every start node gets a step. agent_task, review and judge create one work item for config.role_key; debate and vote create min_instances work items of their role — visible right away via work.list_available(run_id, role_key). human_gate creates an approval a human answers in the web app (see harness.list_pending_approvals; the run goes waiting_for_user). condition, loop, create_flow_nodes and end run without agents; end completes the run. Returns the created run.

workspace_idharness_idharness_version_idtitleinputsource_node_idsbudgetmax_run_duration_secondsmax_work_itemsmax_tokensmax_cost_usd

harness.update_role

Update an agent role of a draft version. Only the fields you provide are changed — omitted fields keep their current values. A role of a published version is refused with version.published_immutable — create a new version instead.

role_idnamedescriptionobjectivesystem_instructionsresponsibilitiesprohibited_actionsoutput_schemamin_instancesmax_instances

harness.validate

Validate a harness version before publishing. Returns valid=false if there is at least one error; each error and warning carries a machine code, a location (field: "version", "role:<key>", "node:<name>" or "edge:<from>-><to>") and a message saying what to fix. Errors (block publishing): graph.empty; graph.no_start (every node has incoming edges; loop back-edges do not count); graph.cycle (a cycle not formed by a loop node, lists the nodes); graph.unreachable_node; node.name_duplicate; node.unknown_type; node.role_missing (agent_task/review/debate/vote/judge without config.role_key); node.role_unknown (config.role_key matches no role); node.config_invalid (config.lease_seconds outside 60..3600, retry_policy.max_attempts outside 1..10, negative timeout_seconds); node.condition_invalid (condition node without a valid config.condition or without exactly one incoming edge); node.end_has_outgoing; node.loop_invalid (config.max_iterations not 1..100, no continue or exit edge, or no edge back from the body); node.flow_nodes_without_gate (a path to create_flow_nodes without human_gate); edge.condition_invalid (not a JSON object, all/any mixed or empty, empty field path, unsupported op — supported: eq, neq, in, not_in, gt, gte, lt, lte, contains, exists, not_exists; in/not_in need an array value); role.instances_invalid (min_instances < 1 or > max_instances); limits.exceeded (200 nodes, 500 edges, 50 roles, 20000 chars of role system_instructions or node config). Warnings (do not block): graph.no_end; role.unused; node.config_ignored (config keys the runtime does not read for that node type); node.field_ignored (input_bindings/output_bindings set); edge.field_ignored (mapping or non-zero priority set); council.isolated_vote (vote/judge without a config.deliberation_key shared with a debate node); node.unimplemented_type (parallel_group and transform complete immediately with empty output). Policies (see policy.not_enforced from harness.set_policy) and input/output schemas are not checked.

harness_version_id

Harness: очередь работ

06
work.claim

Claim a work item by acquiring a lease. This prevents other agents from picking up the same item (mutual exclusion). Returns the work item with input artifacts, the lease expiry time and your role (system_instructions, objective, responsibilities, prohibited_actions, output_schema) — follow the prohibited actions. Call work.get_context next for the run input and predecessor outputs. The lease lasts config.lease_seconds of the node (default 300); call work.heartbeat before it runs out, otherwise it expires, the attempt is spent and the item becomes available again.

work_item_idagent_id

work.complete

Mark a claimed work item as completed. output is first checked against your role's output_schema and, for a step leading into an end node, against the version's output_schema: a mismatch is refused with InvalidArgument output.schema_violation listing JSON pointers and reasons, the lease stays yours — fix output and call again. Then it releases the lease and records result_artifact_ids, outcome and output in the step output; outcome selects conditional outgoing edges. The run then advances. If a tools policy with require_approval matches work.complete for your role, the step instead waits for a human to approve the result (run status waiting_for_user). Not needed for vote work (council.cast_vote/council.abstain close it) or for judge work (council.submit_judgement closes it). Debate work completes with this tool; the step ends when the round's work is all closed.

work_item_idresult_artifact_idsoutcomeoutputusageinput_tokensoutput_tokenscost_usd

work.fail

Mark a work item as failed. The failure spends one attempt out of max_attempts: while attempts remain the item goes back on the queue for another agent and the step stays alive. Once attempts run out — or when you pass no_retry — the step fails and the run is marked failed. max_attempts comes from the node's retry_policy.max_attempts (default 3).

work_item_iderror_messageno_retryusageinput_tokensoutput_tokenscost_usd

work.get_context

Everything you need to do a work item, in one call: the run (id, title, status, input, source_node_ids — the Flownix nodes the run is about), the workflow node (name, type, config — config.description often holds the step instructions), your role (key, system_instructions, objective, responsibilities, prohibited_actions, output_schema), input_artifact_ids (result_artifact_ids of the chosen predecessor steps) and the outputs of predecessor steps, plus deliberation_id for debate/vote/judge nodes and, for a vote node, a ballot block (ballot_id, method, quorum, threshold, allow_abstain, status and options with proposal_id and title) to use with council.cast_vote or council.abstain. Call it right after work.claim. Refused with a permission error for a run in a project your session cannot access. What is included follows the version's context policy (harness.set_context_policy): without one you get run input, role and predecessors; a policy may drop run_input or role, add all_steps (outputs of every completed step of the run, in completion order), strip output keys listed in exclude, and cap step outputs at max_tokens (JSON bytes / 4) — the earliest outputs are dropped first, context_truncated is true and omitted_workflow_node_ids names them; read them with harness.get_run if you need them.

work_item_id

work.heartbeat

Extend the lease on a claimed work item by the node's lease length (config.lease_seconds, default 300). Call it well before lease_expiry while you work. If the lease expires first, the attempt is spent and the item goes back on the queue. Returns the work item with the new lease_expiry.

work_item_id

work.list_available

List available (unclaimed) work items of a run. Each work item is work for one agent on an agent_task, review, debate, vote or judge step. Filter by role_key to find items of your role. Returns {work_items: [...]}, each with id, workflow_node_id, role_key, input_artifact_ids and, for debate/vote/judge, deliberation_id.

run_idrole_key

Harness: обсуждение

10
council.abstain

Abstain on an open ballot (ballot_id from the ballot block of work.get_context). Refused when the ballot has allow_abstain=false. Abstentions count toward quorum but not for any option. If agent_id holds the lease on the vote work item, the abstention also completes it — do not call work.complete afterwards.

ballot_idagent_idrationale_summary

council.attach_evidence

Attach evidence to a claim. Evidence provides support, contradiction, or context for claims. Use this to back up facts with code references, documents, test results, or external URLs. Returns the evidence link with its relation to the claim.

claim_idtypeuricontent_snapshotmetadata

council.cast_vote

Cast a vote on an open ballot. Take ballot_id and the options (proposal_id) from the ballot block of work.get_context for your vote work item. If agent_id holds the lease on that vote work item, the vote also completes it — do not call work.complete afterwards; the ballot closes when votes plus abstentions reach quorum, all voters' work is closed, or its timeout passes, and the step outputs outcome winner|tied|no_quorum|no_consensus. Voting again before the ballot closes replaces your vote. Returns the recorded vote.

ballot_idagent_idoption_idscorerankrationale_summaryconfidence

council.get_deliberation

Read a deliberation with all its material in one call: subject, phase, current round and max_rounds; every proposal with author, title, body and its claims with evidence; every critique with its target and the responses to it; ballots with votes (votes stay hidden on an anonymous ballot until it is closed); and decisions, including a judge's selected_proposal_ids, summary and rationale. Use it for cross-review of colleagues' positions and before judging.

deliberation_id

council.respond_to_critique

Respond to a critique: accept, partially_accept, reject, revise_proposal or request_evidence. The response is recorded and shown with the critique in council.get_deliberation; action revise_proposal does not revise anything by itself — call council.revise_proposal.

critique_idauthor_agent_idbodyaction

council.revise_proposal

Revise a proposal after critiques. Creates a revision that supersedes the original; claims are not copied to it — attach them again with council.submit_claim if needed. Withdrawn or rejected proposals cannot be revised. Returns the new proposal.

proposal_idtitlesummarybodyconfidence

council.submit_claim

Submit a claim attached to a proposal. Claims are factual assertions, assumptions, predictions, or risks that support or qualify the proposal. Each claim can have evidence attached and may be verified or contradicted. Returns the created claim.

proposal_idauthor_agent_idtexttypeconfidence

council.submit_critique

Submit a critique on a proposal, claim, or another critique. In a debate step an open critique of severity major or blocking opens another round (new work items) until config.max_rounds is reached; info and minor do not. Each critique should suggest a resolution.

deliberation_idauthor_agent_idtarget_typetarget_idcategoryseveritysummarybody

council.submit_judgement

Submit a final judgement as a judge agent. Unlike voting (which uses ballots), judgements are authoritative decisions made by a designated judge role. Selects winning proposals and records a decision with rationale. If author_agent_id holds the lease on this deliberation's work item, the judgement also completes that work item (step output: decision_id, selected_proposal_ids) and advances the run — do not call work.complete afterwards. Returns the decision.

deliberation_idauthor_agent_idselected_proposal_idssummaryrationaleconfidence

council.submit_proposal

Submit a proposal to a deliberation (deliberation_id from work.get_context of a debate/vote/judge work item). Proposals that are not withdrawn or rejected become the options of the deliberation's vote ballot and the candidates for a judge. Claims can be attached with council.submit_claim and critiqued with council.submit_critique. Returns the created proposal.

deliberation_idauthor_agent_idtitlesummarybodyconfidence

Аудит

01
list_action_events

Get the project's action log (audit trail): who did what, when, and through which channel (api/mcp). Use this before starting work on a task to see recent activity, or to check what changed on a specific entity. Read-only.

project_idevent_typesourceactor_typeentity_identity_typestart_dateend_datelimitskip