using System.Collections.Generic; using System.ComponentModel; using System.Threading.Tasks; using ModelContextProtocol.Server; using Sozsoft.Mcp.Dtos; using Sozsoft.Platform.DeveloperKit; using Sozsoft.Platform.ListForms; namespace Sozsoft.Mcp.Tools; /// /// Ekran (wizard) ve custom component gelistirme araclari. Uretim uygulamadaki Wizard ve /// Custom Components servislerinden gecer; menu, yetki, dil anahtari ve seed dosyasi ekrandaki /// yolla ayni sekilde olusur. /// [McpServerToolType] public sealed class McpDevelopTools(IMcpDevelopAppService developAppService) { [McpServerTool(Name = McpToolNames.GetDevGuide, ReadOnly = true)] [Description("Ekran ve bilesen uretim sozlesmesini okur: wizard alanlari, enum degerleri, editor/lookup/script sozlesmesi, custom component kurallari. section bos ise baslik listesi doner; once listeyi al, sonra ihtiyac duydugun bolumu numarasiyla iste (ornegin 4.2). Rehberde dosya yazmak anlatilan yerlerde dosya yerine bu sunucunun araclarini kullan.")] public async Task GetDevGuideAsync( [Description("'lowcode' (uretim protokolu ve artefakt semalari, varsayilan) ya da 'reference' (JSON kolon sozlesmeleri, tasarimci envanteri).")] string? document = null, [Description("Bolum numarasi (4.2) ya da baslik metninin bir parcasi. Bos birakilirsa baslik listesi doner.")] string? section = null) => await developAppService.GetDevGuideAsync(document, section); [McpServerTool(Name = McpToolNames.CreateTable, Destructive = false, Idempotent = false)] [Description("Ekranin baglanacagi yeni tabloyu SQL Query Manager tablo tasarimcisiyla ayni bicimde olusturur ve script'i seed dosyasina (sql/object) yazar. Id (uniqueidentifier, PK), TenantId ve tam audit kolonlari (CreationTime, CreatorId, LastModificationTime, LastModifierId, IsDeleted, DeletionTime, DeleterId) otomatik eklenir; columns icine yalnizca is kolonlarini yaz. Yalnizca yeni tablo olusturur: tablo varsa reddeder, kolon ekleme/degistirme tablo tasarimcisindan yapilir. SQL Server veri kaynaginda calisir. Ardindan deploy_wizard ile ekrani kur.")] public async Task CreateTableAsync( [Description("Tablo adi; harf/rakam/alt cizgi. Adlandirma icin get_dev_guide'daki tablo onek kuralina uy (ornegin Adm_T_...).")] string tableName, [Description("Is kolonlari. type: nvarchar, nvarchar(MAX), int, bigint, decimal (18,4), float, bit, datetime, datetime2, date, uniqueidentifier, money. maxLength yalnizca nvarchar icin (varsayilan 100). defaultValue: sayi, 'metin' ya da NEWID()/GETDATE()/GETUTCDATE()/SYSUTCDATETIME().")] List columns, [Description("Tam audit kolonlari eklensin mi. Kullanici acikca istemedikce true birak.")] bool fullAudited = true, [Description("TenantId kolonu eklensin mi. Kullanici acikca istemedikce true birak.")] bool multiTenant = true) => await developAppService.CreateTableAsync(new McpCreateTableRequestDto { TableName = tableName, Columns = columns, FullAudited = fullAudited, MultiTenant = multiTenant }); [McpServerTool(Name = McpToolNames.ListWizards, ReadOnly = true)] [Description("Wizard File Manager'daki wizard dosyalarini listeler: dosya adi, ekran kodu, yol (List/Custom), menu yolu ve bagimli wizard'lar.")] public async Task> ListWizardsAsync( [Description("Dosya adi, wizard adi, ekran kodu ya da bilesen adi icinde aranacak metin. Bos birakilabilir.")] string? search = null) => await developAppService.GetWizardsAsync(search); [McpServerTool(Name = McpToolNames.GetWizard, ReadOnly = true)] [Description("Bir wizard seed dosyasini diskteki bicimiyle dondurur (Wizard / ListForm / Fields bolumleri). Var olan bir ekrani degistirmeden once oku.")] public async Task GetWizardAsync( [Description("list_wizards cikisindaki fileName degeri, ornegin 'Tags.json'.")] string fileName) => await developAppService.GetWizardAsync(fileName); [McpServerTool(Name = McpToolNames.DeployWizard, Destructive = true, Idempotent = false)] [Description("Wizard'i deploy eder: ListForm ekrani (ComponentKind 0) ya da bir custom component'i menuye baglayan kayit (ComponentKind 1), yetkileri, dil anahtarlari, menusu ve seed dosyasi birlikte uretilir. Hedef tablo onceden var olmalidir; yoksa once create_table ile olustur. replaceFileName verilirse o wizard ve urettigi kayitlar silinip yeniden uretilir; ekran wizard cevaplarindan yeniden turetildigi icin tasarimcida yapilmis ve wizard'da karsiligi olmayan ayarlar kaybolur. Ne yazacagini get_dev_guide 4. bolumunden ogren.")] public async Task DeployWizardAsync( [Description("Wizard JSON'u: seed dosyasi bicimi ({\"Wizard\": {...}}, get_wizard cikisi gibi) ya da duz wizard cevaplari. Enum alanlari sayi olarak yazilir.")] string wizard, [Description("Guncellemede yerine gecilecek dosyanin adi (list_wizards cikisindaki fileName). Yeni wizard icin bos birak.")] string? replaceFileName = null) => await developAppService.DeployWizardAsync(new McpWizardDeployRequestDto { Wizard = wizard, ReplaceFileName = replaceFileName }); [McpServerTool(Name = McpToolNames.DeleteWizard, Destructive = true, Idempotent = true)] [Description("Bir wizard'i ve yalnizca onun urettigi kayitlari siler; baska yerde kullanilan kayitlar korunur ve raporda gosterilir. Bagimli wizard'i olan bir wizard silinemez, once bagimlilar silinir.")] public async Task DeleteWizardAsync( [Description("Silinecek wizard dosyasinin adi (list_wizards cikisindaki fileName).")] string fileName) => await developAppService.DeleteWizardAsync(fileName); [McpServerTool(Name = McpToolNames.ListComponents, ReadOnly = true)] [Description("Custom component'leri ad, rota ve aciklamasiyla listeler; kod dondurmez. isVisualDesigner true olanlarin kodu tasarimci belgesinden uretilir ve MCP ile degistirilemez.")] public async Task> ListComponentsAsync( [Description("Ad, rota ya da aciklama icinde aranacak metin. Bos birakilabilir.")] string? search = null) => await developAppService.GetComponentsAsync(search); [McpServerTool(Name = McpToolNames.GetComponent, ReadOnly = true)] [Description("Bir custom component'in kodunu, props'unu ve bagimliliklarini dondurur. Degistirmeden once oku.")] public async Task GetComponentAsync( [Description("Bilesenin adi.")] string name) => await developAppService.GetComponentAsync(name); [McpServerTool(Name = McpToolNames.SaveComponent, Destructive = true, Idempotent = true)] [Description("Custom component'i ada gore kaydeder: yoksa ekler, varsa gunceller. Guncellemede verilmeyen alanlar korunur. Kod kurallari ve kullanilabilir kutuphaneler icin get_dev_guide 7. bolumu. Bilesen menude gorunecekse ardindan ComponentKind 1 ile deploy_wizard cagir.")] public async Task SaveComponentAsync( [Description("Bilesenin adi; kimligidir.")] string name, [Description("Bilesenin React kodu. Yeni bilesende zorunlu, guncellemede bos birakilirsa mevcut kod korunur.")] string? code = null, [Description("'/' ile baslayan rota. '/admin/' ile baslamayan rota public sayfa olur. Bos dize rotayi kaldirir, verilmezse mevcut rota korunur.")] string? routePath = null, [Description("Aciklama.")] string? description = null, [Description("Props JSON metni. Tasarimci belgesi (visualDesigner) iceremez.")] string? props = null, [Description("Bagimli bilesen adlarinin JSON dizisi, ornegin [\"PublicHeader\"].")] string? dependencies = null, [Description("Bilesen etkin mi. Yeni bilesende varsayilan true.")] bool? isActive = null) => await developAppService.SaveComponentAsync(new McpComponentSaveRequestDto { Name = name, Code = code, RoutePath = routePath, Description = description, Props = props, Dependencies = dependencies, IsActive = isActive }); [McpServerTool(Name = McpToolNames.DeleteComponent, Destructive = true, Idempotent = false)] [Description("Custom component'i siler. Bilesene bagli bir Custom wizard varsa once delete_wizard ile o silinir.")] public async Task DeleteComponentAsync( [Description("Bilesenin adi.")] string name) => await developAppService.DeleteComponentAsync(name); }