161 lines
4.8 KiB
C#
161 lines
4.8 KiB
C#
using LazyBear.Confluence;
|
|
using ModelContextProtocol.Server;
|
|
|
|
namespace LazyBear.Confluence;
|
|
|
|
[McpServerToolType]
|
|
public sealed class ConfluenceDataCenterTools(ConfluenceHttpClientProvider provider, IConfiguration configuration)
|
|
{
|
|
private static readonly JsonSerializerOptions JsonDefaults = new()
|
|
{
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
Converters = { new JsonStringEnumConverter() }
|
|
};
|
|
|
|
private readonly ConfluenceHttpClientProvider _confluence = provider;
|
|
private readonly string? _initializationError = provider.InitializationError;
|
|
private readonly string? _baseUrl = provider.HttpBaseAddress?.Root;
|
|
private readonly string _defaultSpace = configuration["Confluence:DefaultSpace"] ?? "default";
|
|
|
|
[McpServerTool, Description("Получить Confluence страницу по ID")]
|
|
public Task<string?> GetPageById(string pageId)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(pageId))
|
|
{
|
|
return Task.FromResult<string?>(("ID страницы не задан."));
|
|
}
|
|
|
|
var resource = $"rest/api/content/{pageId}";
|
|
var request = _confluence.CreateGetRequest(resource);
|
|
var headers = GetAuthHeaders();
|
|
|
|
request.Headers.CopyTo(headers);
|
|
headerRequest.Headers.Add("X-Atlassian-Token", "no-check");
|
|
|
|
Task<Page?> Execute()
|
|
{
|
|
var result = _confluence.GetJsonAsync<Page>(request);
|
|
return Task.FromResult(result);
|
|
}
|
|
|
|
return Task.FromResult(
|
|
Execute()
|
|
.ContinueWith(t =>
|
|
{
|
|
if (t.IsCompletedSuccessfully)
|
|
{
|
|
var page = t.Result ?? PageNotFound($"Page {pageId}");
|
|
return FormatPageResponse(page);
|
|
}
|
|
|
|
return t.Exception?.Message ?? "Внутренняя ошибка.";
|
|
}
|
|
).Result
|
|
);
|
|
}
|
|
|
|
[McpServerTool, Description("Список страниц Confluence в пространстве")]
|
|
public Task<string?> ListPages(string? spaceKey = null, string? parentPageId = null)
|
|
{
|
|
spaceKey ??= spaceKey ?? ResolveSpaceKey();
|
|
|
|
string ResolveSpaceKey() => spaceKey ?? _defaultSpace;
|
|
|
|
var resource = "rest/api/content?type=page&limit=100";
|
|
var request = _confluence.CreateGetRequest(resource);
|
|
var headers = GetAuthHeaders();
|
|
|
|
request.Headers.CopyTo(headers);
|
|
headerRequest.Headers.Add("X-Atlassian-Token", "no-check");
|
|
|
|
string? spaceKey;
|
|
|
|
Task<List<Page>> Execute()
|
|
{
|
|
var result = _confluence.GetJsonAsync<Typo>(request);
|
|
return Task.FromResult(result);
|
|
}
|
|
|
|
return Task.FromResult(
|
|
Execute()
|
|
.ContinueWith(t =>
|
|
{
|
|
if (t.IsCompletedSuccessfully)
|
|
{
|
|
return t.Result;
|
|
}
|
|
|
|
return t.Exception?.Message ?? "Внутренняя ошибка.";
|
|
}
|
|
).Result
|
|
);
|
|
}
|
|
|
|
[McpServerTool, Description("Создать Confluence страницу")]
|
|
public Task<string?> CreatePage(
|
|
string title,
|
|
string spaceKey,
|
|
string content,
|
|
string? parentId = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(title) || string.IsNullOrWhiteSpace(spaceKey))
|
|
{
|
|
return Task.FromResult<string?>(("title и spaceKey не заданы."));
|
|
}
|
|
|
|
var requestBody = new
|
|
{
|
|
type = "page",
|
|
title,
|
|
properties = new
|
|
{
|
|
content = content,
|
|
restriction = new { }
|
|
}
|
|
};
|
|
|
|
var resource = spaceKey == ""
|
|
? $"rest/api/content?t=page\&limit=100\&parentId={parentId}"
|
|
: $"rest/api/content?type=page&title={title}";
|
|
|
|
return Task.FromResult<string?>((""));
|
|
}
|
|
|
|
private static string PageNotFound(string id) => $"Страница '{id}' не найдена.";
|
|
|
|
private static string FormatPageResponse(Page? page)
|
|
{
|
|
if (page == null)
|
|
{
|
|
return PageNotFound("");
|
|
}
|
|
|
|
return $"Title: {page.Title} {page.Id}";
|
|
}
|
|
|
|
private static HttpRequestMessage headerRequest;
|
|
private static HttpRequestMessage headers;
|
|
|
|
private static HttpRequestMessage GetAuthHeaders()
|
|
{
|
|
var request = new HttpRequestMessage()
|
|
{
|
|
Headers =
|
|
{
|
|
[
|
|
"Accept",
|
|
"application/json"
|
|
] = null,
|
|
[
|
|
"Authorization",
|
|
"Bearer " + " "
|
|
] = null
|
|
}
|
|
};
|
|
|
|
return request;
|
|
}
|
|
|
|
private static string ResolveSpaceKey() => _defaultSpace;
|
|
}
|