Follow these guidelines when building MCP extension tools.
Use lowercase names with underscores, prefixed by feature area:
blog_post_list -- goodecommerce_product_search -- goodanalytics_report_generate -- goodBlogPostList -- avoid camelCasepost_list -- avoid missing feature prefix, may conflict with other extensionsThe inputSchemaJson field must be a valid JSON object. Follow these conventions:
"type" must be "object""properties" with a "type" and "description""required" array{
"type": "object",
"properties": {
"postId": {
"type": "integer",
"description": "ID of the blog post to retrieve"
},
"includeContent": {
"type": "boolean",
"description": "Include full post content in response (default true)"
}
},
"required": ["postId"]
}
Check required parameters early and return clear error messages:
int postId = McpResponseHelper.GetIntArg(args, "postId");
if (postId == 0) {
return McpResponseHelper.Error(cp, "postId is required");
}
Wrap tool logic in try-catch blocks and always report errors:
try {
// Tool logic
return McpResponseHelper.Success(cp, result);
} catch (Exception ex) {
cp.Site.ErrorReport(ex);
return McpResponseHelper.Error(cp, "Error listing blog posts");
}
Never let exceptions propagate unhandled. The MCP Server will catch them, but the error message will be generic.
Generate unique GUIDs for your collection, addon, and each tool definition record. Never reuse GUIDs from documentation examples. Use Visual Studio (Tools > Create GUID) or an online GUID generator.
Write descriptions that help Claude decide when to use each tool. Include:
Good: "List blog posts with optional filters for status (draft, published, archived) and author. Returns title, slug, status, author, and publish date for each post."
Weak: "Lists posts."
Extension tool definitions are cached by the MCP Server for 5 minutes. During development:
tools/list and verify your tools appearundo_list and undo_apply