using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Sozsoft.Mcp.Dtos; using Sozsoft.Mcp.Services; using Sozsoft.Platform.Localization; using Volo.Abp; using Volo.Abp.Application.Services; namespace Sozsoft.Mcp; /// /// MCP uygulama servislerinin ortak tabani. Kullaniciya gorunen metinler platformun /// PlatformResource kaynagindan okunur; sunucu kaydini cozme ve arac kapisi her /// serviste ayni davranir. /// public abstract class McpAppService : ApplicationService { protected IMcpServerConfigProvider ServerConfigProvider { get; } protected McpAppService(IMcpServerConfigProvider serverConfigProvider) { ServerConfigProvider = serverConfigProvider; LocalizationResource = typeof(PlatformResource); } /// Etkin sunucu kaydinin DTO hali; kayit yoksa null. protected async Task ResolveServerConfigAsync() { var server = await ServerConfigProvider.GetEffectiveServerAsync(); if (server is null) { return null; } return new McpServerConfigDto { Name = server.Name, Url = server.Url, DataSourceCode = server.DataSourceCode, AllowedTools = [.. ServerConfigProvider.SplitMultiValue(server.AllowedTools)], MaxRows = server.MaxRows, AllowWrite = server.AllowWrite, Description = server.Description, TenantName = CurrentTenant.Name }; } /// /// Kaydi zorunlu kilan islemler icin. Kayit yoksa istemcinin nedenini gorebilecegi bir /// hata atar. /// protected async Task RequireServerConfigAsync() => await ResolveServerConfigAsync() ?? throw new UserFriendlyException(L[McpErrorCodes.NoServerRecord]); /// /// Kapali bir araca yapilan cagriyi reddeder: arac sunucu kaydinda kapaliysa ya da /// kullanicinin uygulamada karsilik gelen yetkisi yoksa. Arac listesini suzmek tek basina /// yeterli degildir — istemci listede olmayan bir araci da cagirabilir. /// protected async Task EnsureToolAllowedAsync(string toolName) { var config = await RequireServerConfigAsync(); if (!McpToolPolicy.IsAllowed(true, config.AllowWrite, config.AllowedTools, toolName)) { throw new UserFriendlyException(L[McpErrorCodes.ToolDisabled, toolName, config.Name]); } if (McpToolNames.RequiredPermissions.TryGetValue(toolName, out var permission)) { await AuthorizationService.CheckAsync(permission); } return config; } /// Istenen satir sayisini sunucu kaydindaki tavana kirpar. protected static int ResolveMaxRows(McpServerConfigDto config, int requested) { var ceiling = config.MaxRows > 0 ? config.MaxRows : McpConsts.DefaultMaxRows; return requested > 0 ? Math.Min(requested, ceiling) : ceiling; } }