| name | new-mcp-tool |
| description | Scaffold a new MCP tool with models, service method, and DI registration |
Create a new MCP tool following project conventions. Use $ARGUMENTS for the tool name and description.
Steps
-
Create tool class in the appropriate tools directory
- Static class with
[McpServerToolType] attribute
- Static method with
[McpServerTool(Name = "snake_case_name")] attribute
- Add
[Description("...")] on EVERY parameter
- Use flat parameters (no complex objects)
- Nullable optional service injection for wallet services
- Include
IsConfigured check — return error result if required service not configured
-
Add models to the appropriate models file if needed
-
Add service interface method in the service interface if the tool needs business logic beyond direct API calls
-
Implement service method in the implementation class
-
Update DI registration in Program.cs if new services are needed
-
Write tests following existing test patterns
Patterns to Follow
[McpServerToolType]
public static class MyNewTool
{
[McpServerTool(Name = "my_new_tool")]
[Description("What this tool does")]
public static async Task<string> Execute(
[Description("Parameter description")] string requiredParam,
[Description("Optional parameter")] string? optionalParam = null,
IMyService? myService = null)
{
if (myService is null || !myService.IsConfigured)
return "Error: MyService is not configured. Set MY_ENV_VAR environment variable.";
return JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true });
}
}
Key Conventions
- Tool name:
snake_case (e.g., get_btc_price, check_wallet_balance)
- Class name: PascalCase + "Tool" suffix
- Return JSON-serialized results for structured data
- Use
[Description] on every parameter — MCP clients use these for documentation
- Wallet priority: LND > NWC > Strike > OpenNode
- L402 requires preimage — only works with LND, Strike, CoinOS NWC, CLINK NWC, Alby Hub NWC
Free vs Paid
When you add a tool, update the inventory guard tests — they are the single source of truth for the advertised tool count, and they fail until the code and the declared lists match:
FREE_TOOLS in python/lightning-enable-mcp/tests/test_server.py and FreeTools in dotnet/tests/LightningEnable.Mcp.Tests/ToolInventoryTests.cs — tools that work with just a wallet (no license).
API_KEY_TOOLS / ApiKeyTools in the same files — tools that require an Agentic Commerce subscription + LIGHTNING_ENABLE_API_KEY (e.g. the producer tools create_l402_challenge, verify_l402_payment). Add license-check logic in the tool itself if it should be paid.
Public docs no longer hard-code the count (except the MCP Complete Guide's self-counting table), so there is nothing else to bump.
Suggested follow-up: /mcp-publish-prep when ready to publish