↓ Skip to main content
Rillsoft AI
Connect Rillsoft

Rillsoft AI

Developers: the MCP server contract

What tools/list delivers, how arguments, results and errors are structured, what undo, read-only and session mean – the entry for developers and integrators.

This page describes the contract the MCP server of Rillsoft Project keeps with every client: how a tool is described, how input and output are structured, what an error contains and which rules apply to undo, read-only and session. Starting the server, the handshake and access protection are on the MCP page. The complete tool catalogue is not maintained by hand but generated from tools/list of the released product build; it follows as soon as that build is named.

What an entry in tools/list carries
#

FieldMeaning
namecanonical name with prefix rillsoft_, unique within the server
titleshort display name, English
descriptionselection aid including effect, preconditions and limits, English
inputSchemacomplete JSON schema including nested objects and list items, additionalProperties: false
outputSchemaschema of the successful structuredContent, equally complete
annotationsreadOnlyHint, destructiveHint, idempotentHint, openWorldHint

destructiveHint is conservatively true wherever something is deleted, overwritten, discarded or released with loss. idempotentHint is true only if the same call repeatably has the same effect. openWorldHint is true for file and network access, false for pure access to the document model. The list is sorted ordinally by name so that a client keeps its cache; the order is a sort, not a contract about positions.

Both schemas are enforced at runtime. The server validates arguments before the call reaches the application; a structurally invalid call never touches the project and leaves no undo step. Every successful structuredContent is validated against its outputSchema; a violation is an internal error, not a silent delivery.

Language boundary
#

The server has no session language. It answers every client in the language of the running Rillsoft Project – German, English or Russian. What is read by machines stays the same everywhere:

LevelDE buildEN buildRU buildStability
tool names, arguments, result fields, enum valuesEnglishEnglishEnglishidentical
title, description in tools/listEnglishEnglishEnglishbyte-identical
error codes (error.data.code, _meta.errorCode)EnglishEnglishEnglishidentical
error messages, note[], command, label, conflictTextGermanEnglishRussianlocalised

Even a localised message names taskUuid, machine_role or rillsoft_resource_pool_catalog_list unchanged – the reader should be able to build the next call from it.

Field names and value ranges
#

  • Arguments and result fields carry English lowerCamelCase names, and the same business value has the same name in both directions: what the project tree returns as durationHours, the task update accepts as durationHours. An answer can be passed on without renaming.
  • Enum values are English lower_snake_case: machine_role, capacity_driven, resource_chart; single-part values stay one word. The five dependency types are finish_start, finish_start_no_delay, start_start, finish_finish and start_finish.
  • Every bounded value range appears as an enum in the inputSchema; the description explains the meaning of the values and draws the line to the neighbouring value.
  • Dates in the format DD.MM.YYYY hh:mm (time optional) or YYYY-MM-DDThh:mm; durations in hours. A date such as 31.02.2026 is rejected instead of silently rounded to 3 March.
  • Objects are addressed by their UUID; every creating call returns it. WBS codes are assigned by Rillsoft Project itself.
  • Readable labels from the user interface are called label; they depend on the language and are not keys.

Answer and error
#

Every tool answer delivers the result twice: as plain text in content[0].text (JSON, YAML for reports) and machine-readable in structuredContent. A business rejection comes as isError: true with the stable code in _meta.errorCode; the first line of the text repeats the code:

{"id":9,"jsonrpc":"2.0","result":{"content":[{"text":"errorCode: rejected\nNo task with UUID 'xyz' found","type":"text"}],"isError":true,"_meta":{"errorCode":"rejected"}}}

The same error in three builds – the code is the identifier, the text the explanation:

Build_meta.errorCodecontent[0].text from line 2
Germaninvalid_date_formatUngültiger Wert für 'start': '32.13.2020' — erwartet wird DD.MM.YYYY hh:mm oder YYYY-MM-DDThh:mm
Englishinvalid_date_formatInvalid value for 'start': '32.13.2020' - DD.MM.YYYY hh:mm or YYYY-MM-DDThh:mm is expected
Russianinvalid_date_formatНедопустимое значение для 'start': '32.13.2020' — ожидается DD.MM.YYYY hh:mm или YYYY-MM-DDThh:mm

Schema violations come as JSON-RPC error -32602 with error.data.code and a language-neutral field path in error.data.field, e.g. arguments.criterion with the list of permitted values. The error classes:

Error classBehaviour
schema error (type, required field, unknown field, value range)-32602 before the jump into the application; the project is not touched
validation error (unknown UUID, invalid date, unknown id)tool error before the command begins; project untouched
conflict on completion (working time, fixed dates, write protection)automatic rollback; tool error with the conflict reason
unknown method, batch, lifecycle violation-32601 or -32600
session limit reached-32000

The set of codes is cut at category level – around thirty codes instead of three hundred messages. There is no rejection without a code; where a handler sets none, the collective code rejected applies. Retry rules are built on the code, never on the wording.

Access classes, undo and session
#

Every tool belongs to exactly one access class. It yields both the readOnlyHint and the filtering in read-only mode, so the two cannot diverge.

ClassRule
read-onlychanges neither task, assignment, date nor file; no undo step. Some tools of this class visibly change window or view state – their description says so
mutatingexactly one undo step per call, the same path as an action in the user interface; recalculation, critical path and view are updated on completion
sessionfile and session operations: create, open, save, export a project, switch the pool, undo and redo. They create no undo step; after creating or opening, the command history starts afresh

Undo and redo are tools themselves and operate the same history as the user interface, including steps a person made there. The history stores a complete snapshot per command; very many single calls therefore take time.

Protocol rules that may differ from what you expect
#

  • Only protocol revision 2025-06-18 is negotiated; older revisions are rejected.
  • initialize assigns Mcp-Session-Id; notifications/initialized unlocks the tools. Every further request carries session and MCP-Protocol-Version, otherwise 400. At most 32 sessions, expiry after 30 minutes idle, DELETE /mcp ends one.
  • JSON-RPC batches are rejected. Only the absence of id marks a notification; id: null is a request.
  • params.arguments is required as soon as the tool has parameters; a forgotten arguments would otherwise be a silent call with default values.
  • Paths are absolute (drive or UNC) with the matching extension; listing or deleting files deliberately does not exist.
  • Portfolios have their own open tool; the project tool rejects an .rpp with a hint and vice versa. In a portfolio mutating tools are rejected, the time scale excepted.

A walkthrough in eighteen calls
#

The documented end-to-end sequence across all areas, using the mcp function from the MCP page; <A> is the UUID from the result of the creating call:

# build and assign
mcp '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"rillsoft_project_create","arguments":{"name":"Demo","discardChanges":true}}}'
mcp '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"rillsoft_project_update","arguments":{"start":"05.10.2026 08:00","finish":"27.11.2026 17:00","fixed":true}}}'
mcp '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"rillsoft_task_create","arguments":{"name":"Task A","start":"05.10.2026 08:00","durationHours":16}}}'
mcp '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"rillsoft_task_role_assignment_set","arguments":{"taskUuid":"<A>","roleId":11001,"quantity":2}}}'

# save a baseline, then change the plan
mcp '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"rillsoft_baseline_create","arguments":{"name":"Plan V1"}}}'
mcp '{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"rillsoft_task_update","arguments":{"uuid":"<A>","durationHours":24}}}'

# record actual data
mcp '{"jsonrpc":"2.0","id":7,"method":"tools/call","params":{"name":"rillsoft_task_progress_set","arguments":{"uuid":"<A>","progressPercent":50}}}'
mcp '{"jsonrpc":"2.0","id":8,"method":"tools/call","params":{"name":"rillsoft_project_status_date_set","arguments":{"statusDate":"07.10.2026 08:00"}}}'

# plan/actual (time) …
mcp '{"jsonrpc":"2.0","id":9,"method":"tools/call","params":{"name":"rillsoft_view_state_apply","arguments":{"view":{"name":"time_variance"}}}}'
mcp '{"jsonrpc":"2.0","id":10,"method":"tools/call","params":{"name":"rillsoft_variance_report_get","arguments":{}}}'
# → planned 16 h, actual 24 h, variance 8 h

# … and workload, condensed to weeks
mcp '{"jsonrpc":"2.0","id":11,"method":"tools/call","params":{"name":"rillsoft_view_state_apply","arguments":{"view":{"name":"employee_capacity"}}}}'
mcp '{"jsonrpc":"2.0","id":12,"method":"tools/call","params":{"name":"rillsoft_timescale_apply","arguments":{"unit":"week"}}}'
mcp '{"jsonrpc":"2.0","id":13,"method":"tools/call","params":{"name":"rillsoft_analysis_report_get","arguments":{}}}'

# save, take back a slip, reopen the saved state
mcp '{"jsonrpc":"2.0","id":14,"method":"tools/call","params":{"name":"rillsoft_project_file_save_as","arguments":{"path":"C:/Projects/Demo.rpj"}}}'
mcp '{"jsonrpc":"2.0","id":15,"method":"tools/call","params":{"name":"rillsoft_task_update","arguments":{"uuid":"<A>","durationHours":40}}}'
mcp '{"jsonrpc":"2.0","id":16,"method":"tools/call","params":{"name":"rillsoft_history_undo","arguments":{}}}'
mcp '{"jsonrpc":"2.0","id":17,"method":"tools/call","params":{"name":"rillsoft_project_file_save","arguments":{}}}'
mcp '{"jsonrpc":"2.0","id":18,"method":"tools/call","params":{"name":"rillsoft_project_file_open","arguments":{"path":"C:/Projects/Demo.rpj","discardChanges":true}}}'

Every mutating step can be followed live in the visible Rillsoft Project and taken back there individually with Ctrl+Z; the file steps create no undo step. After every mutating call the recalculated plan is available – dates, float, critical path –, not just the changed record; the evaluations in steps 10 and 13 read exactly this state. The documentation closes the walkthrough with a 19th read-only call (rillsoft_project_tree_get) that checks the saved state. The role id in the example comes from the reference pool of the documentation – in your pool the catalogue call returns it.

What follows here
#

After the contract freeze against the released product build: the catalogue generated from tools/list per tool with purpose, access class, parameters, answer schema, licence and undo notes and a verified example; pages on authentication, security, troubleshooting and changes per product version. Until then: what tools/list of your installation returns is the contract.

Product version
Rillsoft Project 10
Verification
Details from the Rillsoft Project 10 product documentation (as of 2026-09-08); reconciliation with the released build is pending.