RibbonSmith
Allows adding custom ribbon buttons in Dynamics 365 that trigger SAP integrations, such as calling JavaScript functions to send data to SAP.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@RibbonSmithAdd a 'Send Email' button to the contact ribbon."
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.
RibbonSmith talks to your Dataverse environment with plain Web API calls under
your own identity. Nothing is installed in the environment; a small
unmanaged container solution (RibbonEditMCP_<entity>) is created per edited
entity to carry the customizations — the same "workspace solution" mechanism
the Ribbon Workbench used.
Why
Hand-writing RibbonDiffXml fails easily: ids, locations, template aliases and
element order must all be exactly right, and the feedback loop (import → publish
→ check) is slow. RibbonSmith closes the loop for an agent:
Grounding — read tools return the real composed ribbon (every valid location, control id, command and sequence) as compact JSON.
Declarative writes —
ribbon_add_button& friends generate schema-correct XML; the escape hatchribbon_edit_diffaccepts raw XML for advanced cases.Validation before anything touches the server — references, locations, element order, web-resource existence, unsupported-entity blocklist.
Transactional publish — validate → backup → async import → publish → verify the change is actually live by re-reading the composed ribbon.
Instant revert — every checkout and publish snapshots a restorable backup.
Related MCP server: Dynamics 365 Business Central Admin MCP Server
Setup
Prerequisites: Node.js ≥ 20 and a Dataverse user with permission to create/ import solutions and publish (e.g. System Administrator / System Customizer).
npm install
npm run buildRegister with Claude Code:
claude mcp add ribbonsmith --env RIBBON_MCP_ENV_URL=https://yourorg.crm4.dynamics.com -- node <absolute-path>/ribbonsmith/dist/index.jsOr copy .mcp.json.example to your project's .mcp.json.
Authentication
On the first call that needs the network, RibbonSmith acquires a token using
the first strategy that works (override with RIBBON_MCP_AUTH):
Strategy |
| How it works |
Service principal |
| Set |
Azure CLI |
| Reuses your |
Browser SSO |
| Opens your browser for a normal Microsoft Entra sign-in (auth code + PKCE on a localhost loopback), then caches and silently refreshes tokens — the same sign-in experience as Microsoft's official Dataverse MCP local proxy. |
In auto mode (default) the order is: clientsecret (if env vars present) →
azcli (if available) → interactive. Tokens from the interactive flow are
cached in the workspace directory; delete token-cache.json to sign out.
The interactive flow uses the public client id Microsoft ships in its own
Dataverse QuickStart samples (51f81489-…), requesting the standard
user_impersonation delegated permission — so unlike the official Dataverse
MCP server's proxy, no tenant admin consent or Power Platform admin center
enablement is required. If your tenant restricts that client id, register
your own public client app (redirect URI http://localhost, Dynamics CRM
user_impersonation permission) and set RIBBON_MCP_CLIENT_ID.
The edit lifecycle
ribbon_checkout ──► edit tools (local only) ──► ribbon_preview_diff ──► ribbon_publish
│ │
└── backup (restorable) backup (pre-publish) ──────────────┘
ribbon_restore_backup ◄── revert anytimeribbon_checkout{ entity: "account" }— snapshots the current ribbon customizations (backup) and creates a local working copy of the entity'sRibbonDiffXml.Edit locally — none of these touch the environment:
ribbon_get_structure(your map of valid targets),ribbon_add_button,ribbon_hide_control,ribbon_customize_command(copy an out-of-the-box command into the diff to modify it),ribbon_edit_diff(validated raw XML),ribbon_remove_customization,ribbon_discard.ribbon_preview_diff— the exact XML that will be published + full validation report.ribbon_publish— validates, backs up, submits an async solution import, publishes, then verifies the controls are live (or hidden) in the freshly retrieved composed ribbon. Server-side imports take 1–3 minutes; if the import outlastswaitSeconds(default 120), the tool returnsstatus: "importing"— callribbon_publish_statusto complete it.ribbon_restore_backup— re-import any backup and publish: full revert.
Working files and backups live under ~/.dataverse-ribbon-mcp/<env-host>/
(override with RIBBON_MCP_WORKSPACE). Everything is a plain file; worst case,
import a backup zip manually through the maker portal.
Example: agent session
User: Add a "Send to SAP" button on the account form that calls
new_/js/sap.js: sendToSap(recordId), only for existing records.
ribbon_checkout { entity: "account" }
ribbon_get_structure { entity: "account", location: "Form" }
ribbon_add_button {
entity: "account",
id: "new_.account.SendToSap.Button",
location: "Mscrm.Form.account.MainTab.Save.Controls._children",
label: "Send to SAP",
sequence: 45,
modernImage: "ExportToExcel",
action: { type: "JavaScriptFunction", library: "new_/js/sap.js",
functionName: "sendToSap",
parameters: [{ type: "CrmParameter", value: "FirstPrimaryItemId" }] },
enableRules: [{ type: "FormStateRule", id: "new_.account.SendToSap.Existing",
state: "Existing", default: true }]
}
ribbon_preview_diff { entity: "account" }
ribbon_publish { entity: "account" }
→ { status: "published", verification: { status: "verified" }, backupId: "..." }Tool reference
Tool | Network | Purpose |
| yes | WhoAmI, checkouts, recent backups |
| yes | Begin editing; snapshot backup + local working copy |
| cached | Composed ribbon as JSON (tabs → groups → controls) |
| cached | One command's actions + rules (for reuse/customization) |
| no | Current working |
| no* | Declarative button/command/rules/labels |
| no* |
|
| no* | Copy an OOTB command into the diff |
| no* | Replace the whole working diff (validated) |
| no | Remove one element from the diff by id |
| no* | Diff XML + validation report |
| yes | Validate → backup → async import → publish → verify |
| yes | Poll/complete a pending publish or restore import |
| no | Reset working copy to last exported state |
| no | List restorable snapshots |
| yes | Re-import a snapshot + publish (revert) |
* validation may consult the cached composed ribbon and check web-resource existence over the network.
Safety model
Every
ribbon_checkoutand everyribbon_publishwrites a timestamped solution zip before any change;ribbon_restore_backupre-imports it.Publishes only ever touch the
RibbonDiffXmlnode inside a fresh export of the container solution — entity metadata is never round-tripped (the entity ships as anunmodified="1"shell).Validation blocks publishes on: malformed XML, wrong element order, missing
Mscrm.Templates, duplicate ids, unresolved command/rule/label references, missing web resources, unsupported system entities.Import failures surface the importjob's own error text; imports are transactional server-side, so a failed import changes nothing.
Status & limitations
Entity ribbons: stable. The full lifecycle (add → publish → verify → hide → publish → verify → restore → verify) is covered by a live E2E suite (
test/e2e/run-e2e.ts) plus 56 unit tests over a real composed ribbon.Application ribbon (
APPLICATION): EXPERIMENTAL. Implemented per the documented schema (component type 50, diff underImportExportXml) but not yet covered by the live E2E suite. Keep backup ids at hand.Classic
RibbonDiffXmlonly: commands built with the modern Power Apps command designer (Power Fx /appaction) are not read or written. Classic customizations render fine in Unified Interface.Flyout/Menu/group/tab creation goes through
ribbon_edit_diff(raw XML).One editor per entity at a time is assumed (shared container solution).
Development
npm test # unit tests (vitest)
npx tsc --noEmit # typecheck
npx tsx test/e2e/run-e2e.ts https://yourorg.crm4.dynamics.com
# live E2E — modifies + restores the
# 'contact' ribbon in that environment!docs/ARCHITECTURE.md — module map, data flows, why async import, testing strategy.
docs/RIBBON-CONCEPTS.md — a primer on ribbon XML (composed ribbon vs diff, locations, commands/rules, Command Checker).
Acknowledgments
RibbonSmith re-implements, as MCP tools, the declarative editing model pioneered by Scott Durow's Ribbon Workbench — for years the way humans customized Dynamics ribbons safely. This project shares no code with it; the mechanism (workspace solution → RibbonDiffXml splice → import → publish) was studied from its observable behavior and from Microsoft's public documentation of the ribbon schemas and solution APIs.
License
Available Tools
16 toolsribbon_add_buttonAdd a button (declarative)A
Add a button with its command, rules and labels to the local working copy in one declarative call. The server generates schema-correct XML with proper id conventions, $LocLabels:/$webresource: prefixes and element order. Requires ribbon_checkout first. Get the location from ribbon_get_structure (a group id + '.Controls._children').
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Unique button id, convention: <publisherprefix>.<entity>.<Name>.Button, e.g. new_.account.Approve.Button | |
| label | Yes | Button label (LCID 1033) | |
| action | No | What the command does when the button is clicked. | |
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| command | No | Reuse an EXISTING command id instead of creating one (omit 'action' when set) | |
| image16 | No | Web resource name for 16x16 icon (classic) | |
| image32 | No | Web resource name for 32x32 icon (classic) | |
| tooltip | No | ||
| location | Yes | CustomAction Location, e.g. 'Mscrm.Form.account.MainTab.Save.Controls._children' to append into a group | |
| sequence | No | Position among siblings; OOTB controls are spaced by 10. Default 100. | |
| enableRules | No | ||
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. | |
| modernImage | No | Unified Interface icon name (e.g. 'Add') or SVG web resource | |
| displayRules | No | ||
| templateAlias | No | Layout slot of the target group (see group.template in ribbon_get_structure). Default 'o1'. | |
| labelTranslations | No | Extra label translations: { '1031': 'Genehmigen' } | |
| tooltipDescription | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that the server generates schema-correct XML with id conventions and prefixes, and that the operation targets the local working copy, implying a checkout/publish workflow. No annotations exist, so this context is valuable, though it omits error behavior and mutability details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences: purpose, server behavior, prerequisites/location. 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?
Covers the essential workflow (checkout, get location, add) and server-side XML generation, making it understandable for an agent. Missing return value and formal alternative guidance, but given rich schema, it is reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 76% of parameters; description adds the crucial guidance that location comes from ribbon_get_structure as a group id + '.Controls._children', and clarifies label/webresource prefixing. This compensates for the most complex parameter without duplicating 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?
Clearly states it adds a button with command/rules/labels declaratively, and distinguishes from sibling tools by focusing on adding vs customizing/hiding. The phrase 'one declarative call' clarifies the abstraction level.
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?
Mentions prerequisite 'Requires ribbon_checkout first' and instructs to get location from ribbon_get_structure, giving clear context for when to invoke. However, it does not explicitly name alternatives or conditions where another sibling tool (e.g., ribbon_customize_command) should be used.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_checkoutCheck out a ribbon for editingA
Begin editing the ribbon of an entity (or the application ribbon). Creates/reuses a temporary unmanaged solution containing only the entity shell, exports it, stores the export as a restorable backup, and initializes a local working copy of the entity's RibbonDiffXml. All edit tools operate on this local copy; nothing changes in the environment until ribbon_publish.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses side effects: creates/reuses a temporary unmanaged solution, exports it, stores a restorable backup, and initializes a local copy. It also explicitly states that nothing changes in the environment until ribbon_publish, providing critical behavioral context beyond just 'checkout'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, efficiently front-loaded with purpose and followed by a concise process explanation. Every sentence adds value, and the description avoids redundant or verbose language.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with multiple side effects, the description is complete: it covers the workflow (temporary solution, export, backup, local copy), the scope (entity or application), and the critical constraint that changes only materialize on ribbon_publish. It enables an agent to understand when and how to use the tool within the broader ribbon workflow.
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 details about the 'entity' (logical name or 'APPLICATION') and 'environment' (URL, optional). The description does not add additional parameter-specific meaning, so it meets the baseline without exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool's purpose: 'Begin editing the ribbon of an entity (or the application ribbon).' It uses a specific verb ('checkout'/'begin editing') and resource (ribbon), and distinguishes itself from siblings like ribbon_publish and ribbon_discard by detailing the checkout process that initializes a local working copy.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear workflow context: 'All edit tools operate on this local copy; nothing changes in the environment until ribbon_publish.' This tells an agent to use checkout before any edit tool and to publish later. However, it does not explicitly name alternatives or exclusions, such as using ribbon_get_structure for read-only inspection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_customize_commandCustomize an existing commandA
Copy an out-of-the-box command definition from the composed ribbon into the working diff so it can be modified (the Ribbon Workbench 'Customise Command' operation). Rule definitions that are core (Mscrm.*) stay as id references; non-core rule bodies are copied too. After copying, edit the returned XML with ribbon_edit_diff, or publish as-is to pin the current behavior.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| commandId | Yes | The command to copy, e.g. 'Mscrm.NewRecordFromGrid' | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It discloses a meaningful nuance: core rule definitions (Mscrm.*) remain as ID references while non-core rule bodies are copied, and it implies a possible pinning use case. However, it omits important behavioral details for a mutation tool: whether a checkout is required (ribbon_checkout exists as a sibling), whether existing customizations in the working diff are overwritten, and what happens to the working diff state. This leaves gaps in the agent's understanding of side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loaded with the primary action and purpose. The second sentence adds an important behavioral detail, and the third sentence guides the next steps. Every sentence earns its place, with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (3 params, no output schema, no annotations), the description is fairly complete. It explains the tool's purpose, a key behavioral nuance (core vs non-core rules), and the return value ('returned XML') plus follow-up actions. However, it does not mention prerequisites like checkout or whether it overwrites existing working-diff entries, which are important for safe usage. The sibling list provides some context but does not substitute for explicit guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not add extra parameter-level meaning beyond what the schema already provides; it only contextualizes the overall operation. It mentions the returned XML but not how the parameters relate to it. Thus, no additional semantics are contributed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb ('Copy') and resource ('an out-of-the-box command definition from the composed ribbon into the working diff'). It also names the equivalent Ribbon Workbench operation, which helps the agent map this to a known concept. It distinguishes itself from sibling tools like ribbon_get_command (which presumably reads without copying) and ribbon_add_button (which creates new commands).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool: when an existing out-of-the-box command needs to be customized. It also gives workflow guidance by mentioning subsequent steps ('edit the returned XML with ribbon_edit_diff, or publish as-is to pin the current behavior'). However, it does not explicitly state when not to use it or compare to alternative tools such as ribbon_add_button for new commands, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_discardDiscard local changesA
Reset the working copy to the last exported/published state. Does not touch the environment.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses an important boundary: 'Does not touch the environment,' indicating the operation is local-only. However, it does not mention whether the action is reversible, whether backups are created, or any permission requirements. It adds some transparency but lacks depth for a destructive operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler: it immediately states the primary action and then adds a key safety clarification. Every word earns its place, making it appropriately sized and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with full schema coverage and no output schema, the description is reasonably complete. It explains the core operation and clarifies that the environment is untouched. However, given the destructive nature and the large set of sibling tools, it could benefit from stating what happens to checked-out status or how it relates to backups. Still, it is adequate for the tool's simplicity.
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 provides 100% coverage with descriptions for both parameters (entity and environment), including an experimental note for APPLICATION. The tool description itself adds no parameter-specific meaning, so the baseline of 3 applies, as the schema already does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Reset the working copy to the last exported/published state.' It also clarifies scope with 'Does not touch the environment,' which distinguishes it from sibling tools like publish or restore_backup that affect the environment.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: this tool should be used when the user wants to discard local changes and revert to the last exported/published state. However, it does not explicitly state when not to use it, nor does it reference alternatives like ribbon_restore_backup for undoing published changes. The guidance is minimal but not misleading.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_edit_diffReplace the working RibbonDiffXmlA
Escape hatch for anything the declarative tools don't cover (flyouts, menus, groups, tabs, command edits): replace the entire working RibbonDiffXml with the supplied XML. The XML is parsed, normalized to schema element order and validated; errors are returned without saving unless 'force' is set. Read the current state first with ribbon_get_diff.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | Save even with validation errors (they will still block publish) | |
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. | |
| ribbonDiffXml | Yes | Complete <RibbonDiffXml>...</RibbonDiffXml> element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It convincingly discloses key behaviors: XML parsing, normalization to schema element order, validation, and that errors are returned without saving unless 'force' is set. It also hints at the destructive nature by saying 'replace the entire working RibbonDiffXml.' It does not mention permissions or reversibility, but the detail provided is strong.
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, front-loaded with the primary purpose, and every sentence adds value: what it does, how it behaves, and a required precondition. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (replacement, validation, force flag), the description covers the most important aspects: purpose, behavior, and a prerequisite. It does not explicitly state what happens on successful save (only errors are mentioned), nor does it mention potential need for checkout, but the overall guidance is sufficient for making an informed call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds some context around the 'force' behavior and the need to provide a complete XML, but these are already implied by the schema ('Save even with validation errors', 'Complete <RibbonDiffXml>'). The description does not significantly extend parameter meaning 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 the tool's purpose: 'replace the entire working RibbonDiffXml with the supplied XML.' It uses a specific verb ('replace') and resource ('RibbonDiffXml'), and distinguishes itself from siblings by framing it as an 'escape hatch for anything the declarative tools don't cover.'
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 indicates when to use this tool: when declarative tools don't cover something (flyouts, menus, groups, tabs, command edits). It also provides a clear prerequisite: 'Read the current state first with ribbon_get_diff,' guiding the agent on the correct workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_get_commandGet a command definitionA
Return the full definition of a command from the composed ribbon: its actions, enable rules and display rules (with rule bodies where they are defined). Use this before customizing or reusing an out-of-the-box command.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| commandId | Yes | e.g. Mscrm.NewRecordFromGrid | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It states the tool returns the full definition including rule bodies, but it does not explicitly mention read-only behavior, side effects, permissions, or the experimental nature of APPLICATION support, which is only noted in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences that front-load the main function and then give usage context. Every word earns its place; there is no redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides both the tool's primary function and its intended usage context. It gives a good sense of the return content (actions, enable rules, display rules with bodies) but lacks output structure details and the experimental warning for APPLICATION support, which is 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?
Schema coverage is 100%, so each parameter already has a detailed description. The tool description adds no additional parameter semantics beyond what the schema provides, which is the baseline for this dimension.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns the full definition of a command, listing its actions and rules, which distinguishes it from sibling tools like ribbon_get_structure or ribbon_get_diff. The verb 'Return' and the resource 'command definition' make the purpose specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this before customizing or reusing an out-of-the-box command,' providing a clear, actionable context for when to invoke the tool. It does not explicitly exclude alternatives or mention siblings, but the context is strong enough to guide an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_get_diffGet the working RibbonDiffXmlA
Return the current working copy of the entity's RibbonDiffXml (requires checkout) — the complete declarative customization state that will be published.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals that the tool returns the un-published working copy and explicitly mentions the checkout requirement — a meaningful condition. The verb 'Return' implies a read operation, but the description does not touch on error cases (e.g., no checkout) or return representation, which keeps it from a perfect score.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that opens with the action and object, then adds the critical detail about checkout. Every clause earns its place — 'current working copy', 'requires checkout', and 'complete declarative customization state' all add unique value without 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 read-only getter with two well-documented parameters and no output schema, this description adequately conveys the return value's nature and a key precondition. It could mention the expected return format or behavior when checkout is missing, but the name, title, and description together give an agent enough to invoke and interpret this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage of both parameters, including detailed descriptions (e.g., the 'APPLICATION' experimental note and the environment default). The description adds no parameter-specific meaning beyond what the schema already contains, so it meets the baseline for well-covered schemas rather than exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return') and names a concrete resource ('the entity's RibbonDiffXml'), further narrowing it to the 'current working copy' — the full declarative customization state. This clearly distinguishes it from sibling getters like ribbon_get_structure and ribbon_get_command, which target more focused pieces. The phrase 'complete declarative customization state that will be published' removes any ambiguity about scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states a clear prerequisite: 'requires checkout', telling the agent this tool is only usable when an active checkout exists. It also frames the return as the full working state, implicitly steering away from the more partial getters. However, it does not explicitly name alternatives or state when not to use it, leaving the differentiation from sibling getters somewhat implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_get_structureGet composed ribbon structureA
Return the entity's fully composed ribbon (base + all customizations) as a compact JSON tree of tabs, groups and controls with ids, commands, labels, sequences and template aliases. This is the ground truth for valid Location values ('.Controls._children'), ids to hide, commands to reuse, and sequence placement. Filter by location and optionally by tab/group id to keep output small.
| Name | Required | Description | Default |
|---|---|---|---|
| tabId | No | Only return this tab (exact id) | |
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| groupId | No | Only return the tab/groups containing this group id | |
| refresh | No | Bypass the cached ribbon and re-retrieve from the server | |
| location | No | Ribbon surface: Form (record form), HomepageGrid (main grid), SubGrid, or All. | All |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses the return format (compact JSON tree) and the concept of being the ground truth, which is helpful. Yet it does not mention caching behavior (e.g., refresh parameter bypasses cache), potential errors, or explicitly state that the operation is read-only, leaving some behavioral aspects implicit.
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: the first defines the output and contents, the second explains utility and filtering. Every phrase earns its place with no redundancy or filler, and the key details are 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 output structure, intended use cases, and filtering options, which is sufficient for an agent to invoke the tool correctly. The schema provides detailed parameter semantics, including the experimental APPLICATION note. While no output schema exists, the description adequately characterizes the response shape; a minor gap is the lack of explicit mention of caching or error behavior, but this is not critical for a simple getter.
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 all parameters already have descriptions. The main description reinforces filtering by location and tab/group id, but adds no new semantic details beyond the schema. Given the baseline of 3 for full schema coverage, no further credit is warranted.
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 the specific verb 'Return' and the resource 'fully composed ribbon', then details the contents (tabs, groups, controls) and the output format (compact JSON tree). This clearly distinguishes it from sibling getters like ribbon_get_command, which targets a single command rather than the full structure.
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 explains the tool's utility as the ground truth for valid Location values, ids to hide, commands to reuse, and sequence placement, indicating it should be used before ribbon modifications. It also gives practical advice to filter by location and tab/group id to keep output small. However, it does not explicitly compare against alternative getters like ribbon_get_diff or ribbon_get_command, so prohibitions are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_hide_controlHide a ribbon controlA
Remove an existing (usually out-of-the-box) control from the ribbon via HideCustomAction in the local working copy. The control id comes from ribbon_get_structure. Note: per Microsoft docs, for commands you own, an always-false display rule is often preferable; HideCustomAction removes the node others may target.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| controlId | Yes | Id of the control to hide, e.g. 'Mscrm.HomepageGrid.account.Delete' | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description must carry safety and side-effect information. It discloses that the removal occurs in the local working copy, that it removes the node others may target, and that APPLICATION support is experimental (in schema). It does not mention reversibility, publish requirement, or permissions, leaving some ambiguity for a destructive action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action and mechanism. The caveat about display rules earns its place, 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 mutation tool with no annotations, the description covers what, how, where (local working copy), and source of input. It omits explicit next steps like publish or discard, but the sibling ribbon_publish/ribbon_discard and 'local working copy' phrasing partially cover that 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%; every parameter (entity, controlId, environment) has a description. The description adds the useful pointer that controlId comes from ribbon_get_structure, but otherwise relies on the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses specific verb 'Remove' with resource 'control from the ribbon' and mechanism 'HideCustomAction'. It distinguishes from siblings by targeting usually out-of-the-box controls and sourcing ids from ribbon_get_structure.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context: hide via HideCustomAction; explicitly cautions that for commands you own, an always-false display rule is often preferable, creating an exclusion. It stops short of naming sibling tools like ribbon_customize_command, but the guidance is actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_list_backupsList ribbon backupsA
List backup zips (taken at checkout and before every publish) that ribbon_restore_backup can re-import.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | No | Filter by entity | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must disclose behavioral traits itself. It adds context about backup timing and restore compatibility, but does not explicitly state that this is a non-destructive read operation or describe what happens when no backups exist. The verb 'List' implies read-only, but the description could be more explicit.
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?
A single sentence that starts with the action, and includes relevant context (backup timing and restore linkage) without waste. Every clause adds value.
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 this is a simple list operation with no required parameters, no output schema, and a clearly stated purpose, the description covers the essential information. The tie to ribbon_restore_backup makes the tool's role in the workflow clear. Minor omission: no description of the response format, but that's acceptable given the tool name.
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 both parameters ('Filter by entity' and environment with env var fallback), so the description need not repeat them. It adds no parameter-specific semantics beyond the schema, so a 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 opens with 'List backup zips' – a specific verb and resource – and clarifies the backups are 'taken at checkout and before every publish,' making it distinct from sibling tools like ribbon_get_structure or ribbon_checkout. The connection to ribbon_restore_backup further solidifies its purpose.
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 explains the backups are those 'that ribbon_restore_backup can re-import,' linking directly to a sibling tool and signaling this list is a prerequisite for restore operations. It also states when backups are created, giving context for when to use this tool. It does not explicitly state exclusions, but the linkage provides clear usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_preview_diffPreview and validate pending changesA
Show the working RibbonDiffXml alongside the full validation report (schema order, id uniqueness, command/rule/label references, location existence against the real ribbon, web resource existence) without touching the environment. Always call before ribbon_publish.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden for behavioral disclosure. It explicitly states 'without touching the environment,' which is a critical safety guarantee, and enumerates the validation checks performed (schema order, id uniqueness, refs, location, web resource existence). This exceeds minimal transparency, though it omits details like behavior when no pending changes exist.
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: the first delivers the action, content, validation scope, and non-mutating nature; the second gives an imperative usage directive. No words are wasted, and the most important information ('without touching the environment' and 'Always call before ribbon_publish') is prominent.
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 and no annotations, the description effectively covers what the tool returns (working XML + validation report), the scope of validation, the safety profile, and the intended call timing. It could add edge-case behavior (e.g., no pending changes) but is sufficiently complete for a dry-run validation tool among many ribbon siblings.
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% description coverage for both parameters, including the entity logical name and the optional environment URL with clear examples. The tool description adds no additional parameter-level detail, but the schema's documentation is sufficiently complete that 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 uses a specific verb ('Show') and names the exact resource ('working RibbonDiffXml alongside the full validation report'), listing the validation categories. It also distinguishes from sibling tools by noting it runs 'without touching the environment,' positioning it as a non-mutating preview rather than an edit or publish tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The explicit instruction 'Always call before ribbon_publish' clearly states when to use this tool, giving a strong usage signal. It does not mention when not to use it or name alternative tools for specific scenarios, but the placement relative to the publish workflow is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_publishPublish the working diff to the environmentA
Validate, back up the current server state, then write the working RibbonDiffXml to the environment: splice into a fresh solution export, submit an async solution import, wait up to waitSeconds, then PublishXml and verify the changes are live by re-reading the composed ribbon. If the import outlasts the wait, returns status 'importing' — finish with ribbon_publish_status. Returns the backup id for ribbon_restore_backup.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. | |
| waitSeconds | No | How long to wait for the server-side import before returning 'importing' (default 120) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It thoroughly explains the side effects: it backs up current server state, performs an async import, publishes via PublishXml, and verifies by re-reading. It also discloses timeout behavior ('returns status 'importing'') and what is returned (backup id). This is rich, honest, and goes well beyond basic expectations.
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 structured as a concise, linear sequence of steps, packed with essential information about the publishing pipeline, timeout handling, and return values. Every sentence and clause earns its place, with no fluff or repetition. It is front-loaded with the primary action ('Validate, back up, then write').
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 tool is complex (multi-step, async, mutating), yet the description explains the full workflow, return status, backup id, and how to handle timeouts. Since there is no output schema, the description adequately covers return values and follow-up behavior. It is complete for an agent to decide when to use it and what to expect.
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% coverage of all three parameters with detailed descriptions. The tool description adds marginal value by referencing waitSeconds in the workflow ('wait up to waitSeconds') and mentioning entity specifics implicitly, but it does not offer significant new semantic meaning beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: to publish the working RibbonDiffXml to the environment, with a specific process (validate, backup, import, publish, verify). It distinguishes itself from sibling tools like ribbon_publish_status (explicitly mentioned as a follow-up for long imports) and ribbon_restore_backup (via the returned backup 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?
It provides clear context on when to use this tool (when you have a working diff to publish) and explicitly directs to ribbon_publish_status if the import outlasts the wait. However, it does not enumerate exclusions or alternative tools beyond that, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_publish_statusCheck / complete a pending publish or restoreA
Poll the async solution import started by ribbon_publish or ribbon_restore_backup. When the import has finished, this completes the operation: publishes the ribbon, verifies it live, and syncs local state. Call repeatedly (imports typically take 1-3 minutes) until status is 'published'/'restored'.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals that the tool polls an async operation, then completes it by publishing, verifying live, and syncing local state. It also notes the expected duration and the need for repeated calls, which helps the agent understand the polling behavior. However, it does not mention error handling or what happens if the import fails.
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 concise sentences, front-loaded with the main purpose, then elaborates on the completion behavior and provides usage guidance. Every sentence contributes value with no 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?
Given the two-parameter schema and lack of output schema, the description covers essential contextual information: what operation it completes, how long it takes, and the success statuses. It also implies the need for entity context. It does not cover failure modes or what happens if the import never completes, 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?
Schema description coverage is 100%, with detailed descriptions for both parameters, including the experimental note for APPLICATION and the environment variable fallback. The tool description itself adds no extra 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 clearly states the tool's purpose: 'Poll the async solution import started by ribbon_publish or ribbon_restore_backup' and 'completes the operation: publishes the ribbon, verifies it live, and syncs local state.' This distinguishes it from sibling tools like ribbon_publish and ribbon_restore_backup, which initiate operations, and ribbon_status, which only checks status without completing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context by referencing the initiating tools ('started by ribbon_publish or ribbon_restore_backup') and provides explicit directive to 'Call repeatedly (imports typically take 1-3 minutes) until status is 'published'/'restored'.' This tells the agent when and how to use the tool, though it doesn't explicitly say when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_remove_customizationRemove an element from the working diffA
Remove a CustomAction, HideCustomAction, CommandDefinition, rule or LocLabel from the local working copy by its Id. Un-hides / un-customizes after the next publish. Use ribbon_get_diff to list current ids.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Id of the element to remove (any section) | |
| entity | Yes | Entity logical name (e.g. 'account'), or 'APPLICATION' for the application ribbon. Note: APPLICATION support is EXPERIMENTAL (implemented per documented schema but not yet covered by the live end-to-end test suite) — take extra care and keep the backup ids at hand. | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. It states that removal happens in the 'local working copy' and that the change 'un-hides / un-customizes after the next publish,' which implies a deferred, reversible-ish operation. It lacks explicit statements about permissions, restore options, or error behavior, but the given context is more than minimal.
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, front-loaded with the action and target, and every clause carries meaning. There is no filler or repetition of schema details, making it both concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no output schema and no annotations, the description adequately covers the operation's scope (what elements, where, when), the prerequisite id discovery, and the deferred publish effect. It does not mention error handling or specific edge cases, but for this complexity level, the context is reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers all parameters with descriptions (100% coverage), so the baseline is 3. The description adds value by linking the 'id' parameter to the workflow ('by its Id' and 'Use ribbon_get_diff to list current ids'), which helps the agent understand how to obtain valid values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: removing specific ribbon customization elements (CustomAction, HideCustomAction, CommandDefinition, rule, LocLabel) from the local working copy by Id. It distinguishes itself from sibling tools like ribbon_edit_diff and ribbon_discard by naming the exact element types and the 'working diff' context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance on a prerequisite: 'Use ribbon_get_diff to list current ids.' It also clarifies when the effect takes place ('after the next publish'). However, it does not mention alternative tools or explicit when-not-to-use conditions, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_restore_backupRestore a ribbon backupA
Re-import a backup solution zip (restoring the entity's RibbonDiffXml to that point in time), publish, and reset the local working copy to match. This is the revert mechanism. Like ribbon_publish, the import runs async — if it outlasts waitSeconds, finish with ribbon_publish_status.
| Name | Required | Description | Default |
|---|---|---|---|
| backupId | Yes | Backup id from ribbon_list_backups or a ribbon_publish result | |
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. | |
| waitSeconds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well by disclosing side effects: re-import, publish, reset local working copy, and async execution with waitSeconds. It does not cover permissions or error conditions, but the core behavioral traits are transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the main action, and every sentence adds value. It avoids redundancy and clearly communicates the workflow and async caveat in a compact format.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and no annotations, the description sufficiently covers purpose, workflow, side effects, and async follow-up. It could mention prerequisites or failure modes, but the core operational context is complete 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?
Schema coverage is 67%, and the description adds meaning beyond the schema by explaining waitSeconds semantics ('if it outlasts waitSeconds, finish with ribbon_publish_status') and implying backupId source via 'backup solution zip' plus the schema's description. The description enhances understanding of the async timeout behavior.
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+resource: 'Re-import a backup solution zip (restoring the entity's RibbonDiffXml to that point in time), publish, and reset the local working copy to match.' It clearly identifies this as 'the revert mechanism' and distinguishes it from sibling tools like ribbon_publish by focusing on backup restoration.
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 that this is the revert mechanism and explicitly mentions the async behavior with a reference to ribbon_publish_status as a follow-up. However, it does not explicitly state when NOT to use this tool or compare it to other restore/undo alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ribbon_statusRibbon workspace statusA
Show the connection (WhoAmI), current checkouts with dirty state, and recent backups for a Dataverse environment. Start here to orient yourself.
| Name | Required | Description | Default |
|---|---|---|---|
| environment | No | Dataverse environment URL, e.g. https://myorg.crm4.dynamics.com. Optional when the RIBBON_MCP_ENV_URL environment variable is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. The verb 'Show' implies a read-only operation, and it lists informational categories, but it does not explicitly state that no changes are made or address permission requirements. The description adds some transparency by naming WhoAmI, dirty state, and backups, but it could be more explicit about absence of side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct, two sentences long, with the action leading. The first sentence lists the key data points, and the second provides a clear usage directive. No filler or redundant 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?
Without an output schema, the description appropriately summarizes the returned content (connection, checkouts, backups) at a high level. It does not detail the exact response structure, but for a status overview tool, this is sufficient for an agent to know what to expect. The inclusion of 'recent backups' and 'dirty state' gives helpful context for interpreting the tool's output.
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 optional parameter 'environment', including its format and fallback to an environment variable. The description adds no additional parameter semantics beyond what is already in the schema, 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 clearly states the tool's function with a specific verb ('Show') and resource (connection, checkouts, backups for Dataverse). It differentiates from siblings like ribbon_list_backups and ribbon_checkout by aggregating multiple status types into a single overview. The phrase 'Start here to orient yourself' reinforces its role as an entry point.
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 usage context by saying 'Start here to orient yourself', implying this is the first tool to invoke when checking workspace state. However, it does not explicitly mention alternatives or when not to use this tool, such as deferring to ribbon_list_backups for detailed backup history or ribbon_checkout for specific checkout details.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
16 tool updates
v0.1.0- First observed
ribbon_add_button - First observed
ribbon_checkout - First observed
ribbon_customize_command - First observed
ribbon_discard - First observed
ribbon_edit_diff - First observed
ribbon_get_command - First observed
ribbon_get_diff - First observed
ribbon_get_structure - First observed
ribbon_hide_control - First observed
ribbon_list_backups - First observed
ribbon_preview_diff - First observed
ribbon_publish - First observed
ribbon_publish_status - First observed
ribbon_remove_customization - First observed
ribbon_restore_backup - First observed
ribbon_status
TDQS
Each tool targets a distinct aspect of the ribbon editing workflow: status, checkout, inspection, editing actions, validation, publishing, and backup/restore. Even the get_* tools return different data (structure, command, diff), leaving no ambiguity about which tool to call.
All tools share the 'ribbon_' prefix and use snake_case with a verb_noun structure (get_structure, add_button, restore_backup). Single-word verbs like status, checkout, and publish are also clear and consistent with the overall pattern, with no mixed conventions.
With 16 tools, the set is slightly above the typical 3-15 range, but each tool maps to a distinct step in the ribbon lifecycle (checkout, edit, validate, publish, backup). The count is justified by the complexity of Dataverse ribbon customization and no tool feels redundant.
The tool set provides full lifecycle coverage: start (status, checkout), inspect (get_*), modify (add, hide, customize, edit, remove), validate (preview_diff), publish (publish, publish_status), and revert (backups, restore). The escape hatch 'ribbon_edit_diff' covers any edge cases, leaving no obvious dead ends.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Debug, build, and manage Power Automate cloud flows with AI agents
Read-only finance and operations controls for AI agents with evidence and safe next actions.
- mcp-serverOAuthcom.make
Give your AI agents the tools to build, manage, and run automation workflows.
Governed app access for AI agents: 1,000+ apps & 12,000+ tools via Code Mode MCP.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceEnables AI assistants to search and analyze Microsoft Dynamics 365 Finance & Operations artifacts, read local source code, and generate context-aware solutions through natural language.28712-
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Dynamics 365 Business Central environments through natural language commands, including environment, app, session, and extension management.189MIT
- AlicenseAqualityAmaintenanceEnables AI agents to query, inspect, and manage Microsoft Dataverse records, metadata, schema, forms, views, and Power Platform environments via the Dataverse OData Web API.972MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to perform CRUD operations, query data, fetch schemas, and execute custom operations on Microsoft Dynamics 365 CRM entities.202MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Longman006/ribbonsmith'
If you have feedback or need assistance with the MCP directory API, please join our Discord server