MCP SeriesGenerator

Un servidor .NET para generar y validar números de serie de vehículos.

Documentación

Este es un repositorio para pruebas con el Model Context Protocol

Instrucciones para ejecutar el proyecto

Ejecución con docker:

1. Acceda a la carpeta del directorio raíz en la terminal, ejemplo:

cd mcp_seriesgenerator

2. Ejecución del contenedor:

docker-compose up -d

3. Luego ejecute el siguiente comando del script de powershell, el archivo docker.ps1 se encuentra en el directorio raíz (El script copiará los archivos del contenedor docker a su máquina local)

powershell -ExecutionPolicy ByPass -File docker.ps1

Ejecución con la aplicación de escritorio Claude:

1. Abra la aplicación de escritorio Claude para la configuración

2. Menú - Archivo - Configuración - Desarrollador - Editar Config

3. Abra el archivo de configuración en la ubicación: \user\AppData\Roaming\Claude\claude_desktop_config.json (Guarde el archivo y reinicie Claude para Desktop)

{
    "mcpServers": {
    "serialNumberGenerator": {
      "command": "dotnet",
      "args": [
        "run",
        "--project",
        "C:\\ABSOLUTE\\PATH\\TO\\PROJECT",
        "--no-build"
      ]
    }
  }
}

4. Busque el ícono de "Search & Tools", escriba algo como Upload Vehicle e inserte el archivo con los números de serie. Ejemplo:

series.txt
1313MEXXXA7989-1
0708BRAXXC4014-3
1414ARGXXA5834-9
1213ASMXXC8348-2
0202ARGXXC2614-E
0606BRAXXA6466-8
0606MEXXXA3820-4

5. Más información en: https://modelcontextprotocol.io/quickstart/server

Pruebas con Mcp Server sin aplicaciones cliente:

1. El Model Context Protocol (MCP) permite que los servidores expongan herramientas que pueden ser invocadas externamente de manera estandarizada.

1.1. Primero, es necesario configurar el Mcp Server y sus herramientas que serán expuestas en la aplicación. Aquí configuramos con StdioServerTransport:

//class src/McpSeriesGenerator.App/Program.cs
builder.Services.AddMcpServer()
    .WithStdioServerTransport()
    .WithTools<VehicleTool>();
builder.Services.AddScoped<VehicleTool>();

1.2. En el proyecto, hay recursos creados para la herramienta del Mcp Server. Entre algunos de ellos, tenemos, por ejemplo, ReturnsIfTheSerialNumberIsValid.

//class src/McpSeriesGenerator.App/McpServer/VehicleTool.cs
[McpServerTool(Name = "ReturnsIfTheSerialNumberIsValid"), Description("Validate serial number with check digit.")]
public string ReturnsIfTheSerialNumberIsValid(
    [Description("Enter a serial number with check digit")] string SerialNumber)
{
    if (string.IsNullOrWhiteSpace(SerialNumber))
    {
        return "Serial number cannot be empty.";
    }
    var vehicle = Vehicle.Create(SerialNumber);
    if (vehicle.VehicleSerialNumber.ValidateCheckDigit())
    {
        return "This serial number is valid";
    }
    return "This serial number is invalid";
}

2. En el proyecto de pruebas de integración, hay comunicación a través de StdioServerTransport para la simulación real de una integración entre la aplicación cliente y el Mcp Server.

2.1. En el siguiente código, en el método constructor, se crea una instancia de proceso para ejecutar el proyecto del Mcp Server externamente desde el proyecto de pruebas de integración.

//class test/McpSeriesGenerator.Integration/McpServer/ProcessFixture.cs
public ProcessFixture()
{
    string appDll = Path.Combine(AppContext.BaseDirectory, "McpSeriesGenerator.App.dll");
    _process = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            FileName = "dotnet",
            Arguments = $"\"{appDll}\"",
            RedirectStandardInput = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            UseShellExecute = false,
            CreateNoWindow = true
        }
    };
    _process.Start();
    if (_process == null)
    {
        throw new InvalidOperationException("Failed to start MCP server process");
    }
}

2.2. Ejemplo de método de prueba con la herramienta ReturnsIfTheSerialNumberIsValid:

//class test/McpSeriesGenerator.Integration/McpServer/VehicleToolTest.cs
public async Task MCPServer_ShouldResponseToReturnsIfTheSerialNumberIsValid()
{
    Assert.NotNull(_fixture._process);

    _ = Task.Run(async () =>
    {
        string? err;
        while ((err = await _fixture._process.StandardError.ReadLineAsync()) != null)
            Console.WriteLine("[STDERR] " + err);
    });
    var jsonString = JsonSerializer.Serialize(new
    {
        jsonrpc = "2.0",
        id = 1,
        method = "tools/call",
        @params = new
        {
            name = "ReturnsIfTheSerialNumberIsValid",
            arguments = new { SerialNumber = "0202ARGXXC2614-E" }
        }
    });
    await _fixture._process.StandardInput.WriteLineAsync(jsonString);
    await _fixture._process.StandardInput.FlushAsync();
    if (_fixture._process.StandardOutput.Peek() > 0)
    {
        var responseOut = await _fixture._process.StandardOutput.ReadLineAsync();
        Assert.True(!string.IsNullOrWhiteSpace(responseOut));
        Assert.Contains("jsonrpc", responseOut);
        JsonNode? node = JsonNode.Parse(responseOut);
        Assert.NotNull(node);
        Assert.NotNull(node?["result"]);
        Assert.NotNull(node?["result"]?["isError"]);
        Assert.True(bool.TryParse(node?["result"]?["isError"]?.ToString(), out bool isError));
        Assert.False(isError);
    }
}

Tecnologías y herramientas utilizadas:

  • General:
    1. .NET - .NET SDK 9;
  • Pruebas:
    1. XUnit - Pruebas unitarias para garantizar la estabilidad del código;
  • Tecnología de contenedores:
    1. Docker - Contenerización de la aplicación para facilitar las pruebas;
  • Herramientas:
    1. MCP - Model context protocol (Versión: 0.3.0-preview.1);
    2. Claude - Aplicación de escritorio Claude para cliente MCP (Versión de Windows: 0.10.38).