Writing a New MCP Tool
The MCP tool surface is the agent-facing API. Every tool added here is
callable by any agent that has access to the relevant endpoint, so the
bar for landing one is "is this useful enough to justify a slot in the
decision tree on `FindingTheRightMcpTool`?".
When to use this runbook
When you have a concrete new agent operation in mind. Don't write
speculative tools — the cost of a never-called tool is a slot wasted
in the agent's decision space.
Context
A tool implements `com.wikantik.mcp.tools.McpTool`:
```java
public interface McpTool {
String name();
McpSchema.Tool definition();
McpSchema.CallToolResult execute( Map< String, Object > arguments );
}
```
Read tools live in `wikantik-knowledge/src/main/java/com/wikantik/knowledge/mcp/`
alongside `GetPageByIdTool`, `SearchKnowledgeTool`, and the others.
Write tools live in `wikantik-admin-mcp/src/main/java/com/wikantik/mcp/tools/`
alongside `MarkPageVerifiedTool` and `WritePagesTool`.
Registration happens in the matching initializer:
- `wikantik-knowledge/.../mcp/KnowledgeMcpInitializer` — adds tools to
the assembled `tools` list when the relevant manager
(`StructuralIndexService`, `ForAgentProjectionService`, etc.) is
configured.
- `wikantik-admin-mcp/.../McpServerInitializer` (or the registry it
uses) — adds tools and classifies them as read-only or
author-configurable.
Walkthrough
The frontmatter `steps` are the canonical sequence. A few elaborations:
- **Description style.** The description field is what agents read when
picking tools. Phrase it as a *trigger condition*, not an
implementation summary. Bad: "Returns a JSON object containing the
page's metadata." Good: "Resolve a canonical_id to the current page
descriptor. Prefer this over get_page when citing sources."
- **JSON schema strictness.** Required vs. optional matters — agents
pick required-only paths first. Don't mark a field required unless
it's truly required.
- **Test pattern.** `GetPageForAgentToolTest` and
`MarkPageVerifiedToolTest` both follow the same template: mock the
underlying service, assert `name()`, `definition()` shape, error
paths (missing argument, unknown id), and a happy-path
serialisation check.
Pitfalls
The frontmatter `pitfalls` capture the failure modes. The most common
in practice is the registration omission — the tool compiles, the test
passes, but the initializer never adds it. Cross-check by running the
relevant `McpToolRegistryTest` (or the equivalent for knowledge-mcp).