Skip to main content
Glama
openl-tablets

OpenL MCP Server

Official

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
OPENL_TIMEOUTNoOptional timeout in ms60000
OPENL_BASE_URLYesBase URL of OpenL Studio
OPENL_PASSWORDNoPassword for basic auth
OPENL_USERNAMENoUsername for basic auth
OPENL_PERSONAL_ACCESS_TOKENNoPersonal access token

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{}
prompts
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
openl_get_startedA

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.

openl_list_guidesA

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.

openl_get_guidesA

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.

openl_get_project_agent_contextA

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.

openl_get_versionA

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.

openl_list_deploymentsA

List active deployments across production environments, optionally filtered by production repository ID and deployed project name. Returns deployment names, repositories, and deployed project revisions.

openl_deploy_projectA

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'.

openl_redeploy_projectA

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.

openl_list_repositoriesA

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'.

openl_list_branchesA

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.

openl_list_repository_featuresA

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.

openl_repository_project_revisionsA

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.

openl_list_deploy_repositoriesA

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.

openl_start_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.

openl_get_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.

openl_get_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.

openl_get_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.

openl_list_project_local_changesA

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.

openl_restore_project_local_changeA

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.

openl_read_project_fileA

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.

openl_write_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.)

openl_delete_project_fileA

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.

openl_search_project_filesA

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).

openl_copy_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.

openl_move_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.

openl_list_projectsA

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.

openl_get_projectB

Get comprehensive project information including details, modules, dependencies, and metadata. Returns full project structure, configuration, and status.

openl_project_statusA

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.

openl_open_projectA

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.

openl_save_projectA

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'.

openl_close_projectA

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.

openl_create_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.

openl_create_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.

openl_list_project_branchesA

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.

openl_check_project_mergeA

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.

openl_merge_project_branchesA

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.

openl_get_merge_conflictsA

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.

openl_read_merge_conflict_fileA

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.

openl_cancel_merge_conflictsA

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.

openl_delete_projectA

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.

openl_delete_project_branchA

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.

openl_start_traceA

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.

openl_step_traceA

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.)

openl_resume_traceA

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.

openl_inspect_trace_frameA

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).

openl_set_trace_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.

openl_get_trace_valueA

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).

openl_expand_trace_treeA

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).

openl_stop_traceA

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).

openl_watch_trace_cellsA

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.

openl_list_tablesA

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.

openl_get_tableA

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().

openl_delete_tableA

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).

openl_update_tableA

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.

openl_append_tableA

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.

openl_create_project_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.

openl_append_table_rowsA

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.

openl_append_table_columnsA

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.

openl_insert_table_rowsA

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.

openl_insert_table_columnsA

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.

openl_delete_table_rowsA

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.

openl_delete_table_columnsA

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.

openl_update_table_rowA

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.

openl_update_table_columnA

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.

openl_update_table_cellA

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.

openl_merge_table_cellsA

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.

openl_unmerge_table_cellsA

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.

openl_update_table_rangeA

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.

openl_run_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.

openl_get_table_dependenciesA

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.

openl_list_project_modulesA

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.

openl_list_module_sheetsA

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.

openl_list_table_property_definitionsA

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.

openl_copy_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.

Prompts

Interactive templates invoked by user choice

NameDescription
append_tableAppend complete raw source rows to an existing OpenL table safely
create_ruleComprehensive guide for creating OpenL rules, spreadsheets, and data definitions from raw workbook source
create_rule_decision_tablesCreate OpenL decision tables through their authoritative raw workbook layout
create_rule_spreadsheetCreate OpenL Spreadsheet tables through their authoritative raw workbook layout
create_testCreate OpenL test tables from their authoritative raw workbook source
datatype_vocabularyCreate and edit Datatype and Vocabulary tables through raw workbook source
deploy_projectOpenL deployment workflow with mandatory validation checks, test execution requirements, and environment selection (dev, test, staging, prod)
dimension_propertiesExplanation of OpenL dimension properties for business versioning (state, country, lob, effectiveDate) vs Git versioning, with runtime selection logic
local_projectsWorking with projects in repository 'local': no open/save/close, no Git; table/rule/test tools work directly without opening
project_agents_mdHow to load and correctly apply a project's AGENTS.md guidance with openl_get_project_agent_context: walk up to the repo root, read every applicable file, and apply nearest-file-wins precedence
project_historyGuide for viewing a project's committed Git history with openl_repository_project_revisions and its local workspace changes with openl_list_project_local_changes, and when to use each
run_testTest selection logic and workflow for running OpenL tests efficiently based on scope (single table, multiple tables, or all tests)
update_testUpdate OpenL test cases through the authoritative raw table source
validate_after_editWorkflow for validating OpenL projects after editing tables/rules: call openl_project_status, branch on compileState, surface errors with location, and re-validate after fixes

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

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