sozsoft-platform/api/modules/Sozsoft.Mcp/Sozsoft.Mcp.HttpApi/McpHttpApiModule.cs
2026-09-10 17:40:43 +03:00

64 lines
2.9 KiB
C#

using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using ModelContextProtocol.AspNetCore;
using Sozsoft.Mcp.Tools;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Modularity;
namespace Sozsoft.Mcp;
/// <summary>
/// /mcp ucunun sunum katmani. Araclar yalnizca uygulama sozlesmesini tanir; kimlik dogrulama,
/// kiraci cozumu, unit of work ve yetki kontrolu istegin gectigi ABP ardisik duzeninden gelir.
/// Ucun kendisi host tarafinda <c>MapMcp</c> ile baglanir.
/// </summary>
[DependsOn(
typeof(McpApplicationContractsModule),
typeof(AbpAspNetCoreMvcModule)
)]
public class McpHttpApiModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<McpOAuthOptions>(options =>
{
options.BaseUrl = (configuration["App:SelfUrl"] ?? string.Empty).TrimEnd('/');
options.AuthorizationServer = (configuration["AuthServer:Authority"] ?? string.Empty).TrimEnd('/');
});
context.Services
.AddMcpServer(options =>
{
options.ServerInfo = new() { Name = McpServerInfoDefaults.Name, Version = McpServerInfoDefaults.Version };
options.ServerInstructions = McpServerInfoDefaults.Instructions;
})
.WithHttpTransport(options =>
{
// Durumsuz kip: her istek kendi ABP kapsaminda kosar, boylece kimlik, kiraci
// cozumu ve unit of work istekle birlikte dogru kurulur. Durumlu kipte oturum
// kapsami initialize istegine baglanir ve sonraki cagrilar yanlis kiracinin
// baglaminda kalabilir; ayrica ters vekil arkasinda oturum yapisakligi gerekmez.
options.SessionMode = HttpServerSessionMode.Stateless;
})
.WithTools<McpSchemaTools>()
.WithTools<McpQueryTools>()
.WithTools<McpDataTools>()
.WithRequestFilters(filters => filters.AddListToolsFilter(next => async (requestContext, cancellationToken) =>
{
var result = await next(requestContext, cancellationToken);
// Arac listesi kiracinin sunucu kaydina ve kullanicinin uygulamadaki yetkilerine
// gore suzulur. Cagri aninda da ayni kural uygulanir
// (McpAppService.EnsureToolAllowedAsync): istemci listede olmayan bir araci da
// cagirabilir, suzme tek basina bir yetki siniri degildir.
var schemaAppService = requestContext.Services!.GetRequiredService<IMcpSchemaAppService>();
var available = (await schemaAppService.GetAvailableToolsAsync()).ToHashSet(System.StringComparer.Ordinal);
result.Tools = [.. result.Tools.Where(tool => available.Contains(tool.Name))];
return result;
}));
}
}