feat(worker): add external MCP list-management tools
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
72
src/ClaudeDo.Worker/External/ListMcpTools.cs
vendored
Normal file
72
src/ClaudeDo.Worker/External/ListMcpTools.cs
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
using System.ComponentModel;
|
||||
using ClaudeDo.Data.Models;
|
||||
using ClaudeDo.Data.Repositories;
|
||||
using ClaudeDo.Worker.Hub;
|
||||
using ModelContextProtocol.Server;
|
||||
|
||||
namespace ClaudeDo.Worker.External;
|
||||
|
||||
public sealed record ListSummaryDto(string Id, string Name, string? WorkingDir, string DefaultCommitType);
|
||||
|
||||
[McpServerToolType]
|
||||
public sealed class ListMcpTools
|
||||
{
|
||||
private readonly ListRepository _lists;
|
||||
private readonly HubBroadcaster _broadcaster;
|
||||
|
||||
public ListMcpTools(ListRepository lists, HubBroadcaster broadcaster)
|
||||
{
|
||||
_lists = lists;
|
||||
_broadcaster = broadcaster;
|
||||
}
|
||||
|
||||
[McpServerTool, Description("Create a new task list. workingDir sets the git repo tasks run against; commitType defaults to 'chore'.")]
|
||||
public async Task<ListSummaryDto> CreateList(
|
||||
string name, string? workingDir, string? commitType, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
throw new InvalidOperationException("name is required.");
|
||||
|
||||
var entity = new ListEntity
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Name = name,
|
||||
WorkingDir = string.IsNullOrWhiteSpace(workingDir) ? null : workingDir,
|
||||
DefaultCommitType = string.IsNullOrWhiteSpace(commitType) ? CommitTypeRegistry.DefaultType : commitType,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
};
|
||||
await _lists.AddAsync(entity, cancellationToken);
|
||||
await _broadcaster.ListUpdated(entity.Id);
|
||||
return ToDto(entity);
|
||||
}
|
||||
|
||||
[McpServerTool, Description("Rename a list and/or change its working dir and default commit type. Pass null to leave a field unchanged.")]
|
||||
public async Task<ListSummaryDto> UpdateList(
|
||||
string listId, string? name, string? workingDir, string? commitType, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await _lists.GetByIdAsync(listId, cancellationToken)
|
||||
?? throw new InvalidOperationException($"List {listId} not found.");
|
||||
|
||||
if (name is not null) entity.Name = name;
|
||||
if (workingDir is not null)
|
||||
entity.WorkingDir = string.IsNullOrWhiteSpace(workingDir) ? null : workingDir;
|
||||
if (commitType is not null)
|
||||
entity.DefaultCommitType = string.IsNullOrWhiteSpace(commitType) ? CommitTypeRegistry.DefaultType : commitType;
|
||||
|
||||
await _lists.UpdateAsync(entity, cancellationToken);
|
||||
await _broadcaster.ListUpdated(listId);
|
||||
return ToDto(entity);
|
||||
}
|
||||
|
||||
[McpServerTool, Description("Delete a list and its tasks. Irreversible.")]
|
||||
public async Task DeleteList(string listId, CancellationToken cancellationToken)
|
||||
{
|
||||
_ = await _lists.GetByIdAsync(listId, cancellationToken)
|
||||
?? throw new InvalidOperationException($"List {listId} not found.");
|
||||
await _lists.DeleteAsync(listId, cancellationToken);
|
||||
await _broadcaster.ListUpdated(listId);
|
||||
}
|
||||
|
||||
private static ListSummaryDto ToDto(ListEntity l) =>
|
||||
new(l.Id, l.Name, l.WorkingDir, l.DefaultCommitType);
|
||||
}
|
||||
Reference in New Issue
Block a user