Skip to main content
Version: 1.2

MCP Resource Types

Register custom resource type handlers to expose files, data, or content from any protocol as MCP resources.

Quick Start​

builder.Services
.AddCoreAIMcpServer()
.AddCoreAIFtpMcpResources()
.AddCoreAISftpMcpResources()
.AddMcpResourceType<MyDatabaseResourceHandler>("database");

Or, using the builder pattern with stores:

builder.Services.AddCrestAppsCore(crestApps => crestApps
.AddAISuite(ai => ai
.AddMcpServer(mcpServer => mcpServer
.AddYesSqlStores()
.AddFtpResources()
.AddSftpResources()
)
)
);

Problem & Solution​

MCP resources represent files, URLs, or data that clients can read. FTP and SFTP handlers are available as optional packages (CrestApps.Core.AI.Mcp.Ftp and CrestApps.Core.AI.Mcp.Sftp), and applications often need additional resource types for databases, APIs, blob storage, or custom protocols. Resource type handlers provide a pluggable extension point.

Built-in Resource Types​

TypeHandlerProtocol
ftpFtpResourceTypeHandlerFTP/FTPS
sftpSftpResourceTypeHandlerSFTP

Register them explicitly with AddCoreAIFtpMcpResources() and AddCoreAISftpMcpResources().

Registration​

builder.Services.AddMcpResourceType<MyHandler>("my-type", entry =>
{
entry.DisplayName = "My Resource Type";
entry.Description = "Reads resources from my custom source";
});

AddMcpResourceType<THandler>(type, configure?)​

ParameterDescription
typeUnique type identifier string
configureOptional action to set display name and description

Implementing a Resource Type Handler​

public sealed class BlobStorageResourceHandler : McpResourceTypeHandlerBase
{
private readonly BlobServiceClient _blobClient;

public BlobStorageResourceHandler(BlobServiceClient blobClient)
{
_blobClient = blobClient;
}

protected override async Task<McpResourceReadResult> GetResultAsync(
McpResourceReadContext context,
CancellationToken cancellationToken)
{
var containerClient = _blobClient.GetBlobContainerClient(context.ContainerName);
var blobClient = containerClient.GetBlobClient(context.ResourcePath);

var download = await blobClient.DownloadContentAsync(cancellationToken);
var content = download.Value.Content.ToString();

return new McpResourceReadResult
{
Contents = [new TextResourceContents
{
Text = content,
Uri = context.Uri,
MimeType = "text/plain",
}],
};
}
}

Key Interfaces​

IMcpResourceTypeHandler​

public interface IMcpResourceTypeHandler
{
Task<McpResourceReadResult> ReadAsync(
McpResourceReadContext context,
CancellationToken cancellationToken = default);
}

McpResourceTypeHandlerBase​

A convenience base class — implement GetResultAsync() instead:

protected abstract Task<McpResourceReadResult> GetResultAsync(
McpResourceReadContext context,
CancellationToken cancellationToken);