OpenL MCP Server
OfficialThe OpenL MCP Server connects AI assistants to OpenL Studio — a Business Rules Management System — enabling them to manage repositories, projects, rules/tables, tests, traces, and deployments programmatically.
Repository & Project Management
List repositories, branches, features, and project revision history
List, open, save, close, and create projects; branch from specific revisions
Track and restore local (unsaved) project changes
File & Table (Rules) Operations
List, get, update, append, create, and delete tables (Decision Tables, Spreadsheets, Datatypes, Test tables, etc.)
Read, write, search, copy, move, and delete project files
Apply raw-source edits to tables
Testing
Start project-level or table-specific test runs
Retrieve results in summary, full, or table-specific formats
Tracing & Debugging
Start, cancel, and export traces
Navigate trace trees; inspect nodes, parameters, context, and errors
Load lazy-loaded parameter values
Deployment
List deploy repositories and active deployments
Deploy new projects or redeploy/rollback existing deployments
AI Prompts
14 expert guidance templates for complex workflows (e.g., creating rules, running tests, deploying)
Core Features: Type-safe validation (Zod), PAT-based authentication, pagination for list operations, and multiple response formats (JSON, Markdown variants).
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@OpenL MCP Serverlist my repositories"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
OpenL MCP Server
Let an AI assistant work with your OpenL Studio business rules. Connect Claude (Desktop or Code), Cursor, or VS Code to OpenL Studio, then ask in plain language to view, edit, test, and deploy rules.
Get started (about 5 minutes)
Copy your OpenL Studio address from your browser's address bar (for example
http://localhost:8080).Create a Personal Access Token in OpenL Studio (User Settings → Personal Access Tokens). Skip this if your Studio has no login screen.
Follow the Quick Start — paste one configuration block into your AI client and send a test message.
Nothing to install — your AI client downloads and starts the server for you
(published on npm as openl-mcp;
no Node.js on your machine? use the
Docker option).
Related MCP server: Operaton MCP
Documentation
🚀 Quick Start — connect Claude Code, Claude Desktop, Cursor, or VS Code
📖 Usage Examples — what to ask once connected, and what the tools cover
⚙️ Advanced Guide — all server settings, authentication, Docker, shared HTTP mode
🖥️ CLI Guide — use the same binary as a shell tool (no MCP client needed)
🐛 Troubleshooting — common issues and solutions
🗂️ Full documentation index — including developer docs
Tools and prompts
The server gives the AI client tools covering OpenL Studio repositories, projects,
files, rules tables, tests, an interactive rule debugger (tracing), and
deployments — see Usage Examples. It also ships 14
expert guidance prompts for complex workflows (e.g. create_rule,
deploy_project) — see prompts/.
Reporting a problem? Include the running build:
npx -y openl-mcp --versionConfiguration
End users: the Quick Start covers everything. All server settings (base URL, token, timeout, HTTP mode, debug logging) are in the Advanced Guide.
Development
npm run build # Build TypeScript
npm test # Run all tests
npm run lint # Check code quality
npm run watch # Dev mode with auto-rebuildSee the Contributing Guide for development guidelines, Architecture for how the code is organized, and the Testing Guide for test suites.
License
LGPL-3.0 - GNU Lesser General Public License v3.0 (follows OpenL Studio project license).
Available Tools
74 toolsopenl_append_tableAppend Raw Source RowsA
Append RawSource rows to an existing table. Typed append DTOs are intentionally unsupported. Every row must cover ALL columns of the table; wrong-width rows are rejected before anything is written. Use { value: null } for a blank cell and preserve covered placeholders for merged regions. For modifying or reordering use a narrow raw action tool or update_table; remove rows/columns only with the corresponding delete action. The response returns the CURRENT tableId after relocation, and the read-back triggers recompilation.
| Name | Required | Description | Default |
|---|---|---|---|
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| appendData | Yes | RawSource append payload. Typed table append DTOs are intentionally unsupported because they are lossy and incomplete. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry openWorldHint, so the description carries the burden of behavioral disclosure. It discloses that wrong-width rows are rejected before anything is written, that the response returns the CURRENT tableId after relocation, and that read-back triggers recompilation. It does not mention permission requirements or error behavior, but the provided side-effect details are valuable and non-obvious.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences and every sentence carries distinct information: scope, unsupported DTOs, width constraint, blank-cell encoding, alternative routing, and response side effects. It is dense but not bloated, and the core purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a nested-payload tool with no output schema, the description covers the critical behavioral contract: rejection atomicity, merged-region handling, tableId volatility, and recompilation. Combined with the fully described input schema, it gives an agent enough to invoke the tool correctly, though the exact full response shape is not specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful semantic guidance beyond the schema: the all-columns width requirement, the '{ value: null }' blank-cell encoding, and the instruction to preserve covered placeholders for merged regions. These details help the agent construct correct appendData payloads.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Append RawSource rows to an existing table', a specific verb plus resource, and immediately distinguishes itself from typed append DTOs and sibling actions like update_table and delete actions. The scope is precise and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use this tool (appending raw rows) and when not to: 'For modifying or reordering use a narrow raw action tool or update_table; remove rows/columns only with the corresponding delete action.' This directly routes the agent away from inappropriate sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_append_table_columnsAppend Table Columns (raw)A
Add ONE OR MORE columns to the END of a table's raw source. 'cells' is a 2D array: outer = columns left to right, inner = that column's cells top to bottom (one per row). Pass a single column to add one, several for a block. Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| cells | Yes | Columns left to right, each a non-empty list of cells top to bottom (one cell per row; use { value: null } for a blank cell). Pass one column to add/insert a single column, several for a block. Each column as tall as the table. | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only openWorldHint as annotation, the description carries the behavioral disclosure burden and does so thoroughly. It reveals the volatile location-derived tableId, explains that the response returns current tableId and previousTableId when relocated, and discloses the non-obvious recompile behavior triggered by reading the table back. This is exactly the kind of behavioral context an agent needs beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: main action first, then the data-structure contract, position semantics, the volatile-id warning, and the recompile side effect. Nothing is redundant, and the most decision-relevant information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating table operation with no output schema, the description covers everything an agent needs: what to pass, how cells map to columns, where columns are added, how to handle the volatile tableId, and what follow-up calls may see after recompile. It is complete relative to the tool's complexity and the sibling set.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds significant semantic value beyond the schema. It re-explains the 'cells' 2D structure in clearer terms, clarifies 0-based positioning, and explains the tableId volatility and response contract. While projectId and response_format gain little new meaning, the tricky parameters are well supplemented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair ('Add ONE OR MORE columns to the END of a table's raw source') and immediately distinguishes this tool from related siblings like openl_insert_table_columns and openl_append_table_rows by emphasizing END, columns, and raw source. It also clarifies the 2D 'cells' array orientation, leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: append at the end, works on any table type because it operates on raw source, and supports one or many columns at once. It does not explicitly name sibling alternatives or state when not to use them, but the placement and raw-source emphasis provide enough contextual guidance for an agent to select it correctly in most cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_append_table_rowsAppend Table Rows (raw)A
Add ONE OR MORE rows to the END of a table's raw source. 'cells' is a 2D array: outer = rows top to bottom, inner = that row's cells left to right (one per column; use { value: null } for blanks). Pass a single row to add one, several for a block. Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| cells | Yes | Rows top to bottom, each a non-empty list of cells left to right (one cell per column; use { value: null } for a blank cell). Pass one row to add/insert a single row, several for a block. Each row as wide as the table. | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only include openWorldHint=true, so the description carries most of the burden. It discloses important behaviors: it appends to raw source, can change the table's ID due to relocation, returns current tableId and previousTableId, and triggers a recompile via reading the table back. This exceeds the minimal safety disclosure expected.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place: it covers data structure, positioning, raw source, ID volatility, and recompile side-effect. It's front-loaded with the core append behavior. Slightly dense, but not bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-param tool with no output schema and only openWorldHint annotation, the description is quite complete. It explains side effects that an agent must know (ID changes, recompile trigger). It doesn't detail response format beyond tableId/previousTableId, but since no output schema exists, a brief note on response shape could push it to 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all parameters. The description adds useful context about the 2D array orientation and blank-cell syntax, but it doesn't add much beyond the schema's own descriptions. Baseline 3 is appropriate because the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool adds one or more rows to the end of a table's raw source, with specific details on the 2D array structure. It distinguishes itself from siblings like openl_insert_table_rows (adds rows elsewhere) and openl_update_table_row by emphasizing 'END' and 'raw source'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context—when to use it to add rows, how to handle blanks, and mentions it works for any table type because it operates on raw source. It doesn't explicitly contrast with openl_insert_table_rows or openl_append_table (which may be a high-level wrapper), but the positional and raw-source details provide enough guidance. No explicit exclusions, though.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_cancel_merge_conflictsClear Pending Merge ConflictsADestructive
Abort the pending merge-conflict workflow by clearing its session state. This does not modify files or branches, but the stored conflict analysis is discarded; run the merge again to recreate it.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true, and the description adds valuable specifics: the stored conflict analysis is discarded, files and branches are untouched, and the workflow can be recreated by rerunning the merge. This gives the agent a precise mental model of the side effects. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences: the first states the action, and the second qualifies scope and recovery. There is no filler, and the most important behavioral distinction is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple cancellation tool with no output schema and strong annotations, the description fully covers what happens, what does not happen, and how to undo the state change. No critical information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%; both projectId and response_format have detailed descriptions, including how to obtain projectId and what each response_format value means. The tool description itself adds no parameter-level meaning, but the schema fully carries that burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Abort') and resource ('pending merge-conflict workflow'/'session state'), and immediately clarifies that it does not modify files or branches. This makes it clearly distinct from sibling tools like openl_get_merge_conflicts and openl_merge_project_branches.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly frames when to use this tool: when a pending merge-conflict workflow needs to be aborted, and it notes that rerunning the merge recreates the analysis. It does not explicitly name alternatives or exclusions, but the usage context is unambiguous enough for an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_check_project_mergeCheck Project MergeARead-onlyIdempotent
Check merge direction, branch relationship, permissions, and blockers without changing Git. This is not a conflict preview: status='mergeable' means the source has changes absent from the target, not that the merge is conflict-free; conflicts are discovered only by openl_merge_project_branches. status='up-to-date' means the target already contains the source. canMerge reports whether Studio permits the attempt after permission, protection, and lock checks. mode='receive' merges otherBranch into the project's current branch; mode='send' merges the current branch into otherBranch. Discover merge targets with openl_list_project_branches(scope='repository'), because a valid target may not hold the project yet.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | receive merges the other branch into the project's current branch; send merges the current branch into otherBranch. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| otherBranch | Yes | The other branch: source for receive mode, target for send mode. Discover all merge targets with openl_list_project_branches(scope='repository'). | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though annotations already declare readOnlyHint, idempotentHint, and openWorldHint, the description adds valuable behavior: 'without changing Git,' precise semantics of status='mergeable' vs 'up-to-date,' and what canMerge reflects after permission/protection/lock checks. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tightly packed sentences, no filler; the most important discriminator ('not a conflict preview') appears early. Each sentence adds a distinct piece of information needed to use the tool correctly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only check tool with no output schema, the description covers the outcome semantics (status, canMerge), mode direction, permissions/blockers, and target discovery. An agent has enough to select and invoke it correctly without needing to infer behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaningful parameter context: mode receive/send direction, otherBranch as source or target depending on mode, and the discovery path for valid otherBranch values. ProjectId and response_format are already well described in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with a specific verb and resource: 'Check merge direction, branch relationship, permissions, and blockers without changing Git.' It distinguishes itself from openl_merge_project_branches by explicitly stating it is not a conflict preview, so an agent can differentiate it from the sibling merge tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states when this tool is appropriate (pre-merge check, no mutation) and when it is not ('This is not a conflict preview'), pointing to openl_merge_project_branches for conflict discovery. It also directs the agent to openl_list_project_branches(scope='repository') to discover targets, including the caveat that a valid target may not hold the project yet.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_close_projectClose ProjectADestructive
Close a project. If the project has unsaved changes (status EDITING), you must either save (saveChanges: true with comment) or discard (discardChanges: true). When discarding, ask the user for confirmation and then call again with confirmDiscard: true. Prevents accidental data loss.
| Name | Required | Description | Default |
|---|---|---|---|
| comment | No | Git commit comment. Required if saveChanges is true. Optional if saveChanges is false or omitted. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| saveChanges | No | If true, save changes before closing (requires comment). If false or omitted and project has unsaved changes, will error unless discardChanges is true. | |
| confirmDiscard | No | When closing with discardChanges: true and project has unsaved changes, must be set to true (explicitly) to confirm. Omitted or false will return a confirmation prompt. Ask the user first, then call again with confirmDiscard: true. | |
| discardChanges | No | If true, close without saving (unsaved changes will be lost). When project is EDITING, you must also set confirmDiscard: true to confirm. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true, and the description adds concrete behavioral detail: unsaved changes trigger an error unless saved or discarded, and discarding requires explicit user confirmation. This meaningfully extends the annotation by explaining the destructive path and the safeguard. No contradiction with annotations was found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four compact sentences front-load the core action and immediately cover the conditional close paths and the confirmation requirement. Every sentence contributes decision-relevant information, with no filler or redundant restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive closure tool, the description covers the main state-dependent branch, the user-confirmation loop, and the data-loss prevention rationale. With no output schema, return values are not described, but the fully documented input schema and workflow covers what an agent needs to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema descriptions cover 100% of the parameters, so the baseline is 3. The description reinforces relationships between saveChanges/comment, discardChanges/confirmDiscard, and the EDITING status, but the schema already documents these details. It adds context, though not substantial new semantic information beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource, 'Close a project,' which cleanly distinguishes it from save, open, and delete siblings. It further clarifies that closing may involve saving or discarding changes, making the action's finality clear. It does not explicitly name sibling tools for differentiation, so it misses a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit conditional workflow: if the project is EDITING, either pass saveChanges with a comment or discard; when discarding, ask the user first and call again with confirmDiscard: true. This is clear usage context and a safety protocol. It does not explicitly contrast with alternatives like openl_save_project, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_copy_project_fileCopy Project FileA
Copy a file within a project to a new project-relative path. Maps to POST /projects/{projectId}/file-copy. Intermediate destination folders are created automatically. There is NO overwrite option — if destinationPath already exists the call fails with HTTP 409; choose a different destination or delete the existing file first. The copy is staged in the working copy — commit it with openl_save_project. Use 'branch' to pin the project's branch. Use this to scaffold a new module from an existing one or clone a test set.
| Name | Required | Description | Default |
|---|---|---|---|
| branch | No | Branch the project must be on for this operation. Ignored when blank. Fails if the repository has no branches or the project is on another branch. Omit for repository 'local' and non-branch repositories. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| sourcePath | Yes | Project-relative path of the source file (e.g. 'rules/Model.xlsx'). | |
| destinationPath | Yes | Project-relative destination path (e.g. 'rules/Model-copy.xlsx'). Intermediate folders are created automatically. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only openWorldHint=true in annotations, the description carries the behavioral burden — and it delivers: it discloses that the copy is staged in the working copy and requires openl_save_project to commit, that intermediate folders are auto-created, and that a conflict yields HTTP 409. This is exactly the side-effect and failure-mode context an agent needs beyond the bare annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: core behavior, folder auto-creation, the no-overwrite failure mode, staging/commit requirement, branch pinning, and use cases. Dense but well front-loaded — the most decision-critical facts (no overwrite, 409, staged copy) appear in the first three sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter tool with no output schema and a large sibling family, the description covers behavior, failure modes, side effects, and the follow-up workflow (commit with openl_save_project) — nearly everything required to invoke it correctly. The only gap is that the return value/response shape is never mentioned, which matters slightly more because no output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters, including path formats and branch behavior; the baseline 3 applies. The description adds minor reinforcement ('Use branch to pin the project's branch') but no new parameter-level meaning beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and resource — 'Copy a file within a project to a new project-relative path' — and the endpoint mapping POST /projects/{projectId}/file-copy confirms the operation. The closing use-case guidance ('scaffold a new module from an existing one or clone a test set') further distinguishes it from sibling file operations like move, write, or delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear when-to-use context ('Use this to scaffold a new module from an existing one or clone a test set') and an explicit exclusion: 'There is NO overwrite option — if destinationPath already exists the call fails with HTTP 409; choose a different destination or delete the existing file first.' It stops short of naming sibling alternatives (e.g., openl_move_project_file or openl_write_project_file) by name, so it earns a 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_copy_tableCopy TableA
Copy a table inside the same project using Studio's server-side copy operation, preserving formatting, merged cells, comments, and complete table structure. Provide the destination module and new table name; optionally choose a sheet, create a new .xlsx module with modulePath, or replace the source properties. The copy remains in the working copy—use openl_save_project for Git-backed projects.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name for the copied table. | |
| tableId | Yes | ID of the source table to copy. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| sheetName | No | Destination worksheet name. Defaults to the copied table's name. | |
| moduleName | Yes | Name of the destination module. It must already exist unless modulePath is supplied. | |
| modulePath | No | Project-relative .xlsx path for a new destination module. Omit when moduleName already exists. | |
| properties | No | Replacement table properties. Omit to retain the source table's properties. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations providing only openWorldHint and no read-only/destructive hints, the description carries the behavioral burden. It discloses that the copy is server-side, preserves structure, and 'remains in the working copy,' which is important context for persistence. It does not fully explain overwrite behavior or failure cases, but the core side-effect model is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences carry the essential purpose, usage, and persistence caveat. Information is front-loaded: the verb and resource appear immediately, optional behaviors are compactly listed, and the working-copy note is placed last where it is easy to remember. There is no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter tool with no output schema and sparse annotations, the description covers the key operational context: what is copied, where it goes, how to create a new module, and how persistence works. It could be more explicit about cross-project limitations and the exact meaning of 'replace the source properties,' but the essential guidance is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful semantics by clarifying that moduleName/name are destination values, that modulePath creates a new .xlsx module, and that properties can be replaced. This goes beyond the schema's basic 'name' and 'pattern' descriptions, though it does not elaborate on projectId or response_format beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Copy a table inside the same project using Studio's server-side copy operation.' It further distinguishes this from file copying by emphasizing preserved table structure such as formatting, merged cells, and comments, and by naming table-focused options like sheet names and module paths.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states what is needed to use the tool ('Provide the destination module and new table name') and outlines the optional variations: choosing a sheet, creating a new .xlsx module, or replacing properties. It also gives a key follow-up action ('use openl_save_project for Git-backed projects'). It does not explicitly name sibling alternatives or exclusion conditions, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_create_projectCreate or Copy ProjectA
Create a new OpenL project in a design repository and commit it. Two modes, selected by the template argument:
• CREATE (omit template): create a BLANK project from the default empty skeleton.
• COPY (pass template = an existing project's exact projectId from openl_list_projects): use Studio's server-side project-copy API to copy that source project's FULL structure and rename its descriptor to projectName. Do not pass the displayed project name because mapped repositories may contain multiple projects with the same name.
Both modes are committed and indexed atomically. Omit branch for the repository's configured/default branch, or pass a target branch from openl_list_branches(); Studio also supports creating a missing branch from the base branch. Returns the new project name, commit revision, and Studio's opaque projectId. A name collision, missing copy source, or missing permission is rejected with an actionable error. Local repositories are not supported.
| Name | Required | Description | Default |
|---|---|---|---|
| branch | No | Target branch for either BLANK creation or CLONING. Omit for the repository's configured/default branch. Studio selects an existing branch case-insensitively; when the branch does not exist, Studio may create it from the repository base branch. Use openl_list_branches() first to avoid accidental branch creation. | |
| comment | No | Commit comment for audit. Applied to both BLANK creation and CLONING; Studio supplies its configured create/copy comment when omitted. | |
| template | No | How to create the project (the ticket's `template`). OMIT to create a BLANK project from the default empty skeleton. To CLONE an existing project, pass its exact opaque projectId from openl_list_projects() without modification: its full structure is copied (rules, tests, settings, request/response examples) and the project is renamed to projectName. Never pass the displayed project name because mapped repositories may contain multiple projects with the same name. | |
| repository | Yes | Repository identifier. Pass either the 'id' or the 'name' field from openl_list_repositories() — the tool accepts both (and is case-insensitive). DO NOT invent values like 'Design Repository' or 'design-repo'; the actual names are typically short tokens (e.g. 'Design'). Always call openl_list_repositories() first if you don't already have the value in context. | |
| projectName | Yes | Name for the new project (the ticket's `project`). Becomes the project folder name and — when cloning — the renamed project name written into rules.xml. Must be unique in the repository; a collision is rejected with 409. Allowed characters: letters, digits, space, '_' and '-'. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses atomic commit/indexing, server-side full-structure copying, descriptor renaming, default-vs-target branch behavior, return values, and failure modes (collision, missing source, missing permission). There is no contradiction with the annotations, and the side effects are clearly described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well structured: objective first, then modes, branch default, return values, and errors. Every sentence carries useful decision-relevant information with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-mode, six-parameter mutating tool with no output schema, it states what is returned, how the caller should obtain prerequisite IDs, how errors surface, and what is unsupported. An agent has enough to invoke it correctly and recover from likely failures.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all six parameters in detail (100% coverage), so the baseline is 3. The prose adds cross-parameter meaning by tying the template choice to the two modes and clarifying that branch/projectName semantics apply consistently to both creation and copy.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action (create/copy) on a specific resource (OpenL project) and separates the two modes by the template argument. It clearly distinguishes this from branch-creation, save, and deploy siblings by focusing on project creation with commit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete invocation rules: omit template for blank creation, pass an exact opaque projectId from openl_list_projects for copying, omit branch for default, and pre-call openl_list_branches to avoid accidental branch creation. It names an exclusion (local repositories are not supported), though it does not explicitly contrast itself with close alternatives like openl_create_project_branch.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_create_project_branchCreate Project BranchA
Create a new branch in a project's repository from a specified revision. Allows branching from specific revisions, tags, or other branches. If no revision is specified, the HEAD revision will be used.
| Name | Required | Description | Default |
|---|---|---|---|
| revision | No | Revision to branch from. Allows to branch from specific revision, tag or another branch. If not specified, HEAD revision will be used. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| branchName | Yes | Git branch name (e.g., 'main', 'development', 'feature/new-rules') | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only an openWorldHint annotation and no read-only or destructive hints, the description carries the behavioral disclosure burden. It goes beyond the title by explaining that the branch may originate from a specific revision, tag, or branch, and that HEAD is used by default. It does not describe failure modes, but the core mutation and default behavior are transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences lead with the core action, then explain the branching sources and default revision. Every sentence adds useful information with no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple creation tool, the description plus full schema coverage gives the agent what it needs to invoke correctly: required parameters, default behavior, and response format options are covered. No output schema exists, and the description doesn't specify the return shape or error-on-existing-branch behavior, costing one point.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all four parameters. The description only restates the revision default already present in the schema and adds no new parameter-level meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('Create a new branch in a project's repository') and clarifies the revision source, including tags and other branches. This scope clearly differentiates it from sibling branch tools like list/delete/merge branches.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool: when a new branch is needed in a project repository. It doesn't explicitly name alternatives or state when not to use it, but the operation is unambiguous so the agent can infer the correct choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_create_project_tableCreate New TableA
Create a table from its complete RawSource 2D cell matrix. Typed table creation DTOs are intentionally unsupported because they omit workbook features and do not round-trip reliably. Requires moduleName plus table { tableType: "RawSource", name, source }. By default moduleName identifies an existing module; pass modulePath ending in .xlsx to create a new module. Build the exact OpenL grid from the bundled guides or copy an existing raw source, including covered cells/spans where needed. Studio table write APIs cannot set cell formatting, so style is rejected. The response is metadata, not a compilation result; call openl_project_status afterward.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | ||
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| sheetName | No | Name of the sheet where the table will be created within the Excel file. If not provided, the table name will be used as the sheet name. | |
| moduleName | Yes | Name of an existing project module where the table will be created (for example, 'Main' or 'Rules'). | |
| modulePath | No | Project-relative .xlsx path for a new module. When omitted, moduleName must identify an existing module. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The only annotation is openWorldHint, so the description carries the behavioral burden, and it does so well: it discloses unsupported DTOs, the style-rejection behavior, the need for covered cells/spans, and the fact that the response is metadata, not a compilation result. These are exactly the non-obvious behaviors an agent needs before calling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then adds each constraint as a separate compact sentence: DTOs, module modes, source construction, style, and response semantics. There is no filler or redundant explanation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex nested-source tool with no output schema, it covers the payload shape, module creation mode, source construction, style limitation, and the follow-up status call. It stops short of describing what metadata fields the response contains, which would have made it fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 83%, so the baseline is 3, and the description largely restates what the schema already documents, such as moduleName vs modulePath, style rejection, and required table fields. While 'Build the exact OpenL grid from the bundled guides or copy an existing raw source' adds some practical guidance, the 'Requires moduleName plus table...' phrasing omits projectId, so it earns no higher credit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific action and resource: create a table from its complete RawSource 2D cell matrix. This clearly separates the tool from project creation and table mutation tools via the create + RawSource scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete conditions: use moduleName for an existing module, pass a .xlsx modulePath to create a new module, and call openl_project_status afterward. It also explains that typed table creation DTOs are unsupported, though it does not explicitly name update/copy sibling tools as alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_delete_projectDelete ProjectADestructive
Permanently delete a project through Studio. This may create a deletion commit in its design repository. Safety guard: confirmProjectName is required and must exactly match the project's current backend name; the handler reads the project immediately before deletion. An optional comment becomes the deletion commit message.
| Name | Required | Description | Default |
|---|---|---|---|
| comment | No | Optional deletion commit message, validated by the repository's comment template when configured. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
| confirmProjectName | Yes | Required safety confirmation: exact project name returned by openl_get_project(). The delete is rejected if it does not match. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though annotations already declare destructiveHint and openWorldHint, the description adds significant behavioral detail: deletion is permanent, a deletion commit may be created, confirmProjectName must match the current backend name, and the handler reads the project immediately before deleting. This gives the agent a clear and actionable safety model beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences front-load the action, then cover side effects and the safety requirement. Every sentence contributes distinct information: what the tool does, what side effects may occur, and what safeguards and parameters matter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive tool with complete schema coverage and meaningful annotations, the description is sufficient. It covers permanence, repository side effects, safety confirmation requirements, and commit behavior, while the response_format enum in the schema defines the expected output shapes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description still adds value by explaining that confirmProjectName must match the project's current backend name and that the handler reads the project right before deletion. It also clarifies that the optional comment becomes the deletion commit message, reinforcing and extending the schema's parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Permanently delete a project through Studio,' and further clarifies that deletion may create a commit in the design repository. This unambiguously distinguishes it from sibling tools like openl_delete_project_file, openl_delete_project_branch, and openl_delete_table.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended context is clear: use this tool when you need to permanently remove an entire project, and the safety guard tells callers they must provide the exact current backend project name. It does not explicitly name alternatives or exclusion cases, but the operation and prerequisites are specific enough that an agent can correctly route to it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_delete_project_branchDelete Project BranchADestructive
Delete a branch from the repository hosting a project. The tool first reads project-aware branch metadata: a base branch is always rejected, and a protected branch requires force=true plus confirmForce=true (and eligible Studio permissions). It then performs a safe-delete preflight against the repository base branch when the target is the project's current branch. A branch with commits absent from base, unsaved changes, or no authoritative divergence check is rejected unless confirmDataLoss=true explicitly acknowledges the reported risk. confirmBranchName must exactly equal branch. If the project is open on the deleted branch, Studio closes it first. Branch names containing '/' are supported.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | Bypass protected-branch restrictions for eligible managers. Default false. | |
| branch | Yes | Exact branch name from openl_list_project_branches(). The repository base branch cannot be deleted. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| confirmForce | No | Must be true when force=true, confirming the protected-branch bypass. | |
| confirmDataLoss | No | Explicitly allow deletion after the tool reports that the branch has commits absent from the base branch, has unsaved working-copy changes, or its divergence from base cannot be verified (for example, the base is unknown, the merge check fails or checks different branches, or the target is not current). Omit for the initial safe-delete attempt. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
| confirmBranchName | Yes | Required safety confirmation; must exactly equal branch. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint and openWorldHint, and the description goes well beyond them by disclosing the internal preflight, the exact confirmation gates, the side effect of closing the project if open, and support for slash-containing branch names. No hidden destructive behavior is omitted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but each sentence covers a distinct, necessary fact for safely invoking a destructive operation. The purpose is front-loaded, and the safety conditions are ordered logically from metadata check to preflight to confirmations and side effects.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive seven-parameter tool with no output schema, the description thoroughly covers preconditions, guards, confirmations, and side effects. The only minor gap is that it does not describe what payload or status the tool returns after deletion, which would be useful since no output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds relational meaning: force and confirmForce must appear together for protected branches, confirmBranchName must equal branch exactly, and confirmDataLoss acknowledges a reported risk. These relationships are not all explicit in the individual schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a clear verb and resource ('Delete a branch from the repository hosting a project') and the rest of the description disambiguates this from create/list branch operations by detailing deletion-specific protections. It is unambiguous and distinct from sibling branch tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when deletion is permitted: base branches are always rejected, protected branches require force plus confirmForce, and unsafe data-loss cases require confirmDataLoss. It does not explicitly name alternative tools, but there is no dedicated alternative deletion sibling, and the conditions effectively state when-not.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_delete_project_fileDelete Project FileADestructive
Delete a file or folder from a project by its project-relative path. Maps to DELETE /projects/{projectId}/files/{path}. The backend auto-cleans dangling references to the deleted resource from the project configuration. Like writes, the deletion is staged in the working copy — commit it with openl_save_project. Use 'branch' to pin the project's branch (omit for local/non-branch repositories). Use this to remove legacy assets or deprecate docs. This is a destructive operation.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Project-relative path to the resource (e.g. 'rules/Model.xlsx'). Do NOT include the project name itself; paths are relative to the project root. A trailing slash denotes a folder. | |
| branch | No | Branch the project must be on for this operation. Ignored when blank. Fails if the repository has no branches or the project is on another branch. Omit for repository 'local' and non-branch repositories. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint annotation, the description discloses that deletion is staged in the working copy, requires a follow-up commit via openl_save_project, and that dangling references are auto-cleaned. These behavioral details are valuable and not present in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each earning its place: purpose, REST mapping, staging/commit behavior, branch guidance, and destructive warning. Information is front-loaded with the core action first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the essential deletion semantics, staging, branch handling, and destructive nature. No output schema exists, but the main return-format options are fully specified in the parameter schema. Minor omission: no explicit note about what happens to open file handles or if deletion fails on non-empty folders, but the description is otherwise sufficient for safe invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and each parameter is already well-documented (e.g., path relative to project root, branch constraints, response_format enum). The tool description adds little beyond the schema, which is acceptable per the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb + resource ('Delete a file or folder from a project by its project-relative path') and maps to a specific REST endpoint. This clearly distinguishes the tool from siblings like openl_write_project_file, openl_move_project_file, and openl_copy_project_file.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit context: use for removing legacy assets or deprecating docs, pin branch via 'branch', and commit staged deletion with openl_save_project. Does not name alternative tools explicitly, but the workflow context is clear enough for an agent to select correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_delete_tableDelete TableADestructive
Delete an ENTIRE table from a project. The whole table area is cleared from the sheet regardless of table type, so the table no longer exists once the project is recompiled. To remove only a row or column WITHIN a table, use openl_delete_table_rows / openl_delete_table_columns instead. If the given id went stale through an edit made via this server, it is resolved to the current id automatically. The studio does not auto-compile after the delete — run openl_project_status afterward to confirm the project still compiles (a dangling reference to the deleted table surfaces there).
| Name | Required | Description | Default |
|---|---|---|---|
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark destructiveHint and openWorldHint, so the description carries the burden of explaining consequences. It goes well beyond that: the entire table is cleared regardless of type, the table no longer exists after recompile, stale ids are auto-resolved, and no auto-compile occurs afterward—so the agent knows to check project status. This richly complements the annotations and does not contradict them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each earning its place. The primary action and scope are front-loaded, the alternative tool routing comes second, and the two behavioral caveats (stale-id resolution and no auto-compile) are compact and specific. No filler or repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive table-level operation with no output schema, the description explains the effect, the alternatives, the stale-id behavior, and the recommended follow-up project-status check. The only minor gap is that it does not describe what the tool's response itself will look like or explicitly warn about irreversibility—though destructiveHint covers the latter implicitly. Overall, very complete for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema coverage is 100%, and the schema already provides detailed parameter descriptions, especially for tableId and projectId. The description adds one meaningful behavioral detail beyond the schema: stale ids are resolved automatically. This is helpful context for tableId semantics, though not strictly required given the schema's richness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Delete an ENTIRE table from a project.' It clearly defines the scope ('whole table area is cleared... regardless of table type') and distinguishes itself from openl_delete_table_rows / openl_delete_table_columns, making the tool's unique purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to use this tool versus the row/column deletion siblings, naming the alternatives and the condition ('To remove only a row or column WITHIN a table'). It also provides post-action guidance: run openl_project_status afterward to confirm compilation and check for dangling references. This is actionable routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_delete_table_columnsDelete Table Columns (raw)ADestructive
Delete ONE OR MORE columns starting at 'position' (1..width-1) from a table's raw source, shifting the columns to the right left. 'count' defaults to 1. The leading-label column (0) cannot be deleted. Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of columns to delete starting at 'position' (default 1). | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| position | Yes | 0-based index of the first column to delete (1..width-1). The leading-label column (0) cannot be deleted. Columns to the right of the deleted block shift left. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the destructiveHint annotation by explaining the actual destructive behavior (shifting columns, leading-label protection), the possibility of id changes, the response always returning the current tableId, and the recompile side effect. This is rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries necessary information, and the core operation is front-loaded in the first clause. The description is long, but the complexity of the tool (id volatility, raw-source semantics, recompile behavior) justifies the length. Some sentences are dense and could be split, but nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive mutation tool with no output schema, the description covers the essential context: what gets deleted, what cannot be deleted, how positions work, how ids may change, what the response contains, and a caveat about compilation. An agent has enough to call this tool correctly and handle side effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful semantic context beyond the schema: 0-based indexing clarifies the header row, column 0 as leading labels, and the default count of 1. It reinforces and slightly extends the schema explanations without redundancy.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'delete' and resource 'columns from a table's raw source', specifying position-based deletion and the shifting behavior. It also clarifies the leading-label column cannot be deleted, unambiguously distinguishing it from other table mutation tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context is clearly defined: it operates on the RAW source, works for any table type, and explains the exact positional semantics. It doesn't explicitly name sibling alternatives or say when not to use this tool, but the 'raw source' framing and row/column behavior give sufficient guidance for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_delete_table_rowsDelete Table Rows (raw)ADestructive
Delete ONE OR MORE rows starting at 'position' (1..height-1) from a table's raw source, shifting the rows below up. 'count' defaults to 1. The header row (0) cannot be deleted. Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of rows to delete starting at 'position' (default 1). | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| position | Yes | 0-based index of the first body row to delete (1..height-1). The header row (0) cannot be deleted. Rows below the deleted block shift up. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive and open-world behavior, but the description goes much further: it explains row shifting, the protected header, table relocation causing tableId changes, the response returning the current tableId and previousTableId, and the recompile side effect. These are critical behavioral details beyond what the annotations or schema provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is relatively long but dense with necessary caveats: id volatility, recompile behavior, and response semantics. It is front-loaded with the core delete behavior and each sentence adds operational value, though a few details repeat what is already in the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema, the description appropriately explains the key response detail, the current tableId and previousTableId, and it warns about the table's id changing. It covers destructive behavior, positional constraints, and the recompile side effect well, though it does not describe error cases or the full response shape.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 even without extra parameter detail. The description reinforces the default count and the meaning of position, but most parameter semantics are already fully documented in the input schema; the main added value is clarifying that the returned tableId may change after relocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the operation: deleting one or more rows from a table's raw source, starting at a given position, with rows below shifting up. It also clarifies scope limits such as the header row being undeletable and positions being 0-based, making it easy to distinguish from sibling tools like openl_delete_table_columns or openl_update_table_row.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives useful context by noting that this operates on the RAW source and works for any table type, which implies broad applicability. However, it does not explicitly mention sibling alternatives or state when not to use this tool, such as when deleting columns or the whole table instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_deploy_projectDeploy Project to ProductionA
Deploy a project to production environment. Publishes rules to a deployment repository for runtime execution. Use production repository name (not ID) - e.g., 'Production Deployment' instead of 'production-deploy'.
| Name | Required | Description | Default |
|---|---|---|---|
| comment | No | Deployment reason comment (e.g., 'Deploy version 1.2.0', 'Production release') | |
| projectId | Yes | Project ID to deploy. Use the exact 'projectId' value from openl_list_projects() response. | |
| deploymentName | Yes | Name for the deployment (e.g., 'InsuranceRules', 'AutoPremium'). This will be the deployment identifier. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
| productionRepositoryId | Yes | Target production repository name (display name, not ID). Use the 'name' field from openl_list_deploy_repositories() response (e.g., if list_deploy_repositories returns {id: 'production-deploy', name: 'Production Deployment'}, use 'Production Deployment' here, NOT 'production-deploy'). Must be configured in OpenL Studio. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The openWorldHint annotation is present, and the description adds meaningful context beyond it by disclosing the real-world consequence: rules are published to a deployment repository for runtime execution, meaning the deployment affects production behavior. This is exactly the kind of side-effect disclosure that helps an agent. It stops short of 5 because it doesn't address whether an existing deployment is overwritten or whether this action is reversible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: the core action, the behavioral consequence, and the critical name-vs-ID gotcha with a concrete example. No filler, no repetition of schema-level defaults.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a production-deployment tool with openWorldHint and no output schema, the description covers the core semantics well but leaves gaps: no mention of what the response contains, no guidance on when to choose openl_redeploy_project over this tool, and no indication of whether deploying over an existing deployment is allowed. The params are well-documented in the schema, which carries some weight here, but the deploy-vs-redeploy decision is an important missing piece.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline of 3 applies — every parameter already carries a rich description, including the exact source of projectId and the name-vs-ID rule for productionRepositoryId. The description's repository-name warning repeats what the schema already documents, adding no net new meaning for parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Deploy'), resource ('a project'), and target ('production environment'), and adds what the operation actually accomplishes ('Publishes rules to a deployment repository for runtime execution'). It is clearly distinguishable from most siblings, but it does not explicitly differentiate itself from the closely related openl_redeploy_project, so it misses the top score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The core usage context is implied clearly: use this when deploying a project to production and publishing its rules for runtime execution. However, no alternatives or exclusions are named — notably there is no 'use openl_redeploy_project for existing deployments' guidance, which an agent would need given that sibling exists. The practical 'use repository name, not ID' advice is helpful but is a parameter-format rule, not a tool-selection rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_expand_trace_treeExpand Call-Tree NodeARead-onlyIdempotent
Load one level of a profiling run's executed call tree on demand. The tree is lazy: the /stack tree root (a profiling openl_start_trace / openl_resume_trace with includeTree: true) and every node returned here are ONE level deep — each step carries a childrenTotal count instead of nested children. Expand a step whose childrenTotal > 0 by naming its node (uri + instance) and the step's ref; the reply is a TreeChildrenView { children, total } where each child is itself shallow (its own steps' childrenTotal), expanded by calling this tool again. Page a loop's many sub-calls with offset/limit (default 100): when total > offset + children.length the reply sets hasMore: true and nextOffset — call again with that offset to get the next page. A returned node may also carry notRetained — sub-calls that ran but were dropped once the retained tree hit its size limit (report as '+N not retained'). Requires a profiling run (profiling: true retains the tree). To find what's slow use the constant-size profile overview instead; use this to walk one branch's call structure. Valid while the debug session is alive (including after the run completes).
| Name | Required | Description | Default |
|---|---|---|---|
| uri | Yes | Source URI of the node whose step to expand: the root node's `uri` from the /stack `tree` (a profiling openl_start_trace / openl_resume_trace with includeTree: true), or a child node's `uri` from an earlier openl_expand_trace_tree page. | |
| step | Yes | Reference of the step within that node to expand, e.g. 'R1C0' — a step whose `childrenTotal` > 0 (a step with childrenTotal 0 or absent made no sub-calls). | |
| limit | No | How many sub-calls to return per page (backend default 100). Keep it modest — a page of many wide nodes can still be large. | |
| offset | No | Index of the first sub-call to return, for paging a loop's thousands of children (default 0). When the response's total exceeds offset + returned children, call again with offset advanced by the returned count (the reply's nextOffset). | |
| instance | Yes | Zero-based execution index of that node in the run (its `instance`; 0 for the root) — picks the exact loop iteration when the table ran more than once. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnly, idempotent, and openWorld hints, so the safety profile is covered. The description adds substantial behavioral detail beyond those hints: the lazy one-level expansion model, `childrenTotal` instead of nested children, paging via `hasMore`/`nextOffset`, `notRetained` dropped sub-calls, the profiling prerequisite, and validity after the run completes. No statement contradicts the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place: it covers purpose, prerequisites, pagination, special cases like `notRetained`, and the alternative tool. It is front-loaded with the core action, then unfolds the lazy-tree model and paging details in a logical order. Given the tool's complexity and the absence of an output schema, the density is appropriate rather than bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema present, the description carries the full burden of explaining the return shape, and it does: the reply is a TreeChildrenView { children, total }, with `hasMore` and `nextOffset` for paging, and possible `notRetained` counts. It also covers lifecycle constraints (profiling run required, valid while the debug session is alive) and how to start from the /stack `tree` root. Nothing needed for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds meaning the schema alone does not fully convey. It explains that `step` must reference a node with `childrenTotal > 0`, that `offset`/`limit` page a loop's many sub-calls with `nextOffset`, and that `instance` picks the exact loop iteration. This transforms the parameters from raw JSON fields into a coherent iteration contract.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Load one level of a profiling run's executed call tree on demand.' It also distinguishes itself from sibling tools by naming the lazy-tree mechanism, the /stack `tree` root, and the alternative 'constant-size `profile` overview' for finding slow spots. This makes it unmistakable which operation this tool performs and how it differs from nearby tracing tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool: only for a profiling run with `includeTree: true`, and only for expanding nodes whose `childrenTotal` is greater than 0. It also gives a clear when-not-to-use directive: 'To find what's slow use the constant-size `profile` overview instead; use this to walk one branch's call structure.' This is explicit routing with no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_guidesGet GuidesARead-onlyIdempotent
Return the FULL markdown bodies of 1-5 bundled documents by the exact ids from openl_list_guides (e.g. 'spec/rules.xml', 'guide/introduction/basic-concepts'). Unknown ids fail with an error naming them — this tool never falls back to the index; look ids up with openl_list_guides first. Bodies are returned verbatim and are NOT truncated, so mind each entry's size_bytes from the index and request only what you need. Read-only, local — never calls OpenL Studio.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | 1-5 guide ids exactly as returned by openl_list_guides (e.g. 'spec/rules.xml', 'guide/introduction/basic-concepts'). Each entry's size_bytes is in the index — fetch only what you need. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. Description adds key behaviors: never calls OpenL Studio (local), returns verbatim without truncation, fails with error naming unknown ids. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is three concise sentences, each adding essential information. Front-loaded with the main action, no redundant words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description fully compensates by stating return format (full markdown), truncation behavior (none), error handling (fails for unknown ids), and prerequisite (use list_guides). Complete for a retrieval tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema description already explains the parameter semantics. The description reinforces the size_bytes note and adds context about error behavior for invalid ids, providing additional value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns full markdown bodies of bundled documents by exact ids, distinguishing it from sibling openl_list_guides which lists guide metadata. It specifies the action (return bodies), the resource (guides by id), and scope (full, verbatim).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to look up ids with openl_list_guides first, warns about unknown ids failing, advises to mind size_bytes and fetch only what is needed. This provides clear when-to-use and prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_merge_conflictsGet Merge ConflictsARead-onlyIdempotent
Get the pending merge conflicts stored in this Studio HTTP session: grouped file paths, BASE/OURS/THEIRS revision details, and the default merge commit message. This is read-only evidence for a user who will resolve the conflict manually in Studio; the MCP server intentionally does not expose conflict resolution. Available only after openl_merge_project_branches returns status='conflicts'; use the same MCP server instance throughout inspection.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even with rich annotations (readOnlyHint, openWorldHint, idempotentHint), the description adds significant behavioral context: the conflicts are session-bound, the tool only works after a specific merge status, the same MCP server instance must be reused, and resolution is intentionally not exposed. These details go well beyond the structured annotations and inform safe invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with no filler. The first sentence front-loads the tool's purpose and output contents, the second establishes read-only intent and limits, and the third provides the required precondition and session-consistency warning. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low complexity (two parameters, no output schema), the description is complete: it summarizes the return contents, states the precondition, discloses the session-bound behavior, and explains the tool's role in the manual resolution workflow. An agent has enough context to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, so the schema already fully documents projectId and response_format with helpful guidance. The tool description adds no additional parameter-level meaning beyond referring to the overall session context, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get the pending merge conflicts stored in this Studio HTTP session,' and enumerates the exact contents returned (grouped file paths, BASE/OURS/THEIRS revision details, default merge commit message). It also distinguishes this from conflict resolution tools by stating the MCP server intentionally does not expose conflict resolution, making the tool's scope unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit precondition—'Available only after openl_merge_project_branches returns status='conflicts''—and provides an important session-scoped instruction to use the same MCP server instance. It also clarifies the tool is read-only evidence for manual resolution, which implies when not to use it, but it does not name alternative sibling tools such as openl_cancel_merge_conflicts or openl_read_merge_conflict_file.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_projectGet Project DetailsBRead-onlyIdempotent
Get comprehensive project information including details, modules, dependencies, and metadata. Returns full project structure, configuration, and status.
| Name | Required | Description | Default |
|---|---|---|---|
| include | No | Optional response expansions from the Studio API. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the description's main job is to add context beyond safety. It does add return-content context ('full project structure, configuration, and status') but does not explain how the 'include' expansions modify the response or what 'deleted' or 'descriptor' mean. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core action and scope. There is minor redundancy between 'comprehensive project information' and 'full project structure,' and 'status' appears only in the second sentence, but overall the text is efficient and not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Basic invocation is clear: projectId is required and response_format is documented. However, with no output schema, the description does not adequately explain how the include options affect the returned data, nor does it clarify the difference between json and markdown outputs beyond what the schema already says. Given the large sibling set, some routing ambiguity remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already provides strong descriptions for projectId and response_format, plus the enum for include. The description adds only generic references to modules and dependencies, which are not clearly mapped to specific parameters or include values. The baseline of 3 applies because the schema carries the parameter documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('Get comprehensive project information') and identifies the broad scope: details, modules, dependencies, metadata, structure, configuration, and status. It does not explicitly distinguish itself from related siblings such as openl_project_status or openl_list_project_modules, so it is clear but not fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool instead of alternatives. It does not mention that openl_list_projects supplies the projectId, nor does it note that openl_project_status or openl_list_project_modules might be more targeted for narrower needs. An agent is left to infer usage from the generic 'get comprehensive project information' phrasing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_project_agent_contextGet Project Agent ContextARead-onlyIdempotent
Resolve the agent guidance (AGENTS.md hierarchy) that applies to a project — call this BEFORE working on or creating anything in the project. Starting at the project directory — or the optional 'folder' sub-directory — this walks UP through every parent folder to the repository root, collects every AGENTS.md found, and returns them concatenated in ONE markdown document ordered from the root folder (lowest priority) down to the project folder (highest priority); on conflicting instructions, each later section overrides the earlier ones. AGENTS.md files live not only in the project but often in a workspace/monorepo root above it. Levels with no AGENTS.md are skipped (not an error); a project with none returns a short 'no files' note. When the guidance references bundled reference guides by id, those ids are listed at the end — fetch them with openl_get_guides. The search direction is fixed — to search a project's own subtree by glob/content instead, use openl_search_project_files.
| Name | Required | Description | Default |
|---|---|---|---|
| branch | No | Branch the project must be on for this operation. Ignored when blank. Fails if the repository has no branches or the project is on another branch. Omit for repository 'local' and non-branch repositories. | |
| folder | No | Optional project-relative sub-folder to start the walk-up from, e.g. 'rules' or 'rules/pricing'. Use this to get the AGENTS.md chain that applies to a file deeper inside the project ('the AGENTS.md nearest the edited file wins'). Omit to start at the project root. Do NOT include the project name; the path is relative to the project root. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnly, openWorld, idempotent), the description details the upward traversal, concatenation order, skipping of missing levels, and listing of reference guide ids. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence adds necessary information; front-loaded with primary use. No wasted words despite length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without an output schema, the description fully explains the return value (concatenated markdown or 'no files' note) and mentions related guide retrieval. Complete for a read-only retrieval tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the description adds value by explaining the 'folder' parameter's use for deeper file context and reminding to use exact 'projectId' from list. Slightly above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the purpose: resolving agent guidance (AGENTS.md hierarchy) for a project. It distinguishes itself from the sibling 'openl_search_project_files' by noting that for file-level search, use that instead.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'call this BEFORE working on or creating anything in the project', providing clear context for when to use. Also mentions alternative for subtree search, aiding decision.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_startedGet StartedARead-onlyIdempotent
Read-only. Call this FIRST, once per session, before any other openl_ tool. Returns the mandatory workflow protocol and a workspace orientation: when to call openl_get_project_agent_context (before working on or creating any project), how to discover the bundled OpenL reference documentation (openl_list_guides / openl_get_guides), and the edit → validate → save loop. Takes no arguments and never calls OpenL Studio.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, idempotentHint, and openWorldHint. The description adds value by stating 'Takes no arguments and never calls OpenL Studio,' which goes beyond the annotations and provides further behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, consisting of three sentences with no wasted words. It is front-loaded with key information: 'Read-only. Call this FIRST,' and each sentence contributes meaningfully.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters and no output schema, the description covers the essential context: what it returns, order of use, and that it never calls OpenL Studio. It is sufficiently complete for a simple initialization tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters and schema coverage is 100%. With no parameters, the description doesn't need to add parameter information, and the baseline of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: it returns the mandatory workflow protocol and workspace orientation. It explicitly says to call this first before any other openl_ tool, distinguishing it from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidelines: 'Call this FIRST, once per session, before any other openl_ tool.' It also explains when to call openl_get_project_agent_context and mentions related documentation tools, offering clear context without explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_tableGet Table Structure & DataARead-onlyIdempotent
Get a table as its authoritative RawSource 2D cell matrix. Typed/parsed table views are intentionally unsupported because they are incomplete and cannot safely round-trip workbook content. startRow/maxRows read a large table in row slices (a windowed response carries totalRows), and styles=true adds each cell's Excel style. A window cannot replace the whole table: openl_update_table rejects totalRows and independently refuses a source with fewer rows than the live table, so removing the marker cannot erase omitted rows. For a large table whose complete response becomes a preview, use the narrow raw table action tools instead. A table id changes when an edit relocates the table; stale ids produced by this server are resolved automatically, otherwise refresh ids with openl_list_tables().
| Name | Required | Description | Default |
|---|---|---|---|
| styles | No | If true, each raw cell carries its Excel style (background/font colour, bold/italic/underline, alignment, indent, borders). | |
| maxRows | No | Maximum number of source rows, counted from startRow; omit to read to the end. A windowed response carries totalRows. | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| startRow | No | Zero-based index of the first source row; omit to start at the top. Combine with maxRows to read a large table in slices. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even with readOnly/idempotent/openWorld annotations, the description adds substantial behavioral detail: RawSource is authoritative, typed/parsed views are intentionally unsupported for round-trip safety, windowed responses carry totalRows, and stale table IDs are auto-resolved. It also explains why a window cannot erase omitted rows, which is valuable safety context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but front-loaded with the core purpose and every sentence earns its place: caveats about typed views, slicing, window safety, alternative tools, and ID volatility. It is dense rather than bloated, though a slightly more compact treatment of the window-safety warning would improve it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter read tool with no output schema, the description covers return mode, row-slicing behavior, style enrichment, window limitations, and ID handling. It could say a bit more about the shape of the returned RawSource cell matrix, but the guidance is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema by explaining how startRow/maxRows combine to slice a table, what styles=true produces, and why tableId is volatile. The projectId and response_format parameters remain covered by the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific action and resource: 'Get a table as its authoritative RawSource 2D cell matrix.' It also distinguishes itself from typed/parsed views and from the narrow raw table tools, so an agent can tell what mode this getter operates in.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: use slicing with startRow/maxRows for large tables, and choose the narrow raw table action tools when a complete response would become a preview. It is slightly vague because 'narrow raw table action tools' is not explicitly enumerated, but the routing intent is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_table_dependenciesGet Table DependenciesARead-onlyIdempotent
Get the table dependency graph as an adjacency list. Omit tableId for the whole project graph, optionally restricted by module and layer (executable, datatype, or all); provide tableId for its dependency/dependent neighborhood with optional direction and depth. Executable nodes include signatures, return types, and dimension properties; datatype nodes include inheritance and declared field references; vocabulary nodes include their value type, total value count, and a bounded first/last values preview. Dispatchers represent versioned executable tables, self-loops represent recursion or self-reference, and cycles are derived from dependency edges. JSON preserves the graph nodes directly. Markdown renders executable calls as a Mermaid flowchart and the data model, including declared fields, vocabulary value previews, and reference cardinalities, as a Mermaid ER diagram; vocabulary headers use Name, preview rows leave the redundant type column visually empty, and a + N more marker identifies a truncated middle. Inheritance is shown separately when present. Detailed Markdown adds per-node metadata, while concise Markdown stays textual.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | When tableId is provided, maximum traversal depth from that table. | |
| layer | No | When tableId is omitted, return executable tables, datatype/vocabulary nodes, or both (backend default all). | |
| module | No | When tableId is omitted, limit the project graph to this module. Discover names with openl_list_project_modules(). | |
| tableId | No | Optional table whose dependency neighborhood to return. Omit to return the whole project (or module) graph. | |
| direction | No | When tableId is provided, relations to traverse (backend default BOTH). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, and the description adds substantial behavioral detail: what executable, datatype, and vocabulary nodes contain; how dispatchers, self-loops, cycles, and inheritance are represented; how truncation and previews appear; and how JSON vs Markdown variants render. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but densely informative, moving from core behavior to mode selection to output rendering. Every sentence adds distinct value, including the Mermaid rendering details that matter for choosing response_format. There is no tautology or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, the description covers the response semantics surprisingly well: it defines the adjacency-list graph, the node types, the meaning of dispatchers, self-loops, and cycles, and the differences between JSON and the Markdown variants. Required projectId and parameter constraints are already covered by the schema, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is a 3. The description adds conditional meaning beyond the schema, such as 'omit tableId for the whole project graph' vs 'provide tableId for its dependency/dependent neighborhood,' and explains how response_format affects the output. It does not independently document every parameter, but it meaningfully supplements the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get the table dependency graph as an adjacency list.' It then clearly distinguishes the two main call modes: whole project/module graph when tableId is omitted, and dependency/dependent neighborhood when tableId is provided. This makes the tool's purpose immediately distinguishable from sibling table tools like openl_get_table or openl_list_tables.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains when to omit or provide tableId, when to use direction and depth, and how module and layer restrict the graph. It even points to openl_list_project_modules() for discovering module names. It stops short of explicitly naming sibling tools to avoid or saying 'use this instead of X,' so it is just below a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_test_resultsGet Full Test ResultsA
Get full test execution results with pagination support. Returns complete test execution summary including testCases array grouped by table. IMPORTANT: Pagination applies to test tables (not individual test cases). Each page returns test results aggregated by table (e.g., 'TestTable1' with 7 tests, 'TestTable2' with 8 tests). Supports filtering failures and pagination (page/offset/size). Use openl_start_project_tests() first to start test execution.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (0-based). Mutually exclusive with offset | |
| size | No | Page size (number of results per page, maximum 200) | |
| limit | No | Page size (alias for size, maps to size parameter) | |
| offset | No | Offset for pagination. Mutually exclusive with page | |
| unpaged | No | Return all results without pagination. Mutually exclusive with page, offset, size, and limit | |
| failures | No | Number of failed test units to include in the summary (default: 5, min: 1) | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| failuresOnly | No | Show only failed tests (default: false) | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only openWorldHint=true in annotations, the description carries the disclosure burden and delivers: it flags the non-obvious gotcha that 'Pagination applies to test tables (not individual test cases)' with concrete examples, explains aggregation by table, and reveals the sequencing dependency on openl_start_project_tests. This is exactly the kind of behavioral context that prevents a wrong call, and it contradicts nothing in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences with the high-value information front-loaded: purpose first, then the pagination gotcha, then the sequencing prerequisite. The example ('TestTable1' with 7 tests) earns its place, though 'Supports filtering failures and pagination (page/offset/size)' is mildly redundant with the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter tool with no output schema, the description compensates well by specifying the return structure, the pagination unit, and the required predecessor call. It leaves some edge behavior unaddressed (error behavior when no tests have run, unpaged behavior with huge result sets) and doesn't position itself against the two sibling test-result tools, but nothing critical is missing for making a correct call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description adds genuine value on top by explaining that page/offset/size operate on tables rather than individual test cases and that failures/failuresOnly filter at the aggregated level. The 'IMPORTANT' note reframes the pagination params in a way the individual param descriptions do not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Get full test execution results') and describes the return shape ('testCases array grouped by table'), which an agent can act on. It distinguishes from siblings like openl_get_test_results_summary largely through the word 'full' and the table-grouping detail, but it never names those siblings explicitly, so the differentiation is implicit rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context for when to call it: it is the full-results tool with table-level pagination, and it states the hard prerequisite 'Use openl_start_project_tests() first to start test execution.' It does not give when-not-to-use guidance or name alternatives such as openl_get_test_results_summary / openl_get_test_results_by_table, which is a mild gap given the sibling cluster.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_test_results_by_tableGet Test Results By TableB
Get test execution results filtered by specific table ID. Returns filtered test execution summary with only test cases for the specified table. Supports pagination (page/offset/size) for efficient data retrieval. Use openl_start_project_tests() first to start test execution.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (0-based). Mutually exclusive with offset | |
| size | No | Page size (number of results per page, maximum 200) | |
| limit | No | Page size (alias for size, maps to size parameter) | |
| offset | No | Offset for pagination. Mutually exclusive with page | |
| tableId | Yes | Table ID to filter test results for a specific table | |
| unpaged | No | Return all results without pagination. Mutually exclusive with page, offset, size, and limit | |
| failures | No | Number of failed test units to include in the summary (default: 5, min: 1) | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| failuresOnly | No | Show only failed tests (default: false) | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The only annotation is openWorldHint=true, which is weak — it does not declare read-only or destructive behavior, so the description carries most of the transparency burden. The description adds useful behavioral context (filtering to a single table's test cases, pagination support, and the prerequisite that test execution must already be started), but it leaves the safety profile implicit — read-only must be inferred from the verb 'get' — and says nothing about result volatility between calls or failure behavior. No contradiction with the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, all informative and front-loaded: purpose first, return scope second, pagination third, and the prerequisite last. The only minor waste is the overlap between sentence 1 ('filtered by specific table ID') and sentence 2 ('only test cases for the specified table'), and the pagination sentence partly duplicates schema content, but there is no fluff or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 10 parameters, no output schema, and only a weak openWorldHint annotation, the description covers the core workflow (filter by table, paginate, run tests first) and the rich schema covers parameter semantics. However, the agent is left without a picture of the return structure — 'test execution summary' is never concretely defined — and there is no guidance on polling/waiting for test completion or how this tool relates to the sibling summary tool. Adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: every parameter, including pagination mutual-exclusivity rules, defaults, limits, and the response_format enum, is documented in the schema itself. The description only echoes table filtering and pagination at a high level and adds no syntax or constraint information beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair: 'Get test execution results filtered by specific table ID,' and elaborates that it returns 'only test cases for the specified table,' which meaningfully scopes the operation. It is clear about what the tool does, but it never names sibling tools like openl_get_test_results or openl_get_test_results_summary, and its use of the word 'summary' creates a slight overlap with openl_get_test_results_summary, so differentiation relies mostly on the name and the table-ID qualifier.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives one explicit sequencing rule — 'Use openl_start_project_tests() first to start test execution' — which is genuinely useful for an agent planning a multi-step workflow. However, it provides no guidance on when to choose this tool over the near-siblings openl_get_test_results and openl_get_test_results_summary, and no conditions for when not to use it, so the selection among the three results tools is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_test_results_summaryGet Test Results SummaryA
Get brief test execution summary without detailed test cases. Returns aggregated statistics (execution time, total tests, passed, failed) without the testCases array. Use openl_start_project_tests() first to start test execution.
| Name | Required | Description | Default |
|---|---|---|---|
| unpaged | No | Return all results without pagination | |
| failures | No | Number of failed test units to include in the summary (default: 5, min: 1) | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| failuresOnly | No | Include only failed tests. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the key behavioral trait: it returns only aggregated statistics and deliberately omits the testCases array. It also surfaces the dependency on a prior test-start call. With only openWorldHint in annotations, this adds meaningful context beyond the structured data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. It front-loads the purpose and return content, then gives the essential prerequisite. It avoids repeating schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description covers the core return fields but leaves behavior for response_format variants, pagination, and failuresOnly implicit. It also does not state what happens if test execution has not been started, beyond the prerequisite instruction.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters including projectId, failures, failuresOnly, unpaged, and response_format. The description adds no parameter-level meaning beyond the schema, so it meets the baseline but does not go further.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action and resource: getting a brief summary of test execution, and explicitly notes that detailed testCases are excluded. It differentiates itself from the detailed test-results siblings by what it omits, though it does not name the specific sibling tool to use for detailed results.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides a clear, important prerequisite by instructing the agent to call openl_start_project_tests() first. However, it does not explicitly state when to choose this tool over openl_get_test_results or openl_get_test_results_by_table, leaving that differentiation implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_trace_valueExpand Lazy ValueARead-onlyIdempotent
Fetch the full value of a parameter that openl_inspect_trace_frame returned lazily (lazy: true with a parameterId). Valid while the debug session is alive. By default only name, description, and value are returned; withSchema: true adds the value's JSON Schema (large — request it only when the type structure itself matters).
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| withSchema | No | Also return the value's JSON Schema (default false — the schema is large and rarely needed; the value itself already shows the structure). | |
| parameterId | Yes | Parameter ID from a lazy ParameterValue (lazy: true) returned by openl_inspect_trace_frame. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld, and idempotent behavior, so the description does not need to restate those. It adds valuable behavioral context beyond annotations: the operation is only valid while the debug session lives, and the default response contains only name/description/value while withSchema adds a potentially large JSON Schema. This gives the agent clear expectations about side effects and response scope.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly written sentences. The core purpose is front-loaded, the session-validity caveat is immediately relevant, and the withSchema warning earns its place without padding. No redundant restatement of already-schema-covered parameter details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, idempotent fetch tool with no output schema, the description adequately explains what is returned by default, what the optional schema adds, and the liveness constraint tied to the debug session. It could go further by mentioning that a stale parameterId might fail or become invalid after the session ends, but overall it gives enough context for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, and the description adds meaning on top of that by explaining where parameterId comes from (a lazy ParameterValue from openl_inspect_trace_frame) and clarifying why withSchema should be used sparingly. This bridges the schema to the tool's workflow context, which is genuinely useful.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fetch'), a specific resource ('full value of a parameter returned lazily'), and the exact condition that triggers its use (lazy: true with a parameterId). The title 'Expand Lazy Value' is reinforced and the tool is clearly distinguished from openl_inspect_trace_frame, which produces the lazy reference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is explicit: use this tool when openl_inspect_trace_frame returned a parameter with lazy: true, and only while the debug session remains alive. It also gives guidance on when to avoid withSchema due to its size. Slightly less than a 5 because it does not explicitly name alternative tools or say when not to use the tool, but the guidance is strong enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_get_versionGet Server Version and Build InfoARead-onlyIdempotent
Report this MCP server's own version and build identity for diagnostics and bug reports: the package version, the build id (version plus the short commit it was built from, suffixed '.dirty' for a modified working tree), the full commit and its date, the branch or tag, the build timestamp, and the Node.js/platform/architecture it runs on. Quote 'build.id' when reporting a problem — nightly builds between two releases share the same version and are otherwise indistinguishable. Needs no OpenL Studio connection and returns no configuration, credentials, or URLs. A build.source of 'unavailable' means this install shipped without build metadata, so only the version is known.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description builds on them with substantial added context: it discloses that no connection is required, explicitly states it returns no configuration, credentials, or URLs (security-relevant), explains the build.id format and '.dirty' suffix, and interprets the 'unavailable' build.source edge case. This goes well beyond the annotation baseline.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences and roughly 115 words — near the upper limit, but every sentence earns its place: field enumeration, a practical reporting tip (quote build.id), a security-relevant exclusion, and an edge-case interpretation. The purpose is front-loaded in the first clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero required parameters and no output schema, the description must carry the return-value documentation, and it does: it enumerates all fields, explains the build.id disambiguation convention for nightly builds, covers the missing-metadata case, and confirms the tool's connectivity and data-safety profile. Nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — the single response_format parameter has a full enum and per-value explanations. The description doesn't need to add parameter detail, and the baseline 3 applies because the schema fully carries that burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Report this MCP server's own version and build identity for diagnostics and bug reports.' It enumerates the exact fields returned, and no sibling tool overlaps with version reporting, so an agent can distinguish it immediately from the 80+ operational tools in the sibling list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use it ('for diagnostics and bug reports') and gives a condition that makes it uniquely available ('Needs no OpenL Studio connection'). It does not name alternatives or exclusions, but none are needed since no sibling performs version reporting.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_insert_table_columnsInsert Table Columns (raw)A
Insert ONE OR MORE columns at 'position' in a table's raw source, shifting the columns at and to the right of it. 'position' is 1..width (width appends to the end). 'cells' is a 2D array (columns × that column's cells). Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| cells | Yes | Columns left to right, each a non-empty list of cells top to bottom (one cell per row; use { value: null } for a blank cell). Pass one column to add/insert a single column, several for a block. Each column as tall as the table. | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| position | Yes | 0-based index the first new column will occupy (1..width; width appends to the end). Columns at and to the right of it shift right. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only openWorldHint in annotations, the description carries the full burden and exceeds it: it discloses column shifting, table relocation altering the location-derived id, the response returning current tableId plus previousTableId, and the absence of auto-compile with the read-back recompile trigger. No contradiction with the openWorldHint annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core operation, and every sentence earns its place: position semantics, cell array shape, raw-source guarantee, id volatility, and the recompile quirk. It is dense rather than brief, but the length is justified given the surprising id-relocation and compile behaviors an agent must know.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter mutation tool with no output schema and only an openWorldHint annotation, the description is remarkably complete: it covers operation semantics, coordinate conventions, cell structure, the id-change failure mode, response fields, and post-edit recompile behavior — everything needed to invoke it correctly and chain subsequent calls.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description adds genuine value beyond the schema by clarifying the coordinate system ('row 0 is the header row, column 0 carries the leading labels' — so position 1 is the first data column), the cells dimensionality ('columns × that column's cells'), and instructing agents to use the returned tableId for subsequent calls.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Insert ONE OR MORE columns at position in a table's raw source, shifting the columns at and to the right of it' — with the key scope qualifier 'Operates on the table's RAW source, so it works for any table type.' This clearly separates it from siblings like openl_append_table_columns (append) and openl_insert_table_rows (rows).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear usage context: it operates on the raw source and works for any table type, and the position range '1..width (width appends to the end)' implicitly covers the insert-vs-append decision. However, it never names an alternative sibling explicitly nor states when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_insert_table_rowsInsert Table Rows (raw)A
Insert ONE OR MORE rows at 'position' in a table's raw source, shifting the rows at and below it down. 'position' is 1..height (height appends to the end). 'cells' is a 2D array (rows × that row's cells). Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| cells | Yes | Rows top to bottom, each a non-empty list of cells left to right (one cell per column; use { value: null } for a blank cell). Pass one row to add/insert a single row, several for a block. Each row as wide as the table. | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| position | Yes | 0-based index the first new row will occupy (1..height; height appends to the end). Rows at and below it shift down. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the openWorldHint annotation. It discloses that location-derived tableId can change when the table is relocated, that the response returns the current tableId and previousTableId when changed, and that the tool reads the table back to trigger recompilation. This is exactly the kind of operational behavior an agent needs to know and is not visible from the schema or annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place. It front-loads the core operation, then covers positional edge cases, the critical id-volatility behavior, and the recompilation side effect. There is no redundant fluff or repetition of schema details that were already explained.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the absence of an output schema, the description is remarkably complete. It explains the insertion position semantics, the raw-source behavior, the volatile tableId and how to obtain the current one, the previousTableId field, and the recompilation trigger. An agent has enough context to call it correctly and interpret the critical parts of the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameters are already documented. The description adds valuable semantics beyond the schema: it explains that 'cells' is a 2D array with rows and per-row cells, clarifies 0-based positioning with row 0 as header and column 0 as leading labels, and warns that tableId is volatile. It does not add much about response_format, but the schema already documents that fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Insert ONE OR MORE rows at position in a table's raw source'. It clearly distinguishes this row-insertion tool from sibling operations like openl_insert_table_columns and openl_append_table_rows by emphasizing position-based insertion, RAW source, and row-shifting behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: it works on the RAW source, works for any table type, and positions range from 1..height where height appends to the end. It does not explicitly name alternatives or state when-not-to-use scenarios, but the positional and raw-source details give an agent enough context to select it appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_inspect_trace_frameInspect Stack FrameARead-only
Freeze and read the full state of one suspended stack frame: input parameters, runtime context, result (for a completed frame), sub-steps with computed values, and for a decision table the killer feature — 'decision' (which rule fired and how each condition evaluated per rule) plus 'ruleNames' (all rules, for per-rule breakpoints). Values may come lazy (lazy: true + parameterId) — expand with openl_get_trace_value. By default the response is trimmed (no value JSON schemas); full: true lifts the trim. To surface an anomaly among many neutral factors, filter the steps: onlyExecutedSteps drops not-yet-computed ones, and excludeStepValues drops steps whose value is a neutral constant (e.g. [1] in rating) — lazy step values are resolved before the comparison, so a neutral factor that came lazy is dropped too. withHighlights: true additionally returns the A1-keyed cell highlight overlay and the raw table grid to merge it with. Valid only while suspended (a terminal session answers 409 — read its final state from the last returned stack).
| Name | Required | Description | Default |
|---|---|---|---|
| full | No | Return the complete untrimmed response, including value JSON schemas (default false — trimmed via ?fields to save tokens). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| frameIndex | Yes | Stack frame index from the frames[] of the last stack response (0 = root, highest = current). | |
| withHighlights | No | Also return the frame's cell-highlight overlay (A1-keyed) plus the raw table grid to merge it with (default false). | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
| excludeStepValues | No | Drop executed steps whose scalar value equals one of these — to hide neutral factors and surface the outlier (e.g. [1] in rating, where a factor of 1.0 means 'no effect'). Lazy step values are resolved before the comparison, so a neutral factor that came lazy is dropped too. Do not use for tables where those values are meaningful. | |
| onlyExecutedSteps | No | Keep only executed steps (drop pending/current-without-value) so the response is just the computed factors (default false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/openWorldHint annotations, the description discloses substantial behavior: the response is trimmed by default and full: true lifts the trim; lazy values may need expansion; excludeStepValues resolves lazy values before comparison so neutral lazy factors are dropped; withHighlights returns an A1-keyed overlay plus raw grid; and a terminal session answers 409. There is no contradiction with the annotations — 'read' aligns with readOnlyHint=true, and openWorldHint aligns with the caveat that the world may have moved on.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single dense paragraph is information-rich with no filler — every clause covers a distinct behavior (frame contents, laziness, trimming, filters, highlights, 409 semantics). The core purpose is front-loaded and the terminal-session caveat is placed at the end. At roughly 180 words for a tool with 7 params and decision-table complexity it is appropriately sized, though the wall-of-text structure with nested parentheticals could be more scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining return values — and it does, enumerating input parameters, runtime context, result, sub-steps, decision, ruleNames, and the optional highlight overlay. It covers preconditions (suspended only), error semantics (409), parameter behaviors, and the openl_get_trace_value handoff for lazy values. Nothing an agent needs to call this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description genuinely adds meaning beyond the schema: it explains the 'why' of the filters (surfacing an anomaly), the interplay between onlyExecutedSteps and excludeStepValues, and the lazy-value resolution behavior before neutral comparison. It also frames the decision/ruleNames output as the 'killer feature' for per-rule breakpoints, giving purpose beyond the schema's bare property definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource — 'Freeze and read the full state of one suspended stack frame' — and enumerates exactly what that state contains (input parameters, runtime context, result, sub-steps with computed values, decision/ruleNames). It clearly distinguishes itself from siblings like openl_get_trace_value (lazy expansion) and other trace tools. An agent can tell exactly what this tool returns without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit precondition and exclusion: 'Valid only while suspended (a terminal session answers 409 — read its final state from the last returned stack)' tells the agent when not to call and what to do instead. It also routes lazy-value expansion to openl_get_trace_value and explains when the step filters are warranted (surfacing an anomaly among neutral factors). It stops short of contrasting with every related trace sibling (e.g., openl_expand_trace_tree, openl_watch_trace_cells), so the guidance is strong but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_branchesList Git BranchesARead-onlyIdempotent
List all Git branch names in a repository. Use this to see available branches before switching or comparing versions. Pass either the id or name from openl_list_repositories() — both are accepted (case-insensitive). Do not invent example values; call openl_list_repositories() first if not in context.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| repository | Yes | Repository identifier. Pass either the 'id' or the 'name' field from openl_list_repositories() — the tool accepts both (and is case-insensitive). DO NOT invent values like 'Design Repository' or 'design-repo'; the actual names are typically short tokens (e.g. 'Design'). Always call openl_list_repositories() first if you don't already have the value in context. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly, idempotent, and open-world behavior, so the bar for additional disclosure is lower. The description adds useful behavioral detail: both repository id and name are accepted, matching is case-insensitive, and agents should not invent example values. This goes beyond the annotations and helps correct invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core purpose before usage and parameter guidance. It contains minor redundancy with the schema's repository parameter description, but every sentence adds practical value and there is no irrelevant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only listing operation with one required parameter, the description covers the main things an agent needs: what the tool does, when to use it, how to obtain a valid repository identifier, and a warning against inventing values. It does not explain output details or pagination, but given the schema's response_format and limit/offset defaults, the description is reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description reinforces the key repository parameter by explaining that id or name from openl_list_repositories() is accepted and is case-insensitive, but this largely repeats what the schema already states. Limit and offset have no description in the schema and are not addressed in the description, so the 50% schema coverage gap is not fully compensated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('List all Git branch names') and a concrete resource ('a repository'), making the core purpose clear. It also gives a use case ('before switching or comparing versions'), but it does not explicitly differentiate itself from sibling tools like openl_list_project_branches.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear when-to-use context: to see available branches before switching or comparing versions. It also provides a prerequisite workflow: call openl_list_repositories() first if the repository value is not already in context. It does not mention alternatives or when not to use this tool, but the guidance is otherwise strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_deploymentsList Active DeploymentsARead-onlyIdempotent
List active deployments across production environments, optionally filtered by production repository ID and deployed project name. Returns deployment names, repositories, and deployed project revisions.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| project | No | Deployed project name to filter deployments by. | |
| repository | No | Production repository ID to filter deployments by. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is established. The description adds useful behavioral context by specifying the 'active' state, 'production environments' scope, and the returned fields, which goes beyond what the annotations alone provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the action, scope, optional filters, and return contents without any filler. Every clause adds information, and no space is wasted on redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with five optional parameters and no required inputs, the description covers the main operational need: what it lists, how it can be filtered, and what the result contains. It does not mention ordering or pagination explicitly, but the schema documents limit/offset defaults and the annotations cover safety, making the description adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema describes project, repository, and response_format, but leaves limit and offset without semantic descriptions. The tool description adds clarity by calling repository a 'production repository ID' and project a 'deployed project name,' but it does not compensate for the missing pagination semantics beyond what the schema already supplies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('List active deployments'), defines the scope ('across production environments'), and names the two optional filters. It also states what is returned ('deployment names, repositories, and deployed project revisions'), which clearly separates it from sibling tools like openl_list_repositories or openl_list_deploy_repositories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: when the agent needs active production deployments, optionally filtered by repository or project. It does not explicitly exclude alternatives or name sibling tools for comparison, but the scope and optional filters make the intended use obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_deploy_repositoriesList Deployment RepositoriesARead-onlyIdempotent
List all deployment repositories in OpenL Studio. Returns repository names, their types, and status information. Use this to discover all available deployment repositories before deploying projects.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description adds useful output detail by stating it returns names, types, and status, but it does not disclose pagination behavior or how 'all' interacts with the limit/offset parameters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences contain all essential information with no filler. The first sentence states the action and output; the second sentence provides the use case. Everything present earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers what the tool does, what it returns, and when to use it, which is adequate for a simple read-only list tool. However, it omits pagination semantics, does not disambiguate from sibling tools like list_deployments or list_repositories, and has no output schema, leaving some gaps for an agent deciding how to call it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33%, with limit and offset lacking descriptions in the schema. The tool description does not mention any parameters or compensate for this gap, leaving pagination semantics and response format options unexplained despite the tool claiming to list all repositories.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List all deployment repositories in OpenL Studio' and enumerates the returned content (repository names, types, and status). This distinguishes it from siblings like list_deployments or list_repositories by name, although it does not explicitly name or contrast those alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Use this to discover all available deployment repositories before deploying projects' provides a clear use context. However, it does not mention when not to use it or how it compares to similar tools such as openl_list_repositories or openl_list_deployments.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_guidesList GuidesARead-onlyIdempotent
List the OpenL reference documentation bundled with this server — METADATA ONLY (id, type, title, source path, size in bytes), never bodies; fetch bodies with openl_get_guides. The bundle embeds the OpenL Tablets docs at the release tag matching the targeted OpenL Studio version: 'specification' entries are config-file/project-layout specs (rules.xml, rules-deploy.xml, project structure, openl-maven-plugin), 'guide' entries are the Reference Guide chapters (table types, table properties, functions and data types, projects, BEX/function appendices). Filter with 'type' and/or case-insensitive 'search' over id+title; results are paginated (limit/offset). Read-only, local — never calls OpenL Studio.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Filter by document type: 'specification' (config-file and project-layout specs, e.g. rules.xml) or 'guide' (OpenL Tablets Reference Guide chapters). Omit for both. | |
| limit | No | ||
| offset | No | ||
| search | No | Case-insensitive substring matched against each entry's id and title (e.g. 'decision table', 'spreadsheet', 'rules.xml'). | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and idempotentHint, and the description adds complementary behavioral detail: it never returns bodies, never calls OpenL Studio, embeds docs at a specific release tag, and explains the meaning of the two entry types. This goes well beyond annotation defaults without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient, front-loading the most decision-relevant fact (metadata only, use openl_get_guides for bodies) before explaining entry categories and filtering. Every clause adds useful information; nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description specifies the exact metadata fields returned, explains the content categories, covers filtering and pagination, names the companion tool for bodies, and notes the local read-only nature. This is complete enough for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaningful parameter context beyond the schema: it clarifies what 'type' values represent, that 'search' is case-insensitive over id and title, and that results are paginated via limit/offset. It does not describe response_format, but the schema already provides a solid enum description for it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('List'), a clear resource ('OpenL reference documentation bundled with this server'), and an explicit scope ('METADATA ONLY') that distinguishes it immediately from openl_get_guides. It also names the sibling for retrieving bodies, removing ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly directs agents to use openl_get_guides when bodies are needed, establishes this as the metadata-browsing entry point, and clarifies filtering and pagination behavior. It also notes the tool is read-only and local, giving clear context for when it is appropriate to invoke.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_module_sheetsList Module WorksheetsARead-onlyIdempotent
List worksheet names in a project module. First call openl_list_project_modules to get the exact moduleName. Use a returned sheet name as the destination sheet when creating or copying a table.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| moduleName | Yes | Module name exactly as returned by openl_list_project_modules(). | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true, covering the safety profile. The description adds workflow context beyond those annotations: correct results depend on a preceding call to openl_list_project_modules, and outputs are meant to feed table creation/copying operations. No contradiction exists between the 'List' verb and the read-only annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero filler. The core purpose is front-loaded in the first sentence, and the second sentence packs both the prerequisite call and the downstream usage into one efficient clause. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with 2 required parameters, full schema coverage, and strong annotations, the description covers the full usage arc: what it returns (worksheet names), how to prepare inputs (exact moduleName from a prior call), and what to do with results (destination sheet for create/copy operations). The lack of an output schema is mitigated because the description implies the return shape. Minor gaps remain around error behavior or handling of invalid module names, but these are not critical for a read-only listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with rich inline guidance: projectId must be used 'without modification or reformatting' and moduleName must be 'exactly as returned by openl_list_project_modules().' The description's mention of calling openl_list_project_modules first mostly reinforces what the schema already says, adding marginal value. Baseline 3 is appropriate when the schema carries the parameter burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb plus resource: 'List worksheet names in a project module.' This cleanly distinguishes it from sibling tools like openl_list_project_modules (lists modules, not sheets) and openl_list_tables (lists tables). The title 'List Module Worksheets' reinforces the same scope without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit sequencing context: 'First call openl_list_project_modules to get the exact moduleName' states the precondition, and 'Use a returned sheet name as the destination sheet when creating or copying a table' states the downstream purpose. It does not name alternatives to avoid or explicit when-not conditions, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_project_branchesList Project BranchesARead-onlyIdempotent
List branch metadata in the repository that hosts a project, including repository base and protected flags. scope='project' (default) returns branches that already hold the project and are candidates for switching or deletion. Inspect the flags before deletion: the base branch cannot be deleted, while a protected branch requires force and explicit confirmation. scope='repository' returns every repository branch, including branches that do not hold the project yet; use it to discover otherBranch values before openl_check_project_merge or openl_merge_project_branches. Unlike openl_list_branches, this tool is project-aware and returns safety metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | Branches to list: 'project' (default) returns branches that already hold the project and can be switched to; 'repository' returns every repository branch, including merge targets that do not hold the project yet. | project |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, and the description adds meaningful safety context beyond those flags: it explains the two scope behaviors, the meaning of base/protected flags, and the consequences for deletion. There is no contradiction between the description and annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: core purpose, scope semantics, deletion safety, merge workflow usage, and sibling differentiation. It is efficiently structured with the most important information front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only listing tool with 3 parameters and no output schema, the description covers all essential operational context: what it lists, what the two scopes mean, safety flags, and how it relates to nearby merge/delete tools. The response_format parameter is already fully documented in the schema, so no additional description is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description goes further by explaining the practical semantics of scope values: project scope returns branches that 'already hold the project' and are 'candidates for switching or deletion,' while repository scope is for discovering otherBranch values before merge operations. This adds decision-relevant meaning beyond the raw enum descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List branch metadata in the repository that hosts a project, including repository base and protected flags.' It also explicitly differentiates from openl_list_branches by calling this tool 'project-aware and returns safety metadata,' so an agent can distinguish it from siblings even before comparing schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit routing guidance: use repository scope to 'discover otherBranch values before openl_check_project_merge or openl_merge_project_branches,' and inspect flags before deletion because the base branch cannot be deleted while protected branches require force and confirmation. It also contrasts with openl_list_branches, making the choice between tools clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_project_local_changesList Local Change HistoryARead-onlyIdempotent
List local change history for a project. Returns list of workspace history items with versions, authors, timestamps, and comments. NOTE: Requires the project to be opened (openl_open_project first); not available for repository 'local' (local projects cannot be opened). Uses session-based project context; no projectId parameter.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description adds valuable context beyond the annotations: it specifies the output contents, the session-based project context, and the no-projectId behavior, plus the open-project requirement. It does not describe failure behavior when the project is not open, but that is a minor gap given the explicit prerequisite.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler: the first states what it does, the second states what it returns, and the third delivers the prerequisite and caveat. The key constraints are front-loaded in a Note marker, making them easy to spot.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list operation with one optional parameter and no output schema, the description is complete: it states the returned item fields, the session-based context, the prerequisite, and the local-repository limitation. An agent has everything it needs to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the only parameter, response_format, is fully documented in the schema. The description adds meaning by explicitly stating there is no projectId and that the tool uses session-based project context, which helps an agent understand why the parameter list is just one optional format choice. This exceeds the baseline for full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('List local change history for a project') and enumerates the return fields (versions, authors, timestamps, comments), which clearly distinguishes it from sibling operations like openl_restore_project_local_change. It is immediately obvious what the tool does and how it differs from the related mutation tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states a prerequisite ('Requires the project to be opened (openl_open_project first)') and an exclusion ('not available for repository 'local''), giving clear guidance on when this tool is valid. It does not explicitly contrast this list operation with the sibling restore tool or other history-related commands, stopping just short of full when-not/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_project_modulesList Project ModulesARead-onlyIdempotent
List the modules declared by a project, including module names, rules-root paths/patterns, and modules matched by a pattern. Use the returned name when creating/copying a table, selecting a module graph, or listing worksheets.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnlyHint and idempotentHint, so the safety profile is established. The description adds that the result includes module identifiers and rules-root information intended for subsequent operations, which is useful behavioral context beyond what annotations alone provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The primary action and output contents are front-loaded, followed by one sentence of downstream guidance that earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by listing the return fields and explaining how to use the returned names downstream. It is sufficient for a simple read-only list operation, though exact response structure and edge cases like empty projects are not described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: both projectId and response_format have detailed descriptions, including where projectId comes from and the available response formats. The tool description adds no parameter-specific detail beyond this, so it meets the baseline without exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb and resource: 'List the modules declared by a project.' It further enumerates the returned contents (module names, rules-root paths/patterns, and modules matched by a pattern), making the tool's scope concrete and distinguishable from sibling tools like openl_list_module_sheets or openl_list_tables.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The second sentence provides concrete downstream use cases: 'Use the returned name when creating/copying a table, selecting a module graph, or listing worksheets.' This gives clear context for when this tool matters, though it does not explicitly name alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_projectsList ProjectsARead-onlyIdempotent
List projects with the Studio filters for repository, status, dependency, name, author, branch, tags, sorting, and response expansions. Results are paginated (default 50, maximum 200): when a complete inventory is required, follow pagination.has_more and call again with pagination.next_offset until has_more is false. Returns project names, status (OPENED/CLOSED), metadata, and a convenient 'projectId' field from API to use with other tools. For local-only projects, do not pass repository filter 'local' (it may fail); list every page without that filter and filter results by repository === 'local' client-side. For such projects, open/save/close do not work; table/rule/test tools work without opening. IMPORTANT: The 'projectId' is returned exactly as provided by the API and should be used without modification. Pass either the id or name from openl_list_repositories() — both are accepted (case-insensitive). Do not invent example values; call openl_list_repositories() first if not in context. Use this to discover and filter projects.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Project name filter (partial, case-insensitive). | |
| sort | No | Field used to sort the returned page. | |
| tags | No | Filter by project tags. Tags must be prefixed with 'tags.' in the query string (e.g., tags.version='1.0', tags.environment='production'). This is handled automatically by the API client - provide as object with tag names as keys. | |
| limit | No | ||
| author | No | Last-modifying author filter (partial, case-insensitive). | |
| branch | No | Branch filter (partial, case-insensitive). | |
| offset | No | ||
| status | No | Filter by project status. | |
| include | No | Optional response expansions and listing behavior from the Studio API. | |
| dependsOn | No | Return projects that depend on this project identifier. | |
| repository | No | Filter by repository name (display name, not ID). Use the 'name' field from openl_list_repositories() response (e.g., if list_repositories returns {id: 'design-repo', name: 'Design Repository'}, use 'Design Repository' here, NOT 'design-repo'). Omit to show projects from all repositories. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, and open-world behavior. The description goes well beyond that by explaining pagination mechanics (has_more/next_offset), response contents, local-only project limitations (open/save/close fail, table/rule/test work), the exactness of projectId, and the required workflow with openl_list_repositories(). No contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but densely packed with necessary caveats: pagination, repository filter pitfalls, local-only behavior, and projectId handling. It is front-loaded with the core purpose and then builds logically through operational details. It could be tightened, but every sentence earns relevance given the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by summarizing returned fields (project names, status, metadata, projectId) and fully specifying the pagination protocol. It also covers edge cases like local-only projects and the proper way to obtain repository values. Minor gaps remain, such as not enumerating the full status set and not detailing the effect of each include expansion, so it is strong but not exhaustive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is high (83%), but the description's repository guidance directly contradicts the schema: it claims 'Pass either the id or name from openl_list_repositories() — both are accepted', while the schema explicitly says to use the display name and NOT the ID. This is actively misleading for a key parameter. The description does add useful pagination semantics and client-side local filtering, but the contradiction undermines parameter reliability.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('List projects') and enumerates the filtering dimensions, returning fields, and the projectId convenience field. It explicitly states the tool's role ('Use this to discover and filter projects'), setting it apart from sibling list tools that target repositories, deployments, or branches. No ambiguity about what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear when-to-use guidance ('Use this to discover and filter projects') and provides detailed operational conditions: paginate until has_more is false, do not pass repository filter 'local' for local-only projects, and call openl_list_repositories() first for valid repository values. It does not explicitly contrast this tool with close siblings like openl_get_project, but the intended use is nonetheless clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_repositoriesList Design RepositoriesARead-onlyIdempotent
List all design repositories in OpenL Studio. Returns repository information including 'id' (internal identifier) and 'name' (display name). Use the 'name' field when working with repositories in other tools. Either the 'id' or 'name' is accepted by other tools (case-insensitive). The actual values are usually short tokens like 'design' — never invent values such as 'Design Repository' or 'design-repo'.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description adds valuable behavioral detail about case-insensitive id/name acceptance and the short-token format of actual values, which goes beyond annotations. No contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each carrying useful information: purpose, return fields, usage guidance, and a warning against invented values. It could be slightly tightened by merging the 'name' guidance with the id/name acceptance sentence, but there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with zero required parameters and no output schema, the description provides enough return-value semantics and practical guidance. It lacks explicit contrast with sibling list tools and does not mention pagination behavior, but those are minor for this straightforward operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33%, with only response_format documented. The description does not clarify limit, offset, or how response_format affects output. Since low schema coverage requires more compensation from the description, this gap is significant.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List all design repositories in OpenL Studio.' It also clarifies the returned fields ('id' and 'name') and gives concrete value examples, making the tool's purpose unambiguous and distinct from sibling tools like openl_list_deploy_repositories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives useful operational guidance, such as preferring the 'name' field and never inventing repository values. However, it does not explicitly state when to use this tool instead of alternatives like openl_list_deploy_repositories, leaving tool-selection partly to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_repository_featuresGet Repository FeaturesARead-onlyIdempotent
Get features supported by a design repository (branching, searchable, etc.). Use this to check if a repository supports specific features like branching before performing operations that depend on those features. Pass either the id or name from openl_list_repositories() — both are accepted (case-insensitive). Do not invent example values; call openl_list_repositories() first if not in context.
| Name | Required | Description | Default |
|---|---|---|---|
| repository | Yes | Repository identifier. Pass either the 'id' or the 'name' field from openl_list_repositories() — the tool accepts both (and is case-insensitive). DO NOT invent values like 'Design Repository' or 'design-repo'; the actual names are typically short tokens (e.g. 'Design'). Always call openl_list_repositories() first if you don't already have the value in context. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint and idempotentHint, so the safety profile is covered elsewhere. The description adds behavioral value beyond them: it discloses that the tool accepts id or name case-insensitively and, consistent with openWorldHint, warns agents not to fabricate values and to obtain them from openl_list_repositories() first. No contradiction with any annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with purpose and followed by usage, parameter, and workflow guidance in decreasing order of importance. Minor redundancy: sentence 3 largely repeats repository-parameter details already present in the schema, but the overall length stays appropriate and every sentence serves a distinct function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with two parameters, no output schema, and no nested objects, the description covers purpose, when to use it, parameter semantics, and the prerequisite workflow. The one gap is that it doesn't describe the shape of the returned feature list, but the tool name and examples make the return content reasonably predictable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — the repository parameter already documents id/name acceptance, case-insensitivity, and the anti-invention warning in full, and response_format has a complete enum with per-value explanations. The description restates this guidance in prose rather than adding new meaning, so the baseline 3 for high-coverage schemas applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get features supported by a design repository,' with concrete examples ('branching, searchable, etc.'). This clearly distinguishes it from sibling tools like openl_list_repositories (which lists repositories themselves) and openl_list_branches (which lists branches) — this tool targets repository capabilities, not the repositories or their branches.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit triggering condition: use it to check feature support 'before performing operations that depend on those features.' It also names the prerequisite call, openl_list_repositories(), and instructs calling it first when the value is not in context. However, it does not name sibling alternatives to prefer instead, stopping short of a full when-not/else statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_table_property_definitionsList Allowed Table PropertiesARead-onlyIdempotent
List the properties Studio allows in the requested table context, including value type, whether multiple values are accepted, and allowed enum values. Omit tableType for entries inside a Properties table; provide a public table kind for properties that may be declared on that kind.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| tableType | No | Optional public table kind. Omit for properties allowed inside a Properties table; provide a kind to get properties allowed on that table kind. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only, open-world, and idempotent, lowering the bar for behavioral disclosure. The description adds useful context beyond those annotations by specifying what the response will contain: value type, multiplicity, and allowed enum values.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences carry the full purpose, the tableType decision rule, and the output contents with no filler. The most important scoping instruction is front-loaded and directly actionable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description appropriately explains the return value shape. It covers the key usage distinction for tableType and relies on the schema for parameter details. It could go slightly further by noting behavior for invalid or unknown table kinds, but current coverage is strong.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all three parameters thoroughly. The description restates the tableType behavior already present in the schema description, adding little new semantic value beyond confirming the tool's output contents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'List' with a clear resource: properties allowed in a requested table context. It names the decisive distinction between omitting tableType for Properties-table entries versus providing a public table kind, which separates this tool from all sibling list tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear, actionable context on when to omit versus provide tableType, which effectively tells the agent how to select the correct request scope. It does not explicitly name alternatives, but this tool has a unique purpose among the siblings, so the lack of exclusions is not a significant gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_list_tablesList Project TablesARead-onlyIdempotent
List tables/rules in a project with optional filters for kind, name, and properties. Results are paginated (default 50, maximum 200): when a complete inventory is required, follow pagination.has_more and call again with pagination.next_offset until has_more is false. Returns table metadata including 'tableId' (the 'id' field) which is required for calling get_table(), update_table(), append_table(), or run_project_tests(). Use the 'tableId' field from the response to reference specific tables in other API calls. IMPORTANT: a table id is derived from its location and changes when an edit relocates the table (it had no room to grow in place). After openl_update_table/openl_append_table, use the 'tableId' those tools return (or re-run openl_list_tables); an id from a listing taken before such an edit is stale.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Filter by table kinds (array of strings). Valid values: 'Rules', 'Spreadsheet', 'Datatype', 'Data', 'Test', 'TBasic', 'Column Match', 'Method', 'Run', 'Constants', 'Conditions', 'Actions', 'Returns', 'Environment', 'Properties', 'Other'. Omit to show all kinds. | |
| name | No | Filter by table name fragment (e.g., 'calculate', 'Premium'). Omit to show all tables. | |
| limit | No | ||
| offset | No | ||
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| properties | No | Filter by project properties. Properties must be prefixed with 'properties.' in the query string (e.g., properties.state='CA', properties.lob='Auto'). This is handled automatically by the API client. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly/openWorld/idempotent, and the description adds substantial behavior beyond that: pagination default/max and loop semantics, tableId-as-id-field mapping, and the warning that table IDs go stale after update/append operations. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences are front-loaded with the core purpose, then move logically through pagination, output usage, and a critical staleness warning. Every sentence earns its place, and the IMPORTANT cue highlights the highest-risk behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description covers the essential return guidance: pagination fields, tableId presence and meaning, and downstream tool requirements. Combined with annotations for safety/idempotence and a detailed input schema, nothing needed for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 71%, and the schema already documents kind, name, limit, offset, projectId, properties, and response_format. The description's mention of filters and pagination defaults mostly restates schema facts rather than adding new parameter-level meaning, though the exact projectId emphasis is useful context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('tables/rules in a project') with optional filters, clearly identifying it as the inventory operation among table-related siblings such as get_table, update_table, and delete_table. It also signals its role as the source of tableId values needed by downstream table tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context: optional filters, explicit pagination loop with has_more/next_offset, and the need to re-list after edits that change table IDs. It does not explicitly contrast against a single-table getter, so it falls just short of naming alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_merge_project_branchesMerge Project BranchesADestructive
Attempt to merge project branches. The tool first repeats the relationship and permission precheck: up-to-date returns without a write, and permission/lock blockers fail before merge. The precheck does not predict conflicts, so an allowed attempt can still return status='conflicts'. mode='receive' merges otherBranch into the current branch; mode='send' merges the current branch into otherBranch. A conflict result creates read-only, session-bound conflict state: inspect it on this same MCP server, then hand resolution to the user in Studio or cancel the pending state. Never choose OURS or THEIRS automatically. force is only for an eligible protected-target bypass and requires confirmForce=true.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | receive merges the other branch into the project's current branch; send merges the current branch into otherBranch. | |
| force | No | Bypass eligible protected-target restrictions. Default false. Use only after Studio reports blockedBy='bypass-required'. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| otherBranch | Yes | The other branch: source for receive mode, target for send mode. Discover all merge targets with openl_list_project_branches(scope='repository'). | |
| confirmForce | No | Must be true when force=true, confirming the protected-branch bypass. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond what destructiveHint/openWorldHint already provide: discloses the repeated precheck, the no-write short-circuit on up-to-date, precheck's inability to predict conflicts, the read-only session-bound conflict state, the force/confirmForce coupling, and the explicit prohibition on auto-resolving conflicts. This is extensive behavioral disclosure that meaningfully reduces agent surprise. No contradiction with the annotations — the 'attempt' language and destructiveHint are consistent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Approximately 150 words and dense, but every sentence earns its place given the destructive, two-mode, conflict-lifecycle complexity. Front-loaded correctly: purpose first, then precheck behavior, then mode semantics, then conflict handling, then guardrails. Slightly long, yet the length is commensurate with the operational risk the tool carries.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite high complexity (6 params, two modes, conflict lifecycle, force bypass) and no output schema, the description covers precheck outcomes, the status='conflicts' result, and the conflict-state lifecycle well. However, it never enumerates the other status values an agent may receive (e.g., what a successful merge returns), and no output schema exists to fill that gap — leaving agents to guess at the full response shape for round-tripping.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 with the schema doing the heavy lifting. The description adds genuine value on top: clarifies the directionality of mode ('receive merges otherBranch into the current branch; send merges the current branch into otherBranch'), tightens force semantics to 'eligible protected-target bypass' with confirmForce coupling, and explains conflict-state consequences of an allowed attempt. Slight redundancy with schema text, but the enrichment justified a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with 'Attempt to merge project branches' — a specific verb plus resource, with the 'attempt' qualifier accurately signaling open-world failure. The description distinguishes this from sibling conflict-inspection tools (openl_get_merge_conflicts, openl_read_merge_conflict_file, openl_cancel_merge_conflicts) by centering on the merge execution itself and the conflict state it creates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides strong when-to-use guidance: precheck short-circuits (up-to-date returns without a write, permission/lock blockers fail early), force is reserved for protected-target bypass with confirmForce=true, and the explicit guardrail 'Never choose OURS or THEIRS automatically.' The one gap is that conflict inspection and cancellation are described generically ('inspect it on this same MCP server... cancel the pending state') rather than naming the sibling tools openl_get_merge_conflicts, openl_read_merge_conflict_file, and openl_cancel_merge_conflicts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_merge_table_cellsMerge Table Cells (raw)AIdempotent
Merge a rectangular range of cells into one in a table's raw source, keeping the value of the top-left cell at ('row','column'). The range ('rowspan'×'colspan') must cover more than one cell and stay within the table. Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| row | Yes | 0-based row index of the top-left cell of the range (0..height-1). | |
| column | Yes | 0-based column index of the top-left cell of the range (0..width-1). | |
| colspan | Yes | Number of columns the merged cell spans (>= 1). | |
| rowspan | Yes | Number of rows the merged cell spans (>= 1). | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the sparse annotations (openWorldHint, idempotentHint) by disclosing that the top-left value is retained, that a relocating edit changes the location-derived id, and that the response returns the current tableId plus previousTableId when changed. It also explains the recompile trigger for openl_project_status and defines the 0-based coordinate semantics for header and label columns. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries an operational fact: action, constraint, raw-source scope, indexing, id volatility, and recompile behavior. The description is longer than average but front-loads the core action and then layers necessary caveats; there is no filler or repeated schema boilerplate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description explicitly states what the response contains (current tableId, previousTableId when changed) and why it matters for subsequent calls. It also covers the side effect on openl_project_status and the range validity constraint, so an agent has what it needs to call the tool and interpret its result. Minor omissions like error behavior are secondary given the detailed schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all parameters are individually documented; the description adds value by clarifying the coordinate frame (row 0 = header, column 0 = leading labels) and the validity condition that the range must cover more than one cell. It also reinforces the volatile tableId behavior that the schema already partially states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Merge a rectangular range of cells into one in a table's raw source.' It states the top-left value retention behavior and the validity constraints, and it distinguishes the tool from siblings like openl_unmerge_table_cells and openl_update_table_cell by emphasizing the RAW source and any-table-type applicability.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is intended for raw-source merging and notes it works for any table type, but it never names alternative tools or states when to prefer this over openl_update_table_range or openl_update_table_cell. There are no explicit when-not-to-use conditions, leaving the agent to infer routing from the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_move_project_fileMove or Rename Project FileA
Move or rename a file within a project. Maps to POST /projects/{projectId}/file-move. Intermediate destination folders are created automatically and the source file is deleted after the move. A destination collision fails with HTTP 409. The move is staged in the working copy — commit it with openl_save_project. Use 'branch' to pin the project's branch. Use this to rename a file or relocate it to another folder.
| Name | Required | Description | Default |
|---|---|---|---|
| branch | No | Branch the project must be on for this operation. Ignored when blank. Fails if the repository has no branches or the project is on another branch. Omit for repository 'local' and non-branch repositories. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| sourcePath | Yes | Project-relative path of the source file (e.g. 'rules/Model.xlsx'). | |
| destinationPath | Yes | Project-relative destination path (e.g. 'rules/Model-copy.xlsx'). Intermediate folders are created automatically. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the generic openWorldHint annotation, the description discloses the key side effects: automatic creation of intermediate folders, deletion of the source file, HTTP 409 on collision, and staging in the working copy requiring a later commit. This is substantial transparency for a mutation tool and matches the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five short sentences front-load the action and then pack in endpoint, side effects, and error behavior. It is dense but not padded; only the endpoint mapping is arguably optional.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers operation semantics, failure mode (409), staging workflow, and branch handling, which is complete for a focused move/rename tool. The absence of an output schema means response shape is not described, but the response_format parameter and simple operation mitigate that gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All parameters have rich schema descriptions, so the description carries no extra burden. It reinforces branch pinning and intermediate folder creation, but adds no new parameter semantics beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific operation ('Move or rename a file within a project') with concrete resource paths and endpoint. The 'source file is deleted after the move' detail differentiates it from sibling openl_copy_project_file, while rename/relocate language separates it from write/delete tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit intended use—'Use this to rename a file or relocate it to another folder'—and identifies the follow-up commit with openl_save_project. It does not explicitly contrast with copy/write/delete siblings, but the side-effect description ('source file is deleted') makes the choice clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_open_projectOpen Project for EditingA
Open a project for editing. Supports opening on specific branches or viewing specific Git revisions. Use this before making changes to project tables or rules.
| Name | Required | Description | Default |
|---|---|---|---|
| branch | No | Open project on a specific Git branch (e.g., 'main', 'development', 'feature/new-rules') | |
| revision | No | Open project at a specific Git revision/commit hash for read-only viewing | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
| openDependencies | No | Also open dependency projects (backend default false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only provide openWorldHint, so the description carries most of the behavioral burden. It does communicate that opening is a preparatory/editing action and that revision mode is for viewing, but it does not disclose side effects such as whether the currently open project is replaced, whether resources are locked, or what state the project enters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, each earning its place: core action, branch/revision capability, and workflow placement. No filler or redundant restatement of structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description does not explain what the tool returns or what 'opening' changes in the current work context. The required parameter, branch/revision modes, and suggested usage are present, making it operable, but the stateful behavior and return semantics remain under-specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and all parameters have clear descriptions, so the baseline is 3. The main description adds a high-level branch/revision framing but does not materially enrich the parameter semantics beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Open a project for editing.' The description also distinguishes the tool from read-only alternatives by emphasizing it is the prerequisite before changing tables or rules, and by contrasting branch-based editing with Git revision viewing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use guidance: 'Use this before making changes to project tables or rules.' It does not name sibling alternatives or state when not to use it, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_project_statusGet Project StatusAIdempotent
Get the project's compile state, diagnostics, pending changes, and module/test summary. By default wait=true: a supplied branch switches the opened design project to that branch before validation; if Studio reports idle, the tool lazily starts compilation through the tables API; if compilation is already running, it waits for a terminal state (ok/warnings/errors) and emits progress notifications when available. Set wait=false only for a fast read-only snapshot, which may legitimately return idle or compiling and never switches branches. Edits made through the MCP table tools already trigger recompilation.
| Name | Required | Description | Default |
|---|---|---|---|
| wait | No | When true (default), returns a conclusive compile state: an idle project is compiled lazily through Studio's tables API, while an already-running compilation is followed over the real-time status topic until compileState is terminal (ok/warnings/errors). Progress notifications are emitted when available. Set false only for a one-shot read-only snapshot that may return idle or compiling. | |
| branch | No | Optional target branch. With wait=true (default), the tool switches an opened design project to this branch before validating it. With wait=false, this is a read-only assertion and Studio returns 409 when it differs from the currently opened branch. Omit for repositories that do not support branches and for repository 'local'. | |
| severity | No | Filter compilation.messages.items to only these severities. Useful when the project has many warnings and you want to isolate errors: pass severity: ['ERROR']. Default: all severities. Note: items are always sorted ERROR → WARN → INFO before any filter or truncation is applied, so errors are visible without this filter. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| timeoutMs | No | Max time in milliseconds to wait for compilation when wait=true. On expiry, the last-seen status is returned (no error). Default 120000 (2 minutes). Cap 600000 (10 minutes). Ignored when wait=false. | |
| maxMessages | No | Cap the number of items returned in compilation.messages.items. The list is sorted ERROR → WARN → INFO first so the most actionable items are preserved when capped. Pair with severity to bound very large diagnostic lists. Default: no cap (relies on the response-format character truncation). | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses non-obvious side effects: branch switching before validation, lazy compilation start when idle, waiting on a live status topic, progress notifications, 409 on wait=false branch mismatch, and timeout fallback. This goes well beyond the annotations' readOnlyHint=false and idempotentHint=true, giving the agent an accurate model of when the tool mutates state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences: purpose first, then default/wait behavior, then the read-only exception, then the recompilation note. Every sentence carries a distinct fact needed to call the tool safely, with no redundant filler or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, the description names what it returns (compile state, diagnostics, pending changes, module/test summary) and the key terminal states (ok/warnings/errors). The schema fills in per-parameter details like timeout and severity. It could further describe the exact response shape or failure modes for unopened projects, but overall it is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the parameter descriptions are already detailed, covering wait semantics, branch mismatch behavior, severity sorting, timeout caps, and response formats. The main description's extra behavioral notes add useful context but do not materially improve parameter understanding beyond what the schema already documents. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: it returns compile state, diagnostics, pending changes, and module/test summary. This clearly differentiates it from sibling tools like openl_get_project or openl_get_test_results_summary, which cover only subsets of that status surface. Very little inference is needed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage direction: default wait=true behavior, 'Set wait=false only for a fast read-only snapshot', and 'Omit for repositories that do not support branches'. It also notes that table edits already trigger recompilation. It does not name sibling alternatives for when to prefer openl_get_test_results_summary or openl_list_project_local_changes, so I won't give full marks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_read_merge_conflict_fileRead Merge Conflict File VersionARead-onlyIdempotent
Read one BASE, OURS, or THEIRS version of a conflicted file from the current session as read-only evidence for manual user resolution in Studio. Never infer or apply a winning side automatically. UTF-8 and base64 binary chunks are returned in a JSON text envelope with MIME and byte-range metadata. Both forms include nextOffset while more data remains. length targets at most 16000 bytes; a UTF-8 chunk may include up to 3 extra bytes to finish its last character. The backend still downloads the whole file before this client-side slice. Use the exact file path from openl_get_merge_conflicts.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Project-relative conflicted file path from openl_get_merge_conflicts(). | |
| side | Yes | Version to read: common ancestor, current branch, or merging branch. | |
| length | No | Target bytes returned from offset. Default and maximum target 16000; a UTF-8 response may add up to 3 bytes to finish a character. Continue with nextOffset when hasMore is true. | |
| offset | No | Byte offset in the downloaded file. Default 0. | |
| encoding | No | Content encoding. Default auto detects binary content. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true, so the safety profile is covered. The description adds meaningful behavioral context: backend download behavior (whole file downloaded before client-side slice), byte-length targeting with potential +3 UTF-8 bytes, nextOffset continuation semantics, and chunked return format. It also clarifies the read-only nature for manual resolution, going beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but organized: core purpose first, then behavioral constraints, then return format details, then parameter semantics. Every sentence adds information; there is no filler. It is longer than the typical tool description, but the complexity of chunked reads, encoding variants, and side selection justifies the length. The front-loading of the read-only/manual-resolution constraint is effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read tool with no output schema, the description covers the return envelope (MIME, byte-range, nextOffset, hasMore), the side semantics, the file-path provenance, and the encoding forms. It doesn't explicitly document the exact JSON envelope field names beyond nextOffset, but the output is client-side and an agent can infer the structure. Given the 7 parameters and chunked-read complexity, the description is nearly complete, with only minor room for more explicit output-field documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema itself documents all 7 parameters thoroughly. The description adds value by explaining the byte-length semantics (up to 3 extra UTF-8 bytes), the continuation pattern via nextOffset, and the default encoding behavior. The description's mention of 'JSON text envelope with MIME and byte-range metadata' complements the response_format parameter. The file path provenance from openl_get_merge_conflicts also reinforces the file parameter's meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads one BASE, OURS, or THEIRS version of a conflicted file as read-only evidence for manual resolution. It explicitly says it never infers or applies a winning side automatically, distinguishing it from merge-resolution tools. The exact file path source is named (openl_get_merge_conflicts), making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs to use the exact file path from openl_get_merge_conflicts and frames this as evidence for manual user resolution, implying it should not be used to auto-apply changes. While it doesn't name specific alternative tools for applying resolutions, the behavioral constraint 'Never infer or apply a winning side automatically' provides clear when-not-to-use guidance. The explicit file-path sourcing also removes ambiguity about which conflict to read.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_read_project_fileRead Project FileARead-onlyIdempotent
Read any file in a project by its project-relative path — text or binary, and folder listings too. Maps to GET /projects/{projectId}/files/{path}. Behavior by path/params: (1) a FILE path returns its content — UTF-8 text is returned verbatim, while binary is returned as base64 'content' in a JSON text envelope with byte and MIME metadata (use encoding to force 'utf-8' or binary; default 'auto' detects); (2) a FILE path with view='meta' returns JSON metadata (name, size, extension, lastModified); (3) a FOLDER path (empty string for the root, or a path ending in '/') lists its entries (use recursive, viewMode FLAT/NESTED, extensions, namePattern, foldersOnly); (4) a FOLDER path with download=true returns a ZIP as base64 in the same JSON text envelope. Optional 'version' reads a historical revision; 'branch' pins the project branch. Optional byte range (offset/length) is applied client-side AFTER fetching the whole file (the backend does not support partial transfers), so the entire file is loaded into memory; for very large/binary files, bound the RETURNED size with offset/length and read in chunks (a full file's base64 can exceed MCP message limits). Use this to read AGENTS.md, README.md, schemas, manifests, or to inspect/export xlsx rule files.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Project-relative path to a file or folder (e.g. 'rules/Model.xlsx' or 'rules/'). Empty string (default) or a path ending in '/' lists the project root / that folder; a file path returns the file content. | |
| view | No | For a file, set to 'meta' to return JSON metadata (name, size, extension, lastModified) instead of the file content. Omit to read content (files) or list entries (folders). | |
| branch | No | Branch the project must be on for this operation. Ignored when blank. Fails if the repository has no branches or the project is on another branch. Omit for repository 'local' and non-branch repositories. | |
| fields | No | Comma-separated response fields to return for metadata/listing responses, including nested selection (e.g. 'id,name'). When omitted, the full response is returned. | |
| length | No | Maximum number of bytes of file content to return starting at 'offset'. Omit for the rest of the file. Byte count, not character count (see the note on 'offset'). | |
| offset | No | Byte offset to start reading file content from (default 0). NOTE: the backend does not support partial transfers, so the whole file is fetched and then sliced client-side. offset/length are BYTE offsets — a range boundary that lands inside a multi-byte UTF-8 character makes that character decode to U+FFFD (�) at the seam; for exact bytes use encoding='base64'. | |
| version | No | Historical revision (commit hash) to read. Omit to read the latest revision. Applies to file content/metadata and folder listing/ZIP. An unknown revision yields 404. | |
| download | No | For a folder, set true to download the folder and its contents as a ZIP archive (base64 content in a JSON text envelope). Ignored for files. | |
| encoding | Yes | How to return file content. 'auto' (default) returns text as UTF-8 and binary as base64 content in a JSON text envelope; 'utf-8' forces text; 'base64' forces the base64 envelope. Ignored for metadata/listing responses. | auto |
| viewMode | No | Folder listing only: FLAT returns a flat list, NESTED returns a tree (default FLAT). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| recursive | No | Folder listing only: include nested resources recursively (default false). | |
| extensions | No | Folder listing only: filter by file extensions without the dot, e.g. ['xlsx','xml']. | |
| foldersOnly | No | Folder listing only: if true, return only folders (default false). | |
| namePattern | No | Folder listing only: filter by name (case-insensitive contains match). | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses substantial behavior beyond the readOnly/idempotent annotations: byte ranges are applied client-side AFTER fetching the whole file because the backend does not support partial transfers, full-file base64 can exceed MCP message limits, and byte-offset boundaries inside multi-byte UTF-8 characters decode to U+FFFD at the seam. It also documents the encoding auto-detect JSON envelope, metadata view, folder listing modes, and ZIP download behavior. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Long but justified for 16 parameters and four distinct behavior modes; the purpose and endpoint are front-loaded and the numbered behavior modes make it scannable. Every sentence earns its place — there is no filler, and the critical memory/byte-range caveat is positioned before the closing use-case sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and covers the main shapes: verbatim UTF-8 text, base64 JSON envelope with byte and MIME metadata, metadata JSON (name, size, extension, lastModified), folder listings, and ZIP envelopes. Version/branch behavior and the MCP message-limit hazard are also covered, leaving no critical gap an agent would need to guess at.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds coordinating semantics beyond individual parameter docs: how encoding behaves for file vs folder paths, that offset/length bounds the returned size after a full fetch, and the chunked-read strategy for large files. This clarifies parameter interplay that the schema's per-field descriptions do not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Read any file in a project by its project-relative path' — and maps to a concrete endpoint (GET /projects/{projectId}/files/{path}). It distinguishes itself from the write/delete/search/copy/move project-file siblings by enumerating its full scope: file content, folder listings, metadata, and ZIP downloads.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use guidance ('Use this to read AGENTS.md, README.md, schemas, manifests, or to inspect/export xlsx rule files') that makes intended use concrete. It does not explicitly name exclusions or say 'use X instead for Y', so differentiation from alternatives rests on the read-only scope, the endpoint mapping, and sibling names rather than an explicit routing statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_redeploy_projectRedeploy with New VersionA
Redeploy an existing deployment with a new project version. Use this to update a deployment with a newer version of the project or rollback to a previous version.
| Name | Required | Description | Default |
|---|---|---|---|
| comment | No | Commit comment describing the change (e.g., 'Updated CA premium rates', 'Fixed calculation bug') | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| deploymentId | Yes | Deployment ID to redeploy (from list_deployments response) | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry openWorldHint, not a readOnly or destructive hint, so the description must disclose side effects. It says 'redeploy' and 'update/rollback,' but does not say whether the existing deployment is replaced in place, whether the same deployment ID remains valid, or what happens to the previous version.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, with the core action front-loaded before the use cases. Every sentence contributes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple schema and full parameter descriptions, the definition is mostly sufficient. However, there is no version parameter, so an agent may need to know how the 'new project version' is selected or whether the project must be saved/published first; the description leaves that implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and each parameter already has a meaningful description, so the bar is met by the schema. The description adds no parameter-level details, which is acceptable at the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+object: 'Redeploy an existing deployment with a new project version.' The second sentence makes the scoped use cases explicit (update to newer version, rollback to previous), and 'existing deployment' distinguishes it from deploy-style siblings like openl_deploy_project.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States exactly when to use it: 'Use this to update a deployment with a newer version of the project or rollback to a previous version.' It does not name an alternative or give when-not-to-use conditions, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_repository_project_revisionsGet Project Revision HistoryARead-onlyIdempotent
Get revision history (commit history) of a project in the branch it is currently on. Addressing the project by its stable ID keeps history available after an unsaved rename. Returns revisions with commit hashes, authors, timestamps, and commit types, with pagination and optional search and technical-revision filters. Use the projectId returned by openl_list_projects; do not construct it from the displayed project name.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (0-based). Mutually exclusive with offset; the backend defaults to 0 when both are omitted. | |
| size | No | Page size (default: 50, max: 200) | |
| offset | No | Item offset (0-based). Mutually exclusive with page. | |
| search | No | Search term to filter revisions by commit message or author | |
| techRevs | No | Include technical revisions (default: false) | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds meaningful behavior beyond that: history remains available after an unsaved rename and the response includes commit hashes, authors, timestamps, commit types, pagination, and filters. No rate-limit or auth details are given, but the annotation coverage makes this acceptable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each carrying distinct information: scope, stable-ID rationale, return contents, and identifier provenance. The description is front-loaded with the action and resource, though the third sentence is slightly list-heavy with multiple return fields and filter concepts.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description appropriately states the returned revision fields and available filters. Combined with high schema coverage and read-only/idempotent annotations, this gives an agent enough to invoke the tool correctly, though the exact paginated response shape is not described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents every parameter, including the projectId provenance rule. The description reinforces the projectId guidance and summarizes pagination, search, and technical-revision filters, but it does not add parameter-level detail beyond what the schema provides. The baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with an explicit verb and resource combination: 'Get revision history (commit history)' scoped to the branch the project is currently on. This is clearly distinguishable from sibling tools like branch listing or local-change tools, so an agent can identify it as the commit-history read without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides concrete selection and invocation guidance: use the projectId returned by openl_list_projects and do not construct it from the displayed project name. It also clarifies that the history is branch-scoped and lists available filters, though it does not explicitly mention when not to use this tool or name a sibling alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_restore_project_local_changeRestore Previous Local VersionADestructive
Restore a project to a specified version from its local history. Use the historyId from openl_list_project_local_changes response. NOTE: Requires the project to be opened first; not available for repository 'local'. Uses session-based project context; no projectId parameter.
| Name | Required | Description | Default |
|---|---|---|---|
| historyId | Yes | History ID to restore (from list_project_local_changes response) | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true, and the description adds useful behavioral context: session-based project context, no projectId parameter, and the requirement that the project be open. This goes beyond what the annotations alone convey, though it does not detail exactly what happens to current uncommitted changes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core purpose, followed by essential usage constraints. Each sentence adds necessary information with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive restore operation with no output schema, the description covers the key prerequisites, source of the required parameter, and a repository limitation. It does not describe the expected return value or post-restore confirmation, which would make it fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both parameters. The description adds value by specifying the source of historyId ('from openl_list_project_local_changes response') and clarifying that no projectId parameter exists, reducing ambiguity for the agent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Restore a project to a specified version from its local history') with a specific verb and resource. It differentiates from sibling tools like openl_list_project_local_changes by referencing historyId and the local-history context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a concrete prerequisite ('Requires the project to be opened first'), an important exclusion ('not available for repository 'local''), and explains how to obtain the required historyId. It does not explicitly name alternative tools, but gives enough context for correct use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_resume_traceResume to Next StopA
Resume the suspended debug session and wait (inside this call — no agent-side polling) until it stops again: at the next breakpoint, at an exception, or at completion. Unlike openl_step_trace(out), which only runs the current frame to its exit, resume runs to the NEXT breakpoint or the end. Returns the stack (compact — steps for the active frame only) at the stop; on a terminal 'error' status it carries the structured 'error', and on 'completed' of a profiling run the constant-size 'profile' overview (set includeTree: true for the one-level 'tree' root, then drill in with openl_expand_trace_tree). On timeout (default 30s) the still-running status is returned — call openl_resume_trace again to keep waiting (it re-attaches without re-resuming), or openl_stop_trace to give up.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| timeoutMs | No | Maximum time to wait for the next suspension or completion, in milliseconds. Default 30000, cap 600000. On timeout the current (still running) status is returned — call openl_resume_trace again to keep waiting, or openl_stop_trace to give up. | |
| profileTop | No | Number of hotspots (slowest tables) in the 'profile' overview (backend default 20). | |
| includeTree | No | Also return the executed call tree's ROOT node ('tree'), not just the bounded 'profile' overview (default false). Against a current OpenL Studio the tree is lazy — one level deep: the root's steps each carry a 'childrenTotal' count instead of nested children, so a large run is no longer returned whole. Drill into a branch with openl_expand_trace_tree; to find the hot table use 'profile' and replay into it with a breakpoint. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses critical behavioral traits beyond the openWorldHint annotation: the call blocks inside the tool ('no agent-side polling'), timeout returns the still-running status, re-calling re-attaches without re-resuming, and return payloads vary by status ('error' carries structured error, 'completed' profiling run carries 'profile'). This gives the agent an accurate model of the tool's runtime behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded with the core behavior and wait semantics, then branches into alternatives, return values, timeout handling, and tree details. Each clause earns its place, though the single long paragraph is slightly harder to scan than structured sections would be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a blocking debug-resume tool with no output schema, the description is remarkably complete: it covers stop conditions, return shapes, timeout behavior, re-entry semantics, escape hatch via openl_stop_trace, profile/tree options, and how to drill into the tree. An agent has enough information to invoke it correctly and handle all major outcomes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds substantial meaning: timeoutMs behavior (defaults, cap, and resume-on-timeout semantics), includeTree's lazy one-level tree behavior and childrenTotal counts, and profileTop's hotspot count. It connects parameters to real workflow decisions rather than repeating schema names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Resume the suspended debug session and wait... until it stops again.' It names the stop conditions (next breakpoint, exception, completion) and explicitly distinguishes itself from openl_step_trace(out), so an agent can immediately tell what this tool does and how it differs from a close sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use context: use it after a session is suspended and you want to run to the next stop. It names the alternative openl_step_trace, explains when to call openl_resume_trace again (on timeout), and when to give up via openl_stop_trace. It also instructs on includeTree and openl_expand_trace_tree for drilling into the tree.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_run_tableRun TableA
Execute a regular (non-Test) table with caller-provided JSON and return its result. This is a single high-level operation: it starts Studio's asynchronous run and waits inside the tool call until the result is ready, emitting progress notifications instead of requiring agent-side polling. Pass inputJson as an object keyed by method parameter name or as { params: { parameterName: value }, runtimeContext? }; { params: [...] } is rejected because Studio silently runs it with null arguments. A top-level array is passed as the value of a single array-valued parameter, not as positional arguments. Set withSchema only when the result/parameter JSON Schemas are needed because they can be large. Studio permits one table run per HTTP session, so wait for an active call to finish before starting another. Use openl_start_project_tests and the test-result tools for Test tables. Cancelling the MCP call also cancels and clears the Studio run.
| Name | Required | Description | Default |
|---|---|---|---|
| tableId | Yes | Table ID of a regular executable table. Use openl_list_tables() to discover it; use the Tests tools instead for Test tables. | |
| inputJson | Yes | Method input as JSON. Use an object keyed by method parameter name, or { params: { parameterName: value }, runtimeContext? }. A top-level array is the value of a single array-valued parameter, not a positional argument list. The value is sent to Studio unchanged. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| timeoutMs | No | Maximum time for the complete Studio start-and-result workflow, in milliseconds. Default 120000 (2 minutes), maximum 600000 (10 minutes). A timeout cancels the pending Studio run. | |
| fromModule | No | Optional module name whose runtime context should be used. Usually omit; discover module names with openl_list_project_modules(). | |
| withSchema | No | Include result and parameter JSON Schemas. Default false because schemas can be large. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the hidden asynchronous start-and-wait behavior, progress notifications, run cancellation when the MCP call is cancelled, and the session-level limitation on concurrent runs. These are behavioral traits not present in the annotations, which only provide openWorldHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence contributes necessary operational context: invocation shape, async behavior, parameter semantics, concurrency limits, and alternatives. It is front-loaded with the core purpose and then addresses edge cases in a logical order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, 7 parameters, absence of an output schema, and the need to coordinate Studio's async lifecycle, the description covers all critical guidance: input format, timeout behavior, schema inclusion, response format, session limits, and cancellation semantics. No essential calling information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description goes beyond the schema by explaining the accepted inputJson shapes, why { params: [...] } is rejected, how top-level arrays are interpreted, and when withSchema should be used. This materially reduces the chance of malformed calls.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the operation as executing a regular (non-Test) table with caller-provided JSON and returning the result. It explicitly contrasts with Test-table tools, so an agent can distinguish this from sibling tools without inspecting their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states when to use this tool: for a regular table run where the call itself waits for the asynchronous Studio run to finish. It explicitly directs agents to openl_start_project_tests and the test-result tools for Test tables, and it warns about the one-run-per-HTTP-session constraint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_save_projectSave Project to GitA
Save project changes to Git. Works only when project status is EDITING (after opening and making changes). Requires comment (used as revision/commit message). Creates a new revision and transitions project to OPENED. Optional closeAfterSave: true saves and closes in one request. Use after update_table, append_table, or other edits. Does not work for repository 'local'.
| Name | Required | Description | Default |
|---|---|---|---|
| comment | Yes | Required. Comment for the new revision (commit message). Save only works when project status is EDITING; after save a new revision is created and project transitions to OPENED. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| closeAfterSave | No | Optional. If true, close the project after saving (sends status CLOSED with comment in one request). Use when user asks to 'save and close'. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the provided openWorldHint annotation, the description discloses important behavioral side effects: it creates a new revision, transitions the project to OPENED, requires EDITING status, and supports a one-request save-and-close via closeAfterSave. This gives the agent a clear model of the tool's state-changing behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, with no filler. Each sentence carries essential information: core action, precondition, required parameter, side effects, optional flag, typical usage context, and an exclusion. It is easy to scan and understand quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a state-changing Git save operation with no output schema, the description provides all necessary context: preconditions, required inputs, side effects, optional behavior, typical invocation timing, and a clear limitation. The agent can select and invoke this tool correctly without additional documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all four parameters thoroughly. The description adds some reinforcement about 'comment' as the commit message and closeAfterSave behavior, but it does not provide significant meaning beyond what is already in the input schema. A baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Save project changes to Git'. It clearly identifies the tool's function and the key behavioral effects (creates a new revision, transitions to OPENED), distinguishing it from related siblings like openl_close_project or openl_open_project.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: only when project status is EDITING and after operations like update_table or append_table. It also states when-not-to-use: does not work for repository 'local'. This is strong situational guidance even without naming an alternative tool because this tool is the designated save operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_search_project_filesSearch Project FilesARead-onlyIdempotent
Search a project's files and folders by ant-glob path 'pattern' (e.g. 'rules//*.xlsx'), file 'extensions', resource 'type' (FILE/FOLDER/ANY), and/or a case-insensitive 'content' substring. Maps to POST /projects/{projectId}/file-search. CONTENT LIMITATION: Studio searches inside TEXT files only. It does not inspect binary formats such as XLSX/XLS/ZIP/images; find those only by path pattern, extension, or name, then read/download them separately. Combining content with a binary-only pattern or extension therefore returns no matches even when that text is visible in an Excel workbook. IMPORTANT: set recursive=true to search nested folders — by default (recursive omitted/false) only the project's TOP LEVEL is searched, and a '' glob alone does NOT descend (so a project-wide search needs recursive=true, and to match files in subfolders use a '/' pattern such as '/.xlsx', not '.xlsx'). Scope SUBTREE (default) searches within the project and may target a historical 'version'; scope ANCESTORS walks up to the repository root. Returns matching nodes (path, name, type, size, ...), paginated client-side via 'limit'/'offset' (the response carries pagination metadata; the server returns the full match set). Use 'branch' to pin the project's branch. Use this for questions like "where is portability loading mentioned in XML or Markdown?" (content, recursive=true) or "list every xlsx under rules" (pattern '**/*.xlsx', recursive=true, without content).
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | Project-relative path to start the search from. | |
| type | No | Restrict results to files, folders, or both (ANY, default). | |
| limit | No | ||
| scope | No | SUBTREE (default) searches within the project; ANCESTORS walks up to the repository root. | |
| branch | No | Branch the project must be on for this operation. Ignored when blank. Fails if the repository has no branches or the project is on another branch. Omit for repository 'local' and non-branch repositories. | |
| fields | No | Comma-separated response fields to return per result (e.g. 'path,name,type'). When omitted, the full response is returned. | |
| offset | No | ||
| content | No | Case-insensitive substring to match inside TEXT files only. Studio does not inspect binary content such as XLSX/XLS/ZIP/images; use pattern/extensions to locate binary files instead. | |
| pattern | No | Ant-glob path pattern, e.g. 'rules/**/*.xlsx' or '**/*.xml'. This can find binary files by path, but content is never searched inside them. | |
| version | No | Historical revision (commit hash) to search; SUBTREE scope only. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| recursive | No | Whether to descend into nested folders. IMPORTANT: defaults to false (top level only) — set true to search the whole project/subtree. A '**' glob still needs recursive:true to actually descend. | |
| extensions | No | Filter by file extensions without the dot, e.g. ['xlsx','xml']. With content, only matching text files are inspected; binary extensions such as xlsx can be located but not searched internally. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavior beyond the annotations: the text-only content limitation for binaries, the recursive default trap (top-level only; '**' alone does not descend), client-side pagination with the server returning the full match set, scope semantics for SUBTREE vs ANCESTORS, version targeting, and branch pinning behavior. None of this appears in the annotations, yet all of it shapes call results. The readOnlyHint=true annotation is fully consistent with the described search semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long (~200 words) but every section earns its place given 14 parameters and multiple non-obvious traps; critical warnings are front-loaded in CAPS and the core function leads the first sentence. It loses a point because it partially restates schema content — extensions, scope, recursive, and branch each already have parameter descriptions in the schema — making it denser than strictly necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description discloses the return shape ('path, name, type, size'), pagination behavior, endpoint mapping, scope/version/branch semantics, the binary content limitation, and recursion defaults. For a 14-parameter tool with three enums and a high trap surface, there is no meaningful missing context an agent would need before invoking it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high (86%), so the schema already documents most parameters; the description goes beyond it on the foot-gun parameters: recursive's '**' trap, content's text-only restriction, and pattern's binary caveat with the '**/' vs '*.xlsx' distinction. The description adds real nuance that the schema alone does not convey, though the schema still carries the primary weight for the majority of parameters, so a 4 is appropriate rather than a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names the exact verb, resource, and the four search dimensions ('ant-glob path pattern', 'extensions', 'type' FILE/FOLDER/ANY, case-insensitive 'content' substring). It maps to a concrete endpoint and ends with two realistic query examples that leave no doubt about what the tool does. The scope ('search a project's files and folders') clearly distinguishes it from siblings like openl_read_project_file, which reads a known file, and openl_list_projects, which lists projects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use guidance is given with concrete questions ('where is portability loading mentioned in XML or Markdown?') and the exact parameter recipe to answer them (content, recursive=true; pattern '**/*.xlsx', recursive=true, without content). It also states when NOT to use content search — binary files must be 'read/download them separately' — and warns that combining content with a binary pattern yields no matches. This is full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_set_trace_breakpointsRead / Replace BreakpointsA
Read the active breakpoint keys and the available targets (rule tables, deduplicated by name; with an active session only tables reachable from the traced one). When 'set' is provided it REPLACES the whole set first (empty array clears all). Key forms: '' stops at entry of every same-named table version; '' at that exact table (uri from frames[].uri); '#R{r}C{c}' at a spreadsheet cell; '#rule' when ANY rule of that decision table fires; '#' when a specific rule fires (rule names from openl_inspect_trace_frame ruleNames/decision). Append '@N' to any key to break only on the table's N-th execution (0-based) — e.g. '#R48C0@3'; without it a cell breakpoint hits every pass of a table that runs many times (one per coverage/iteration). N matches frames[].instance and the 'instance' of an openl_watch_trace_cells series, so a watch outlier at instance 3 is reached with '@3'. Works without a session — set breakpoints before openl_start_trace; changes during a session apply at the next frame enter or line change.
| Name | Required | Description | Default |
|---|---|---|---|
| set | No | When provided, REPLACES the whole breakpoint set (empty array clears all). Key forms: '<name>' (entry of any same-named table), '<uri>' (entry of that table), '<uri>#R{r}C{c}' (spreadsheet cell), '<uri>#rule' (any decision-table rule fires), '<uri>#<ruleName>' (specific rule fires). Append '@N' to any key to break only on the table's N-th execution (0-based, matching frames[].instance and a watch series' instance) — e.g. '<uri>#R48C0@3'. Omit to just read the current set and available targets. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the openWorldHint annotation, the description discloses replacement semantics, empty-array clearing, sessionless operation, session-dependent target filtering, and instance-matching behavior. This is rich behavioral context that significantly helps an agent predict side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but dense, front-loading the primary read/replace behavior before detailing key forms. Every section serves a purpose, though some key-form syntax is duplicated from the schema. This is acceptable for a complex tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers return values (active keys and available targets), replacement behavior, key forms, instance matching, and session timing. With no output schema, this is sufficient for an agent to invoke the tool correctly and interpret its result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema descriptions are already detailed. The description adds non-redundant semantics around '@N' matching frames[].instance and watch-series instances, plus timing of breakpoint changes. The repetition of key-form syntax is somewhat redundant but reinforces understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb-resource pair: read active breakpoint keys/targets and replace the whole breakpoint set when 'set' is provided. This distinguishes it from trace-control siblings like start/stop/step/resume trace.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete timing guidance: breakpoints can be set before a session, and changes during a session apply at the next frame enter or line change. It also explains the '@N' instance semantics relative to related tools like openl_watch_trace_cells. It does not explicitly name alternatives to prefer instead, but the tool is unique among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_start_project_testsStart Project TestsA
Start project test execution. For design repositories the project is automatically opened if closed; for repository 'local' the project is not opened (tests run directly). Returns execution status and metadata. Test results can be retrieved using openl_get_test_results_summary, openl_get_test_results, or openl_get_test_results_by_table.
| Name | Required | Description | Default |
|---|---|---|---|
| tableId | No | Table ID to run tests for a specific table. Table type can be test table or any other table. If not provided, tests for all test tables in the project will be run. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| fromModule | No | Module name to run tests from. | |
| testRanges | No | Test ranges to run. Can be provided only if tableId is Test table. Example: '1-3,5' to run tests with numbers 1,2,3 and 5. If not provided, all tests in the test table will be run. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only openWorldHint in annotations, the description carries the burden of behavioral context. It discloses a non-obvious side effect (automatic project opening for design repositories, not for local) and states the return type (execution status and metadata). It does not mention whether execution is asynchronous or blocks, but it provides meaningful behavior beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no filler: the main action is front-loaded, the repository-specific caveat follows, and the result-retrieval guidance closes it. Every sentence adds information that is not available from the schema alone.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter tool with no output schema, the description covers the lifecycle by saying what is returned and which sibling tools retrieve the actual results. It could be more explicit about whether the call blocks until tests finish or only kicks off execution, but the essential call-and-follow-up flow is clear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the property descriptions already explain projectId, tableId, fromModule, testRanges, and response_format. The description adds no parameter-level meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and object, 'Start project test execution,' which clearly distinguishes this from the many project-management and trace siblings. It further differentiates itself from the result-retrieval tools by name and by noting what happens after execution.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the action and covers a key conditional: design repositories auto-open the project, while 'local' runs tests directly. It also tells the agent where to get results afterward via openl_get_test_results_summary, openl_get_test_results, or openl_get_test_results_by_table, though it does not explicitly say when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_start_traceStart Debug SessionA
Start an interactive debug session for a table and run to the first stop. Returns the execution stack (status + frames root→current). Default stopAtEntry: true suspends at the entry of the first frame; from there use openl_step_trace / openl_resume_trace and openl_inspect_trace_frame. For test tables pass testRanges (e.g. '2'); for regular rules pass inputJson { params, runtimeContext? }; omitting both replays the previous run's remembered input. Cheapest way to understand a whole run: profiling: true with stopAtEntry: false and no breakpoints — completes in this one call and returns 'profile', a constant-size overview of the top-N slowest tables (selfMillis/totalMillis/count) plus nodeCount/distinctTables/totalMillis. For a profiling overview pass inputJson (or testRanges) together with profiling: true and stopAtEntry: false EXPLICITLY every time — do not rely on replay (omitting the input): a replay only reproduces the compact profile if the remembered run was itself a profiling run, otherwise it can return a much larger stack that overflows the response limit. Find the hot or unexpected table in profile.hotspots, then replay into it with a breakpoint to inspect live values. The executed 'tree' is omitted by default; set includeTree: true to get its ROOT node (one level — each step carries a childrenTotal count) and browse a branch level by level with openl_expand_trace_tree. One active session per user — starting a new one terminates the previous. Idle sessions are reaped after ~10 minutes.
| Name | Required | Description | Default |
|---|---|---|---|
| tableId | Yes | Table ID to debug (e.g., 'calculatePremium_1234'). Get from openl_list_tables(). | |
| inputJson | No | For regular rules: JSON input. Use object with params (required) and runtimeContext (optional). E.g. { params: { age: 25 }, runtimeContext: { lob: 'Auto' } }. Omit BOTH inputJson and testRanges to replay the previous run's remembered input (e.g. restarting with profiling or new breakpoints). | |
| profiling | No | Retain the executed call tree — structure and timings, NO values (default false). With stopAtEntry: false and no breakpoints the run completes in this single call and returns a constant-size 'profile' overview (top-N slowest tables); the tree's root node comes with includeTree: true and is browsed level by level with openl_expand_trace_tree. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| fromModule | No | Module name to trace in the context of a specific opened module. Usually omit. | |
| profileTop | No | Number of hotspots (slowest tables) in the 'profile' overview (backend default 20). | |
| testRanges | No | For test tables: comma-separated test-case ranges (e.g., '1-3,5'). Omit for regular rule execution. | |
| breakpoints | No | Initial breakpoint set — REPLACES the current set before starting. Key forms: '<name>' (entry of any same-named table), '<uri>' (entry of that table), '<uri>#R{r}C{c}' (spreadsheet cell), '<uri>#rule' (any decision-table rule fires), '<uri>#<ruleName>' (specific rule fires). Append '@N' to any key to break only on the table's N-th execution (0-based) — e.g. '<uri>#R48C0@3' hits the 4th run; N matches frames[].instance and a watch series' instance, so a watch outlier at instance 3 is reached with '@3'. Without '@N' a cell breakpoint hits EVERY pass. | |
| includeTree | No | Also return the executed call tree's ROOT node ('tree'), not just the bounded 'profile' overview (default false). Against a current OpenL Studio the tree is lazy — one level deep: the root's steps each carry a 'childrenTotal' count instead of nested children, so a large run is no longer returned whole. Drill into a branch with openl_expand_trace_tree; to find the hot table use 'profile' and replay into it with a breakpoint. | |
| stopAtEntry | No | Suspend at the entry of the first frame (default true). Set false to run straight to the first breakpoint — or, with no breakpoints, to completion. | |
| breakOnErrors | No | Suspend on an uncaught rule error so its frame can be inspected (backend default true). Set false to let the error terminate the run. | |
| detailedTitles | No | Build value-rich business-view titles in the retained tree (backend default false). This can substantially increase response size. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only openWorldHint in annotations, the description carries the full behavioral burden and does so thoroughly. It discloses session lifecycle ('One active session per user — starting a new one terminates the previous'), idle reaping, replay hazards and response-limit overflow, output shape for profiling, lazy tree behavior, and the meaning of profiling vs stack modes. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but it is dense and organized: core behavior, input-mode selection, profiling workflow, tree browsing, and session lifecycle. The front-loaded first sentence gives immediate orientation. A small amount of redundancy with the already-detailed schema descriptions prevents a perfect score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter, no-output-schema tool, the description is unusually complete. It explains what the response contains in each mode (stack frames, constant-size profile overview, lazy tree root), how to navigate the session using sibling tools, how to handle replay, and what side effects to expect. Nothing critical for selecting or invoking the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description adds meaningful cross-parameter guidance beyond the schema: combining inputJson/testRanges with profiling: true and stopAtEntry: false, the explicit warning against relying on replay, and the workflow of finding a hot table and replaying into it with a breakpoint. It does not rename or redefine individual parameters, so it stops short of a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb-and-resource statement: 'Start an interactive debug session for a table and run to the first stop.' It also names the related trace tools it coordinates with, so an agent can clearly distinguish this entry point from openl_step_trace, openl_resume_trace, openl_inspect_trace_frame, and openl_expand_trace_tree.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: test tables vs regular rules, replay behavior when both inputs are omitted, when to set profiling: true, and why profiling should be requested explicitly rather than via replay. It also routes the agent from this call to follow-up tools like openl_step_trace, openl_resume_trace, openl_inspect_trace_frame, and openl_expand_trace_tree.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_step_traceStep (Into / Over / Out)A
Step the suspended debug session once and return the new stack. For declarative rules (decision tables, spreadsheets, rating) the main move is type: 'out' — run the current frame to its own exit so its result is inspectable — combined with breakpoints; 'into'/'over' are advanced (imperative TBasic/loops). A step that finishes a frame first suspends at that frame's exit — the frame is still on the stack with completed: true and its result readable via openl_inspect_trace_frame (or pass withValues: true to bundle those variables into this response); the next step continues in the caller. An exception suspends at the throwing frame before it propagates. The stack is returned compact — steps only for the active frame; use openl_inspect_trace_frame for another frame's detail. Valid only while suspended. (openl_resume_trace differs: it runs to the next breakpoint or completion, not just to this frame's exit.)
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | 'out' (main tool for declarative rules — decision tables, spreadsheets, rating): run the current frame to its own exit so its result is inspectable, then continue in the caller. 'into' / 'over' are ADVANCED (imperative TBasic / loops): 'into' enters the next call or sub-step; 'over' advances to the next sub-step of the current frame (nested calls run through). For 'which table returned what', prefer 'out' plus breakpoints over stepping through expressions. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| profileTop | No | Number of hotspots (slowest tables) in the 'profile' overview (backend default 20). | |
| withValues | No | After the step, also return the active frame's variables (the same content as openl_inspect_trace_frame on the top frame) as 'variables' — saves the usual step→inspect round-trip when you step 'out' to read a frame's result. Default false. | |
| includeTree | No | Also return the executed call tree's ROOT node ('tree'), not just the bounded 'profile' overview (default false). Against a current OpenL Studio the tree is lazy — one level deep: the root's steps each carry a 'childrenTotal' count instead of nested children, so a large run is no longer returned whole. Drill into a branch with openl_expand_trace_tree; to find the hot table use 'profile' and replay into it with a breakpoint. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses several non-obvious behaviors not present in the annotations: finishing a frame suspends at that frame's exit with completed: true, the next step continues in the caller, exceptions suspend at the throwing frame, and the returned stack is compact with only the active frame's steps. This substantially exceeds what annotations alone provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: core action, mode selection, frame-exit behavior, exception behavior, response shape, validity condition, and sibling differentiation. It is front-loaded with the essential operation before diving into nuances.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even without an output schema, the description explains what the response contains (the new stack, optional variables, optional tree root), how the compact stack is scoped, when variables can be bundled, and how to get details for other frames. This is complete for a tool with significant debug-session complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and parameter descriptions are already thorough, so the baseline is 3. The description adds extra strategic meaning beyond the schema, especially around the 'type' parameter ('out' plus breakpoints for declarative rules, into/over advanced) and the value of 'withValues' for avoiding a separate inspect round-trip.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and resource: 'Step the suspended debug session once and return the new stack.' It clearly differentiates this stepping behavior from related trace operations and the description goes on to contrast with openl_resume_trace and openl_inspect_trace_frame.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: it is 'Valid only while suspended,' recommends 'out' as the main move for declarative rules, marks 'into'/'over' as advanced for imperative code, and names alternatives such as openl_resume_trace and openl_inspect_trace_frame with the conditions that select them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_stop_traceTerminate Debug SessionAIdempotent
Terminate the debug session and free its worker and lazy-value registry. Idempotent — succeeds even when no session is active. Breakpoints survive (they are session-scoped, not run-scoped).
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the idempotentHint annotation by explaining what gets freed, that the call is safe when no session exists, and that breakpoints are session-scoped rather than run-scoped. No annotation contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, high-information sentences with the core action first, then idempotence, then a meaningful behavioral caveat. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter idempotent cleanup tool, the description fully explains purpose, side effects, safe-call behavior, and breakpoint persistence. No output schema is required to make the invocation decision clear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including a detailed projectId description and response_format enum. The tool description adds no parameter-level semantics, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource: 'Terminate the debug session' and further specifies 'free its worker and lazy-value registry.' This clearly distinguishes it from sibling trace tools like start_trace, step_trace, and resume_trace.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides useful context for when to call it by noting idempotence ('succeeds even when no session is active') and that breakpoints survive termination. It doesn't explicitly name alternative debug-control tools or state 'use when you are done debugging,' but the guidance is nonetheless clear and practical.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_unmerge_table_cellsUnmerge Table Cells (raw)AIdempotent
Unmerge the merged cell that covers ('row','column') in a table's raw source, splitting it back into individual cells. Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| row | Yes | 0-based row index of any cell in the merged region (0..height-1). | |
| column | Yes | 0-based column index of any cell in the merged region (0..width-1). | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the openWorldHint and idempotentHint annotations, the description discloses important side effects: an edit that relocates the table changes its location-derived id, the response returns the current tableId plus previousTableId when changed, and the tool triggers a recompile because the studio does not auto-compile. These are exactly the behavioral details an agent needs to sequence subsequent calls correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loads the core action before explaining coordinate semantics, id volatility, and compile behavior. A few phrases such as 'raw source' are repeated, but every sentence carries necessary operational information; nothing is fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema, the description compensates by explaining the key response fields (current tableId, previousTableId) and the recompile side effect. Coupled with full parameter schema coverage, the description gives an agent everything needed to invoke the tool and handle the consequences of the edit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all five parameters. The description adds meaningful semantic context on top: positions are 0-based, row 0 is the header row, column 0 carries leading labels, and tableId is volatile and should be taken from the latest response. This is genuine added value beyond the parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific operation ('Unmerge the merged cell that covers ('row','column')'), a specific resource ('in a table's raw source'), and the result ('splitting it back into individual cells'). It also differentiates the raw-source mode from the sibling openl_merge_table_cells and from general table update tools, so an agent can tell what this tool does without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives useful context by emphasizing that it operates on the RAW source and 'works for any table type,' which implies broad applicability. However, it does not explicitly say when to prefer this tool over alternatives such as openl_update_table_cell or openl_merge_table_cells, nor does it state any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_update_tableReplace Entire TableADestructiveIdempotent
Replace the ENTIRE table RawSource matrix with a modified version. Typed table DTOs are intentionally unsupported. Use for modifying, reordering, or structural changes that preserve or add rows; row removal is rejected, so use openl_delete_table_rows with an explicit position/count. Prefer the narrow raw action tools for isolated edits and append_table for additions. Required workflow: call get_table() without styles=true, preserve the complete matrix including covered cells/spans, modify it, then pass the full RawSource object here. Before writing, the tool reads one live row to verify the submitted source is not shorter than the table; this prevents a sliced view from deleting unseen rows even if totalRows was removed. Studio table write APIs cannot change formatting, so cell style is read-only and rejected. The response returns the CURRENT tableId after relocation. The tool reads the table back to trigger recompilation, so openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| view | Yes | Full, non-windowed RawSource structure from openl_get_table() with modifications applied. Send the complete source matrix, not only changed cells; a view carrying totalRows is rejected, and the handler independently rejects a source with fewer rows than the live table. | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations (destructiveHint, idempotentHint, openWorldHint) are substantially augmented, not contradicted: the description discloses the pre-write verification read, rejection of row removal and style, the volatile tableId relocation behavior, and the read-back that triggers recompilation affecting openl_project_status. This contextualizes the destructiveHint rather than merely repeating it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries distinct information and purpose is front-loaded, but the description is dense and slightly overlaps schema content (e.g., style read-only rejection is also documented in the source items schema). The length is justified by the tool's risk profile and complexity, though a bit of tightening is possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-complexity, destructive whole-table replacement with no output schema, the description covers: what to send, what is rejected (row removal, style, typed DTOs, windows), the safety verification mechanism, the critical volatile return (CURRENT tableId after relocation), and the recompilation side effect. Nothing an agent needs to call it safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with rich per-property docs, so baseline is 3. The description adds a concrete construction recipe for the complex view/source parameter (call get_table without styles=true, preserve covered cells and spans, modify, pass the full RawSource) and explains why the source cannot be shorter than the live table, which goes modestly beyond the schema's static descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: 'Replace the ENTIRE table RawSource matrix with a modified version.' It distinguishes itself from siblings by stating what it is for (modifying, reordering, structural changes) and what it is not for (row removal → openl_delete_table_rows; isolated edits → narrow raw action tools; additions → append_table). An agent can select it correctly without inspecting sibling schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (modifying/reordering/structural changes that preserve or add rows), when not to (row removal is rejected), and names concrete alternatives (openl_delete_table_rows, narrow raw action tools, append_table). It also mandates a required workflow (get_table without styles=true → preserve matrix → modify → pass full RawSource), leaving no ambiguity about prerequisites or ordering.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_update_table_cellUpdate Table Cell (raw)AIdempotent
Update the value of a single existing cell at ('row','column') in a table's raw source. 'value' is required: pass a string/number/boolean to set the cell, or null to clear it. Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| row | Yes | 0-based row index of the cell (0..height-1). | |
| value | Yes | New cell value (string, number, or boolean) to set, or null to clear the cell. Required — pass null explicitly to clear so the intent is unambiguous. | |
| column | Yes | 0-based column index of the cell (0..width-1). | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations, revealing that edits can relocate the table and change its location-derived id, that the response returns the current tableId plus previousTableId, and that the tool reads the table back to trigger recompile. This is exactly the behavioral context an agent needs to safely chain calls.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: purpose, value semantics, raw-source behavior, coordinate conventions, id volatility, and recompile side effect. Critical operational details are front-loaded before the less central compile note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating table cell tool with no output schema, the description fully covers what the agent needs: required value semantics, coordinate system, raw-source behavior, id changes, and side effects on project status. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds useful context: null is the explicit way to clear, row 0 is the header row, column 0 carries leading labels, and the returned tableId should be used for subsequent calls. This enriches the schema's already-solid parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the specific verb ('Update'), the exact resource ('a single existing cell at ('row','column')'), and the scope ('raw source, works for any table type'). This clearly distinguishes it from sibling tools like openl_update_table_row, openl_update_table_column, and openl_update_table_range.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes clear this is for editing one raw-source cell and works across table types, which implies when it applies. However, it does not explicitly name alternatives or state when NOT to use it, leaving some routing inference to the agent rather than spelling out exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_update_table_columnUpdate Table Column (raw)AIdempotent
Overwrite the cells of an existing column at 'position' (0..width-1) in a table's raw source, top to bottom. The table is not resized. Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| cells | Yes | Column cells, top to bottom. Required and non-empty — provide one cell per row (use { value: null } for a blank cell). A cell may set colspan/rowspan to merge. Must not be taller than the table. | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| position | Yes | 0-based index of the column to overwrite (0..width-1). The table is not resized. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses important non-obvious behavior: an edit relocating the table changes its location-derived id and the response returns currentTableId plus previousTableId; the studio does not auto-compile and the tool reads the table back to trigger recompile. This is exactly the kind of behavioral context an agent needs, and it does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is relatively long but every section earns its place: operation, positioning, raw-source scope, id volatility, and recompile behavior. It is front-loaded with the core action. There is minor redundancy with the schema for 0-based positioning, but the extra context is valuable enough to justify the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex table mutation tool with no output schema, the description covers the critical operational details: position bounds, header/label conventions, no resize, raw source behavior, id relocation, response tableId semantics, and recompile triggering. It does not describe the full response shape beyond the id, but the schema and response_format parameter cover the important remaining usage details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so a baseline of 3 is appropriate. The description adds value by clarifying positional semantics not fully captured in the schema: 'row 0 is the header row, column 0 carries the leading labels' and that cells are written 'top to bottom.' This helps an agent construct the cells array correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Overwrite the cells of an existing column at position (0..width-1)... top to bottom.' It also clarifies the scope ('the table is not resized', 'works for any table type'), making it clearly distinguishable from sibling table tools like openl_update_table_cell or openl_update_table_range even though no sibling is named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context: it updates an existing column, is not for resizing, and works on the RAW source for any table type. However, it never explicitly says when to prefer this over siblings such as openl_update_table_row, openl_update_table_cell, or openl_append_table_columns, and no alternatives or exclusions are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_update_table_rangeUpdate Table Range (raw)AIdempotent
Overwrite a rectangular RANGE of cells in place, anchored at the top-left ('row','column'), in a table's raw source. 'cells' is a 2D array (rows × that row's cells); the range must cover more than one cell and fit within the table (not resized). For a single cell use openl_update_table_cell. Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| row | Yes | 0-based row index of the top-left cell of the range (0..height-1). | |
| cells | Yes | Block rows top to bottom, each a non-empty list of cells left to right. Anchored at ('row','column'); must cover more than one cell and fit within the table (the table is not resized). | |
| column | Yes | 0-based column index of the top-left cell of the range (0..width-1). | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses several non-obvious behaviors beyond the annotations: an edit that relocates the table changes its location-derived id; the response always returns the current tableId and previousTableId when changed; the studio does not auto-compile after an edit; and the tool reads the table back to trigger recompile so openl_project_status reflects the change. This is rich, valuable context that annotations (openWorldHint, idempotentHint) do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense with no filler, front-loading the core action and then layering constraints, coordinate conventions, and side-effect warnings. It is longer than strictly necessary but every sentence attends to a distinct fact an agent needs; the structure is well-ordered with the alternative usage and important id-volatility caveat placed logically near related facts.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no output schema and only abstract annotations, the description covers all critical operational context: what happens to the table and its id, how the response reports the current id, the recompile side-effect, coordinate conventions, and the single-cell alternative. An agent has enough information to invoke the tool correctly and reason about follow-up calls.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema: it clarifies the 2D structure of 'cells', the anchoring of ('row','column'), the 0-based coordinate system with row 0 as the header row and column 0 carrying leading labels, and the 'not resized' constraint. This is genuinely useful contextual enrichment, though it also repeats some schema details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and object: 'Overwrite a rectangular RANGE of cells in place, anchored at the top-left ('row','column')'. It clearly identifies the resource (a table's raw source), the operation (overwrite), and the shape (rectangular range), which distinguishes it from the single-cell sibling openl_update_table_cell.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly names an alternative: 'For a single cell use openl_update_table_cell.' It also provides boundary conditions — the range must cover more than one cell, must fit within the table, and operates on the raw source for any table type — which help an agent decide when this tool is appropriate versus other table-edit siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_update_table_rowUpdate Table Row (raw)AIdempotent
Overwrite the cells of an existing row at 'position' (0..height-1) in a table's raw source, left to right. The table is not resized. Operates on the table's RAW source, so it works for any table type. Positions are 0-based (row 0 is the header row, column 0 carries the leading labels). An edit that relocates the table (it had no room to grow in place) CHANGES its location-derived id; the response always returns the table's CURRENT id as 'tableId' (plus previousTableId when it changed) — use it for subsequent calls. Note: the studio does not auto-compile after an edit; this tool reads the table back to trigger the recompile, so a subsequent openl_project_status reflects the change.
| Name | Required | Description | Default |
|---|---|---|---|
| cells | Yes | Row cells, left to right. Required and non-empty — provide one cell per column (use { value: null } for a blank cell). A cell may set colspan/rowspan to merge. Must not be wider than the table. | |
| tableId | Yes | Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables(). | |
| position | Yes | 0-based index of the row to overwrite (0..height-1). The table is not resized. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the minimal openWorldHint/idempotentHint annotations, the description discloses substantial non-obvious behavior: the location-derived tableId can change after relocation, the response returns tableId/previousTableId, and the tool triggers recompile by reading the table back. It also explains the raw-source operation and that the table is not resized.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences carry high-value caveats without filler. The description is front-loaded with the core overwrite operation, and each subsequent sentence adds necessary context about raw-source behavior, position semantics, ID volatility, and recompilation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description covers the most important return behavior (current tableId and previousTableId) and the recompile side effect. It does not detail the full response shape or failure modes, but the operation, constraints, and follow-up guidance are sufficiently complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, providing the baseline. The description still adds value by clarifying position semantics (row 0 is the header row, column 0 holds leading labels) and by warning that tableId is volatile and should be refreshed from the response. This is above the schema-only baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Overwrite') and resource ('cells of an existing row at position in raw source'), and clarifies left-to-right order and no resizing. This distinguishes it from sibling tools like openl_update_table_cell, openl_update_table_column, and openl_insert_table_rows.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives context for when it applies (raw source, any table type, existing row, no resize) but does not explicitly state when to prefer it over siblings or which alternative to use for appending/inserting/resizing rows. The intended usage is implied rather than stated as decision guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_watch_trace_cellsWatch Cells Across a RunA
Answer 'show me this factor across all coverages/iterations' in one call, without dumping frames. Watch SCALAR cells (a single number/string factor, e.g. '$VehiclePriceFactor') — NOT a cell whose value is a big aggregate object (a whole spreadsheet result like '$RateCardPremium'), which makes every captured point huge and can overflow the response; drill into an aggregate with a breakpoint + openl_inspect_trace_frame instead. Runs the table to completion and returns a WatchView: one 'series' per cell with a 'points' array holding the cell's value at each execution of its table (each point carries instance/label/ref/path; value is serialized like any traced value and may come lazy — expand a large one with openl_get_trace_value using its parameterId). Read the series, spot the outlier (e.g. 83.372 among 1.0s), then jump straight to that pass: set a breakpoint '<point.ref>@<point.instance>' (the '@N' suffix targets the N-th execution — same 0-based numbering as the series' 'instance') and replay + openl_inspect_trace_frame to see why. Value JSON Schemas are omitted by default (withSchema: true restores them). Captures cells inside lazy result branches too (nested SpreadsheetResult[]) — the run materializes the whole result. The server caps points per series for a cell deep in a combinatorial branch (benefit × gender × age-band …); each series reports 'total' (the full execution count) and WatchView.truncated flags that some late executions were dropped — inspect a specific one with a '@N' breakpoint. Pass testRanges for a test table or inputJson for a regular rule (omit both to replay the remembered input). This starts a fresh session (terminates any previous one) and clears breakpoints so the run reaches completion.
| Name | Required | Description | Default |
|---|---|---|---|
| cells | Yes | Cell names to watch, e.g. ['$VehiclePriceFactor']. The value of each named cell is captured at EVERY execution of its table across the whole run — one series per cell. | |
| tableId | Yes | Table ID to run (e.g., 'calculatePremium_1234'). Get from openl_list_tables(). | |
| inputJson | No | For regular rules: JSON input { params, runtimeContext? }. Omit BOTH inputJson and testRanges to replay the previous run's remembered input. | |
| projectId | Yes | Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting. | |
| fromModule | No | Module name to run in the context of a specific opened module. Usually omit. | |
| testRanges | No | For test tables: comma-separated test-case ranges (e.g., '1-3,5'). | |
| withSchema | No | Include each watched value's JSON Schema (default false — the schema is large and rarely needed; a value that came lazy still carries its parameterId for openl_get_trace_value). | |
| response_format | No | Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide openWorldHint, so the description carries the full behavioral burden — and it delivers. It discloses side effects (starts a fresh session, terminates previous ones, clears breakpoints), server-side truncation with 'total' and 'truncated' flags, lazy value serialization, and the exact WatchView response shape. It even warns about oversized aggregate values overflowing the response.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but every sentence earns its place for a tool with 8 parameters and no output schema. It is front-loaded with the core purpose, then moves through exclusions, workflow, edge cases, and parameter selection in a logical sequence. The density is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description fully explains the WatchView result: one series per cell, points arrays with instance/label/ref/path, 'total', and truncation flags. It also covers nested lazy branches, overflow risks, breakpoint workflow, and input selection. An agent has everything needed to call and interpret this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description still adds meaningful semantics beyond the schema: inputJson/testRanges interplay and the 'replay the remembered input' behavior, withSchema's impact on large schemas, and the '@N' 0-based instance numbering tied to series entries. This extra context helps an agent choose and combine parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear mission: answer 'show me this factor across all coverages/iterations' in one call without dumping frames. It names the exact resource (SCALAR cells like '$VehiclePriceFactor') and explicitly contrasts this with aggregate-object cells, making the tool's scope unambiguous. It also differentiates from sibling tools like openl_inspect_trace_frame and openl_get_trace_value.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: watch scalar cells, not aggregate objects, and drill into aggregates with a breakpoint plus openl_inspect_trace_frame instead. It also explains when to use testRanges vs inputJson vs omitting both, and how to use a '<ref>@N' breakpoint for specific passes. This is modelable decision logic, not just a vague hint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openl_write_project_fileWrite Project FileA
Create or replace a file in a project by its project-relative path. Provide UTF-8 text in 'content'. For binary files such as xlsx/images/zip, provide base64 bytes in 'blob'; its advertised JSON Schema uses contentEncoding='base64'. The legacy content + encoding='base64' form remains accepted. COMMIT: pass 'message' to commit the write to Git (a new revision is created); omit 'message' and the write stays in the project WORKING COPY (commit it later with openl_save_project). Committing saves ALL pending project changes and works only for design repositories (not 'local'). By default missing parent folders are created (createFolders=true). If the target file already EXISTS, behavior follows conflictPolicy: FAIL (default) returns an error; OVERWRITE replaces the file in place; SKIP leaves the existing file unchanged (reported skipped). Use 'branch' to pin the project's branch (omit for local/non-branch repositories). Use this to add or update docs, schemas, or manifests. (For a NEW file the tool POSTs/creates; OVERWRITE is performed via PUT/update — overwriting a module .xlsx replaces its bytes but to change a module's TABLES use openl_update_table / openl_append_table / openl_create_project_table.)
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only openWorldHint, so the description carries the full behavioral burden and meets it impressively. It discloses the significant side effect that committing saves ALL pending project changes (no per-file commit), the working-copy vs Git-revision distinction, the local-repository exception, folder auto-creation behavior, the FAIL/OVERWRITE/SKIP conflict semantics, branch-pinning behavior, and the module-.xlsx bytes-vs-tables nuance. No contradiction with the openWorldHint annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every block earns its place given the tool's three input modalities, commit semantics, and conflict policy. It is logically front-loaded: purpose → content types → commit behavior → folder creation → conflict handling → branch → use case → table-tool routing. Minor redundancy exists where the message explanation nearly duplicates the schema's message parameter description, but this repetition is acceptable given the importance of the commit side effect.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex mutation tool with no output schema and minimal annotations, the description covers an exceptional amount: content types, commit side effects, conflict policies, folder creation, branch semantics, and sibling-tool routing. The remaining gaps are the return value structure (no output schema exists and the description doesn't characterize the response beyond response_format options) and permission/authentication requirements. These are minor against the overall coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real value by explaining the relationship between the three anyOf modalities: UTF-8 text goes in 'content', binary goes in 'blob' (with an explicit note that its schema uses contentEncoding='base64'), and the legacy content + encoding='base64' form remains accepted. This disambiguation is crucial because the raw anyOf structure alone would leave an agent unsure which branch to pick. The description also adds the 'committing saves ALL pending changes' semantic that enriches the message parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb and resource ('Create or replace a file in a project by its project-relative path') and immediately clarifies scope. It goes further by distinguishing file writes from table operations, naming openl_update_table / openl_append_table / openl_create_project_table as the tools for changing a module's TABLES, and separating itself from the many file-sibling tools (read/delete/copy/move) via the clear create-or-replace framing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Use this to add or update docs, schemas, or manifests.' It also states an explicit exclusion — overwriting a module .xlsx replaces bytes only, but changing TABLES requires the table tools — and names the commit-later alternative (openl_save_project). The commit-vs-working-copy decision is spelled out in terms of message presence, leaving no ambiguity about how to select behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
76 tool updates
v1.2.0- Changed
openl_append_table8 fields changed- added
Input schema / properties / appendData / additionalPropertiesAdded value: +false - changed
Input schema / properties / appendData / descriptionPrevious value: -"Data structure to append to the table. Structure depends on tableType: Datatype uses 'fields'; SimpleRules/SmartRules use 'rules'; SimpleLookup/SmartLookup use 'rows' (array of maps); Data/Test use 'rows' (array of { values }); SimpleSpreadsheet uses 'steps'; Spreadsheet uses 'rows' (row headers) + 'cells' (2D cell array); Vocabulary uses 'values'; RawSource uses 'rows' (array of cell-arrays)."New value: +"RawSource append payload. Typed table append DTOs are intentionally unsupported because they are lossy and incomplete." - removed
Input schema / properties / appendData / oneOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "fields": { - "description": "Array of field definitions to append", - "items": { - "additionalProperties": false, - "properties": { - "defaultValue": { - "description": "Default value for the field" - }, - "name": { - "description": "Field name", - "type": "string" - }, - "required": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ], - "description": "Whether the field is required (backend field is a String; a boolean is accepted and coerced)." - }, - "type": { - "description": "Field type (e.g., 'String', 'int', 'double')", - "type": "string" - } - }, - "required": [ - "name", - "type" - ], - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "Datatype", - "type": "string" - } - }, - "required": [ - "tableType", - "fields" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "rules": { - "description": "Array of rule objects to append. Each rule is a map with condition and action columns.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SimpleRules", - "type": "string" - } - }, - "required": [ - "tableType", - "rules" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "steps": { - "description": "Array of spreadsheet steps to append: [{ name, type?, value }].", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "description": "Step name (referenced elsewhere as $StepName).", - "type": "string" - }, - "type": { - "description": "Step result type, e.g. 'Double'.", - "type": "string" - }, - "value": { - "description": "The step's formula or value, e.g. '= app.annualIncome / 12'. NOT 'formula'." - } - }, - "required": [ - "name", - "value" - ], - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SimpleSpreadsheet", - "type": "string" - } - }, - "required": [ - "tableType", - "steps" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "cells": { - "description": "Required. Cells to append as a non-empty 2D array — one inner array (the row's cells across the columns) per appended row: [[{ value }]]. The formula/value goes in each cell's 'value'.", - "items": { - "items": { - "additionalProperties": false, - "properties": { - "value": {} - }, - "required": [ - "value" - ], - "type": "object" - }, - "type": "array" - }, - "minItems": 1, - "type": "array" - }, - "rows": { - "description": "Optional spreadsheet row headers to append: [{ name, type? }] — when provided, one per appended row (must align 1:1 with 'cells').", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "description": "Row name (referenced elsewhere as $RowName).", - "type": "string" - }, - "type": { - "description": "Row result type, e.g. 'Double', 'String'.", - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "Spreadsheet", - "type": "string" - } - }, - "required": [ - "tableType", - "cells" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "rules": { - "description": "Array of rule objects to append. Each rule is a map with condition and action columns.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SmartRules", - "type": "string" - } - }, - "required": [ - "tableType", - "rules" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "tableType": { - "const": "Vocabulary", - "type": "string" - }, - "values": { - "description": "Array of vocabulary values to append: [{ value }].", - "items": { - "additionalProperties": false, - "properties": { - "value": {} - }, - "required": [ - "value" - ], - "type": "object" - }, - "type": "array" - } - }, - "required": [ - "tableType", - "values" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "rows": { - "description": "Array of lookup rows to append; each row is a map keyed by the table's columns.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SimpleLookup", - "type": "string" - } - }, - "required": [ - "tableType", - "rows" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "rows": { - "description": "Array of lookup rows to append; each row is a map keyed by the table's columns.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SmartLookup", - "type": "string" - } - }, - "required": [ - "tableType", - "rows" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "rows": { - "description": "Array of data rows to append: [{ values: [...] }] (one value per column).", - "items": { - "additionalProperties": false, - "properties": { - "values": { - "items": {}, - "type": "array" - } - }, - "required": [ - "values" - ], - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "Data", - "type": "string" - } - }, - "required": [ - "tableType", - "rows" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "rows": { - "description": "Array of test cases to append: [{ values: [...] }] (one value per header column).", - "items": { - "additionalProperties": false, - "properties": { - "values": { - "items": {}, - "type": "array" - } - }, - "required": [ - "values" - ], - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "Test", - "type": "string" - } - }, - "required": [ - "tableType", - "rows" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "rows": { - "description": "Array of rows to append; each row is an array of cell objects (e.g. { value: string, colspan?: number } or { covered?: boolean }). Each row must cover ALL columns of the table (read it back with openl_get_table(raw=true) to see the width) — use { value: \"\" } for intentionally blank cells; a row narrower than the table is rejected before anything is written.", - "items": { - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "type": "array" - }, - "tableType": { - "const": "RawSource", - "type": "string" - } - }, - "required": [ - "tableType", - "rows" - ], - "type": "object" - } -] - added
Input schema / properties / appendData / propertiesAdded value: +{ + "rows": { + "description": "Non-empty source rows to append. Every row must cover the table's full width; use { value: null } for an intentionally blank cell.", + "items": { + "items": { + "additionalProperties": false, + "description": "Writable raw cell. Studio exposes style only when reading with styles=true; table write APIs do not support changing style, so style is intentionally rejected.", + "properties": { + "cell": { + "type": "string" + }, + "colspan": { + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "covered": { + "type": "boolean" + }, + "rowspan": { + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "value": {} + }, + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "minItems": 1, + "type": "array" + }, + "tableType": { + "const": "RawSource", + "type": "string" + } +} - added
Input schema / properties / appendData / requiredAdded value: +[ + "tableType", + "rows" +] - added
Input schema / properties / appendData / typeAdded value: +"object" - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_append_table_columns2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_append_table_rows2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_cancel_merge_conflicts - Removed
openl_cancel_trace - Added
openl_check_project_merge - Changed
openl_close_project2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_copy_project_file2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_copy_table - Changed
openl_create_project6 fields changed- changed
Input schema / properties / branch / descriptionPrevious value: -"Target branch (the ticket's `defaultBranch`). Honored when CLONING (the source is read from and the clone written to this branch). For a BLANK project, omit this — blank projects are created on the repository's default branch (the create endpoint cannot target a branch); passing branch without template is rejected."New value: +"Target branch for either BLANK creation or CLONING. Omit for the repository's configured/default branch. Studio selects an existing branch case-insensitively; when the branch does not exist, Studio may create it from the repository base branch. Use openl_list_branches() first to avoid accidental branch creation." - changed
Input schema / properties / comment / descriptionPrevious value: -"Commit comment for audit. Applied when creating a BLANK project; clone commit messages are system-generated. Defaults to 'Project <name> is created.' when omitted."New value: +"Commit comment for audit. Applied to both BLANK creation and CLONING; Studio supplies its configured create/copy comment when omitted." - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context" - changed
Input schema / properties / template / descriptionPrevious value: -"How to create the project (the ticket's `template`). OMIT to create a BLANK project from the default empty skeleton. To CLONE an existing project, pass its name (from openl_list_projects()): its full structure is copied (rules, tests, settings, request/response examples) and the project is renamed to projectName. The clone source must be in the same repository."New value: +"How to create the project (the ticket's `template`). OMIT to create a BLANK project from the default empty skeleton. To CLONE an existing project, pass its exact opaque projectId from openl_list_projects() without modification: its full structure is copied (rules, tests, settings, request/response examples) and the project is renamed to projectName. Never pass the displayed project name because mapped repositories may contain multiple projects with the same name." - added
Input schema / properties / template / minLengthAdded value: +1
- Changed
openl_create_project_branch2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_create_project_table9 fields changed- added
Input schema / properties / modulePathAdded value: +{ + "description": "Project-relative .xlsx path for a new module. When omitted, moduleName must identify an existing module.", + "pattern": ".+\\.xlsx$", + "type": "string" +} - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context" - added
Input schema / properties / table / additionalPropertiesAdded value: +false - removed
Input schema / properties / table / descriptionRemoved value: -"Complete table structure (EditableTableView), selected by the CASE-SENSITIVE 'tableType' discriminator (Datatype, Vocabulary, Spreadsheet, SimpleSpreadsheet, SimpleRules, SmartRules, SimpleLookup, SmartLookup, Data, Test, RawSource — lowercase like 'datatype' is rejected). Each table type has a DIFFERENT shape (shown per branch); the backend rejects unknown/extra fields with a 400 'Failed to read request'. Rules tables use args/returnType/headers[{title}]/rules; Data and Test tables use headers[{fieldName}]/rows[{values}] (Test also needs testedTableName) — do NOT mix the two. There is NO 'signature' field. Tip: openl_get_table() on an existing table of the SAME type returns this exact shape to copy." - removed
Input schema / properties / table / oneOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "extends": { - "description": "Parent datatype to extend, if any.", - "type": "string" - }, - "fields": { - "description": "Field definitions: [{ name, type }].", - "items": { - "additionalProperties": false, - "properties": { - "defaultValue": {}, - "name": { - "type": "string" - }, - "required": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ], - "description": "Whether the field is required (backend stores a String; a boolean is accepted and coerced)." - }, - "type": { - "type": "string" - } - }, - "required": [ - "name", - "type" - ], - "type": "object" - }, - "type": "array" - }, - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "tableType": { - "const": "Datatype", - "type": "string" - } - }, - "required": [ - "tableType", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "tableType": { - "const": "Vocabulary", - "type": "string" - }, - "type": { - "description": "Vocabulary element type.", - "type": "string" - }, - "values": { - "description": "Vocabulary values: [{ value }].", - "items": { - "additionalProperties": false, - "properties": { - "value": {} - }, - "required": [ - "value" - ], - "type": "object" - }, - "type": "array" - } - }, - "required": [ - "tableType", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "args": { - "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "description": "Parameter name, e.g. 'app'.", - "type": "string" - }, - "type": { - "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", - "type": "string" - } - }, - "required": [ - "name", - "type" - ], - "type": "object" - }, - "type": "array" - }, - "collect": { - "type": "boolean" - }, - "headers": { - "description": "Column captions, e.g. [{title:'creditScore'},{title:'RET1'}].", - "items": { - "additionalProperties": false, - "properties": { - "title": { - "description": "Column caption.", - "type": "string" - } - }, - "required": [ - "title" - ], - "type": "object" - }, - "type": "array" - }, - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "returnType": { - "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", - "type": "string" - }, - "rules": { - "description": "Rows as maps keyed by the header titles, e.g. { creditScore: '< 580', RET1: 'Poor' }.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SimpleRules", - "type": "string" - } - }, - "required": [ - "tableType", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "args": { - "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "description": "Parameter name, e.g. 'app'.", - "type": "string" - }, - "type": { - "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", - "type": "string" - } - }, - "required": [ - "name", - "type" - ], - "type": "object" - }, - "type": "array" - }, - "collect": { - "type": "boolean" - }, - "headers": { - "description": "Condition column headers: [{ title, width? }].", - "items": { - "additionalProperties": false, - "properties": { - "title": { - "description": "Condition column caption.", - "type": "string" - }, - "width": { - "description": "Number of condition columns this header spans (defaults to 1).", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "type": "object" - }, - "type": "array" - }, - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "returnType": { - "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", - "type": "string" - }, - "rules": { - "description": "Rows as maps keyed by the header captions.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SmartRules", - "type": "string" - } - }, - "required": [ - "tableType", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "args": { - "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "description": "Parameter name, e.g. 'app'.", - "type": "string" - }, - "type": { - "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", - "type": "string" - } - }, - "required": [ - "name", - "type" - ], - "type": "object" - }, - "type": "array" - }, - "collect": { - "type": "boolean" - }, - "headers": { - "description": "Lookup column headers: [{ title?, children? }] — children nest for multi-level column grouping.", - "items": { - "additionalProperties": false, - "properties": { - "children": { - "description": "Nested sub-column headers ({ title, children }) for multi-level grouping.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "title": { - "description": "Header caption.", - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "returnType": { - "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", - "type": "string" - }, - "rows": { - "description": "Lookup rows as maps keyed by the columns.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SimpleLookup", - "type": "string" - } - }, - "required": [ - "tableType", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "args": { - "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "description": "Parameter name, e.g. 'app'.", - "type": "string" - }, - "type": { - "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", - "type": "string" - } - }, - "required": [ - "name", - "type" - ], - "type": "object" - }, - "type": "array" - }, - "collect": { - "type": "boolean" - }, - "headers": { - "description": "Lookup column headers: [{ title?, children? }] — children nest for multi-level column grouping.", - "items": { - "additionalProperties": false, - "properties": { - "children": { - "description": "Nested sub-column headers ({ title, children }) for multi-level grouping.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "title": { - "description": "Header caption.", - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "returnType": { - "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", - "type": "string" - }, - "rows": { - "description": "Lookup rows as maps keyed by the columns.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SmartLookup", - "type": "string" - } - }, - "required": [ - "tableType", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "args": { - "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "description": "Parameter name, e.g. 'app'.", - "type": "string" - }, - "type": { - "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", - "type": "string" - } - }, - "required": [ - "name", - "type" - ], - "type": "object" - }, - "type": "array" - }, - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "returnType": { - "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", - "type": "string" - }, - "steps": { - "description": "Named steps: [{ name, type?, value }]. The formula goes in 'value' (e.g. value: '= app.annualIncome / 12'); there is NO 'formula' field. Reference earlier steps as $StepName.", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "description": "Step name (referenced elsewhere as $StepName).", - "type": "string" - }, - "type": { - "description": "Step result type, e.g. 'Double', 'String'.", - "type": "string" - }, - "value": { - "description": "The step's formula or value, e.g. '= app.annualIncome / 12'. NOT 'formula'." - } - }, - "required": [ - "name", - "value" - ], - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SimpleSpreadsheet", - "type": "string" - } - }, - "required": [ - "tableType", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "args": { - "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "description": "Parameter name, e.g. 'app'.", - "type": "string" - }, - "type": { - "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", - "type": "string" - } - }, - "required": [ - "name", - "type" - ], - "type": "object" - }, - "type": "array" - }, - "cells": { - "description": "2D matrix of cells: [[{ value }]]. The formula/value goes in each cell's 'value'.", - "items": { - "items": { - "additionalProperties": false, - "properties": { - "value": {} - }, - "required": [ - "value" - ], - "type": "object" - }, - "type": "array" - }, - "type": "array" - }, - "columns": { - "description": "Column headers: [{ name, type? }].", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "type": "array" - }, - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "returnType": { - "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", - "type": "string" - }, - "rows": { - "description": "Row headers: [{ name, type? }].", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "Spreadsheet", - "type": "string" - } - }, - "required": [ - "tableType", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "dataType": { - "description": "Element type of the data table.", - "type": "string" - }, - "headers": { - "description": "Columns: [{fieldName}].", - "items": { - "additionalProperties": false, - "properties": { - "displayName": { - "type": "string" - }, - "fieldName": { - "description": "Column accessor, e.g. 'app.age' (an input) or '_res_.eligible' (an expected result).", - "type": "string" - }, - "foreignKey": { - "type": "string" - } - }, - "required": [ - "fieldName" - ], - "type": "object" - }, - "type": "array" - }, - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "rows": { - "description": "Rows as positional { values: [...] }.", - "items": { - "additionalProperties": false, - "properties": { - "values": { - "description": "Positional cell values — one per header, in header order.", - "items": {}, - "type": "array" - } - }, - "required": [ - "values" - ], - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "Data", - "type": "string" - } - }, - "required": [ - "tableType", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "headers": { - "description": "Test columns: [{fieldName}] — inputs like 'app.age' and expected results like '_res_.eligible'.", - "items": { - "additionalProperties": false, - "properties": { - "displayName": { - "type": "string" - }, - "fieldName": { - "description": "Column accessor, e.g. 'app.age' (an input) or '_res_.eligible' (an expected result).", - "type": "string" - }, - "foreignKey": { - "type": "string" - } - }, - "required": [ - "fieldName" - ], - "type": "object" - }, - "type": "array" - }, - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "rows": { - "description": "Test cases as positional { values: [...] } (NOT 'rules'); one value per header.", - "items": { - "additionalProperties": false, - "properties": { - "values": { - "description": "Positional cell values — one per header, in header order.", - "items": {}, - "type": "array" - } - }, - "required": [ - "values" - ], - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "Test", - "type": "string" - }, - "testedTableName": { - "description": "Name of the table/method under test (NOT 'testedMethodName').", - "type": "string" - } - }, - "required": [ - "tableType", - "name", - "testedTableName" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "id": { - "description": "Optional; ignored on create.", - "type": "string" - }, - "kind": { - "description": "Informational only — NOT the discriminator (that is tableType).", - "type": "string" - }, - "messages": { - "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", - "items": {}, - "type": "array" - }, - "name": { - "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", - "type": "string" - }, - "pos": { - "type": "string" - }, - "properties": { - "additionalProperties": {}, - "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "source": { - "description": "2D matrix of raw cells: [[{ value, colspan?, rowspan?, covered? }]].", - "items": { - "items": { - "additionalProperties": false, - "properties": { - "colspan": { - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "covered": { - "type": "boolean" - }, - "rowspan": { - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "value": {} - }, - "type": "object" - }, - "type": "array" - }, - "type": "array" - }, - "tableType": { - "const": "RawSource", - "type": "string" - } - }, - "required": [ - "tableType", - "name" - ], - "type": "object" - } -] - added
Input schema / properties / table / propertiesAdded value: +{ + "id": { + "description": "Table id; ignored on create and validated against the path on update.", + "type": "string" + }, + "kind": { + "description": "Informational table kind.", + "enum": [ + "Rules", + "Spreadsheet", + "Datatype", + "Data", + "Test", + "TBasic", + "Column Match", + "Method", + "Run", + "Constants", + "Conditions", + "Actions", + "Returns", + "Environment", + "Properties", + "Other" + ], + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics tolerated when a get response is round-tripped.", + "items": {}, + "type": "array" + }, + "name": { + "description": "Required nonblank table name (a valid Java identifier, e.g. 'calculatePremium').", + "minLength": 1, + "type": "string" + }, + "pos": { + "type": "string" + }, + "source": { + "description": "Complete 2D source matrix. Preserve cell positions, covered placeholders, and spans when replacing a table. Remove read-only style objects returned by styles=true; Studio table write APIs cannot change formatting.", + "items": { + "items": { + "additionalProperties": false, + "description": "Writable raw cell. Studio exposes style only when reading with styles=true; table write APIs do not support changing style, so style is intentionally rejected.", + "properties": { + "cell": { + "type": "string" + }, + "colspan": { + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "covered": { + "type": "boolean" + }, + "rowspan": { + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "value": {} + }, + "type": "object" + }, + "type": "array" + }, + "type": "array" + }, + "tableType": { + "const": "RawSource", + "type": "string" + } +} - added
Input schema / properties / table / requiredAdded value: +[ + "tableType", + "name", + "source" +] - added
Input schema / properties / table / typeAdded value: +"object"
- Added
openl_delete_project - Added
openl_delete_project_branch - Changed
openl_delete_project_file2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_delete_table2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_delete_table_columns2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_delete_table_rows2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_deploy_project2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_expand_trace_tree - Removed
openl_export_trace - Added
openl_get_merge_conflicts - Changed
openl_get_project3 fields changed- added
Input schema / properties / includeAdded value: +{ + "description": "Optional response expansions from the Studio API.", + "items": { + "enum": [ + "summary", + "status", + "deleted", + "descriptor" + ], + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_get_table6 fields changed- added
Input schema / properties / maxRowsAdded value: +{ + "description": "Maximum number of source rows, counted from startRow; omit to read to the end. A windowed response carries totalRows.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" +} - removed
Input schema / properties / rawRemoved value: -{ - "description": "If true, returns the raw table view as a 2D matrix of cells without any parsing or structure interpretation. Useful for reading tables of unknown or custom types, preserving exact cell positioning and merge regions.", - "type": "boolean" -} - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context" - added
Input schema / properties / startRowAdded value: +{ + "description": "Zero-based index of the first source row; omit to start at the top. Combine with maxRows to read a large table in slices.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / stylesAdded value: +{ + "description": "If true, each raw cell carries its Excel style (background/font colour, bold/italic/underline, alignment, indent, borders).", + "type": "boolean" +}
- Added
openl_get_table_dependencies - Changed
openl_get_test_results4 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context" - changed
Input schema / properties / size / descriptionPrevious value: -"Page size (number of results per page)"New value: +"Page size (number of results per page, maximum 200)" - changed
Input schema / properties / size / maximumPrevious value: -9007199254740991New value: +200
- Changed
openl_get_test_results_by_table4 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context" - changed
Input schema / properties / size / descriptionPrevious value: -"Page size (number of results per page)"New value: +"Page size (number of results per page, maximum 200)" - changed
Input schema / properties / size / maximumPrevious value: -9007199254740991New value: +200
- Changed
openl_get_test_results_summary3 fields changed- added
Input schema / properties / failuresOnlyAdded value: +{ + "description": "Include only failed tests.", + "type": "boolean" +} - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Removed
openl_get_trace_node_details - Removed
openl_get_trace_nodes - Removed
openl_get_trace_parameter - Added
openl_get_trace_value - Added
openl_get_version - Changed
openl_insert_table_columns2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_insert_table_rows2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_inspect_trace_frame - Changed
openl_list_branches2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_list_deploy_repositories2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_list_deployments4 fields changed- added
Input schema / properties / projectAdded value: +{ + "description": "Deployed project name to filter deployments by.", + "type": "string" +} - added
Input schema / properties / repositoryAdded value: +{ + "description": "Production repository ID to filter deployments by.", + "type": "string" +} - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_list_guides2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_list_module_sheets - Added
openl_list_project_branches - Changed
openl_list_project_local_changes2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_list_project_modules - Changed
openl_list_projects10 fields changed- added
Input schema / properties / authorAdded value: +{ + "description": "Last-modifying author filter (partial, case-insensitive).", + "type": "string" +} - added
Input schema / properties / branchAdded value: +{ + "description": "Branch filter (partial, case-insensitive).", + "type": "string" +} - added
Input schema / properties / dependsOnAdded value: +{ + "description": "Return projects that depend on this project identifier.", + "type": "string" +} - added
Input schema / properties / includeAdded value: +{ + "description": "Optional response expansions and listing behavior from the Studio API.", + "items": { + "enum": [ + "summary", + "status", + "deleted", + "descriptor" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / nameAdded value: +{ + "description": "Project name filter (partial, case-insensitive).", + "type": "string" +} - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context" - added
Input schema / properties / sortAdded value: +{ + "description": "Field used to sort the returned page.", + "enum": [ + "name", + "status", + "updated" + ], + "type": "string" +} - changed
Input schema / properties / status / descriptionPrevious value: -"Filter by project status. Valid values: 'LOCAL', 'ARCHIVED', 'OPENED', 'VIEWING_VERSION', 'EDITING', 'CLOSED'."New value: +"Filter by project status." - changed
Input schema / properties / status / enumPrevious value: -[ - "LOCAL", - "ARCHIVED", - "OPENED", - "VIEWING_VERSION", - "EDITING", - "CLOSED" -]New value: +[ + "LOCAL", + "DELETED", + "OPENED", + "VIEWING_VERSION", + "EDITING", + "CLOSED" +]
- Changed
openl_list_repositories2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_list_repository_features2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_list_table_property_definitions - Changed
openl_list_tables2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_merge_project_branches - Changed
openl_merge_table_cells2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_move_project_file2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_open_project3 fields changed- added
Input schema / properties / openDependenciesAdded value: +{ + "description": "Also open dependency projects (backend default false).", + "type": "boolean" +} - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_project_status5 fields changed- changed
Input schema / properties / branch / descriptionPrevious value: -"Optional branch name. When provided, must match the project's currently opened branch (the backend returns 409 on mismatch). Omit for repositories that do not support branches and for projects with repository 'local'."New value: +"Optional target branch. With wait=true (default), the tool switches an opened design project to this branch before validating it. With wait=false, this is a read-only assertion and Studio returns 409 when it differs from the currently opened branch. Omit for repositories that do not support branches and for repository 'local'." - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context" - changed
Input schema / properties / wait / defaultPrevious value: -falseNew value: +true - changed
Input schema / properties / wait / descriptionPrevious value: -"When true, the tool subscribes to the studio's real-time status topic and blocks until compileState is terminal (ok/warnings/errors), emitting MCP progress notifications along the way. Use this immediately after an edit (openl_update_table/openl_append_table/openl_upload_file) to get the post-compile state in one call instead of polling. If the initial state is already terminal, returns immediately. Default false (one-shot snapshot)."New value: +"When true (default), returns a conclusive compile state: an idle project is compiled lazily through Studio's tables API, while an already-running compilation is followed over the real-time status topic until compileState is terminal (ok/warnings/errors). Progress notifications are emitted when available. Set false only for a one-shot read-only snapshot that may return idle or compiling."
- Added
openl_read_merge_conflict_file - Changed
openl_read_project_file4 fields changed- changed
Input schema / properties / download / descriptionPrevious value: -"For a folder, set true to download the folder and its contents as a ZIP archive (returned base64-encoded). Ignored for files."New value: +"For a folder, set true to download the folder and its contents as a ZIP archive (base64 content in a JSON text envelope). Ignored for files." - changed
Input schema / properties / encoding / descriptionPrevious value: -"How to return file content. 'auto' (default) returns text as UTF-8 and binary as base64; 'utf-8' forces text; 'base64' forces base64. Ignored for metadata/listing responses."New value: +"How to return file content. 'auto' (default) returns text as UTF-8 and binary as base64 content in a JSON text envelope; 'utf-8' forces text; 'base64' forces the base64 envelope. Ignored for metadata/listing responses." - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_redeploy_project2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_repository_project_revisions11 fields changed- removed
Input schema / properties / branchRemoved value: -{ - "description": "Branch name (optional, only if repository supports branches)", - "type": "string" -} - added
Input schema / properties / offsetAdded value: +{ + "description": "Item offset (0-based). Mutually exclusive with page.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - changed
Input schema / properties / page / descriptionPrevious value: -"Page number (0-based, default: 0)"New value: +"Page number (0-based). Mutually exclusive with offset; the backend defaults to 0 when both are omitted." - added
Input schema / properties / projectIdAdded value: +{ + "description": "Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting.", + "type": "string" +} - removed
Input schema / properties / projectNameRemoved value: -{ - "description": "Project name within the repository (e.g., 'InsuranceRules', 'AutoPremium', 'ClaimProcessing')", - "type": "string" -} - removed
Input schema / properties / repositoryRemoved value: -{ - "description": "Repository identifier. Pass either the 'id' or the 'name' field from openl_list_repositories() — the tool accepts both (and is case-insensitive). DO NOT invent values like 'Design Repository' or 'design-repo'; the actual names are typically short tokens (e.g. 'Design'). Always call openl_list_repositories() first if you don't already have the value in context.", - "type": "string" -} - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context" - added
Input schema / properties / size / defaultAdded value: +50 - added
Input schema / properties / techRevs / defaultAdded value: +false - changed
Input schema / requiredPrevious value: -[ - "repository", - "projectName" -]New value: +[ + "projectId" +]
- Changed
openl_restore_project_local_change2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_resume_trace - Added
openl_run_table - Changed
openl_save_project2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_search_project_files5 fields changed- changed
Input schema / properties / content / descriptionPrevious value: -"Case-insensitive content substring to match inside files (full-text search)."New value: +"Case-insensitive substring to match inside TEXT files only. Studio does not inspect binary content such as XLSX/XLS/ZIP/images; use pattern/extensions to locate binary files instead." - changed
Input schema / properties / extensions / descriptionPrevious value: -"Filter by file extensions without the dot, e.g. ['xlsx','xml']."New value: +"Filter by file extensions without the dot, e.g. ['xlsx','xml']. With content, only matching text files are inspected; binary extensions such as xlsx can be located but not searched internally." - changed
Input schema / properties / pattern / descriptionPrevious value: -"Ant-glob path pattern, e.g. 'rules/**/*.xlsx' or '**/*.xml'."New value: +"Ant-glob path pattern, e.g. 'rules/**/*.xlsx' or '**/*.xml'. This can find binary files by path, but content is never searched inside them." - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_set_trace_breakpoints - Changed
openl_start_project_tests3 fields changed- changed
Input schema / properties / fromModule / descriptionPrevious value: -"Module name to run tests from (reserved for future use - not currently used)"New value: +"Module name to run tests from." - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_start_trace13 fields changed- added
Input schema / properties / breakOnErrorsAdded value: +{ + "description": "Suspend on an uncaught rule error so its frame can be inspected (backend default true). Set false to let the error terminate the run.", + "type": "boolean" +} - added
Input schema / properties / breakpointsAdded value: +{ + "description": "Initial breakpoint set — REPLACES the current set before starting. Key forms: '<name>' (entry of any same-named table), '<uri>' (entry of that table), '<uri>#R{r}C{c}' (spreadsheet cell), '<uri>#rule' (any decision-table rule fires), '<uri>#<ruleName>' (specific rule fires). Append '@N' to any key to break only on the table's N-th execution (0-based) — e.g. '<uri>#R48C0@3' hits the 4th run; N matches frames[].instance and a watch series' instance, so a watch outlier at instance 3 is reached with '@3'. Without '@N' a cell breakpoint hits EVERY pass.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / detailedTitlesAdded value: +{ + "description": "Build value-rich business-view titles in the retained tree (backend default false). This can substantially increase response size.", + "type": "boolean" +} - changed
Input schema / properties / fromModule / descriptionPrevious value: -"Module name for opened module execution. Usually omit."New value: +"Module name to trace in the context of a specific opened module. Usually omit." - added
Input schema / properties / includeTreeAdded value: +{ + "description": "Also return the executed call tree's ROOT node ('tree'), not just the bounded 'profile' overview (default false). Against a current OpenL Studio the tree is lazy — one level deep: the root's steps each carry a 'childrenTotal' count instead of nested children, so a large run is no longer returned whole. Drill into a branch with openl_expand_trace_tree; to find the hot table use 'profile' and replay into it with a breakpoint.", + "type": "boolean" +} - changed
Input schema / properties / inputJson / descriptionPrevious value: -"For regular rules: JSON input. Use object with params (required) and runtimeContext (optional). E.g. { params: { age: 25 }, runtimeContext: { lob: 'Auto' } }."New value: +"For regular rules: JSON input. Use object with params (required) and runtimeContext (optional). E.g. { params: { age: 25 }, runtimeContext: { lob: 'Auto' } }. Omit BOTH inputJson and testRanges to replay the previous run's remembered input (e.g. restarting with profiling or new breakpoints)." - added
Input schema / properties / profileTopAdded value: +{ + "description": "Number of hotspots (slowest tables) in the 'profile' overview (backend default 20).", + "maximum": 500, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / profilingAdded value: +{ + "description": "Retain the executed call tree — structure and timings, NO values (default false). With stopAtEntry: false and no breakpoints the run completes in this single call and returns a constant-size 'profile' overview (top-N slowest tables); the tree's root node comes with includeTree: true and is browsed level by level with openl_expand_trace_tree.", + "type": "boolean" +} - changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context" - added
Input schema / properties / stopAtEntryAdded value: +{ + "description": "Suspend at the entry of the first frame (default true). Set false to run straight to the first breakpoint — or, with no breakpoints, to completion.", + "type": "boolean" +} - changed
Input schema / properties / tableId / descriptionPrevious value: -"Table ID to trace (e.g., 'calculatePremium_1234'). Get from openl_list_tables()."New value: +"Table ID to debug (e.g., 'calculatePremium_1234'). Get from openl_list_tables()." - changed
Input schema / properties / testRanges / descriptionPrevious value: -"For test tables: comma-separated ranges (e.g., '1-3,5'). Omit for regular rule/table execution."New value: +"For test tables: comma-separated test-case ranges (e.g., '1-3,5'). Omit for regular rule execution."
- Added
openl_step_trace - Added
openl_stop_trace - Changed
openl_unmerge_table_cells2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_update_table7 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context" - changed
Input schema / properties / view / additionalPropertiesPrevious value: -{}New value: +false - changed
Input schema / properties / view / descriptionPrevious value: -"FULL table structure from get_table() with your modifications applied. MUST include: id, tableType, kind, name, plus type-specific data (rules for SimpleRules, rows for Spreadsheet, fields for Datatype). Keep 'tableType' EXACTLY as get_table() returned it (it is a CASE-SENSITIVE discriminator: Datatype, Spreadsheet, SimpleRules, SmartRules, SimpleSpreadsheet, Vocabulary, Data, Test, SimpleLookup, SmartLookup, RawSource — lowercase is rejected). Do NOT send only the changed fields - send the complete structure. Workflow: 1) currentTable = get_table(), 2) currentTable.rules[0]['Column'] = newValue, 3) update_table(view=currentTable)"New value: +"Full, non-windowed RawSource structure from openl_get_table() with modifications applied. Send the complete source matrix, not only changed cells; a view carrying totalRows is rejected, and the handler independently rejects a source with fewer rows than the live table." - added
Input schema / properties / view / propertiesAdded value: +{ + "id": { + "description": "Table id; ignored on create and validated against the path on update.", + "type": "string" + }, + "kind": { + "description": "Informational table kind.", + "enum": [ + "Rules", + "Spreadsheet", + "Datatype", + "Data", + "Test", + "TBasic", + "Column Match", + "Method", + "Run", + "Constants", + "Conditions", + "Actions", + "Returns", + "Environment", + "Properties", + "Other" + ], + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics tolerated when a get response is round-tripped.", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier).", + "type": "string" + }, + "pos": { + "type": "string" + }, + "source": { + "description": "Complete 2D source matrix. Preserve cell positions, covered placeholders, and spans when replacing a table. Remove read-only style objects returned by styles=true; Studio table write APIs cannot change formatting.", + "items": { + "items": { + "additionalProperties": false, + "description": "Writable raw cell. Studio exposes style only when reading with styles=true; table write APIs do not support changing style, so style is intentionally rejected.", + "properties": { + "cell": { + "type": "string" + }, + "colspan": { + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "covered": { + "type": "boolean" + }, + "rowspan": { + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "value": {} + }, + "type": "object" + }, + "type": "array" + }, + "type": "array" + }, + "tableType": { + "const": "RawSource", + "type": "string" + }, + "totalRows": { + "description": "Total row count when the response contains a window.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } +} - removed
Input schema / properties / view / propertyNamesRemoved value: -{ - "type": "string" -} - added
Input schema / properties / view / requiredAdded value: +[ + "tableType", + "source" +]
- Changed
openl_update_table_cell2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_update_table_column2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_update_table_range2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Changed
openl_update_table_row2 fields changed- changed
Input schema / properties / response_format / defaultPrevious value: -"markdown"New value: +"json" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context"New value: +"Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context"
- Added
openl_watch_trace_cells - Changed
openl_write_project_file4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / anyOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "branch": { + "description": "Branch the project must be on for this operation. Ignored when blank. Fails if the repository has no branches or the project is on another branch. Omit for repository 'local' and non-branch repositories.", + "type": "string" + }, + "conflictPolicy": { + "description": "How to handle a target file that already exists: FAIL (default) returns an error; OVERWRITE replaces its content in place; SKIP leaves the existing file unchanged and reports it skipped. Has no effect when creating a new file.", + "enum": [ + "FAIL", + "OVERWRITE", + "SKIP" + ], + "type": "string" + }, + "content": { + "description": "UTF-8 text content.", + "type": "string" + }, + "createFolders": { + "default": true, + "description": "If true (default), missing intermediate folders are created automatically; otherwise the parent folder must already exist.", + "type": "boolean" + }, + "encoding": { + "const": "utf-8", + "description": "Optional explicit UTF-8 encoding; omitted means UTF-8.", + "type": "string" + }, + "message": { + "description": "Optional commit message. PRESENT → the write is committed to Git after saving the project (a new revision is created). ABSENT → the write stays in the project WORKING COPY (commit it later with openl_save_project). NOTE: committing saves ALL pending project changes (OpenL has no per-file commit), and only works for design (Git) repositories — not 'local'.", + "type": "string" + }, + "path": { + "description": "Project-relative path to the resource (e.g. 'rules/Model.xlsx'). Do NOT include the project name itself; paths are relative to the project root. A trailing slash denotes a folder.", + "minLength": 1, + "type": "string" + }, + "projectId": { + "description": "Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting.", + "type": "string" + }, + "response_format": { + "default": "json", + "description": "Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context", + "enum": [ + "json", + "markdown", + "markdown_concise", + "markdown_detailed" + ], + "type": "string" + } + }, + "required": [ + "projectId", + "path", + "createFolders", + "content" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "branch": { + "description": "Branch the project must be on for this operation. Ignored when blank. Fails if the repository has no branches or the project is on another branch. Omit for repository 'local' and non-branch repositories.", + "type": "string" + }, + "conflictPolicy": { + "description": "How to handle a target file that already exists: FAIL (default) returns an error; OVERWRITE replaces its content in place; SKIP leaves the existing file unchanged and reports it skipped. Has no effect when creating a new file.", + "enum": [ + "FAIL", + "OVERWRITE", + "SKIP" + ], + "type": "string" + }, + "content": { + "description": "Legacy base64 binary content. Whitespace and line wrapping are accepted.", + "type": "string" + }, + "createFolders": { + "default": true, + "description": "If true (default), missing intermediate folders are created automatically; otherwise the parent folder must already exist.", + "type": "boolean" + }, + "encoding": { + "const": "base64", + "description": "Marks the legacy content parameter as base64.", + "type": "string" + }, + "message": { + "description": "Optional commit message. PRESENT → the write is committed to Git after saving the project (a new revision is created). ABSENT → the write stays in the project WORKING COPY (commit it later with openl_save_project). NOTE: committing saves ALL pending project changes (OpenL has no per-file commit), and only works for design (Git) repositories — not 'local'.", + "type": "string" + }, + "path": { + "description": "Project-relative path to the resource (e.g. 'rules/Model.xlsx'). Do NOT include the project name itself; paths are relative to the project root. A trailing slash denotes a folder.", + "minLength": 1, + "type": "string" + }, + "projectId": { + "description": "Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting.", + "type": "string" + }, + "response_format": { + "default": "json", + "description": "Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context", + "enum": [ + "json", + "markdown", + "markdown_concise", + "markdown_detailed" + ], + "type": "string" + } + }, + "required": [ + "projectId", + "path", + "createFolders", + "content", + "encoding" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "blob": { + "contentEncoding": "base64", + "contentMediaType": "application/octet-stream", + "description": "Binary file bytes encoded as base64. Uses JSON Schema 2020-12 contentEncoding='base64'.", + "format": "base64", + "pattern": "^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$", + "type": "string" + }, + "branch": { + "description": "Branch the project must be on for this operation. Ignored when blank. Fails if the repository has no branches or the project is on another branch. Omit for repository 'local' and non-branch repositories.", + "type": "string" + }, + "conflictPolicy": { + "description": "How to handle a target file that already exists: FAIL (default) returns an error; OVERWRITE replaces its content in place; SKIP leaves the existing file unchanged and reports it skipped. Has no effect when creating a new file.", + "enum": [ + "FAIL", + "OVERWRITE", + "SKIP" + ], + "type": "string" + }, + "createFolders": { + "default": true, + "description": "If true (default), missing intermediate folders are created automatically; otherwise the parent folder must already exist.", + "type": "boolean" + }, + "message": { + "description": "Optional commit message. PRESENT → the write is committed to Git after saving the project (a new revision is created). ABSENT → the write stays in the project WORKING COPY (commit it later with openl_save_project). NOTE: committing saves ALL pending project changes (OpenL has no per-file commit), and only works for design (Git) repositories — not 'local'.", + "type": "string" + }, + "path": { + "description": "Project-relative path to the resource (e.g. 'rules/Model.xlsx'). Do NOT include the project name itself; paths are relative to the project root. A trailing slash denotes a folder.", + "minLength": 1, + "type": "string" + }, + "projectId": { + "description": "Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting.", + "type": "string" + }, + "response_format": { + "default": "json", + "description": "Response format: 'json' for structured, round-trippable data (default), 'markdown' for human-readable output, 'markdown_concise' for a brief summary (1-2 paragraphs), or 'markdown_detailed' for full details with context", + "enum": [ + "json", + "markdown", + "markdown_concise", + "markdown_detailed" + ], + "type": "string" + } + }, + "required": [ + "projectId", + "path", + "createFolders", + "blob" + ], + "type": "object" + } +] - removed
Input schema / propertiesRemoved value: -{ - "branch": { - "description": "Branch the project must be on for this operation. Ignored when blank. Fails if the repository has no branches or the project is on another branch. Omit for repository 'local' and non-branch repositories.", - "type": "string" - }, - "conflictPolicy": { - "description": "How to handle a target file that already exists: FAIL (default) returns an error; OVERWRITE replaces its content in place; SKIP leaves the existing file unchanged and reports it skipped. Has no effect when creating a new file.", - "enum": [ - "FAIL", - "OVERWRITE", - "SKIP" - ], - "type": "string" - }, - "content": { - "description": "File content, interpreted according to 'encoding'. Use base64 for binary files (xlsx, images, zip).", - "type": "string" - }, - "createFolders": { - "default": true, - "description": "If true (default), missing intermediate folders are created automatically; otherwise the parent folder must already exist.", - "type": "boolean" - }, - "encoding": { - "default": "utf-8", - "description": "How 'content' is encoded: 'utf-8' (default) for text, 'base64' for binary.", - "enum": [ - "utf-8", - "base64" - ], - "type": "string" - }, - "message": { - "description": "Optional commit message. PRESENT → the write is committed to Git after saving the project (a new revision is created). ABSENT → the write stays in the project WORKING COPY (commit it later with openl_save_project). NOTE: committing saves ALL pending project changes (OpenL has no per-file commit), and only works for design (Git) repositories — not 'local'.", - "type": "string" - }, - "path": { - "description": "Project-relative path to the resource (e.g. 'rules/Model.xlsx'). Do NOT include the project name itself; paths are relative to the project root. A trailing slash denotes a folder.", - "minLength": 1, - "type": "string" - }, - "projectId": { - "description": "Project ID returned by backend. Use the exact 'projectId' value from openl_list_projects() response without modification or reformatting.", - "type": "string" - }, - "response_format": { - "default": "markdown", - "description": "Response format: 'json' for structured data, 'markdown' for human-readable (default), 'markdown_concise' for brief summary (1-2 paragraphs), 'markdown_detailed' for full details with context", - "enum": [ - "json", - "markdown", - "markdown_concise", - "markdown_detailed" - ], - "type": "string" - } -} - removed
Input schema / requiredRemoved value: -[ - "projectId", - "path", - "content", - "encoding", - "createFolders" -]
40 tool updates
v1.1.0- Changed
openl_append_table3 fields changed- changed
Input schema / properties / appendData / descriptionPrevious value: -"Data structure to append to the table. Structure depends on tableType: Datatype uses 'fields', SimpleRules/SmartRules use 'rules', SimpleSpreadsheet uses 'steps', Vocabulary uses 'values', RawSource uses 'rows' (array of rows)"New value: +"Data structure to append to the table. Structure depends on tableType: Datatype uses 'fields'; SimpleRules/SmartRules use 'rules'; SimpleLookup/SmartLookup use 'rows' (array of maps); Data/Test use 'rows' (array of { values }); SimpleSpreadsheet uses 'steps'; Spreadsheet uses 'rows' (row headers) + 'cells' (2D cell array); Vocabulary uses 'values'; RawSource uses 'rows' (array of cell-arrays)." - changed
Input schema / properties / appendData / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "fields": { - "description": "Array of field definitions to append", - "items": { - "additionalProperties": false, - "properties": { - "defaultValue": { - "description": "Default value for the field" - }, - "name": { - "description": "Field name", - "type": "string" - }, - "required": { - "description": "Whether field is required", - "type": "boolean" - }, - "type": { - "description": "Field type (e.g., 'String', 'int', 'double')", - "type": "string" - } - }, - "required": [ - "name", - "type" - ], - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "Datatype", - "type": "string" - } - }, - "required": [ - "tableType", - "fields" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "rules": { - "description": "Array of rule objects to append. Each rule is a map with condition and action columns.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SimpleRules", - "type": "string" - } - }, - "required": [ - "tableType", - "rules" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "steps": { - "description": "Array of spreadsheet step objects to append", - "items": {}, - "type": "array" - }, - "tableType": { - "const": "SimpleSpreadsheet", - "type": "string" - } - }, - "required": [ - "tableType", - "steps" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "rules": { - "description": "Array of rule objects to append. Each rule is a map with condition and action columns.", - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "tableType": { - "const": "SmartRules", - "type": "string" - } - }, - "required": [ - "tableType", - "rules" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "tableType": { - "const": "Vocabulary", - "type": "string" - }, - "values": { - "description": "Array of vocabulary value objects to append", - "items": {}, - "type": "array" - } - }, - "required": [ - "tableType", - "values" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "rows": { - "description": "Array of rows to append; each row is an array of cell objects (e.g. { value: string, colspan?: number } or { covered?: boolean })", - "items": { - "items": { - "additionalProperties": {}, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "type": "array" - }, - "type": "array" - }, - "tableType": { - "const": "RawSource", - "type": "string" - } - }, - "required": [ - "tableType", - "rows" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "fields": { + "description": "Array of field definitions to append", + "items": { + "additionalProperties": false, + "properties": { + "defaultValue": { + "description": "Default value for the field" + }, + "name": { + "description": "Field name", + "type": "string" + }, + "required": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + } + ], + "description": "Whether the field is required (backend field is a String; a boolean is accepted and coerced)." + }, + "type": { + "description": "Field type (e.g., 'String', 'int', 'double')", + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "Datatype", + "type": "string" + } + }, + "required": [ + "tableType", + "fields" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "rules": { + "description": "Array of rule objects to append. Each rule is a map with condition and action columns.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "SimpleRules", + "type": "string" + } + }, + "required": [ + "tableType", + "rules" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "steps": { + "description": "Array of spreadsheet steps to append: [{ name, type?, value }].", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Step name (referenced elsewhere as $StepName).", + "type": "string" + }, + "type": { + "description": "Step result type, e.g. 'Double'.", + "type": "string" + }, + "value": { + "description": "The step's formula or value, e.g. '= app.annualIncome / 12'. NOT 'formula'." + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "SimpleSpreadsheet", + "type": "string" + } + }, + "required": [ + "tableType", + "steps" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "cells": { + "description": "Required. Cells to append as a non-empty 2D array — one inner array (the row's cells across the columns) per appended row: [[{ value }]]. The formula/value goes in each cell's 'value'.", + "items": { + "items": { + "additionalProperties": false, + "properties": { + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "type": "array" + }, + "minItems": 1, + "type": "array" + }, + "rows": { + "description": "Optional spreadsheet row headers to append: [{ name, type? }] — when provided, one per appended row (must align 1:1 with 'cells').", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Row name (referenced elsewhere as $RowName).", + "type": "string" + }, + "type": { + "description": "Row result type, e.g. 'Double', 'String'.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "Spreadsheet", + "type": "string" + } + }, + "required": [ + "tableType", + "cells" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "rules": { + "description": "Array of rule objects to append. Each rule is a map with condition and action columns.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "SmartRules", + "type": "string" + } + }, + "required": [ + "tableType", + "rules" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "tableType": { + "const": "Vocabulary", + "type": "string" + }, + "values": { + "description": "Array of vocabulary values to append: [{ value }].", + "items": { + "additionalProperties": false, + "properties": { + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "tableType", + "values" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "rows": { + "description": "Array of lookup rows to append; each row is a map keyed by the table's columns.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "SimpleLookup", + "type": "string" + } + }, + "required": [ + "tableType", + "rows" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "rows": { + "description": "Array of lookup rows to append; each row is a map keyed by the table's columns.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "SmartLookup", + "type": "string" + } + }, + "required": [ + "tableType", + "rows" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "rows": { + "description": "Array of data rows to append: [{ values: [...] }] (one value per column).", + "items": { + "additionalProperties": false, + "properties": { + "values": { + "items": {}, + "type": "array" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "Data", + "type": "string" + } + }, + "required": [ + "tableType", + "rows" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "rows": { + "description": "Array of test cases to append: [{ values: [...] }] (one value per header column).", + "items": { + "additionalProperties": false, + "properties": { + "values": { + "items": {}, + "type": "array" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "Test", + "type": "string" + } + }, + "required": [ + "tableType", + "rows" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "rows": { + "description": "Array of rows to append; each row is an array of cell objects (e.g. { value: string, colspan?: number } or { covered?: boolean }). Each row must cover ALL columns of the table (read it back with openl_get_table(raw=true) to see the width) — use { value: \"\" } for intentionally blank cells; a row narrower than the table is rejected before anything is written.", + "items": { + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "type": "array" + }, + "tableType": { + "const": "RawSource", + "type": "string" + } + }, + "required": [ + "tableType", + "rows" + ], + "type": "object" + } +] - changed
Input schema / properties / tableId / descriptionPrevious value: -"Table identifier - unique ID assigned by OpenL Studio when table is created (e.g., 'calculatePremium_1234')"New value: +"Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables()."
- Added
openl_append_table_columns - Added
openl_append_table_rows - Added
openl_copy_project_file - Added
openl_create_project - Changed
openl_create_project_table6 fields changed- changed
Input schema / properties / moduleName / descriptionPrevious value: -"Name of an existing project module where the table will be created (for example, 'Rules')."New value: +"Name of an existing project module where the table will be created (for example, 'Main' or 'Rules')." - removed
Input schema / properties / table / additionalPropertiesRemoved value: -{} - changed
Input schema / properties / table / descriptionPrevious value: -"Complete table structure (EditableTableView). Must include at least tableType, kind, and name, plus type-specific data (for example rules/headers for Rules tables, rows for Spreadsheet, fields for Datatype). id is optional for create requests."New value: +"Complete table structure (EditableTableView), selected by the CASE-SENSITIVE 'tableType' discriminator (Datatype, Vocabulary, Spreadsheet, SimpleSpreadsheet, SimpleRules, SmartRules, SimpleLookup, SmartLookup, Data, Test, RawSource — lowercase like 'datatype' is rejected). Each table type has a DIFFERENT shape (shown per branch); the backend rejects unknown/extra fields with a 400 'Failed to read request'. Rules tables use args/returnType/headers[{title}]/rules; Data and Test tables use headers[{fieldName}]/rows[{values}] (Test also needs testedTableName) — do NOT mix the two. There is NO 'signature' field. Tip: openl_get_table() on an existing table of the SAME type returns this exact shape to copy." - added
Input schema / properties / table / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "extends": { + "description": "Parent datatype to extend, if any.", + "type": "string" + }, + "fields": { + "description": "Field definitions: [{ name, type }].", + "items": { + "additionalProperties": false, + "properties": { + "defaultValue": {}, + "name": { + "type": "string" + }, + "required": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + } + ], + "description": "Whether the field is required (backend stores a String; a boolean is accepted and coerced)." + }, + "type": { + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "tableType": { + "const": "Datatype", + "type": "string" + } + }, + "required": [ + "tableType", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "tableType": { + "const": "Vocabulary", + "type": "string" + }, + "type": { + "description": "Vocabulary element type.", + "type": "string" + }, + "values": { + "description": "Vocabulary values: [{ value }].", + "items": { + "additionalProperties": false, + "properties": { + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "tableType", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "args": { + "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Parameter name, e.g. 'app'.", + "type": "string" + }, + "type": { + "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "collect": { + "type": "boolean" + }, + "headers": { + "description": "Column captions, e.g. [{title:'creditScore'},{title:'RET1'}].", + "items": { + "additionalProperties": false, + "properties": { + "title": { + "description": "Column caption.", + "type": "string" + } + }, + "required": [ + "title" + ], + "type": "object" + }, + "type": "array" + }, + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "returnType": { + "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", + "type": "string" + }, + "rules": { + "description": "Rows as maps keyed by the header titles, e.g. { creditScore: '< 580', RET1: 'Poor' }.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "SimpleRules", + "type": "string" + } + }, + "required": [ + "tableType", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "args": { + "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Parameter name, e.g. 'app'.", + "type": "string" + }, + "type": { + "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "collect": { + "type": "boolean" + }, + "headers": { + "description": "Condition column headers: [{ title, width? }].", + "items": { + "additionalProperties": false, + "properties": { + "title": { + "description": "Condition column caption.", + "type": "string" + }, + "width": { + "description": "Number of condition columns this header spans (defaults to 1).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "returnType": { + "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", + "type": "string" + }, + "rules": { + "description": "Rows as maps keyed by the header captions.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "SmartRules", + "type": "string" + } + }, + "required": [ + "tableType", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "args": { + "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Parameter name, e.g. 'app'.", + "type": "string" + }, + "type": { + "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "collect": { + "type": "boolean" + }, + "headers": { + "description": "Lookup column headers: [{ title?, children? }] — children nest for multi-level column grouping.", + "items": { + "additionalProperties": false, + "properties": { + "children": { + "description": "Nested sub-column headers ({ title, children }) for multi-level grouping.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "title": { + "description": "Header caption.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "returnType": { + "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", + "type": "string" + }, + "rows": { + "description": "Lookup rows as maps keyed by the columns.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "SimpleLookup", + "type": "string" + } + }, + "required": [ + "tableType", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "args": { + "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Parameter name, e.g. 'app'.", + "type": "string" + }, + "type": { + "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "collect": { + "type": "boolean" + }, + "headers": { + "description": "Lookup column headers: [{ title?, children? }] — children nest for multi-level column grouping.", + "items": { + "additionalProperties": false, + "properties": { + "children": { + "description": "Nested sub-column headers ({ title, children }) for multi-level grouping.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "title": { + "description": "Header caption.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "returnType": { + "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", + "type": "string" + }, + "rows": { + "description": "Lookup rows as maps keyed by the columns.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "SmartLookup", + "type": "string" + } + }, + "required": [ + "tableType", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "args": { + "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Parameter name, e.g. 'app'.", + "type": "string" + }, + "type": { + "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "returnType": { + "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", + "type": "string" + }, + "steps": { + "description": "Named steps: [{ name, type?, value }]. The formula goes in 'value' (e.g. value: '= app.annualIncome / 12'); there is NO 'formula' field. Reference earlier steps as $StepName.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Step name (referenced elsewhere as $StepName).", + "type": "string" + }, + "type": { + "description": "Step result type, e.g. 'Double', 'String'.", + "type": "string" + }, + "value": { + "description": "The step's formula or value, e.g. '= app.annualIncome / 12'. NOT 'formula'." + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "SimpleSpreadsheet", + "type": "string" + } + }, + "required": [ + "tableType", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "args": { + "description": "Input parameters: [{ name, type }]. There is NO 'signature' field — use this instead.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Parameter name, e.g. 'app'.", + "type": "string" + }, + "type": { + "description": "Parameter type, e.g. 'LoanApplication', 'Integer'.", + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "cells": { + "description": "2D matrix of cells: [[{ value }]]. The formula/value goes in each cell's 'value'.", + "items": { + "items": { + "additionalProperties": false, + "properties": { + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "type": "array" + }, + "type": "array" + }, + "columns": { + "description": "Column headers: [{ name, type? }].", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + }, + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "returnType": { + "description": "Return type, e.g. 'String', 'Double', 'EligibilityResult', 'SpreadsheetResult'.", + "type": "string" + }, + "rows": { + "description": "Row headers: [{ name, type? }].", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "Spreadsheet", + "type": "string" + } + }, + "required": [ + "tableType", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "dataType": { + "description": "Element type of the data table.", + "type": "string" + }, + "headers": { + "description": "Columns: [{fieldName}].", + "items": { + "additionalProperties": false, + "properties": { + "displayName": { + "type": "string" + }, + "fieldName": { + "description": "Column accessor, e.g. 'app.age' (an input) or '_res_.eligible' (an expected result).", + "type": "string" + }, + "foreignKey": { + "type": "string" + } + }, + "required": [ + "fieldName" + ], + "type": "object" + }, + "type": "array" + }, + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "rows": { + "description": "Rows as positional { values: [...] }.", + "items": { + "additionalProperties": false, + "properties": { + "values": { + "description": "Positional cell values — one per header, in header order.", + "items": {}, + "type": "array" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "Data", + "type": "string" + } + }, + "required": [ + "tableType", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "headers": { + "description": "Test columns: [{fieldName}] — inputs like 'app.age' and expected results like '_res_.eligible'.", + "items": { + "additionalProperties": false, + "properties": { + "displayName": { + "type": "string" + }, + "fieldName": { + "description": "Column accessor, e.g. 'app.age' (an input) or '_res_.eligible' (an expected result).", + "type": "string" + }, + "foreignKey": { + "type": "string" + } + }, + "required": [ + "fieldName" + ], + "type": "object" + }, + "type": "array" + }, + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "rows": { + "description": "Test cases as positional { values: [...] } (NOT 'rules'); one value per header.", + "items": { + "additionalProperties": false, + "properties": { + "values": { + "description": "Positional cell values — one per header, in header order.", + "items": {}, + "type": "array" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "type": "array" + }, + "tableType": { + "const": "Test", + "type": "string" + }, + "testedTableName": { + "description": "Name of the table/method under test (NOT 'testedMethodName').", + "type": "string" + } + }, + "required": [ + "tableType", + "name", + "testedTableName" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "description": "Optional; ignored on create.", + "type": "string" + }, + "kind": { + "description": "Informational only — NOT the discriminator (that is tableType).", + "type": "string" + }, + "messages": { + "description": "Read-only diagnostics; tolerated if a payload is copied from openl_get_table().", + "items": {}, + "type": "array" + }, + "name": { + "description": "Table name (a valid Java identifier, e.g. 'calculatePremium').", + "type": "string" + }, + "pos": { + "type": "string" + }, + "properties": { + "additionalProperties": {}, + "description": "Dimension/table properties, e.g. { state: 'CA', lob: 'Auto' }.", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "source": { + "description": "2D matrix of raw cells: [[{ value, colspan?, rowspan?, covered? }]].", + "items": { + "items": { + "additionalProperties": false, + "properties": { + "colspan": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "covered": { + "type": "boolean" + }, + "rowspan": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "value": {} + }, + "type": "object" + }, + "type": "array" + }, + "type": "array" + }, + "tableType": { + "const": "RawSource", + "type": "string" + } + }, + "required": [ + "tableType", + "name" + ], + "type": "object" + } +] - removed
Input schema / properties / table / propertyNamesRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / table / typeRemoved value: -"object"
- Added
openl_delete_project_file - Added
openl_delete_table - Added
openl_delete_table_columns - Added
openl_delete_table_rows - Changed
openl_export_trace3 fields changed- added
Input schema / properties / tableIdAdded value: +{ + "description": "Table id the trace was started for (the same value passed to openl_start_trace). Used to subscribe to the studio's per-table trace-status websocket topic while waiting out the 409 window. OPTIONAL when openl_start_trace ran through this same server instance — the table is remembered automatically; pass it explicitly when the trace was started by another process (e.g. a separate CLI run).", + "type": "string" +} - added
Input schema / properties / waitAdded value: +{ + "description": "When true (DEFAULT), if the trace is still running (backend returns 409 Conflict) the server subscribes to the studio's trace-status websocket and waits until the trace completes or waitTimeoutMs elapses — no client-side polling needed. Set false to get the raw immediate 409 behavior.", + "type": "boolean" +} - added
Input schema / properties / waitTimeoutMsAdded value: +{ + "description": "Maximum time to wait for trace completion, in milliseconds. Default 120000 (2 min), cap 600000 (10 min). On timeout an error is returned explaining that the trace is still running server-side.", + "exclusiveMinimum": 0, + "maximum": 600000, + "type": "integer" +}
- Added
openl_get_guides - Added
openl_get_project_agent_context - Added
openl_get_started - Changed
openl_get_table1 field changed- changed
Input schema / properties / tableId / descriptionPrevious value: -"Table identifier - unique ID assigned by OpenL Studio when table is created (e.g., 'calculatePremium_1234')"New value: +"Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables()."
- Changed
openl_get_test_results1 field changed- changed
Input schema / requiredPrevious value: -[ - "projectId", - "failures", - "unpaged" -]New value: +[ + "projectId" +]
- Changed
openl_get_test_results_by_table1 field changed- changed
Input schema / requiredPrevious value: -[ - "projectId", - "tableId", - "failures", - "unpaged" -]New value: +[ + "projectId", + "tableId" +]
- Changed
openl_get_test_results_summary1 field changed- changed
Input schema / requiredPrevious value: -[ - "projectId", - "failures", - "unpaged" -]New value: +[ + "projectId" +]
- Changed
openl_get_trace_nodes3 fields changed- added
Input schema / properties / tableIdAdded value: +{ + "description": "Table id the trace was started for (the same value passed to openl_start_trace). Used to subscribe to the studio's per-table trace-status websocket topic while waiting out the 409 window. OPTIONAL when openl_start_trace ran through this same server instance — the table is remembered automatically; pass it explicitly when the trace was started by another process (e.g. a separate CLI run).", + "type": "string" +} - added
Input schema / properties / waitAdded value: +{ + "description": "When true (DEFAULT), if the trace is still running (backend returns 409 Conflict) the server subscribes to the studio's trace-status websocket and waits until the trace completes or waitTimeoutMs elapses — no client-side polling needed. Set false to get the raw immediate 409 behavior.", + "type": "boolean" +} - added
Input schema / properties / waitTimeoutMsAdded value: +{ + "description": "Maximum time to wait for trace completion, in milliseconds. Default 120000 (2 min), cap 600000 (10 min). On timeout an error is returned explaining that the trace is still running server-side.", + "exclusiveMinimum": 0, + "maximum": 600000, + "type": "integer" +}
- Added
openl_insert_table_columns - Added
openl_insert_table_rows - Changed
openl_list_branches2 fields changed- changed
Input schema / properties / repository / descriptionPrevious value: -"Repository name (display name, not ID). Use the 'name' field from openl_list_repositories() response (e.g., if list_repositories returns {id: 'design-repo', name: 'Design Repository'}, use 'Design Repository' here, NOT 'design-repo')."New value: +"Repository identifier. Pass either the 'id' or the 'name' field from openl_list_repositories() — the tool accepts both (and is case-insensitive). DO NOT invent values like 'Design Repository' or 'design-repo'; the actual names are typically short tokens (e.g. 'Design'). Always call openl_list_repositories() first if you don't already have the value in context." - changed
Input schema / requiredPrevious value: -[ - "repository", - "limit", - "offset" -]New value: +[ + "repository" +]
- Changed
openl_list_deploy_repositories1 field changed- removed
Input schema / requiredRemoved value: -[ - "limit", - "offset" -]
- Added
openl_list_guides - Changed
openl_list_projects1 field changed- removed
Input schema / requiredRemoved value: -[ - "limit", - "offset" -]
- Changed
openl_list_repository_features1 field changed- changed
Input schema / properties / repository / descriptionPrevious value: -"Repository name (display name, not ID). Use the 'name' field from openl_list_repositories() response (e.g., if list_repositories returns {id: 'design-repo', name: 'Design Repository'}, use 'Design Repository' here, NOT 'design-repo')."New value: +"Repository identifier. Pass either the 'id' or the 'name' field from openl_list_repositories() — the tool accepts both (and is case-insensitive). DO NOT invent values like 'Design Repository' or 'design-repo'; the actual names are typically short tokens (e.g. 'Design'). Always call openl_list_repositories() first if you don't already have the value in context."
- Changed
openl_list_tables1 field changed- changed
Input schema / requiredPrevious value: -[ - "projectId", - "limit", - "offset" -]New value: +[ + "projectId" +]
- Added
openl_merge_table_cells - Added
openl_move_project_file - Added
openl_project_status - Added
openl_read_project_file - Changed
openl_repository_project_revisions1 field changed- changed
Input schema / properties / repository / descriptionPrevious value: -"Repository name (display name, not ID). Use the 'name' field from openl_list_repositories() response (e.g., if list_repositories returns {id: 'design-repo', name: 'Design Repository'}, use 'Design Repository' here, NOT 'design-repo')."New value: +"Repository identifier. Pass either the 'id' or the 'name' field from openl_list_repositories() — the tool accepts both (and is case-insensitive). DO NOT invent values like 'Design Repository' or 'design-repo'; the actual names are typically short tokens (e.g. 'Design'). Always call openl_list_repositories() first if you don't already have the value in context."
- Added
openl_search_project_files - Added
openl_unmerge_table_cells - Changed
openl_update_table2 fields changed- changed
Input schema / properties / tableId / descriptionPrevious value: -"Table identifier - unique ID assigned by OpenL Studio when table is created (e.g., 'calculatePremium_1234')"New value: +"Table identifier - unique ID assigned by OpenL Studio (e.g., 'calculatePremium_1234'). VOLATILE: derived from the table's location, so it changes when an edit relocates the table (it had no room to grow in place) — use the 'tableId' returned by the latest openl_update_table/openl_append_table response, or refresh via openl_list_tables()." - changed
Input schema / properties / view / descriptionPrevious value: -"FULL table structure from get_table() with your modifications applied. MUST include: id, tableType, kind, name, plus type-specific data (rules for SimpleRules, rows for Spreadsheet, fields for Datatype). Do NOT send only the changed fields - send the complete structure. Workflow: 1) currentTable = get_table(), 2) currentTable.rules[0]['Column'] = newValue, 3) update_table(view=currentTable)"New value: +"FULL table structure from get_table() with your modifications applied. MUST include: id, tableType, kind, name, plus type-specific data (rules for SimpleRules, rows for Spreadsheet, fields for Datatype). Keep 'tableType' EXACTLY as get_table() returned it (it is a CASE-SENSITIVE discriminator: Datatype, Spreadsheet, SimpleRules, SmartRules, SimpleSpreadsheet, Vocabulary, Data, Test, SimpleLookup, SmartLookup, RawSource — lowercase is rejected). Do NOT send only the changed fields - send the complete structure. Workflow: 1) currentTable = get_table(), 2) currentTable.rules[0]['Column'] = newValue, 3) update_table(view=currentTable)"
- Added
openl_update_table_cell - Added
openl_update_table_column - Added
openl_update_table_range - Added
openl_update_table_row - Added
openl_write_project_file
31 tool updates
v0.0.0- First observed
openl_append_table - First observed
openl_cancel_trace - First observed
openl_close_project - First observed
openl_create_project_branch - First observed
openl_create_project_table - First observed
openl_deploy_project - First observed
openl_export_trace - First observed
openl_get_project - First observed
openl_get_table - First observed
openl_get_test_results - First observed
openl_get_test_results_by_table - First observed
openl_get_test_results_summary - First observed
openl_get_trace_node_details - First observed
openl_get_trace_nodes - First observed
openl_get_trace_parameter - First observed
openl_list_branches - First observed
openl_list_deploy_repositories - First observed
openl_list_deployments - First observed
openl_list_project_local_changes - First observed
openl_list_projects - First observed
openl_list_repositories - First observed
openl_list_repository_features - First observed
openl_list_tables - First observed
openl_open_project - First observed
openl_redeploy_project - First observed
openl_repository_project_revisions - First observed
openl_restore_project_local_change - First observed
openl_save_project - First observed
openl_start_project_tests - First observed
openl_start_trace - First observed
openl_update_table
TDQS
Most tools target distinct resources, but the set contains several near-overlapping pairs (openl_append_table vs openl_append_table_rows, openl_list_branches vs openl_list_project_branches, openl_update_table vs the finer-grained update_table_row/column/cell/range tools) plus multiple test-result variants. The extensive descriptions and cross-references help, but the volume of similar verb/noun combinations still creates real selection risk.
All tools consistently use the openl_ prefix and overwhelmingly follow a verb_noun snake_case pattern (list_, get_, create_, delete_, update_, append_, insert_, merge_). A few noun-first exceptions such as openl_project_status and openl_repository_project_revisions, plus close variants like append_table vs append_table_rows, are minor deviations.
At 74 tools, this surface far exceeds the typical well-scoped MCP server, and the rubric explicitly flags 50+ tools as extreme. Even accounting for OpenL Studio's broad domain, many granular table-editing and debugging tools could be consolidated, and the sheer count will strain agent context and tool-selection accuracy.
Coverage is broad: project, file, table, test, trace/debug, branch/merge, and deployment workflows are all represented with substantial CRUD-like operations. Minor gaps remain—no undeploy/delete deployment, no project rename or repository management, and merge-conflict resolution is intentionally delegated to the user—but agents can generally work around them.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Deploy, monitor, and manage your OpenClaw AI assistants via natural language.
Create, manage, and test business rules directly from your AI agent via the DecisionRules platform.
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
Plan Salesforce deploys, open pull requests and trigger pipelines from your AI client.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to access and execute automated decision services from IBM Decision Intelligence or IBM Automation Decision Services. It exposes deployed decision operations as tools for platforms like Claude Desktop and IBM watsonx Orchestrate.327Apache 2.0
- AlicenseBqualityBmaintenanceExposes over 300 Operaton BPM REST operations as tools for AI agents to interact with the Operaton engine. It enables managing process deployments, instances, user tasks, and decision tables through natural language commands.100101Apache 2.0
- AlicenseNot gradedqualityAmaintenanceBridges IBM Operational Decision Manager with AI assistants, enabling decisions as tools for integration with platforms like Watson Orchestrate and Claude Desktop.8Apache 2.0
- AlicenseBqualityBmaintenanceEnables AI assistants to manage Rundeck operations including jobs, executions, projects, nodes, system management, key storage, webhooks, and ACL policies via natural language.50591Apache 2.0
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/openl-tablets/openl-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server