重要
SQL MCP Server 以预览版提供,本文档和引擎实现在此评估期间可能会更改。
本快速入门使用 Aspire 生成基于容器的解决方案。 该解决方案包括:
- 包含示例数据的 SQL 数据库
- 由数据 API 生成器提供支持的 SQL 模型上下文协议 (MCP) 服务器
- 用于测试的 MCP 检查器
Aspire 会为你运行所有内容,启动服务和连接容器,并在关闭容器时停止服务。
先决条件
在开始之前安装这些工具。
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)
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 的链接。
预期 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 配置匹配