65 lines
2.9 KiB
C#
65 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;
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
}
|