Skip to content

Prompts

Prompts are reusable templates that help structure interactions with AI models.

Defining a Prompt

zig
try server.addPrompt(.{
    .name = "summarize",
    .description = "Summarize a piece of text",
    .handler = summarizeHandler,
});

Prompt Properties

PropertyTypeDescription
name[]const u8Unique prompt name
title?[]const u8Human-readable title
description?[]const u8Description of the prompt
arguments?[]PromptArgumentExpected arguments
handler*HandlerFunction to generate messages

Handler Functions

zig
fn promptHandler(
    _: ?*anyopaque,
    _: std.Io,
    allocator: std.mem.Allocator,
    args: ?std.json.Value,
) PromptError![]const PromptMessage;

Example Handler

zig
fn codeReviewHandler(
    _: ?*anyopaque,
    _: std.Io,
    allocator: std.mem.Allocator,
    args: ?std.json.Value,
) mcp.prompts.PromptError![]const mcp.prompts.PromptMessage {
    const code = mcp.prompts.getStringArg(args, "code") orelse {
        return error.InvalidArguments;
    };

    const language = mcp.prompts.getStringArg(args, "language") orelse "unknown";

    const system_prompt = try std.fmt.allocPrint(
        allocator,
        "You are a code reviewer. Review the following {s} code for best practices, bugs, and improvements.",
        .{language},
    );

    return &.{
        mcp.prompts.userMessage(system_prompt),
        mcp.prompts.userMessage(code),
    };
}

Prompt Arguments

Define expected arguments:

zig
try server.addPrompt(.{
    .name = "analyze",
    .description = "Analyze text for sentiment",
    .arguments = &.{
        .{ .name = "text", .description = "Text to analyze", .required = true },
        .{ .name = "language", .description = "Language of the text", .required = false },
    },
    .handler = analyzeHandler,
});

Message Types

User Message

zig
mcp.prompts.userMessage("Analyze this text for me")

Assistant Message

zig
mcp.prompts.assistantMessage("I'll analyze the text...")

Only user and assistant roles are supported by mcp.types.Role.

Using PromptBuilder

zig
var builder = mcp.prompts.PromptBuilder.init("my_prompt");
defer builder.deinit(allocator);

_ = try builder.addArgument(allocator, "input", "The input text", true);
_ = try builder.addArgument(allocator, "style", "Output style", false);

const prompt = builder
    .description("A helpful prompt")
    .handler(myHandler)
    .build();

try server.addPrompt(prompt);

Complete Example

zig
const std = @import("std");
const mcp = @import("mcp");

pub fn main(init: std.process.Init) void {
    run(init.io, init.gpa) catch |err| {
        mcp.reportError(err);
    };
}

fn run(io: std.Io, allocator: std.mem.Allocator) !void {
    var server: mcp.Server = .init(allocator, .{
        .name = "prompt-server",
        .version = "1.0.0",
    });
    defer server.deinit();

    // Simple prompt
    try server.addPrompt(.{
        .name = "explain",
        .description = "Explain a concept simply",
        .arguments = &.{
            .{ .name = "concept", .description = "The concept to explain", .required = true },
            .{ .name = "level", .description = "Expertise level (beginner/advanced)", .required = false },
        },
        .handler = explainHandler,
    });

    // Code generation prompt
    try server.addPrompt(.{
        .name = "generate_code",
        .description = "Generate code for a task",
        .arguments = &.{
            .{ .name = "task", .description = "What the code should do", .required = true },
            .{ .name = "language", .description = "Programming language", .required = true },
        },
        .handler = generateCodeHandler,
    });

    try server.run(io, allocator, .stdio);
}

fn explainHandler(
    _: ?*anyopaque,
    _: std.Io,
    allocator: std.mem.Allocator,
    args: ?std.json.Value,
) mcp.prompts.PromptError![]const mcp.prompts.PromptMessage {
    const concept = mcp.prompts.getStringArg(args, "concept") orelse {
        return error.InvalidArguments;
    };

    const level = mcp.prompts.getStringArg(args, "level") orelse "beginner";

    const prompt_text = try std.fmt.allocPrint(
        allocator,
        "Please explain '{s}' at a {s} level. Use simple examples and analogies.",
        .{ concept, level },
    );

    return &.{
        mcp.prompts.userMessage(prompt_text),
    };
}

fn generateCodeHandler(
    _: ?*anyopaque,
    _: std.Io,
    allocator: std.mem.Allocator,
    args: ?std.json.Value,
) mcp.prompts.PromptError![]const mcp.prompts.PromptMessage {
    const task = mcp.prompts.getStringArg(args, "task") orelse {
        return error.InvalidArguments;
    };

    const language = mcp.prompts.getStringArg(args, "language") orelse {
        return error.InvalidArguments;
    };

    const system = try std.fmt.allocPrint(
        allocator,
        "You are an expert {s} programmer. Generate clean, well-documented code.",
        .{language},
    );

    const user = try std.fmt.allocPrint(
        allocator,
        "Write {s} code to: {s}",
        .{ language, task },
    );

    return &.{
        mcp.prompts.userMessage(system),
        mcp.prompts.userMessage(user),
    };
}

Next Steps