Create a New MCP Tool
Steps
Implement a custom tool by creating an XWiki component that implements the MCPTool role interface.
Prerequisites
- The
application-ai-llm-mcp-apimodule as a dependency (forMCPTool). - Dependencies on
mcp-corefor MCP SDK types andxwiki-commons-component-apifor the component framework.
1. Create the component class
Create a Java class in your module implementing org.xwiki.contrib.llm.mcp.MCPTool:
@Component
@Named("my_tool")
@Singleton
public class MyTool implements MCPTool {
@Override
public McpSchema.Tool getToolDefinition() {
// Return tool name, description, and input JSON schema
}
@Override
public McpSchema.CallToolResult execute(McpSchema.CallToolRequest request) {
// Implement the tool logic
}
}- Declare the component
Register the component in src/main/resources/META-INF/components.txt:
com.example.MyTool- Define the tool schema
Use MCPToolSupport.builder() for flat scalar parameters (available in the server module's internal package, or hand-roll for external modules):
private static final MCPToolSupport PARAMS = MCPToolSupport.builder()
.requiredString("query", "The text to search for.")
.integer("limit", "Maximum number of results (default 10).")
.build();For external modules (no access to MCPToolSupport), build the JSON schema directly:
@Override
public McpSchema.Tool getToolDefinition() {
Map<String, Object> schema = Map.of(
"type", "object",
"properties", Map.of(
"query", Map.of("type", "string", "description", "The text to search for.")
),
"required", List.of("query")
);
return new McpSchema.Tool("my_tool", "Does something useful.", schema);
}- Enforce authorization
Use MCPDocumentAccess.resolveAndAuthorize() before loading any document:
@Inject
private MCPDocumentAccess documentAccess;
// Before any operation:
documentAccess.resolveAndAuthorize(reference, Right.VIEW);If your tool does not operate on documents, check wiki-level access through the platform's ContextualAuthorizationManager.
- Return proper results
Return isError results with actionable messages for failure cases:
return MCPToolSupport.errorResult("Error: 'offset' must be a non-negative integer.");
return MCPToolSupport.result("Found: " + count + " results.");- Set metadata
Override the metadata methods:
@Override
public String getCategory() {
return "Search & Navigation";
}
@Override
public String getSummary() {
return "A one-line summary for the man catalog.";
}
@Override
public String getManPage() {
return """
EXAMPLES
Query the wiki for documentation:
my_tool query="API reference"
""";
}- Register the toolÂ
Install your extension in XWiki. The tool component is automatically discovered and registered with the MCP server on the next request (no restart needed).
FAQ
Can my tool be disabled by the administrator?
Yes. Override isEnabled() for a global kill switch. Per-wiki visibility is controlled through the enabledTools configuration list, which your tool id must match to be registered on that wiki. Override isWrite() to return true if your tool modifies content - write tools are off by default per wiki.