Watch Aspire live streamsDocsTry Aspire
Watch Aspire live streamsDocsTry

Resource MCP servers

Aspire resources can expose their own MCP (Model Context Protocol) servers, enabling AI coding agents to interact directly with databases, APIs, and other services. For example, a PostgreSQL resource can expose SQL query tools, allowing an agent to run queries without leaving the conversation.

When a resource is annotated with WithMcpServer() in the AppHost, Aspire discovers the MCP endpoint and makes its tools available in two ways:

  • Through the Aspire MCP server — resource tools are automatically proxied alongside the built-in Aspire MCP server tools. AI agents see them in their tool list without any extra configuration.
  • Through the CLI — use aspire mcp tools and aspire mcp call to discover and invoke resource tools directly from the terminal.

Use the WithMcpServer() extension method to declare that a resource hosts an MCP server:

apphost.mts
import {
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
} from './.aspire/modules/aspire.mjs';
const
const builder: IDistributedApplicationBuilder
builder
= await
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
();
const
const db: PostgresDatabaseResource
db
= await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addPostgres(name: string, options?: {
userName?: string | ParameterResource;
password?: string | ParameterResource;
port?: number;
}): PostgresServerResource (+1 overload)

Adds a PostgreSQL resource to the application model. A container is used for local development.

addPostgres
("db")
.
PostgresServerResource.addDatabase(name: string, options?: {
databaseName?: string;
} | undefined): PostgresDatabaseResource (+1 overload)

Adds a PostgreSQL database to the application model.

addDatabase
("appdata");
// Expose PostgreSQL MCP tools (SQL queries, schema inspection, etc.)
await
const db: PostgresDatabaseResource
db
.
PostgresDatabaseResource.withPostgresMcp(options?: {
configureContainer?: ((obj: PostgresMcpContainerResource) => Promise<void>) | undefined;
containerName?: string;
} | undefined): PostgresDatabaseResource (+1 overload)

Adds a Postgres MCP server container and configures it to connect to the database represented by builder.

withPostgresMcp
();
await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.build(): DistributedApplication

Builds the distributed application

build
().
DistributedApplication.run(cancellationToken?: cancellationToken): void

Runs the distributed application

run
();
  • Postgres MCP container imageCompanion · PostgreSQLDocker Hub
    docker.io/crystaldba/postgres-mcp:0.3.0

    Added by WithPostgresMcp()withPostgresMcp().

    Source

Tags reflect the latest defaults on the microsoft/aspire main branch, and may be newer than the version pinned by the package you install.

Use aspire mcp tools to list all MCP tools exposed by running resources:

Aspire CLI
aspire mcp tools

For machine-readable output including input schemas:

Aspire CLI — JSON output
aspire mcp tools --format Json

Use aspire mcp call to invoke a specific tool on a resource:

Aspire CLI
aspire mcp call <resource> <tool> --input '{"key": "value"}'

For example, to run a SQL query on a PostgreSQL resource:

Aspire CLI — Query example
aspire mcp call appdata query --input '{"sql": "SELECT * FROM users LIMIT 5"}'

You can add any container that implements the MCP protocol as an MCP-enabled resource. Use WithMcpServer() to tell Aspire where the MCP endpoint lives:

apphost.mts
import {
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
} from './.aspire/modules/aspire.mjs';
const
const builder: IDistributedApplicationBuilder
builder
= await
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
();
// Add a custom MCP server container
const
const myMcpServer: ContainerResource
myMcpServer
= await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addContainer(name: string, image: AddContainerOptions): ContainerResource

Adds a container resource to the application.

addContainer
("my-mcp", {
AddContainerOptions.image?: string | undefined
image
: "myregistry/my-mcp-server",
AddContainerOptions.tag?: string | undefined
tag
: "latest" })
.
ContainerResource.withHttpEndpoint(options?: {
port?: number;
targetPort?: number;
name?: string;
env?: string;
isProxied?: boolean;
} | undefined): ContainerResource (+1 overload)

Adds an HTTP endpoint

withHttpEndpoint
({
targetPort?: number | undefined
targetPort
: 8080 })
.
ContainerResource.withMcpServer(path?: string, endpointName?: string): ContainerResource (+1 overload)

Marks the resource as hosting a Model Context Protocol (MCP) server on the specified endpoint.

withMcpServer
("/mcp");
await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.build(): DistributedApplication

Builds the distributed application

build
().
DistributedApplication.run(cancellationToken?: cancellationToken): void

Runs the distributed application

run
();

The WithMcpServer() method accepts an optional path and endpoint name:

  • WithMcpServer() — uses the default HTTP endpoint at the root path
  • WithMcpServer("/mcp") — uses the default HTTP endpoint at /mcp
  • WithMcpServer("/sse", endpointName: "https") — uses a named endpoint at /sse