Menuing
Tool Panel

Extension Tools,Response and Undo Helpers

Using Response and Undo Helpers

The MCP Server provides two shared helper classes that extension addons should use for consistent response formatting and undo support.

McpResponseHelper

Use McpResponseHelper for extracting arguments and formatting responses.

Extracting Arguments

// Get a string argument with optional default
string status = McpResponseHelper.GetStringArg(args, "status");
string format = McpResponseHelper.GetStringArg(args, "format", "html");

// Get an integer argument with optional default
int pageSize = McpResponseHelper.GetIntArg(args, "pageSize", 50);
int postId = McpResponseHelper.GetIntArg(args, "postId");

// Get a boolean argument with optional default
bool includeInactive = McpResponseHelper.GetBoolArg(args, "includeInactive", false);

Formatting Responses

// Success with data and message
return McpResponseHelper.Success(cp, resultData, "Found 10 posts");

// Success with data only
return McpResponseHelper.Success(cp, resultData);

// Error response
return McpResponseHelper.Error(cp, "Post not found");

Always return McpResponseHelper.Success() or McpResponseHelper.Error() from your tool methods. This ensures Claude receives responses in a consistent JSON format.

McpUndoHelper

Use McpUndoHelper.Capture() to record changes so they can be reverted with the undo_apply tool.

Undo for Create Operations

When your tool creates a new record, capture an undo that will delete it on revert:

var post = DbBaseModel.addDefault<BlogPostModel>(cp);
post.title = title;
post.save(cp);

// Capture undo -- recordDeleted=true means undo will deactivate this record
McpUndoHelper.Capture(
    cp,
    "Blog Posts",           // Content definition name
    post.id,                // Record ID
    post.ccguid ?? "",      // Record GUID
    "blog_post_create",     // Tool name for reference
    new Dictionary<string, string>(),  // Empty -- no previous values
    true                    // true = this was a newly created record
);

Undo for Update Operations

When your tool modifies an existing record, capture the field values before changing them:

var post = DbBaseModel.create<BlogPostModel>(cp, postId);

// Capture field values BEFORE modification
var fieldsBefore = new Dictionary<string, string> {
    ["title"] = post.title ?? "",
    ["content"] = post.content ?? "",
    ["status"] = post.status ?? ""
};

McpUndoHelper.Capture(
    cp,
    "Blog Posts",
    post.id,
    post.ccguid ?? "",
    "blog_post_update",
    fieldsBefore,
    false  // false = existing record, undo will restore field values
);

// Now apply the modifications
post.title = newTitle;
post.save(cp);

The fieldsBefore dictionary must contain all fields that your tool modifies. When undo_apply is called, these values are written back to the record.

When to Capture Undo

  • Always capture undo for operations that create, update, or delete content
  • Read-only tools (list, get) do not need undo
  • Capture undo BEFORE making changes for update operations
  • Capture undo AFTER creating the record for create operations (you need the new record ID)