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; /// /// /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 MapMcp ile baglanir. /// [DependsOn( typeof(McpApplicationContractsModule), typeof(AbpAspNetCoreMvcModule) )] public class McpHttpApiModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); Configure(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() .WithTools() .WithTools() .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(); var available = (await schemaAppService.GetAvailableToolsAsync()).ToHashSet(System.StringComparer.Ordinal); result.Tools = [.. result.Tools.Where(tool => available.Contains(tool.Name))]; return result; })); } }