Getting started with Prompts
This page covers the shortest path to a working prompt: what a prompt is, the two ways to declare one, and how a client sees it. For the full feature set — arguments and defaults, message roles, titles and icons, runtime listing, and completion — 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.Prompts to your uses clause. System.Rtti is also needed,
because a handler receives its arguments as an array of TValue.
Declare a prompt in one call
TTMSMCPPrompts.RegisterPrompt is the shortest route. It takes a name, a
description, and the handler that builds the conversation:
procedure TForm1.RegisterSummarizePrompt;
var
Arg: TTMSMCPPromptArgument;
begin
{ Server is a TTMSMCPServer dropped on the form. }
Server.Prompts.RegisterPrompt('summarize_ticket',
'Asks the model to summarize a support ticket in three sentences',
function(const Args: array of TValue): TTMSMCPPromptMessages
begin
Result := TTMSMCPPromptMessages.Create(nil);
Result.AddUserMessage(Format(
'Summarize support ticket %s in three sentences.', [Args[0].AsString]));
end);
{ RegisterPrompt declares no arguments, so declare them separately -
the client needs them to build the prompts/get call. }
Arg := Server.Prompts.FindByName('summarize_ticket').Arguments.Add;
Arg.Name := 'ticket_id';
Arg.Description := 'Identifier of the ticket to summarize';
Arg.Required := True;
end;
The description matters more than it looks. A client shows it next to the prompt in its palette, and it is also returned with the messages, so write it for a reader who cannot see your code.
Note the second half of that snippet. RegisterPrompt declares no arguments, so
the argument the handler reads as Args[0] has to be declared separately — the
client has nothing to ask the user for otherwise.
Declare a prompt with the builder
For anything beyond one argument, the fluent builder keeps the whole declaration in one expression — the prompt, its handler, and its arguments:
procedure TForm1.RegisterReviewUnitPrompt;
var
Prompt: TTMSMCPPrompt;
begin
Prompt := TTMSMCPPrompt.CreateBuilder
.Name('review_unit')
.Title('Review a unit')
.Description('Asks the model to review one source unit for a named concern')
.Handler(
function(const Args: array of TValue): TTMSMCPPromptMessages
begin
Result := TTMSMCPPromptMessages.Create(nil);
Result.AddUserMessage(Format(
'Review the unit %s. Focus on %s and list findings as a numbered list.',
[Args[0].AsString, Args[1].AsString]));
end)
.AddArgument
.Name('unit_name')
.Description('Unit to review, for example TMS.MCP.Prompts.pas')
.Required(True)
.&End
.AddArgument
.Name('focus')
.Description('What to concentrate on, for example memory management')
.Required(False)
.&End
.Build;
{ AddPrompt copies the declaration into the server collection instead of
reparenting the instance, so do not free the prompt you built. }
Server.Prompts.AddPrompt(Prompt);
end;
TTMSMCPPrompt.CreateBuilder returns a builder class; every call returns the
builder again, so the chain reads top to bottom. AddArgument switches to the
argument builder, and .&End switches back. &End needs the ampersand because
End is a reserved word.
Ownership
TTMSMCPPrompts.AddPrompt copies the declaration into a new item in the
collection rather than reparenting the instance you pass. The prompt returned by
Build is therefore never owned by the server's collection — do not free it
after adding.
The collection the handler returns works the other way: create it with
TTMSMCPPromptMessages.Create(nil), fill it, return it, and let the framework
free it. Do not free it in the handler.
Run it
Start the server and connect any MCP client. The prompt appears in the client's
prompt list with the name, title, and description you declared, and each
argument you added becomes a field the user fills in. Selecting it calls
prompts/get, and the messages your handler returns are inserted into the
conversation in order.
See also
- User guide — the full feature set
- Defining prompts — arguments, icons, runtime listing
- Prompt messages — roles, defaults, completion
- API reference