fes-mcp
This server exposes curated, read-only Sisense environment operations as MCP tools—governance, asset/user management, lifecycle tasks, and well-checks—that run with the caller's own Sisense permissions.
Access management: list users, groups, roles, dashboard shares, data model shares, datasecurity rules, and analyze unused columns.
Dashboards: list/search dashboards by ID or title, inspect widgets and widget types, retrieve dashboard scripts, and get columns referenced by dashboards.
Data models: describe model structure, get schemas/table schemas, row counts, query table data, list connections/elasticubes, and fetch model shares or datasecurity details.
Folders and plugins: retrieve the folder tree/folder metadata and list installed plugins.
Reporting: list Report Manager reports with filtering (ids, name, enabled, priority, status, owner).
Well-checks: run a composite full wellcheck across dashboards and data models (structure, widget counts, pivot fields, custom/island tables, unused columns).
Click on "Deploy 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., "@fes-mcpList all users who haven't logged in for 30 days"
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.
Sisense Meta-Management MCP Server
⚠️ Experimental Project Notice
Community-Contributed Tool from Sisense Field Engineering (FES)
This project is an experimental tool developed by Sisense Field Engineering to facilitate customer learning and exploration of Sisense capabilities. It is not part of the core Sisense product release lifecycle and does not undergo the same validation, support, or certification processes as generally available (GA) Sisense features. It is provided "as-is" — see Support and contributing.
A standards-conformant MCP server that exposes Sisense environment operations as AI-ready tools, backed by the PySisense SDK: governance, asset and user/group management, lifecycle tasks, and well-checks — not chart-building or analytics Q&A.
It works for any Sisense user: every tool call runs with the calling user's own Sisense credential, so results and permissions are exactly what that user can see and do in Sisense itself, enforced natively by Sisense's APIs.
Tools only, no agent. Claude Desktop, Claude Code, claude.ai, Cursor — any MCP client brings its own agent; this project advertises and executes a curated subset of the ~170 SDK methods in the registry (dashboards, data models, users/groups, folders, plugins, queries, …) — one tool per capability, with near-duplicates excluded so an agent never has to choose between near-identical methods.
Architecture
The MCP spec's modern shape, as two cooperating services shipped as two
Docker images (sisense-fes-auth, sisense-fes-mcp — built from one multi-stage Dockerfile
with shared layers):
fes-auth — the authorization server (AS). Owns everything about who is calling: OAuth 2.1 for MCP clients (PKCE, dynamic client registration, discovery), the browser sign-in page, and the credential vault mapping each issued MCP token to the user's Sisense token. It proxies every tool call to the resource server with the Sisense credential injected.
fes-mcp — the resource server (RS). Stateless, OAuth-unaware. Reads the injected credential from each request, verifies it against Sisense (cached), and runs the tool as that user against that Sisense instance.
flowchart LR
subgraph clients [MCP clients]
C1[Claude Desktop]
C2[Claude Code]
C3[claude.ai / Cursor]
end
subgraph box [one host - docker compose]
subgraph AS [fes-auth : authorization server]
O[OAuth 2.1\nPKCE + DCR + discovery]
L[/login page/]
V[(vault\nMCP token → Sisense credential)]
P[/mcp proxy\ninjects credential headers/]
end
subgraph RS [fes-mcp : resource server]
T[Tool layer\nregistry-driven, curated]
D[Dispatcher\nper-credential PySisense client]
end
end
R[(tool registry JSON\nauto-generated from SDK)] -.defines.-> T
C1 & C2 & C3 -- "MCP over HTTPS\nBearer <MCP token>" --> P
C1 & C2 & C3 -. "browser: sign in once" .-> L
P -- "Authorization: Bearer <Sisense token>\nX-Sisense-Url: <instance>\n(internal network only)" --> T
T --> D
D -- "REST, as the signed-in user" --> F[(Sisense Fusion Deployment)]The seam between the two services is just those two headers plus the 401 contract, so each half can evolve — or be replaced — without the other noticing. There is no shared secret between the two; trust is the internal network (the RS's port is never published).
Sign-in flow (what a user experiences)
Each user adds the connector once in their MCP client, naming their own Sisense instance in the URL:
https://your-host/mcp?target=https://acme.sisense.comsequenceDiagram
participant U as User (browser)
participant C as MCP client
participant A as fes-auth
participant S as Sisense
C->>A: POST /mcp?target=<sisense url> (no token)
A-->>C: 401 + resource metadata URL (carries target)
C->>A: discovery + client registration (RFC 7591)
C->>U: open browser at A's /login
Note over U,A: target present → instance fixed,<br/>only username/password asked<br/>(no target → domain field shown)
U->>A: username/password (or API token for SSO)
A->>S: POST /api/v1/authentication/login
S-->>A: user's Sisense token (kept server-side, in the vault)
A-->>C: authorization code → MCP access token (PKCE)
Note over C,A: from here, silent — token refresh is automaticThe client never sees Sisense credentials; the server never stores passwords (used once to mint the user's token, then discarded). Users on SSO/MFA instances sign in by pasting their personal Sisense API token instead.
Tool call (steady state)
sequenceDiagram
participant C as MCP client
participant A as fes-auth (proxy)
participant R as fes-mcp (tools)
participant S as Sisense (target)
C->>A: POST /mcp (Bearer <MCP token>)
A->>A: validate token → vault → Sisense credential
A->>R: same request + Authorization: Bearer <Sisense token><br/>+ X-Sisense-Url: <instance>
R->>S: verify credential (TTL-cached) · SDK call as that user
S-->>R: result (user's permissions, user in audit log)
R-->>A: MCP response (streamed)
A-->>C: MCP response (streamed)Credential lifecycle and self-healing
The resource server re-verifies each (instance, token) pair against Sisense after
FES_MCP_VERIFY_TTLseconds (default 300). A token revoked in Sisense turns into an HTTP 401 within at most that window.fes-auth treats an RS 401 as credential dead: it deletes the vault entry and re-challenges the MCP client, whose next move is to re-run the sign-in flow. Server-side revocation therefore propagates with no manual steps.
Sessions are in-memory (no database): restarting fes-auth signs everyone out — each user's next call pops the browser login again (with
?target=set, that's just username/password). Dynamically registered OAuth clients are also in-memory, so a client that registered via DCR may need to reconnect (or re-add the connector) after a restart; CIMD clients are unaffected, since their client ID is a URL the server resolves fresh. Restarting fes-mcp is invisible: it holds no state.
Related MCP server: Britive MCP Server
Deployment (docker compose)
Tagged releases publish ready-to-run images to GitHub Container Registry:
ghcr.io/hnegi01/sisense-fes-auth and ghcr.io/hnegi01/sisense-fes-mcp
(no registry login needed). Or build from source:
docker compose up --buildThis builds the two images (docker build --target fes-auth|fes-mcp) and
publishes only fes-auth on :8200; fes-mcp stays internal. Terminate TLS in
front (ALB / nginx / Caddy) — MCP clients require HTTPS for OAuth — and set
FES_MCP_PUBLIC_URL to that public URL:
FES_MCP_PUBLIC_URL=https://your-host.example.com docker compose up -d --buildUsers then add https://your-host.example.com/mcp?target=https://their-instance.sisense.com
as a custom connector. The ?target= part is optional — without it the login
page asks for the Sisense URL as a third field.
Endpoints on fes-auth: /mcp (proxied MCP), /login, /.well-known/* +
/authorize + /token + /register (OAuth 2.1), / (status), /healthz.
Hardening included: per-IP login rate limiting, CSRF-protected login form,
access logs with request ids.
OAuth discovery requires the server's paths at the origin root, so give
it its own hostname — or, on a shared hostname, route exactly these paths to
fes-auth at the proxy. A path prefix (https://host/some-prefix/mcp) will
not work.
Quick start (local dev)
Requires Python 3.11+ and uv. Local dev skips
the AS entirely: stdio transport defaults to env auth — one credential from
.env, everything runs as you.
uv sync
cp .env.example .env # set SISENSE_DOMAIN / SISENSE_TOKEN
uv run fes-mcp # stdio transportMCP client config (e.g. claude_desktop_config.json):
{
"mcpServers": {
"sisense-fes": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/fes_mcp", "fes-mcp"]
}
}
}To run the full split locally without Docker:
FES_MCP_TRANSPORT=http uv run fes-mcp & # RS on :8200 (upstream auth)
FES_MCP_PORT=8300 FES_MCP_RS_URL=http://127.0.0.1:8200 uv run fes-auth
# connector: http://127.0.0.1:8300/mcp?target=https://your.sisense.comLayout
src/fes_mcp/—settings(env config) ·registry(load/filter) ·schema_patches(field-description overlay) ·dispatcher(per-credential SDK dispatch) ·upstream(RS credential verification) ·auth(OAuth provider + login page) ·authserver(fes-auth service + proxy) ·middleware(access logs) ·server(FastMCP assembly)config/tools.registry.with_examples.json— auto-generated tool registry. Never handwritten; regenerate with./refresh_registry.shwhen PySisense updates.config/allowlist.txt— the curated tool surface, one tool per line. Delete/comment a line to remove a tool. Tools not listed are never exposed, so registry refreshes can't silently widen the surface. (Migration tools are not listed — they need a dual-instance connection this server doesn't model.)Mutating tools are gated behind
FES_MCP_ALLOW_MUTATIONS=true— see Security for the full mutation safeguards.Payload parameters carry full nested schemas straight from the SDK's TypedDict contracts (pysisense ≥ 1.1.0) — e.g.
create_user'suser_datadeclaresemailandroleas required, so an agent gathers them before calling instead of failing inside the SDK.schema_patches.pyoverlays only human-written per-field descriptions (the contracts carry structure, not prose); free-form payloads like JAQL stay unconstrained.
Technical and security considerations
Credential handling
The MCP client never sees Sisense credentials, and the server never stores
passwords — a password is used once against Sisense's login API to mint the
user's own token, then discarded. Sisense tokens live in fes-auth's in-memory
vault, keyed to the MCP access token, and survive refresh rotation. In dev
mode the single env credential (SISENSE_DOMAIN/SISENSE_TOKEN) stays on
your machine. Nothing is persisted to disk — there is no database and no
encryption-at-rest surface; a fes-auth restart clears the vault and users
sign in again.
Hardening on the hosted surface: per-IP login rate limiting, CSRF-protected login form, access logs with request ids, and per-call tool logs (tool / user domain / outcome / duration).
Authorization
Nothing custom: authorization is Sisense's job. Every tool call runs with the calling user's own Sisense token, so Sisense enforces their real permissions on every API call and permission errors surface to the client verbatim. This is also why the server is not admin-only — any Sisense user gets exactly their own scope.
Trust between the two services
fes-auth ↔ fes-mcp trust is network-level: no shared secret. The RS's port
must never be reachable from outside the internal network (compose publishes
only fes-auth). Defense in depth: FES_MCP_ALLOWED_SISENSE_ORIGINS pins
which Sisense origins the RS will accept in X-Sisense-Url.
Mutations
Mutating tools are exposed only when FES_MCP_ALLOW_MUTATIONS=true, always
carry destructiveHint, are blocked server-side as a second layer when
disabled, and are written to a mutation audit log.
On top of that, mutating tools ask the human for approval before executing.
The confirmation shows the exact arguments about to run (secrets masked), the
approval is bound to those arguments, and abort or decline changes nothing.
It works on both protocol generations: current (stateless) connections use an
MCP input_required round trip, older connections use MCP elicitation.
A client that cannot render the confirmation proceeds under its own
tool-approval flow plus the destructiveHint annotation, like any standard
MCP server — the authorization boundary is always the user's own Sisense
permissions.
Data flow to the LLM provider
This server has no summarization or data-redaction layer: every tool result —
full rows, not {ok, count} metadata — is returned to the MCP client and
lands in the model's context. This is what makes multi-step
tool chaining work: the model can only reason over, filter, and feed one
tool's output into the next call if it actually sees the data.
The consequence: whoever connects this server to an MCP client is accepting that Sisense data (dashboard contents, query results, user lists, …) flows to that client's LLM provider — e.g. Anthropic, for Claude — under their own terms with that provider. The server cannot enforce or scope this; it is a per-deployment acceptance to make consciously.
Recommended usage guidelines
Start read-only: keep
FES_MCP_ALLOW_MUTATIONS=false(the default) until you've built confidence in a non-production environment.Curate
config/allowlist.txtdown to the tools your deployment actually needs — fewer tools means less data exposure and a clearer approval story.Prefer non-production Sisense instances while exploring; the tools are only as safe as the signed-in user's permissions.
Test destructive operations in a non-production environment first; the server asks for confirmation with the exact arguments before any write.
Configuration
Variable | Default | Used by | Purpose |
| — | fes-mcp | dev-mode ( |
|
| both | verify TLS when calling Sisense |
| by transport: http ⇒ | fes-mcp | credential source |
|
| fes-mcp |
|
|
| both | HTTP bind |
| — | fes-auth | public base URL (OAuth discovery/redirects) |
| — | fes-auth | the resource server to proxy tool calls to |
|
| fes-mcp | seconds a verified (instance, token) pair is trusted |
| — (accept any) | both | allowed Sisense instances (exact origins and |
|
| fes-mcp | comma-separated tool_ids / modules override |
|
| fes-mcp | expose mutating tools |
| bundled registry | fes-mcp | alternate registry JSON |
|
| both | log verbosity |
|
| both | directory for |
Tests
uv run python -m pytest # unit tests: mocked, no credentialsIntegration tests run against a real Sisense instance and are read-only; see tests/integration/README.md for setup:
uv run python -m pytest tests/integration -m integrationRegistry regeneration
./refresh_registry.sh # rebuild config/ from the installed PySisense SDKNew SDK methods land in the registry but stay hidden until explicitly
added to config/allowlist.txt.
Support and contributing
This is an experimental, community-contributed project maintained by Sisense Field Engineering and provided "as-is."
Do not open a GSS ticket — this is not a GA Sisense feature.
For usage questions or help getting started, contact your Customer Success Manager (CSM), who will route feedback to the Field Engineering team.
Issues and contributions are welcome through the repository.
License
Available Tools
36 toolsaccess_management_get_datamodel_columnsaccess_management.get_datamodel_columnsARead-only
Retrieve columns from a DataModel by collecting them from its datasets and tables. Resolves the DataModel ID by title, then walks its datasets and tables to gather every column.
Returns: list[dict[str, Any]] A list of dictionaries, each containing datamodel_id, datamodel_name, table, and column. An empty list is returned if the DataModel cannot be found or has no columns.
| Name | Required | Description | Default |
|---|---|---|---|
| datamodel_name | Yes | The name of the DataModel from which to extract columns. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is a read-only, non-destructive operation. The description adds meaningful behavioral details beyond those annotations: it resolves the DataModel by title, walks datasets and tables, and returns an empty list if the DataModel is not found or has no columns. This gives the agent useful expectations about edge cases.
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 wasted words: purpose, resolution/collection process, and return format/edge behavior. Each sentence contributes necessary information and the most important action 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?
Given the simple single-parameter input and the presence of read-only annotations, the description is complete. It explains the return value shape and the empty-list behavior, which is especially important because no output schema is provided.
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 extra semantic value by clarifying that datamodel_name is resolved as a title to an ID, which is critical for correct invocation. It also reinforces that an unknown title yields an empty list rather than an error.
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 ('Retrieve columns') and resource ('DataModel'), and distinguishes itself by explaining it collects columns from datasets and tables after resolving the DataModel ID by title. This clearly differentiates it from sibling tools like datamodel_get_table_schema, which target a single table 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 clearly implies when to use the tool: when you have a DataModel title and need all its columns aggregated from datasets and tables. However, it does not explicitly mention alternatives or state when not to use this tool, leaving some inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
access_management_get_groupsaccess_management.get_groupsARead-only
Retrieve groups — one named group, or all of them. Fetches the groups defined on the Sisense server. With name the API filters server-side to that group; without it, every group is returned. One row per group.
Returns: list[dict[str, Any]] | dict[str, Any] A list of raw group objects as returned by the API (each with _id, name, defaultRole, and related fields). Without name, an empty list means the server genuinely has …
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Group name to filter by. Omit for all groups. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and non-destructive, so the description correctly adds value beyond them: it discloses server-side filtering, one row per group, raw API objects with key fields, and the meaning of an empty list. This is exactly the behavioral detail an agent needs beyond the safety hints.
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 focused and front-loaded, with each sentence serving a purpose: scope, filtering behavior, output shape, and empty-list semantics. No filler or redundant restatement of the tool name is present.
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 one optional parameter, no output schema, and supported by read/write annotations, the description covers the return type, key returned fields, filtering behavior, and edge-case meaning of an empty result. Nothing needed for correct invocation or interpretation 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% for the single optional parameter, so the baseline is 3. The description adds extra meaning by clarifying the server-side filter behavior and tying the parameter to the return shape ('one row per group'), going slightly beyond the schema's one-line description.
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 action ('Retrieve'), the resource ('groups defined on the Sisense server'), and the input-dependent scope ('one named group, or all of them'). It also distinguishes this tool from sibling group-related tools like use or role tools by specifying exactly what kind of group data it returns.
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: provide `name` for a server-side filtered lookup, omit it to fetch every group. It does not explicitly name sibling alternatives or say when not to use this tool, but the boundary between 'one group' and 'all groups' is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
access_management_get_my_useraccess_management.get_my_userARead-only
Retrieve the currently logged-in user for the API token. Sends GET /api/users/loggedin. Use this to resolve migration user identity (email, username, internal ID) for the authenticated admin token.
Returns: dict[str, Any] The logged-in user object from the API, or {"error": "..."} on failure.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, covering the safety profile. The description adds value beyond this by disclosing the concrete HTTP endpoint, the return type (dict[str, Any]), and the failure shape ({"error": "..."}). It does not mention rate limits or other failure modes, but for a zero-parameter read call the disclosure is solid.
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, each earning its place: the primary action, the endpoint plus use case, and the return/error format. It is front-loaded with the most important information. Slightly dense with the 'Returns:' type annotation, but that detail justifies itself given the absence of an output 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 zero-parameter, read-only tool with no output schema, this description is complete. It covers what the tool does, the exact endpoint, the intended migration-user-identity scenario, the return object type, and the error case. An agent has everything needed to invoke it correctly and interpret the 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?
The tool takes zero parameters with 100% schema coverage, so there is nothing for the description to document. The baseline of 4 applies, and the description's mention of 'for the API token' correctly signals that the identity is derived from the token rather than passed in.
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 ('Retrieve the currently logged-in user for the API token') and names the exact endpoint (GET /api/users/loggedin). This clearly distinguishes it from siblings like access_management_get_user and access_management_get_users_all, which target specific users or all users rather than the token's own identity.
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 an explicit intended use case: 'Use this to resolve migration user identity (email, username, internal ID) for the authenticated admin token.' This is clear context an agent can act on. However, it does not name alternatives or state when NOT to use this tool versus the similarly named get_user/get_users_all siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
access_management_get_rolesaccess_management.get_rolesARead-only
Retrieve all Sisense roles. Sends GET /api/roles. Returns the raw role list used to build role name-to-ID maps (for example in multi-tenant migration workflows).
Returns: list[dict[str, Any]] | dict[str, Any] A list of role objects on success, or {"error": "..."} on failure.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint and destructiveHint=false, so the safety profile is clear. The description adds value by specifying the exact GET endpoint, stating it returns the raw role list, and documenting an `{"error": "..."}` failure shape. This is transparent beyond the structured fields, though it does not cover auth or rate-limit 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 generally tight and front-loaded, starting with the action and endpoint. There is minor redundancy between 'Returns the raw role list...' and the later 'Returns: list[dict[str, Any]]...' line, but it remains compact and readable.
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 zero-parameter, read-only list endpoint with no output schema, this description is complete. It includes the endpoint, success return type, failure format, and a representative use case, so an agent has enough information to invoke it correctly and interpret the 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?
There are zero parameters, so the schema already covers everything relevant. The description still adds useful return semantics with the list/error types, which is appropriate for a parameterless tool.
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 'Retrieve', names the exact resource ('all Sisense roles'), and even spells out the HTTP endpoint `GET /api/roles`. This clearly distinguishes the tool from the many sibling getters that target users, groups, dashboards, or datamodel objects.
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 a concrete use case: building role name-to-ID maps for multi-tenant migration workflows. This helps an agent understand when this exact list is needed, though it does not explicitly discuss when not to use it or name alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
access_management_get_unused_columns_bulkaccess_management.get_unused_columns_bulkARead-only
Run unused-column analysis for one or more data models and return a combined per-model outcome.
Returns: dict[str, Any] Always a dict with "results" and "errors": - "results": flat list of column rows across all processed data models, each row shaped as get_datamodel_columns rows plus a "used" boolean. …
| Name | Required | Description | Default |
|---|---|---|---|
| datamodels | Yes | One or more data model references to analyze. **Required.** Each reference can be: - a data model ID, or - a data model title (name). At runtime this parameter is tolerant of a single string and will normalize it to a one-element list. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and non-destructive behavior. The description adds valuable behavioral detail: it always returns a dict with 'results' and 'errors', returns a flat list across models, and normalizes a single string input. This goes beyond the structured annotation coverage.
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: it opens with the core action, then details the return contract in a readable list. It is informative without being bloated, though the trailing ellipsis suggests some content may be omitted and the opening sentence overlaps slightly with the return 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?
Despite lacking an output schema, the description provides enough return structure for an agent to consume the result. It explains the combined across-models behavior and error grouping. It relies on knowledge of get_datamodel_columns row shape, which is reasonable given the sibling tool 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?
The input schema already provides 100% parameter coverage, including accepted reference types and tolerant string normalization. The description does not materially add parameter-level semantics beyond restating 'one or more', 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 clearly states the verb ('Run unused-column analysis') and the resource ('one or more data models'), and explicitly differentiates this as a bulk operation from the single-model sibling access_management_get_datamodel_columns. The output semantics are also described, making the tool's 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 makes it clear this tool is for analyzing multiple data models at once and returns combined results, which implies when to choose it over single-model tools. However, it does not explicitly name alternatives or state conditions for when not to use it, so it falls short of the highest bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
access_management_get_useraccess_management.get_userARead-only
Retrieve one named user by email address, in the canonical user row shape. Fetches users with expanded groups and role data and returns the record matching the provided email address. Changed in 2.0: ROLE_NAME held the display name in 1.x (that value is now ROLE_DISPLAY_NAME); GROUPS still holds the group names and is joined by the new GROUP_IDS. See docs/upgrading.md.
Returns: dict[str, Any] The canonical user row: USER_ID, USER_NAME, EMAIL, FIRST_NAME, LAST_NAME, IS_ACTIVE, ROLE_ID, ROLE_NAME (the raw Sisense value, e.g. "consumer"), ROLE_DISPLAY_NAME …
| Name | Required | Description | Default |
|---|---|---|---|
| user_email | Yes | Email address of the user to retrieve. **Required** — this method always answers "one named user"; use ``get_users_all`` for every user. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false, and the description goes further by disclosing expanded groups/role data, the canonical row shape, and the 2.0 field-name migration from ROLE_NAME to ROLE_DISPLAY_NAME. This adds meaningful behavioral context 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 well structured: core action first, then behavioral detail, then version-change context, then return shape. Every sentence adds distinctive value, and 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?
Even without an output schema, the description supplies the canonical return fields, expanded group/role semantics, and a note on version-specific field naming. This is sufficient for an agent to invoke the tool correctly and interpret 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?
The only parameter, user_email, is already fully described in the schema with format and required status, giving 100% schema coverage. The description merely restates 'by email address' and 'matching record,' so it adds little 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?
The description opens with 'Retrieve one named user by email address,' giving a specific verb, resource, and scope. It clearly differentiates from siblings like get_users_all and get_my_user by emphasizing the single-user, email-based lookup.
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 implies this tool is for retrieving exactly one named user by email rather than listing users. It does not explicitly name alternatives in the description itself, though the schema parameter does direct users to get_users_all for all users.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
access_management_get_users_allaccess_management.get_users_allARead-only
Retrieve every user, one canonical user row each. Reports exactly what Sisense stores: group memberships are unfiltered (Everyone is included — consumers that want to hide a universal group can drop it; a consumer that never received it cannot put it back), and ROLE_NAME carries the raw Sisense value with the UI-facing name in ROLE_DISPLAY_NAME. Changed in 2.0: ROLE_NAME held the display name in 1.x (that value is now ROLE_DISPLAY_NAME), GROUPS is joined by the new GROUP_IDS, and Everyone is no longer filtered out of GROUPS. See docs/upgrading.md.
Returns: list[dict[str, Any]] | dict[str, Any] One row per user, each with USER_ID, USER_NAME, EMAIL, FIRST_NAME, LAST_NAME, IS_ACTIVE, ROLE_ID, ROLE_NAME (raw, e.g. "consumer"), …
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral context beyond the annotations: group memberships are unfiltered, 'Everyone' is included, ROLE_NAME contains the raw Sisense value while ROLE_DISPLAY_NAME is UI-facing, and it documents version 2.0 changes affecting field semantics. This is exactly the kind of non-obvious behavior an agent needs to know.
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 provides meaningful caveats and version-change context. It is longer than strictly necessary, and the upgrade-history detail could arguably live only in the referenced doc, but the structure is logical and each section earns its place for interpretation.
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 properly explains the return shape, lists the key fields, and clarifies important edge cases like the 'Everyone' group and raw ROLE_NAME values. An agent has enough context to invoke the tool correctly and interpret its results.
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 tool has zero parameters and the schema coverage is 100%, so there are no parameter semantics to clarify. The description focuses on return value semantics instead, which is appropriate here.
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: 'Retrieve every user, one canonical user row each.' It clearly distinguishes this from single-user or group-related tools by emphasizing 'every user' and 'canonical user 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 implies when to use this tool by highlighting 'every user' and unfiltered data, but it does not explicitly name alternatives like access_management_get_user or access_management_get_my_user, nor does it state when not to use it. The usage context is present but left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
access_management_users_per_groupaccess_management.users_per_groupARead-only
Retrieve group memberships — one group's members, or every membership. Returns one flat row per (group, user) membership. With group_name the rows are that group's members; without it, every membership on the instance is returned (ask get_groups for the per-group view). Everyone and All users in system are omitted from the all-groups view: Sisense fills both with every user, so they restate get_users_all rather than describing group structure. Naming either one still returns its members. The rule across the SDK: **targeted questions give complete answers; only the …
Returns: list[dict[str, Any]] | dict[str, Any] One row per (group, user) membership, each with GROUP_ID, GROUP_NAME, USER_ID, USER_NAME, EMAIL, FIRST_NAME, LAST_NAME, IS_ACTIVE, ROLE_ID, …
| Name | Required | Description | Default |
|---|---|---|---|
| group_name | No | The name of the group whose members to list. Omit for all memberships. A name that matches no group returns ``{"error": "..."}`` naming it — never a silent empty list. Naming ``Everyone`` or ``All users in system`` returns their members — an explicit request is always honored, even though the all-groups view omits them. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this read-only and non-destructive, and the description adds substantial behavioral detail beyond them: flat-row semantics, omission of synthetic groups in the all-groups view, honoring explicit requests for those groups, and a non-silent error for unmatched group names. It also discloses the return shape and fields despite no output schema, which is valuable 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 front-loaded with the core purpose and mode distinction, and most sentences earn their place by explaining edge cases. It loses a point because some content repeats the schema's group_name notes and the final sentence is truncated ('only the …'), leaving a dangling rule that does not contribute.
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 one-optional-parameter read-only tool with no output schema, the description supplies the return format, field list, error behavior, and alternative tools, so an agent can call it correctly. The incomplete closing sentence and the absence of any mention of pagination or limits are minor gaps, so it is strong but not perfect.
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 group_name with 100% coverage, including omit behavior, error behavior, and Everyone/All users handling. The description mostly reflects those same semantics rather than adding new parameter-level meaning 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 starts with a specific verb and resource: 'Retrieve group memberships' and immediately clarifies the two modes (one group vs. every membership). It also distinguishes itself from the sibling get_groups by noting this tool returns 'one flat row per (group, user) membership' while get_groups gives the per-group view, so there is 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 explicitly tells the agent when to omit vs. provide group_name and points to the alternative get_groups for a per-group view. It also explains that the all-groups view omits Everyone and All users in system because those restate get_users_all, preventing misuse of this tool for all-user queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dashboard_can_be_owneddashboard.can_be_ownedARead-only
Check whether a dashboard can be owned by the current user. Sends GET /api/v1/dashboards/{dashboard_id}/can_be_owned.
Returns: dict[str, Any] The API response on success, or {"error": "..."} on failure.
| Name | Required | Description | Default |
|---|---|---|---|
| dashboard_id | Yes | The dashboard ``oid`` to check. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds the HTTP method and a success/error return shape, but no deeper behavior such as auth requirements, failure modes, or side effects. This is useful but limited context, so a 3 is appropriate.
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, purposeful sentences front-load the action, then give the endpoint and return contract. There is no filler or repetition of schema annotations.
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 one-parameter read-only tool with no output schema, the description covers purpose, endpoint, and return/error format. It is close to complete, though it omits any preconditions or ownership-transfer usage context.
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%, meaning dashboard_id is already documented as 'The dashboard oid to check.' The description adds no parameter-level meaning beyond the endpoint path, 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?
States a specific predicate, 'Check whether a dashboard can be owned by the current user,' and names the exact API call. It is clearly distinguishable from sibling dashboard_get_* tools, which fetch dashboards or shares rather than check ownership eligibility.
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 no explicit guidance about when to use this tool versus alternatives, such as 'before ownership transfer' or 'when confirming eligibility for the current user.' The only clue is 'current user,' which describes the tool's semantics rather than a usage condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dashboard_find_widgets_by_typedashboard.find_widgets_by_typeARead-only
Find all widgets matching a given type across one or more dashboards. Iterates over the specified dashboards (or all dashboards when dashboards is None) and returns every widget whose type field matches widget_type.
Returns: list[dict[str, Any]] A list of match records. Each record contains: - dashboard_id (str): The oid of the containing dashboard. - dashboard_title (str): The title of the containing dashboard. - widget_id …
| Name | Required | Description | Default |
|---|---|---|---|
| dashboards | No | One or more dashboard IDs or titles to search. A bare string is treated as a single-item list. When ``None`` (default), all dashboards on the instance are searched. | |
| max_results | No | Stop after collecting this many matching widgets. ``None`` (default) means no limit. | |
| widget_type | Yes | The widget type to match (for example ``"BloX"``, ``"chart"``, ``"pivot"``). Comparison is case-sensitive. | |
| admin_access | No | When ``True`` (default), enumerates all dashboards on the instance via the admin endpoint and fetches widgets using ``adminAccess=true``, so dashboards owned by other users are included. When ``False``, only dashboards visible to the API token user are scanned. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds meaningful behavioral details beyond the readOnly/destructive annotations: it describes iteration over dashboards, the effect of admin_access on including other users' dashboards, case-sensitive matching, and early stopping via max_results. These are not present in the annotations and help the agent understand side effects and scope. 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 well-structured and efficient: a one-sentence purpose, a brief iteration explanation, and a concise return-value breakdown. Every sentence contributes useful information and there is no filler. The most important scoping 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 tool with four parameters and no output schema, the description covers the main behavioral context: what is searched, how admin access affects scope, how limits work, and the shape of returned records. The return record list is slightly truncated ('widget_id …'), which leaves minor ambiguity about the full record contents, so it is not a perfect 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 description coverage is 100%, so the schema already documents all four parameters including defaults and behavior. The description reinforces some parameter semantics (e.g., dashboards=None means all dashboards, widget_type is case-sensitive) but does not add substantial new meaning beyond the schema. Baseline 3 is appropriate given the high 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 opens with a specific verb and resource: 'Find all widgets matching a given type across one or more dashboards.' This clearly distinguishes it from siblings like dashboard_get_widget_by_id (single widget lookup) and dashboard_get_dashboards (list dashboards). The scope and matching criterion are 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 provides clear context by explaining that it iterates over specified dashboards or all dashboards when none are given, and matches widgets by type. It does not explicitly name alternatives or state when not to use it, but the behavior is specific enough that an agent can infer appropriate usage. A small deduction because no explicit exclusion or alternative guidance is present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dashboard_get_all_dashboardsdashboard.get_all_dashboardsARead-only
Retrieve all dashboards from the Sisense server. Sends GET /api/v1/dashboards/admin?dashboardType=owner using the admin endpoint, which requires elevated access.
Returns: list[dict[str, Any]] | dict[str, Any] A list of dashboard objects on success, or {"error": "..."} on failure.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds value by specifying the exact HTTP endpoint, the required elevated access, and the failure return shape ({'error': '...'}), which goes 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?
The description is compact and front-loaded with the core purpose. Every sentence adds useful information: what it does, which endpoint it calls, what access is required, and what the caller should expect on success or failure.
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 zero-parameter read-only tool, the description is complete. It names the endpoint, auth requirement, success return type, and error format. No output schema exists, so the description's return-value note is especially valuable.
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 tool has zero parameters and the schema coverage is 100%, so there is nothing for the description to explain about parameters. The description instead clarifies the endpoint and return behavior, which is appropriate and sufficient.
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 ('Retrieve all dashboards from the Sisense server'), identifies the exact endpoint, and notes the elevated-access requirement. The word 'all' and the admin endpoint help distinguish it from sibling tools like dashboard_get_dashboards or dashboard_get_dashboard_by_id.
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 use: retrieving all dashboards via the admin endpoint, and it warns that elevated access is required. It does not explicitly name alternatives or say when not to use it, but the scope and access requirement provide sufficient practical guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dashboard_get_dashboard_by_iddashboard.get_dashboard_by_idARead-only
Retrieve a specific dashboard by its ID. Sends GET /api/v1/dashboards/admin?dashboardType=owner&id={dashboard_id} against the admin endpoint.
Returns: list[dict[str, Any]] | dict[str, Any] The matching dashboard objects on success, or {"error": "..."} when the request fails or no dashboard is found.
| Name | Required | Description | Default |
|---|---|---|---|
| dashboard_id | Yes | The ``oid`` of the dashboard to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/destructive annotations, the description discloses the exact HTTP request, the response shape, and the failure contract: it returns an error dict when the request fails or no dashboard is found. It does not cover authorization details or rate limits, but it adds meaningful behavioral context 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 two compact sentences with the primary purpose front-loaded, followed by the endpoint and return contract. There is no filler, redundancy, or unnecessary 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 one-parameter read-only GET with no output schema, the description is complete: it specifies the endpoint, the success return shape, and the error behavior. No critical call-time detail 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%, and the schema already says dashboard_id is 'The oid of the dashboard to retrieve.' The description's endpoint template confirms the parameter's role but adds no substantially new meaning beyond the schema, so 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 starts with a specific verb and resource: 'Retrieve a specific dashboard by its ID.' It also provides the exact GET endpoint, making its scope unambiguous and differentiating it from siblings like dashboard_get_all_dashboards and dashboard_get_dashboards.
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 correct usage context: call this when you already have a dashboard ID and need one specific dashboard. It does not explicitly name sibling alternatives or give when-not-to-use guidance, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dashboard_get_dashboard_columnsdashboard.get_dashboard_columnsARead-only
Retrieve columns referenced by a dashboard, including widget and filter columns. Resolves the dashboard by title with get_dashboard_by_name, exports its full metadata, then extracts column references from both filters and widgets. The final list is deduplicated by table and column.
Returns: list[dict[str, Any]] | dict[str, Any] A list of distinct column entries. Each entry contains dashboard_name, source ("filter" or "widget"), widget_id, table, and column — an empty list means …
| Name | Required | Description | Default |
|---|---|---|---|
| dashboard_name | Yes | Title of the dashboard to retrieve columns from. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though readOnlyHint is already annotated, the description adds valuable behavioral detail: it resolves the dashboard by title, exports full metadata, extracts column references from both filters and widgets, and deduplicates by table and column. It also discloses the exact output fields, which is especially useful given the absence of an output 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 compact and front-loads the main purpose before diving into implementation details. The Returns section is clearly structured and avoids filler. A small amount of internal implementation detail could have been trimmed, but it remains useful for transparency.
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 single-parameter read-only tool, the description covers the operation, the return type, the fields included, the deduplication behavior, and the meaning of an empty list. It does not describe error behavior when a dashboard is not found, and the final 'empty list means …' sentence is cut off, leaving a minor 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?
The input schema already describes dashboard_name as 'Title of the dashboard to retrieve columns from,' so coverage is high. The description adds extra meaning by explaining that the name is used to resolve the dashboard through get_dashboard_by_name, reinforcing that it is a human-readable title rather than an ID.
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: 'Retrieve columns referenced by a dashboard, including widget and filter columns.' It also clarifies the tool resolves by title via get_dashboard_by_name, which distinguishes it from sibling tools like dashboard_get_dashboard_by_id.
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 use is implied through the phrase 'Retrieve columns referenced by a dashboard,' but there is no explicit statement of when to use this tool versus alternatives such as dashboard_get_dashboard_by_id or dashboard_find_widgets_by_type. The guidance is inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dashboard_get_dashboardsdashboard.get_dashboardsARead-only
Retrieve dashboards visible to the authenticated user. Sends GET /api/v1/dashboards, which returns dashboards the current user owns or has been shared to — as opposed to get_all_dashboards, which uses the admin endpoint and requires elevated access.
Returns: list[dict[str, Any]] | dict[str, Any] List of dashboard objects on success, or {"error": "..."} on failure.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Subset of fields to include in the response (for example ``["oid", "title", "owner"]``). When omitted, all fields are returned. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and destructiveHint annotations, the description discloses the exact HTTP method and endpoint, the visibility semantics (owned or shared), and the return shape including the error format. This is strong behavioral 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 two sentences with no filler. The main action and endpoint are front-loaded, followed by a concise comparison to a sibling and a return-type 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?
The description covers what the tool does, its scope, its endpoint, its return type, and its error behavior. With only one optional parameter and no output schema, nothing essential is missing for an agent to invoke 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?
The single parameter 'fields' is already fully documented in the schema with an example and behavior when omitted. With 100% schema description coverage, the tool description does not need to add more, so the baseline score 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 uses a specific verb and resource: 'Retrieve dashboards visible to the authenticated user' via GET /api/v1/dashboards. It explicitly contrasts with get_all_dashboards, making the purpose and scope 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 clearly states when to use this tool versus dashboard_get_all_dashboards: the former uses the user-facing endpoint, while the latter uses the admin endpoint and requires elevated access. This gives an agent an explicit routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dashboard_get_dashboard_scriptdashboard.get_dashboard_scriptARead-only
Build a formatted dashboard script helper object. Retrieves a dashboard export payload and wraps its script content in a :class:SisenseScript helper that can render plain text, markdown, or file output.
Returns: SisenseScript | dict[str, str] A :class:SisenseScript instance when the dashboard is retrieved and has a script. {"error": "..."} when the export fails (including status_code for HTTP failures such as missing …
| Name | Required | Description | Default |
|---|---|---|---|
| dashboard_id | Yes | The dashboard identifier to export. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral detail beyond annotations: it specifies the return type (SisenseScript or error dict), the condition for success (dashboard retrieved and has a script), and error behavior (includes status_code for HTTP failures). This gives an agent a good sense of outcomes without making the description the sole source of safety information.
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 and mostly front-loaded: the first sentence states the primary purpose, and the second covers the return contract. The phrasing 'Build a formatted dashboard script helper object' is slightly abstract but immediately clarified. No redundant filler appears, though the return type sentence could be tightened.
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 single-parameter, read-only tool with annotations and no output schema, the description covers the essential behavioral contract: what it returns on success, what it returns on failure, and how errors are shaped. Minor gaps exist, such as not explicitly describing what happens when a dashboard exists but has no script, but overall it is sufficiently complete for an agent to 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 provides 100% coverage of the single parameter, dashboard_id, with a clear description. The tool description does not add additional meaning about the parameter beyond what is already in the schema. According to the rubric, baseline 3 is appropriate since schema_description_coverage is high and the parameter is simple.
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: building a formatted dashboard script helper object by retrieving a dashboard export and wrapping its script in a SisenseScript helper. This clearly distinguishes it from sibling tools like dashboard_get_dashboard_by_id (which retrieves the dashboard itself) and dashboard_get_widget_script (which targets widget scripts). The verb 'build' plus the resource 'dashboard script helper' makes the 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 implies this tool is used when a formatted dashboard script helper is needed, but it does not explicitly state when to use it over alternatives or when not to use it. No sibling comparisons or exclusions are provided. The usage context is inferable from the clear resource focus, but explicit guidance is absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dashboard_get_widget_by_iddashboard.get_widget_by_idARead-only
Retrieve a single widget by its dashboard and widget IDs. Sends GET /api/v1/dashboards/{dashboard_id}/widgets/{widget_id}. Returns the full widget object as returned by the Sisense API.
Returns: dict[str, Any] The widget object returned by the API, or {"error": "..."} on failure.
| Name | Required | Description | Default |
|---|---|---|---|
| widget_id | Yes | The ``oid`` of the widget to retrieve. | |
| admin_access | No | When ``True`` (default), appends ``?adminAccess=true`` to the request, allowing access to dashboards the API token user does not own. Some Sisense versions reject the ``adminAccess`` query parameter with HTTP 422 (strict query-schema validation); the request is then retried automatically without it. | |
| dashboard_id | Yes | The ``oid`` of the dashboard that contains the widget. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral detail by specifying the exact HTTP GET endpoint and stating that failure returns an error dict rather than raising an unhandled exception.
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 endpoint. There is slight redundancy between 'Returns the full widget object as returned by the Sisense API' and the following 'Returns: dict[str, Any]' line, which 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 simple read-only GET with no output schema and well-covered parameters, the description is complete: it provides the endpoint, the expected return value, the error behavior, and the needed IDs. Combined with the strong input schema coverage, an agent has everything required to call 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?
The input schema has 100% parameter description coverage, including clear definitions for dashboard_id, widget_id, and the admin_access retry behavior. The description itself does not need to add parameter semantics, 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: 'Retrieve a single widget by its dashboard and widget IDs.' It names the exact REST endpoint, making the operation unambiguous and distinguishing it from sibling tools like dashboard_get_dashboard_by_id or dashboard_find_widgets_by_type.
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?
There is no guidance on when to use this tool versus alternatives. It does not mention that dashboard_get_dashboard_by_id should be used for dashboards or that dashboard_find_widgets_by_type should be used when searching by widget type. The usage context is only implied by the endpoint and parameter names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dashboard_get_widget_scriptdashboard.get_widget_scriptARead-only
Build a formatted widget script helper object. Retrieves a dashboard export payload, selects a widget by index/key, and wraps its script content in a :class:SisenseScript helper for downstream rendering.
Returns: SisenseScript | dict[str, str] A :class:SisenseScript instance when the widget is found and has a script. {"error": "..."} when the export fails (including status_code for HTTP failures such as missing …
| Name | Required | Description | Default |
|---|---|---|---|
| widget_id | Yes | The widget identifier or lookup key used in the exported widget mapping. | |
| dashboard_id | Yes | The dashboard identifier to export. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds meaningful behavior: it retrieves an export payload, selects by index/key, wraps script content, and returns an error dict with status_code on export failure. This is useful context 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 compact and front-loaded with the main purpose. The return behavior is appended clearly. Minor redundancy exists ('Build...helper' and later 'wraps...helper') but it is 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 read-only tool with two fully documented parameters and annotations, the description covers the main operation, return type, and failure mode. It does not explain the case where the widget is found but has no script, but this is a minor gap given the overall clarity.
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 minimal new meaning; it mentions selection by index/key but does not enrich the parameter definitions 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 uses specific verbs ('Retrieves', 'selects', 'wraps') and a clear resource (widget script for downstream rendering). It is clearly distinct from siblings like dashboard_get_dashboard_script and dashboard_get_widget_by_id, so an agent can tell 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 clearly indicates the use case: get a widget's script wrapped in a SisenseScript helper for downstream rendering. It does not explicitly name alternatives or exclusion criteria, but the context is strong enough to guide selection among similar dashboard tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
datamodel_describe_datamodeldatamodel.describe_datamodelARead-only
Retrieve data model structure in a flat, row-based format. Resolves the data model by name and flattens its datasets and tables into one row per table, suitable for DataFrame or CSV export. Returns: list[dict[str, Any]] List of row dicts, each representing a single table with model, dataset, connection, and table context. Returns an empty list if the data model is not found.
| Name | Required | Description | Default |
|---|---|---|---|
| datamodel_name | Yes | Name (title) of the data model to describe. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and destructiveHint annotations, the description discloses meaningful behavior: it resolves the data model by name, flattens datasets and tables, returns a list of row dicts, and returns an empty list when the model is not found. 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 primary purpose, then immediately explains the return format and missing-model behavior. Every sentence earns its place, and the return type note compensates for the lack of an output 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 single-parameter, read-only tool with no output schema, the description fully covers what an agent needs: what the tool returns, the row structure, the missing-model behavior, and the use case. 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?
The schema already documents the only parameter with 100% coverage ('Name (title) of the data model to describe'). The description lightly reinforces the meaning by saying it 'resolves the data model by name' but adds no new depth 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 uses a specific verb ('Retrieve') with a concrete resource ('data model structure') and clearly distinguishes its output format ('flat, row-based format', 'one row per table') from sibling tools like datamodel_get_model_schema. The mention of DataFrame/CSV suitability further clarifies its unique role.
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 about when to use this tool: when a flat, row-oriented representation of a data model is needed, especially for DataFrame or CSV export. It does not explicitly name alternatives or exclusions, but the format-oriented context is sufficient for most selection scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
datamodel_generate_connections_payloaddatamodel.generate_connections_payloadARead-only
Generate a connection payload for a given data source type. Builds the provider-specific request body consumed by create_connections. The datasource_type is matched case-insensitively. Supported types are "Athena", "RedShift", "BigQuery", and "DataBricks".
Returns: dict[str, Any] The provider-specific connection payload.
| Name | Required | Description | Default |
|---|---|---|---|
| datasource_type | Yes | Type of data source (matched case-insensitively). | |
| connection_params | Yes | Connection details. Supported keys depend on ``datasource_type``: - Athena: ``name`` (required), ``region`` (required), ``s3_output_location`` (required), ``aws_access_key`` (required), ``aws_secret_key`` (required), ``description``, ``schema``, ``additional_parameters``. - DataBricks: ``name`` (required), ``connection_string`` (required), ``token`` (required), ``description``, ``use_dynamic_schema``, ``schema``. - BigQuery: ``name`` (required), ``service_account_key_path`` (required), ``description``, ``use_service_account``, ``use_proxy_server``, ``use_dynamic_schema``, ``record_field_flattening_level``, ``unnest_arrays``, ``allow_large_results``, ``use_storage_api``, ``additional_parameters``, ``database``. - RedShift: ``server`` (required), ``username`` (required), ``password`` (required), ``name``, ``description``, ``default_database``, ``additional_parameters``. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral detail: datasource_type matching is case-insensitive, the output is a dict payload, and the tool is a payload builder rather than a connector. This goes 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 compact, front-loaded with the core purpose, and every sentence contributes either to scope, supported types, or return type. 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?
Given the rich input schema and annotations, the description is nearly complete. It explains the output type and how the payload is intended to be used. A more explicit note about what happens with unsupported datasource types would improve it, but the supported list and schema enum already cover the main decision.
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 fully documents datasource_type and connection_params, including per-type required and optional keys. The description adds little beyond what the schema already provides, so the baseline score 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 action ('Generate a connection payload') and a clear resource ('for a given data source type'). It distinguishes itself from sibling datamodel tools by explicitly noting it builds the provider-specific request body for create_connections, not performing connection operations.
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: use this to produce a payload consumed by create_connections, with supported datasource types enumerated. It does not explicitly name alternatives or say when not to use it, but the intended use case is strongly implied by the 'consumed by create_connections' phrasing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
datamodel_get_all_datamodeldatamodel.get_all_datamodelARead-only
Retrieve metadata for all data models using an internal API. Sends a POST /api/v2/ecm/ GraphQL query (elasticubesMetadata). This includes additional fields such as build status, size, and timestamps that may not be available through the standard public endpoints.
Returns: list[dict[str, Any]] | dict[str, Any] List of data model metadata objects (each with oid, title, type, status, sizeInMb) on success, or {"error": "..."} on failure.
Uses an internal Linux-only route; on Windows-based Sisense use get_elasticubes instead.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and non-destructive annotations, the description discloses the internal API route, the fact that it sends a POST request, the Linux-only platform constraint, and the exact success/error return shapes. This adds meaningful behavioral context that annotations alone do not 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 front-loaded with the core purpose, then adds the API detail, return type, and platform caveat in a logical order. Every sentence provides useful information for selection and invocation, with no fluff 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 zero-parameter read-only metadata tool, the description is complete: it explains the API mechanism, the returned metadata fields, error behavior, and when to use an alternative. There is no output schema, so the explicit return format in the description fully covers what an agent needs to interpret results.
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 no parameters, so the description needs no parameter-level explanation. With zero parameters, baseline is 4, and the description appropriately focuses on output and platform behavior instead.
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 retrieves metadata for all data models via an internal API, with a specific endpoint and GraphQL query. It also distinguishes itself from the related sibling get_elasticubes by noting the Linux-only route, so an agent can tell them apart.
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 use this tool versus the alternative: on Windows-based Sisense, use get_elasticubes instead. It also clarifies that this tool accesses internal metadata not available through standard public endpoints, giving clear selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
datamodel_get_connectiondatamodel.get_connectionARead-only
Retrieve connections matching a name. Sends GET /api/v2/connections?name=<connection_name> and returns the matching connection list.
Returns: list[dict[str, Any]] | dict[str, Any] List of matching connection objects if found, or {"error": "..."} on failure or when no match is found.
| Name | Required | Description | Default |
|---|---|---|---|
| connection_name | Yes | Name of the connection to filter by. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the readOnlyHint=true and destructiveHint=false annotations by disclosing the HTTP method, endpoint, query parameter, return type, and the error shape on failure or no match. Minor operational details like authentication requirements are not mentioned, but for a read-only GET operation this is 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?
Two compact sentences with the action and endpoint front-loaded, followed only by the return behavior. There is no redundancy or filler, and every sentence contributes useful information.
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 single-parameter, read-only tool with no output schema, the description is complete: it specifies what is retrieved, how the request is made, what the matching data looks like, and what happens on failure or no match. No critical information needed to use the 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?
The input schema already fully describes connection_name with 100% coverage. The description adds that the parameter becomes the name query parameter in the request, but provides no additional constraints, formatting rules, or semantics 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 states a specific verb and resource: 'Retrieve connections matching a name' and gives the exact endpoint GET /api/v2/connections?name=<connection_name>. The name-based filter distinguishes this from the sibling datamodel_get_connections_all, so an agent can tell them apart.
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 indicates this tool is for retrieving connections by name, which provides clear context for invocation. It does not explicitly name the alternative for getting all connections or list when-not-to-use conditions, but the intended usage is explicit rather than merely implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
datamodel_get_connections_alldatamodel.get_connections_allARead-only
Retrieve all connections. Sends GET /api/v2/connections and returns the full connection list.
Returns: list[dict[str, Any]] | dict[str, Any] List of connection objects on success, or {"error": "..."} on failure.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses the concrete HTTP method and path (GET /api/v2/connections) and the exact return shape (list of connection objects or error dict). This adds real behavioral context beyond readOnlyHint and destructiveHint.
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 terse sentences deliver the core action, the endpoint, and the return contract without repetition or fluff. The most important 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 parameterless, read-only tool with annotations covering safety, the description fully specifies the side effect (network GET) and the success/failure return. No output schema exists, so the stated return types are necessary and sufficiently 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 tool has zero parameters, so the description has no parameter documentation burden. The input schema is vacously fully covered, meriting the baseline of 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?
The description uses the specific verb 'Retrieve' with the resource 'all connections' and states the exact endpoint and return type. The emphatic 'all' differentiates it from the sibling datamodel_get_connection, which targets a single connection.
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?
No explicit when-to-use or when-not-to-use guidance is provided. The word 'all' implicitly suggests usage when the full connection list is needed, but no alternatives or exclusions are mentioned, leaving the agent to infer selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
datamodel_get_datadatamodel.get_dataARead-only
Retrieve data from a specific table in a data model. Runs a SQL query against the data model and returns the rows in a row-based format (a list of dicts) compatible with to_dataframe.
Returns: list[dict[str, Any]] | dict[str, Any] List of dictionaries where each dict represents a row — an empty list means the query genuinely returned no data. On failure, returns the standard ``{"ok": False, "error": "...", …
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Optional SQL query to filter the data. When omitted, all rows of the table are selected. | |
| table_name | Yes | Name of the table to retrieve data from. | |
| datamodel_name | Yes | Name of the data model. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only and non-destructive behavior, and the description adds meaningful context: success returns a list of dicts, an empty list means genuinely no data, and failure returns a standard error dict. This goes beyond the annotations 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 front-loaded and mostly efficient, but the failure-return sentence is truncated mid-structure with '...', making it incomplete. It reads as slightly malformed rather than fully polished.
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 specifying the row format, empty-list semantics, and failure return behavior. It omits a full error-dict shape and SQL execution caveats, but for a simple read-only 3-param tool it is fairly 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 description coverage is 100%, so the schema already documents datamodel_name, table_name, and query. The description adds no parameter-specific meaning beyond restating that a SQL query is executed, 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 clearly states the action and resource: 'Retrieve data from a specific table in a data model' via a SQL query. It is distinct from schema/count siblings by emphasizing a row-based list-of-dicts result compatible with to_dataframe.
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 conveys when to use the tool: when table row data is needed, optionally filtered by SQL. However, it never explicitly distinguishes it from alternatives like datamodel_get_row_count or datamodel_get_table_schema, so the routing is 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.
datamodel_get_datasecurity_detaildatamodel.get_datasecurity_detailARead-only
Retrieve detailed datasecurity rules for a data model, including share-level visibility. Each row represents a unique column-level rule and is repeated per share for clarity. Special handling is applied to interpret member values: - If members is an empty list and exclusionary is missing/null, it is interpreted as "Nothing". - If members is empty and exclusionary is False, it is interpreted as "Everything". - If values exist and exclusionary is True, it is treated as a restricted subset.
Returns: list[dict[str, Any]] | dict[str, Any] List of dicts representing datasecurity rules in flat, share-resolved format, each with "datamodel_name", "table_name", "column_name", "data_type", "value", …
| Name | Required | Description | Default |
|---|---|---|---|
| datamodel_name | Yes | Name of the data model to retrieve datasecurity rules for. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnly/destructive annotations by explaining that each row is a column-level rule repeated per share, and by documenting the special interpretation of members and exclusionary values. This gives the agent essential behavioral context that annotations alone do not 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 well-structured: a clear purpose sentence, a row-semantics explanation, a bulleted list for special member-value handling, and a return-format note. Each part earns its place and the most critical 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?
The description covers the key behavioral nuances and return shape well, especially given there is no output schema. However, the union return type 'list[dict[str, Any]] | dict[str, Any]' is not fully clarified, and the trailing '…' leaves the complete set of returned fields slightly vague.
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 is only one parameter, datamodel_name, and the input schema already describes it fully at 100% coverage. The description mentions 'data model' again but adds no new semantic details about the parameter, so the baseline score of 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: 'Retrieve detailed datasecurity rules for a data model', and adds distinguishing details like 'share-level visibility' and 'column-level rule'. This clearly separates it from sibling tools such as datamodel_get_datamodel_shares or datamodel_get_table_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 establishes a clear context: use this when you need detailed datasecurity rules and their share-resolved interpretation for a data model. It does not explicitly mention alternatives or when-not-to-use conditions, so it stops short of a perfect score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
datamodel_get_elasticubesdatamodel.get_elasticubesARead-only
List all ElastiCubes using the legacy v1 endpoint. Sends GET /api/v1/elasticubes/getElasticubes. This endpoint is supported on both Linux and Windows Sisense deployments and returns basic ElastiCube metadata including title, address, and fullname. Prefer get_all_datamodel for Linux deployments when richer metadata (build status, size, timestamps) is needed. Use get_elasticubes when targeting Windows environments or when a lightweight list suffices.
Returns: list[dict[str, Any]] | dict[str, Any] List of ElastiCube objects on success, or {"error": "..."} on failure.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as readOnly and non-destructive, and the description adds useful behavioral context: it calls the legacy v1 endpoint, works on both Linux and Windows, returns only basic metadata fields, and describes both success and error return shapes. 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 primary purpose, followed by endpoint details, usage guidance, and return behavior. Every sentence contributes distinct information with no redundant 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 zero-parameter read-only listing tool, this description is complete: it specifies the endpoint, platform compatibility, metadata scope, alternative tool, and the return/error format. There is no output schema, so the explicit return type fills 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?
The tool has zero parameters and the schema is empty, so there is nothing for the description to add. The description correctly avoids inventing parameter details, matching the baseline of 4 for a no-parameter tool.
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 all ElastiCubes'. It also names the exact legacy v1 endpoint and explicitly distinguishes itself from the sibling tool datamodel_get_all_datamodel by platform support and metadata richness.
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 selection criteria: prefer get_all_datamodel for Linux deployments when richer metadata is needed, and use get_elasticubes for Windows environments or when a lightweight list suffices. This directly tells an agent when to choose this tool over the alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
datamodel_get_model_schemadatamodel.get_model_schemaARead-only
Retrieve the schema of a data model, including tables and columns. Resolves the data model by name and emits one row per column, mapping Sisense numeric column type codes to readable type names.
Returns: list[dict[str, Any]] | dict[str, Any] A list of dicts (one per column) with datamodel_name, datamodel_type, dataset_name, table_name, column_name, and column_type on success, or ``{"error": …
| Name | Required | Description | Default |
|---|---|---|---|
| datamodel_name | Yes | Name (title) of the data model to retrieve the schema for. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context beyond the annotations: it explains the row-per-column emission, type-code mapping, success/error return shape, and the returned field names. This gives the agent a clear picture of what to expect when calling the tool.
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-loaded with the core purpose, followed by output behavior and return fields. It is mostly efficient, though 'one row per column' appears twice (once in the first paragraph and again in the return description), which is a minor 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 single-parameter, read-only schema retrieval tool with no output schema, the description is complete: it covers the input, the resolution behavior, the output format, the returned fields, and the error return shape. An agent has enough information to invoke it correctly and interpret the 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 description coverage is 100%, with datamodel_name documented as 'Name (title) of the data model to retrieve the schema for.' The description reinforces this by saying the model is 'resolved by name,' but adds no substantially new semantic detail beyond what the schema already provides. Baseline 3 is appropriate given the high 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 clearly states a specific action ('Retrieve the schema of a data model') and resource, and goes further by describing the output granularity ('one row per column') and the mapping of numeric type codes. However, it does not explicitly distinguish itself from the closely related sibling datamodel_get_table_schema, so it stops short of full differentiation.
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 usage context is implied: use this when you need the full column-level schema of a named data model. The description does not explicitly state when not to use it or point to alternatives such as datamodel_get_table_schema or datamodel_get_all_datamodel, leaving the agent to infer the proper selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
datamodel_get_row_countdatamodel.get_row_countARead-only
Retrieve the row count for each table in a specific data model. Resolves the data model's tables, counts rows per table, and returns the results in a flat row-based structure suitable for tabular representation.
Returns: list[dict[str, Any]] | dict[str, Any] List of dictionaries, each with "table_name" and "row_count", plus a final entry with the total row count. On failure, returns the standard ``{"ok": False, "error": "...", …
| Name | Required | Description | Default |
|---|---|---|---|
| datamodel_name | Yes | Name of the data model. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this read-only and non-destructive. The description adds meaningful behavioral detail: it resolves tables, counts rows per table, returns a flat list of dictionaries with table_name and row_count plus a total entry, and specifies the failure return shape. This goes beyond the annotations and is especially valuable because no output schema 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 mostly efficient and front-loaded, but the second sentence partly restates the first ('Resolves the data model's tables, counts rows per table') before adding the return shape. Still, the return details are necessary and well placed.
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 one parameter, no output schema, and annotations covering safety, the description provides sufficient context: it states the operation, return structure, final total row entry, and failure format. 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?
The only parameter, datamodel_name, has 100% schema description coverage ('Name of the data model.'). The description adds no new parameter-level detail, so the baseline of 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 uses a specific verb and resource: 'Retrieve the row count for each table in a specific data model.' It is clearly distinct from siblings like datamodel_get_data or datamodel_get_all_datamodel, but it does not explicitly differentiate itself from similar sibling tools, 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 intended use is implied: call this when you need per-table row counts for a named data model. However, there is no explicit when-not-to-use guidance or mention of alternatives such as datamodel_describe_datamodel or datamodel_get_table_schema for schema-level needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
datamodel_get_table_schemadatamodel.get_table_schemaARead-only
Retrieve the schema of a table within a connection's data source. Resolves the connection by name to obtain its oid and provider, then sends POST /api/v1/connection/{id}/table_schema_details.
Returns: dict[str, Any] Table schema details if found, or {"error": "..."} on failure or when no schema is found.
Note: This endpoint is undocumented and may change in future Sisense versions. Use with caution.
| Name | Required | Description | Default |
|---|---|---|---|
| table_name | Yes | Name of the table (sent as ``table``). | |
| schema_name | Yes | Name of the schema (sent as ``schema``). | |
| database_name | Yes | Name of the database (sent as ``Database``). | |
| connection_name | Yes | Name of the connection. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint, openWorldHint, and destructiveHint. The description goes well beyond that by disclosing the POST endpoint, the connection resolution process, the exact return contract (dict or error), and a caution that the endpoint is undocumented and may change. This is substantial behavioral 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?
Three sentences deliver purpose+mechanism, return value, and a risk warning with no filler. The key facts are front-loaded and 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?
The description covers what the tool does, how it executes (connection resolution + POST), what it returns on success and failure, and a stability warning. With readOnly and non-destructive annotations covering the safety profile, nothing essential is missing for an agent to invoke 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?
The input schema already documents all four parameters with descriptions and wire-name mappings, so schema coverage is 100%. The description adds no additional parameter-level meaning beyond the schema's own documentation, making baseline 3 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 'Retrieve the schema of a table within a connection's data source,' a specific verb+resource statement. It also names the exact API endpoint and scope, distinguishing it from sibling tools like datamodel_get_model_schema, which targets model-level 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 provides clear context: this is for retrieving table schema from a connection's data source, and it explains the resolution flow via connection_name. However, it does not explicitly state when to prefer this over datamodel_get_model_schema or datamodel_describe_datamodel, nor does it mention exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
folder_get_all_foldersfolder.get_all_foldersARead-only
Retrieve the full folder tree. Convenience wrapper for get_folders("tree"). Returns the nested folder hierarchy used by Sisense for organizing dashboards.
Returns: list[dict[str, Any]] | dict[str, Any] A list of root-level folder nodes (each may contain nested folders and dashboards keys), or {"error": "..."} on failure.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral detail about the return shape, including nested 'folders' and 'dashboards' keys and the error dict on failure, which is beyond what annotations 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 concise and well-structured: one explanatory sentence, one wrapping-context sentence, and a compact return-type breakdown. Every sentence adds information, and the main purpose is front-loaded rather than buried.
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 zero-parameter, read-only convenience tool with no output schema, the description is complete: it states what the tool returns, how the hierarchy is organized, and what the failure shape looks like. An agent has everything needed to decide whether to call it and to 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?
The tool has zero parameters, so there is no parameter semantics burden on the description. Per the baseline rule, a score of 4 applies because no parameter documentation is needed; the description appropriately focuses on the return value instead.
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: 'Retrieve the full folder tree.' It further clarifies the returned nested hierarchy and names the underlying convenience wrapper, making the tool's purpose unmistakable and distinct from sibling folder_get_folder_id, which targets a specific folder.
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 this is the tool for retrieving the complete folder tree and identifies it as a convenience wrapper for get_folders("tree"), which implies the common use case. It does not explicitly state when not to use it or compare it to folder_get_folder_id, but the usage context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
folder_get_folder_idfolder.get_folder_idARead-only
Retrieve a single folder by OID. Sends GET /api/v1/folders/{folder_id} and returns the folder metadata object.
Returns: dict[str, Any] Folder metadata from the API, or {"error": "..."} if the request fails or no folder is found.
| Name | Required | Description | Default |
|---|---|---|---|
| folder_id | Yes | OID of the folder to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds useful behavioral detail by naming the HTTP endpoint (`GET /api/v1/folders/{folder_id}`) and disclosing the exact return behavior, including the error shape when the request fails or no folder is 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?
The description is compact and front-loaded: it states the core action, the endpoint, and the return format in three short sentences. There is no filler or redundant content beyond what is useful.
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 single-parameter read-only tool with no output schema, the description is complete. It provides the parameter, endpoint, return type, and failure behavior, giving an agent everything needed to invoke it correctly and interpret the 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 description coverage is 100%, and the description repeats the parameter's role ('by OID') without adding significant new meaning. It does place the parameter in the endpoint URL, which adds mild context, but the schema already fully documents folder_id.
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 ('Retrieve'), a resource ('a single folder'), and the key identifier ('by OID'). It clearly distinguishes this tool from sibling folder_get_all_folders by emphasizing single-folder retrieval.
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 implies when to use the tool: when you have a folder OID and need a single folder's metadata. It does not explicitly mention alternatives or exclusions, but the contrast with folder_get_all_folders is evident from the language and context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plugins_get_all_pluginsplugins.get_all_pluginsARead-only
Retrieve all plugins installed on the Sisense instance. Fetches the complete plugin list using paginated requests to GET /api/v1/plugins. All pages are collected and returned as a single flat list.
Returns: list[dict[str, Any]] A list of plugin objects, each containing at minimum: - name (str): API identifier for the plugin. - folderName (str): Filesystem folder name (e.g. "plugin-MyPlugin"). - isEnabled …
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly and destructive annotations, the description reveals meaningful behavior: paginated requests to GET /api/v1/plugins, collection of all pages, and return as a single flat list. It also documents minimum fields in the return objects, though it stops short of describing error or empty-list 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 front-loaded with the purpose, followed by pagination behavior and a concise bulleted return contract. Every sentence carries useful information and the bullet list makes the return fields easy to scan.
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 parameterless, read-only list operation, the description sufficiently covers purpose, pagination, aggregation behavior, and return shape. The explicit Returns section compensates for the absence of an output schema, and the annotations already cover the safety profile.
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 tool has zero parameters and the schema confirms an empty properties object, so the 0-parameter baseline of 4 applies. The description appropriately focuses on behavior and return shape rather than inventing parameter 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 clearly states the specific operation: 'Retrieve all plugins installed on the Sisense instance.' It reinforces scope with 'complete plugin list' and the exact API endpoint, making it easy to distinguish from sibling tools focused on dashboards, datamodels, folders, and reports.
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 by explicitly saying it retrieves all plugins and that all pages are collected, so an agent knows to call this when the full plugin list is needed. It does not name alternatives, but no plugin-specific sibling appears in the provided tool list, so explicit exclusions are less necessary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
report_manager_get_reportsreport_manager.get_reportsARead-only
Retrieve all reports configured in Report Manager. Sends paginated requests to GET /api/v1/report_manager/reports and collects every page into a single flat list. Filters are applied server-side.
Returns: list[dict[str, Any]] | dict[str, Any] A flat list of report objects, or {"error": "..."} on failure.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | No | One or more report ids to filter by. A bare string is treated as a single id. | |
| name | No | Search reports by name. | |
| sort | No | Field to sort results by. Ascending by default, descending if prefixed with ``-``. | |
| limit | No | Page size used for the underlying paginated requests. Default is ``100``. | |
| fields | No | Whitelist of fields to return for each report. Fields can also be excluded by prefixing their name with ``-``. | |
| enabled | No | When provided, filter to only enabled (``True``) or disabled (``False``) reports. | |
| priority | No | Filter reports by priority. One of ``"high"``, ``"normal"``. | |
| statuses | No | One or more running statuses to filter by. A bare string is treated as a single status. | |
| owner_ids | No | One or more owner user ids to filter by. A bare string is treated as a single id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only annotation, the description discloses pagination behavior ('sends paginated requests... collects every page'), server-side filtering, and the failure return shape ({'error': ...}). This tells the agent not to expect partial pages and how failures surface.
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 short and front-loaded: purpose first, then pagination/behavior, then return shape. No sentence is wasted; the endpoint URL and return line add practical detail without bloat.
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 no output schema, the description fully specifies the return type ('list[dict[str, Any]] | dict[str, Any]') and the error shape. Combined with the read-only annotation and comprehensive schema, nothing essential is missing for an agent to call 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%, with every parameter documented in the input schema. The description adds only a general statement that filters are applied server-side, which is a behavioral note rather than parameter-level semantics, so 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 concrete verb and resource ('Retrieve all reports configured in Report Manager') and adds behavioral specificity (paginated requests, flat list). It clearly distinguishes this tool from the dashboard/datamodel/folder/plugin getters among the siblings by naming the Report Manager resource.
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 clear context for when to call it: any time all reports (optionally filtered) are needed, with filters applied server-side. It does not explicitly name alternative tools or list exclusions, but no overlapping report-management siblings exist, so the context is sufficient for an agent to select it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wellcheck_run_full_wellcheckwellcheck.run_full_wellcheckARead-only
Run a composite "full" wellcheck across dashboards and data models. This method is a convenience wrapper that orchestrates multiple dashboard-level and data-model-level checks and returns a structured report that groups their results. It additionally delegates unused-column analysis to AccessManagement.get_unused_columns_bulk when an AccessManagement instance is configured on this WellCheck (the default constructor configures one); otherwise the unused_columns section is an empty list and a warning is logged.
Returns: dict A dictionary with two top-level sections: - "dashboards": { "structure": [...], "widget_counts": [...], "pivot_widget_fields": [...], } - "datamodels": { "custom_tables": [...], "island_tables": [...], …
Can be slow: the m2m check runs real aggregate SQL. Scope it with the dashboards/datamodels parameters whenever the user named specific assets.
| Name | Required | Description | Default |
|---|---|---|---|
| dashboards | No | One or more dashboard references to analyze. Each reference can be: - a Sisense dashboard ID, or - a dashboard title (name). At runtime this parameter is tolerant of a single string and will normalize it to a one-element list. | |
| datamodels | No | One or more data model references to analyze. Each reference can be: - a data model ID, or - a data model title (name). At runtime this parameter is tolerant of a single string and will normalize it to a one-element list. | |
| max_pivot_fields | No | Threshold used by the pivot-fields check. Any pivot widget with more than this number of fields is flagged. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/destructiveHint annotations, the description discloses meaningful runtime behavior: the tool can be slow, the m2m check executes real SQL, unused-column analysis is conditionally delegated to AccessManagement.get_unused_columns_bulk, and the default constructor configures AccessManagement with a fallback empty list and warning. This is substantial behavioral 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 information-dense but well-organized: purpose first, then behavior, then return shape, then a practical performance caveat at the end. Every sentence adds value, especially given there is no output 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 composite tool with no output schema, the description provides sufficient context: what it does, how it behaves conditionally, what the return structure looks like, and when scoping is needed. The schema covers the optional parameters, and annotations cover the read-only safety profile.
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 fully documents the parameters' meaning, formats, and normalization behavior. The description only reinforces scoping via the dashboards/datamodels parameters without adding new semantic detail 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 clearly states a specific verb ('Run a composite full wellcheck') and a resource ('across dashboards and data models'). It distinguishes itself from sibling getter tools by framing it as an orchestration wrapper that groups multiple checks into one structured report.
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 concrete guidance on scoping: 'Scope it with the dashboards/datamodels parameters whenever the user named specific assets.' It also warns about slowness due to real aggregate SQL. It does not explicitly name alternative sibling tools, so it falls just short of full when-to-use versus alternatives guidance.
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.
48 tool updates
v0.1.2- Removed
access_management_get_group - Added
access_management_get_groups - Removed
access_management_get_unused_columns - Changed
access_management_get_unused_columns_bulk2 fields changed- changed
Input schema / properties / datamodels / descriptionPrevious value: -"One or more data model references to analyze. Each reference can be: - a data model ID, or - a data model title (name). At least one data model reference is required. At runtime this parameter is tolerant of a single string and will normalize it to a one-element list."New value: +"One or more data model references to analyze. **Required.** Each reference can be: - a data model ID, or - a data model title (name). At runtime this parameter is tolerant of a single string and will normalize it to a one-element list." - changed
Input schema / requiredPrevious value: -[]New value: +[ + "datamodels" +]
- Changed
access_management_get_user1 field changed- changed
Input schema / properties / user_email / descriptionPrevious value: -"Email address of the user to retrieve."New value: +"Email address of the user to retrieve. **Required** — this method always answers \"one named user\"; use ``get_users_all`` for every user."
- Removed
access_management_get_user_with_role_and_group_names - Removed
access_management_get_users_with_role_names_and_group_names - Changed
access_management_users_per_group2 fields changed- changed
Input schema / properties / group_name / descriptionPrevious value: -"The name of the group whose members to list."New value: +"The name of the group whose members to list. Omit for all memberships. A name that matches no group returns ``{\"error\": \"...\"}`` naming it — never a silent empty list. Naming ``Everyone`` or ``All users in system`` returns their members — an explicit request is always honored, even though the all-groups view omits them." - changed
Input schema / requiredPrevious value: -[ - "group_name" -]New value: +[]
- Removed
access_management_users_per_group_all - Removed
blox_get_blox_actions - Removed
custom_code_export_notebook - Removed
custom_code_get_notebooks - Removed
custom_code_list_notebook_folder_contents - Removed
dashboard_export_dashboard - Added
dashboard_find_widgets_by_type - Removed
dashboard_get_dashboard_by_name - Removed
dashboard_get_dashboard_shares_v1 - Removed
dashboard_get_dashboard_widgets - Added
dashboard_get_widget_by_id - Removed
dashboard_resolve_dashboard_reference - Removed
datamodel_describe_datamodel_raw - Changed
datamodel_generate_connections_payload5 fields changed- added
Input schema / properties / connection_params / additionalPropertiesAdded value: +true - added
Input schema / properties / connection_params / propertiesAdded value: +{ + "additional_parameters": { + "type": "string" + }, + "allow_large_results": { + "type": "boolean" + }, + "aws_access_key": { + "type": "string" + }, + "aws_secret_key": { + "type": "string" + }, + "connection_string": { + "type": "string" + }, + "database": { + "type": "string" + }, + "default_database": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "record_field_flattening_level": { + "type": "string" + }, + "region": { + "type": "string" + }, + "s3_output_location": { + "type": "string" + }, + "schema": { + "type": "string" + }, + "server": { + "type": "string" + }, + "service_account_key_path": { + "type": "string" + }, + "token": { + "type": "string" + }, + "unnest_arrays": { + "type": "boolean" + }, + "use_dynamic_schema": { + "type": "boolean" + }, + "use_proxy_server": { + "type": "boolean" + }, + "use_service_account": { + "type": "boolean" + }, + "use_storage_api": { + "type": "boolean" + }, + "username": { + "type": "string" + } +} - added
Input schema / properties / connection_params / requiredAdded value: +[] - changed
Input schema / properties / datasource_type / descriptionPrevious value: -"Type of data source. One of ``\"Athena\"``, ``\"RedShift\"``, ``\"BigQuery\"``, ``\"DataBricks\"`` (case-insensitive)."New value: +"Type of data source (matched case-insensitively)." - added
Input schema / properties / datasource_type / enumAdded value: +[ + "Athena", + "RedShift", + "BigQuery", + "DataBricks" +]
- Removed
datamodel_get_connections - Added
datamodel_get_connections_all - Removed
datamodel_get_datamodel - Removed
datamodel_get_datasecurity - Removed
datamodel_load_datamodel - Removed
datamodel_resolve_datamodel_reference - Removed
folder_get_folder_ancestors - Removed
folder_get_folders - Removed
folder_get_navver - Removed
metadata_get_datasource_dimensions - Removed
metadata_get_datasource_measures - Removed
metadata_get_datasources - Removed
plugins_get_plugin - Removed
plugins_save_snapshot - Removed
queries_elasticube_run_jaql_query - Removed
queries_elasticubes_run_jaql_csv - Added
report_manager_get_reports - Removed
wellcheck_check_dashboard_structure - Removed
wellcheck_check_dashboard_widget_counts - Removed
wellcheck_check_datamodel_custom_tables - Removed
wellcheck_check_datamodel_import_queries - Removed
wellcheck_check_datamodel_island_tables - Removed
wellcheck_check_datamodel_m2m_relationships - Removed
wellcheck_check_datamodel_rls_datatypes - Removed
wellcheck_check_pivot_widget_fields - Added
wellcheck_run_full_wellcheck
68 tool updates
v0.1.0- First observed
access_management_get_all_dashboard_shares - First observed
access_management_get_datamodel_columns - First observed
access_management_get_group - First observed
access_management_get_my_user - First observed
access_management_get_roles - First observed
access_management_get_unused_columns - First observed
access_management_get_unused_columns_bulk - First observed
access_management_get_user - First observed
access_management_get_user_with_role_and_group_names - First observed
access_management_get_users_all - First observed
access_management_get_users_with_role_names_and_group_names - First observed
access_management_users_per_group - First observed
access_management_users_per_group_all - First observed
blox_get_blox_actions - First observed
custom_code_export_notebook - First observed
custom_code_get_notebooks - First observed
custom_code_list_notebook_folder_contents - First observed
dashboard_can_be_owned - First observed
dashboard_export_dashboard - First observed
dashboard_get_all_dashboards - First observed
dashboard_get_dashboard_by_id - First observed
dashboard_get_dashboard_by_name - First observed
dashboard_get_dashboard_columns - First observed
dashboard_get_dashboard_script - First observed
dashboard_get_dashboard_share - First observed
dashboard_get_dashboard_shares_v1 - First observed
dashboard_get_dashboard_widgets - First observed
dashboard_get_dashboards - First observed
dashboard_get_widget_script - First observed
dashboard_resolve_dashboard_reference - First observed
datamodel_describe_datamodel - First observed
datamodel_describe_datamodel_raw - First observed
datamodel_generate_connections_payload - First observed
datamodel_get_all_datamodel - First observed
datamodel_get_connection - First observed
datamodel_get_connections - First observed
datamodel_get_data - First observed
datamodel_get_datamodel - First observed
datamodel_get_datamodel_shares - First observed
datamodel_get_datasecurity - First observed
datamodel_get_datasecurity_detail - First observed
datamodel_get_elasticubes - First observed
datamodel_get_model_schema - First observed
datamodel_get_row_count - First observed
datamodel_get_table_schema - First observed
datamodel_load_datamodel - First observed
datamodel_resolve_datamodel_reference - First observed
folder_get_all_folders - First observed
folder_get_folder_ancestors - First observed
folder_get_folder_id - First observed
folder_get_folders - First observed
folder_get_navver - First observed
metadata_get_datasource_dimensions - First observed
metadata_get_datasource_measures - First observed
metadata_get_datasources - First observed
plugins_get_all_plugins - First observed
plugins_get_plugin - First observed
plugins_save_snapshot - First observed
queries_elasticube_run_jaql_query - First observed
queries_elasticubes_run_jaql_csv - First observed
wellcheck_check_dashboard_structure - First observed
wellcheck_check_dashboard_widget_counts - First observed
wellcheck_check_datamodel_custom_tables - First observed
wellcheck_check_datamodel_import_queries - First observed
wellcheck_check_datamodel_island_tables - First observed
wellcheck_check_datamodel_m2m_relationships - First observed
wellcheck_check_datamodel_rls_datatypes - First observed
wellcheck_check_pivot_widget_fields
TDQS
Scored across 36 tools
The domain prefixes and resource nouns separate most tools, but several pairs overlap in obvious ways: get_all_dashboards vs get_dashboards, get_all_datamodel vs get_elasticubes, and get_connection vs get_connections_all require close reading of descriptions to disambiguate. The shared read-only 'get everything' pattern across access, dashboards, and datamodels adds selection risk, so the boundaries are not crisp enough for a higher score.
The dominant pattern is domain_prefix_get_resource, and snake_case is used throughout, which makes the set feel predictable. Deviations like access_management_users_per_group, dashboard_can_be_owned, datamodel_describe_datamodel, datamodel_generate_connections_payload, and wellcheck_run_full_wellcheck break the pattern, and singular/plural forms like get_connection vs get_connections_all are inconsistent.
With 36 tools, this server is well above the 25-tool threshold for a heavy surface. The broad read-only scope would feel more manageable if consolidated into fewer aggregate tools per domain, but as-is the agent will carry a large tool list for what is largely a retrieval/wellcheck server.
The tool surface is almost entirely read-only: nearly every tool is a getter plus a single wellcheck runner. There are no create, update, delete, or ownership-changing operations, and datamodel_generate_connections_payload mentions create_connections without actually exposing that tool, creating a clear dead end. Agents can inspect the Sisense instance but cannot act on it.
Maintenance
Related MCP Connectors
Access Oi Contexts, Workflows, Skills, Guardrails, Connections, and reporting tools.
Provides capabilities that let LLM agents perform a range of infrastructure management tasks.
Read AI-gateway analytics, configs, virtual keys, workspaces and users; log request feedback.
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
Related MCP Servers
AlicenseNot gradedqualityBmaintenanceEnables AI assistants to interact with Scalekit's identity and access management platform through natural language queries. Supports managing environments, organizations, users, OIDC connections, workspace operations, and MCP server configurations with OAuth-protected access.205 npm5Apache 2.0
Britive MCP Serverofficial
FlicenseNot gradedqualityDmaintenanceEnables AI agents and users to interact with the Britive platform for dynamic access, query configurations, reporting, and access activity.1-- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Dynamics 365 Business Central environments through natural language commands, including environment, app, session, and extension management.41 npm9MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to interact with OSDU platform services including search, data management, and schema operations.6Apache 2.0