Getting started with Tools
This page covers the shortest path to a working tool: what a tool is, the two ways to declare one, and how a client sees it. For the full feature set — enums, arrays of objects, structured output, content items, and task support — see the user guide.
Prerequisites
- Delphi 11 Alexandria or newer (or C++Builder) with TMS AI Studio installed.
- A VCL or FMX application with a
TTMSMCPServeron a form, or created in code. - A transport assigned to the server so a client can reach it. See MCP Transports; STDIO is the simplest for a first test.
Add TMS.MCP.Tools to your uses clause. TMS.MCP.Helpers is also needed when
you refer to TTMSMCPToolPropertyType values such as ptString directly.
Declare a tool in two lines
TTMSMCPTools.RegisterTool is the shortest route. It takes a name, a
description, the method to run, and the return type:
procedure TForm1.RegisterGreetTool;
var
Prop: TTMSMCPToolProperty;
begin
{ Server is a TTMSMCPServer dropped on the form. }
Server.Tools.RegisterTool('greet_user', 'Generates a greeting for a person',
function(const Args: array of TValue): TValue
begin
Result := Format('Hello, %s!', [Args[0].AsString]);
end,
ptString);
{ RegisterTool creates the tool with no declared input properties, so
declare them separately - the client needs them to build the call. }
Prop := Server.Tools.FindByName('greet_user').Properties.Add;
Prop.Name := 'name';
Prop.Description := 'Name of the person to greet';
Prop.PropertyType := ptString;
Prop.Required := True;
end;
The description matters more than it looks. A client passes it to the language model verbatim, and the model decides whether to call the tool based on that text alone. Write it for a reader who cannot see your code.
Declare a tool with the builder
For anything beyond one argument, the fluent builder keeps the whole declaration in one expression — the tool, its properties, and its hints:
procedure TForm1.RegisterSumTool;
var
Tool: TTMSMCPTool;
begin
Tool := TTMSMCPTool.CreateBuilder
.Name('calculate_sum')
.Title('Sum of two numbers')
.Description('Calculates the sum of two numbers')
.ReturnType(ptFloat)
.ReadOnlyHint(True)
.IdempotentHint(True)
.ExecuteCallback(
function(const Args: array of TValue): TValue
begin
Result := Args[0].AsExtended + Args[1].AsExtended;
end)
.AddProperty
.Name('first')
.Description('First number')
.PropertyType(ptFloat)
.Required(True)
.&End
.AddProperty
.Name('second')
.Description('Second number')
.PropertyType(ptFloat)
.Required(True)
.&End
.Build;
{ Add reparents the tool into the collection, which then owns it.
Do not free Tool afterwards. }
Server.Tools.Add(Tool);
end;
TTMSMCPTool.CreateBuilder returns a builder class; every call returns the
builder again, so the chain reads top to bottom. AddProperty switches to the
property builder, and .&End switches back to the tool builder. &End needs
the ampersand because End is a reserved word.
Ownership
TTMSMCPTools.Add reparents the tool into the collection, which then owns and
frees it. Do not free a tool you have added — that is a double free. Only a
tool you built and never added is yours to free.
Run it
Start the server and connect any MCP client. The tool appears in the client's
tool list with the name, title, and description you declared, and the arguments
you added through AddProperty become the tool's input schema.
See also
- User guide — the full feature set
- Defining tools — property types, enums, arrays, hints
- Tool results — structured output, content items, tasks
- API reference