Skip to content

Your First Tool

A tool is a program another application can call with named inputs and receive a result from. In this tutorial, you will turn a pricing calculation into a tool that an AI application can discover through the Model Context Protocol (MCP).

Complete the Quick Start first. The calculation itself runs as ordinary Devlish code; MCP supplies a way to describe and call it. You will need an MCP-compatible client only for the final connection step.

A calculation needs explicit inputs and an explicit result to be useful as a tool. This example accepts a customer tier and deal size, chooses a discount, and rejects deals below the minimum. Create a tools directory and save the following source as tools/calculate_discount.dvl.

Ask "Customer tier?" as customer tier
Ask "Deal size?" as deal size
discount_rate equals 0.05
If customer_tier is "premium"
discount_rate equals 0.10
If customer_tier is "enterprise"
discount_rate equals 0.15
If deal_size is less than 10000
Fail with record with "minimum_not_met" as code and "Deal size must be at least $10,000" as message
discount equals deal_size times discount_rate
Respond with record with discount as amount and discount_rate as rate and customer_tier as tier

The tool manifest describes the program to the server: where its source lives, what it does, and which inputs a caller should supply. This devlish.toml belongs in the tools directory alongside the source file.

name = "pricing-tools"
version = "0.1.0"
[[tools]]
source = "calculate_discount.dvl"
description = "Calculate the discount amount for a deal based on customer tier and size"
[tools.inputs]
customer_tier = { type = "string", description = "Customer tier: standard, premium, or enterprise" }
deal_size = { type = "number", description = "Total deal value in dollars" }

The server reads that directory and exposes the declared tool to an MCP client. Run it from the parent directory when checking discovery. For normal desktop-client use, the client starts this process using the configuration in the next section.

Terminal window
devlish mcp --tools-dir ./tools/

A configured MCP client can discover the tool and supply its inputs.

An MCP client needs to know which executable to start and where your tools live. The example below is a client configuration for the pricing server; replace the placeholder directory with an absolute path to your tools.

Add to your claude_desktop_config.json:

{
"mcpServers": {
"pricing": {
"command": "devlish",
"args": ["mcp", "--tools-dir", "/path/to/tools"]
}
}
}

Restart Claude Desktop. The tool appears in the tool list.

When Claude decides to call your tool, it sends:

{"customer_tier": "enterprise", "deal_size": 500000}

Your program runs and returns:

{
"success": true,
"responded": true,
"response": {"amount": 75000, "rate": 0.15, "tier": "enterprise"}
}

If the input is invalid (deal_size too small), it returns:

{
"success": false,
"response": {"code": "minimum_not_met", "message": "Deal size must be at least $10,000"}
}

The caller receives an error code and message it can use when deciding whether to request corrected input. Retrying is a client decision, not an automatic behavior of this program.