86 lines
3 KiB
C#
86 lines
3 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// MCP uygulama servislerinin ortak tabani. Kullaniciya gorunen metinler platformun
|
|
/// <c>PlatformResource</c> kaynagindan okunur; sunucu kaydini cozme ve arac kapisi her
|
|
/// serviste ayni davranir.
|
|
/// </summary>
|
|
public abstract class McpAppService : ApplicationService
|
|
{
|
|
protected IMcpServerConfigProvider ServerConfigProvider { get; }
|
|
|
|
protected McpAppService(IMcpServerConfigProvider serverConfigProvider)
|
|
{
|
|
ServerConfigProvider = serverConfigProvider;
|
|
LocalizationResource = typeof(PlatformResource);
|
|
}
|
|
|
|
/// <summary>Etkin sunucu kaydinin DTO hali; kayit yoksa null.</summary>
|
|
protected async Task<McpServerConfigDto?> 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
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Kaydi zorunlu kilan islemler icin. Kayit yoksa istemcinin nedenini gorebilecegi bir
|
|
/// hata atar.
|
|
/// </summary>
|
|
protected async Task<McpServerConfigDto> RequireServerConfigAsync()
|
|
=> await ResolveServerConfigAsync()
|
|
?? throw new UserFriendlyException(L[McpErrorCodes.NoServerRecord]);
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
protected async Task<McpServerConfigDto> 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;
|
|
}
|
|
|
|
/// <summary>Istenen satir sayisini sunucu kaydindaki tavana kirpar.</summary>
|
|
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;
|
|
}
|
|
}
|