快速入门:将 SQL MCP Server 与 .NET Aspire 配合使用

重要

SQL MCP Server 以预览版提供,本文档和引擎实现在此评估期间可能会更改。

本快速入门使用 Aspire 生成基于容器的解决方案。 该解决方案包括:

  • 包含示例数据的 SQL 数据库
  • 由数据 API 生成器提供支持的 SQL 模型上下文协议 (MCP) 服务器
  • 用于测试的 MCP 检查器

Aspire 会为你运行所有内容,启动服务和连接容器,并在关闭容器时停止服务。

显示 Aspire 解决方案、SQL Server、SQL MCP Server 和 MCP 检查器的图表。

先决条件

在开始之前安装这些工具。

1. .NET 10

在此步骤中,你将为快速入门准备好计算机所需的先决条件。

重要

可能已安装此工具。 通过运行 dotnet --version 并确认它报告版本 10 或更高版本来测试它。 如果运行此安装并且 .NET 已存在,它会刷新系统,而不会造成任何问题。

Windows操作系统

winget install Microsoft.DotNet.SDK.10

或下载

https://get.dot.net

2. 容器运行时

在此步骤中,安装 Docker Desktop 以支持 Aspire 项目。

重要

可能已安装此工具。 通过运行 docker --version 来测试它,确认 Docker 是否可用。 如果运行此安装并且 Docker 已存在,它将刷新系统,而不会造成任何问题。

Windows操作系统

winget install Docker.DockerDesktop

macOS

brew install --cask docker

注释

Podman 也有效,但设置会有所不同。 喜欢 Podman 的开发人员可以调整这些步骤。

3. Aspire 和数据 API 生成器工具

在此步骤中,你将创建稍后使用的默认 Aspire 项目文件。

运行以下命令

dotnet new tool-manifest
dotnet tool install aspire.cli
dotnet tool install microsoft.dataapibuilder --prerelease
aspire init

注释

SQL MCP Server 当前处于预发行版中。 使用--prerelease 标志可确保您获取具备本快速入门中使用的所有功能的最新版本数据 API 生成器。

出现提示时,选择所有默认值。

此命令安装该工具并创建以下文件

.
├── .config
│   └── dotnet-tools.json
├── AppHost.cs
└── apphost.run.json

4.完成AppHost.cs文件

在此步骤中,你将使用正确的代码进行更新 AppHost.cs ,以运行本快速入门。

将AppHost.cs的内容替换为以下内容

#:sdk Aspire.AppHost.Sdk@13.0.2
#:package Aspire.Hosting.SqlServer@13.0.2
#:package CommunityToolkit.Aspire.Hosting.McpInspector@9.8.0

using System.ComponentModel;
using Aspire.Hosting;
using Aspire.Hosting.ApplicationModel;

var builder = DistributedApplication.CreateBuilder(args);

var db = AddSqlServer(builder);
WithSqlCommander(db);

var mcp = AddMcpServer(db);
WithMcpInspector(mcp);

await builder.Build().RunAsync();

IResourceBuilder<SqlServerDatabaseResource> AddSqlServer(IDistributedApplicationBuilder builder) => builder
    .AddSqlServer("sql-server").WithDataVolume()
    .AddDatabase("sql-database", "productsdb")
    .WithCreationScript(SqlScript("productsdb"));

IResourceBuilder<ContainerResource> WithSqlCommander(IResourceBuilder<SqlServerDatabaseResource> db) => db
    .ApplicationBuilder.AddContainer("sql-cmdr", "jerrynixon/sql-commander", "latest")
    .WithImageRegistry("docker.io")
    .WithHttpEndpoint(targetPort: 8080, name: "http")
    .WithEnvironment("ConnectionStrings__db", db)
    .WithParentRelationship(db)
    .WaitFor(db)
    .WithUrls(x =>
    {
        x.Urls.Clear();
        x.Urls.Add(new() { Url = "/", DisplayText = "Commander", Endpoint = x.GetEndpoint("http") });
    });

IResourceBuilder<ContainerResource> AddMcpServer(IResourceBuilder<SqlServerDatabaseResource> db) => db
    .ApplicationBuilder.AddContainer("sql-mcp-server", "azure-databases/data-api-builder", "1.7.83-rc")
    .WithImageRegistry("mcr.microsoft.com")
    .WithHttpEndpoint(targetPort: 5000, name: "http")
    .WithEnvironment("MSSQL_CONNECTION_STRING", db)
    .WithBindMount("dab-config.json", "/App/dab-config.json", true)
    .WaitFor(db)
    .WithUrls(x =>
    {
        x.Urls.Clear();
        x.Urls.Add(new() { Url = "/swagger", DisplayText = "Swagger", Endpoint = x.GetEndpoint("http") });
    });

IResourceBuilder<McpInspectorResource> WithMcpInspector(IResourceBuilder<ContainerResource> mcp) => mcp
    .ApplicationBuilder.AddMcpInspector("mcp-inspector")
    .WithMcpServer(mcp)
    .WithParentRelationship(mcp)
    .WaitFor(mcp)
    .WithUrls(x =>
    {
        x.Urls[0].DisplayText = "Inspector";
    });

string SqlScript(string db) => $"""
    CREATE DATABASE {db};
    GO

    SELECT *
    INTO {db}.dbo.Products
    FROM (VALUES
        (1, 'Action Figure', 40, 14.99, 5.00),
        (2, 'Building Blocks', 25, 29.99, 10.00),
        (3, 'Puzzle 500 pcs', 30, 12.49, 4.00),
        (4, 'Toy Car', 50, 7.99, 2.50),
        (5, 'Board Game', 20, 34.99, 12.50),
        (6, 'Doll House', 10, 79.99, 30.00),
        (7, 'Stuffed Bear', 45, 15.99, 6.00),
        (8, 'Water Blaster', 35, 19.99, 7.00),
        (9, 'Art Kit', 28, 24.99, 8.00),
        (10,'RC Helicopter', 12, 59.99, 22.00)
    ) AS x (Id, Name, Inventory, Price, Cost);

    ALTER TABLE {db}.dbo.Products
    ADD CONSTRAINT PK_Products PRIMARY KEY (Id);
    """;

此代码配置以下资源

.
├── SQL Server (sql)
│   └── SQL Database (productsdb)
└── SQL MCP Server (sql-mcp-server)
    └── MCP Inspector (inspector)

显示 Aspire 资源及其连接的示意图。

5.创建 dab-config.json 文件

在项目文件夹中运行这些命令(位于 AppHost.cs 同一文件夹)。

@env('MSSQL_CONNECTION_STRING') 语法告知数据 API 生成器在运行时从环境变量中读取连接字符串。 Aspire 在启动容器时自动设置此变量,因此无需在本地设置它。

dab init --database-type mssql --connection-string "@env('MSSQL_CONNECTION_STRING')" --host-mode Development --config dab-config.json
dab add Products --source dbo.Products --permissions "anonymous:read" --description "Toy store products with inventory, price, and cost."

注释

@env(...) 表达式是 DAB 配置功能,用于在运行时解析环境变量,而不是在 dab init 时进行解析。 生成的 dab-config.json 字符串包含文本字符串,DAB 在容器启动时解析该字符串 @env('MSSQL_CONNECTION_STRING')

该文件 dab-config.json 将 SQL MCP Server 配置为连接到数据库并标识要公开的对象。 在这种情况下,Products 会被暴露。

此命令将新文件添加到项目

dab-config.json

重要

文件 dab-config.json 必须位于运行 aspire run 的同一个目录中,因为绑定挂载使用的是相对路径(./dab-config.json)。

(可选)添加字段说明

此元数据可帮助语言模型理解架构。

dab update Products --fields.name Id --fields.primary-key true --fields.description "Product Id"
dab update Products --fields.name Name --fields.description "Product name"
dab update Products --fields.name Inventory --fields.description "Units in stock"
dab update Products --fields.name Price --fields.description "Retail price"
dab update Products --fields.name Cost --fields.description "Store cost"

测试解决方案

在此步骤中,你将运行 Aspire 环境,并确认 SQL Server、SQL MCP Server 和 MCP 检查器正在协同工作。

1. 启动 Aspire

aspire run

重要

确保 Docker 正在运行。 Aspire 要求容器主机正常工作。

当仪表板打开时,你将看到 Swagger、MCP 和 Inspector 的链接。

显示正在运行环境的 Aspire 仪表板的屏幕截图。

预期 URL

Aspire 仪表板显示这些链接(端口是动态分配的):

Resource Link Description
sql-mcp-server Swagger REST API 文档
sql-mcp-server MCP MCP 终端 (/mcp
督察 Inspector MCP 检查器 UI

2.使用 Swagger 测试 REST API

从仪表板中选择 Swagger

尝试对产品进行GET操作。 此测试确认 SQL MCP Server 正在运行,并且可以连接到数据库。

3. 浏览 MCP 工具

从仪表板中选择 检查器

Try:

  • list_tools 查看可用的 MCP 工具
  • read_records实体Products

尝试筛选器(示例语法):

{ "filter": "Price gt 20" }

此测试确认 MCP 正常工作。

4. 停止 Aspire

若要停止 Aspire,请按 Ctrl+C

Aspire 停止所有服务。 SQL Server 数据在运行之间保留,因为代码使用 .WithDataVolume().WithLifetime(ContainerLifetime.Persistent)

Troubleshooting

SQL MCP Server 容器无法启动

  • 检查 Aspire 仪表板中的容器日志以了解错误详细信息
  • --config验证参数是否与 DAB 容器的预期语法匹配(某些版本可能会改用--ConfigFileName
  • 确保 dab-config.json 存在于你运行 aspire run 的同一目录中

找不到数据库初始化脚本

  • 验证 init-db.sql 是否在 AppHost 项目目录中
  • 检查文件是否包含在项目中,并根据需要复制到输出目录。

MCP 检查器无法连接

  • 确认 SQL MCP Server 容器正在运行且正常运行
  • 验证 MCP 终结点路径 (/mcp) 是否与 DAB 配置匹配