Skip to content

PromptMessage Roles do not serialize with lowercase enum values #55

Open
@baronfel

Description

@baronfel

Describe the bug
When attempting to return a GetPromptResult from a GetPromptHandler, the Role field on the PromptMessage type serializes with an uppercase enum value, while tools like Claude and the MCP Inspector expect a lowercase value only.

To Reproduce
Steps to reproduce the behavior:

  1. Use the following sample program:
using ModelContextProtocol;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol.Protocol.Types;

var builder = Host.CreateApplicationBuilder(args);
builder.Services
    .AddMcpServer()
    .WithStdioServerTransport()
    .WithListPromptsHandler((ctx, ctok) => Task.FromResult(new ListPromptsResult()
    {
        Prompts = [new() { Name = "prompt1", Description = "Prompt 1" }]
    })
    )
    .WithGetPromptHandler((req, ctok) =>
    {
        if (req.Params!.Name == "prompt1")
        {
            return Task.FromResult(new GetPromptResult() { Messages = [new PromptMessage() { Content = new Content() { Text = "do the thing!", Type = "text" }, Role = Role.User }] });
        }
        throw new Exception("Prompt not found");
    });
await builder.Build().RunAsync();
  1. build the app with dotnet build
  2. Run the MCP Inspector: npx @modelcontextprotocol/inspector .\bin\Debug\net9.0\yourapp
  3. list prompts
    Image
  4. select the prompt1 prompt
  5. See the following error:
    Image
[
    {
        "received": "User",
        "code": "invalid_enum_value",
        "options": [
            "user",
            "assistant"
        ],
        "path": [
            "messages",
            0,
            "role"
        ],
        "message": "Invalid enum value. Expected 'user' | 'assistant', received 'User'"
    }
]

Expected behavior
The prompt1 prompt should have been invoked in the MCP inspector.

Logs
See above

Additional context
Pretty sure this is a classic .NET-style enum serialization problem - we need to use lowecase enum serialization. I think we can do that with a naming policy on the Role type specifically?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions