using System.Text.Json;
using NewLife;
using NewLife.Data;
using Stardust.Data.Nodes;
using XCode;
using Stardust.Data.Platform;
namespace Stardust.Web.Mcp.Actions.Nodes;
/// <summary>æœç´¢èŠ‚ç‚¹ã€‚æ”¯æŒæŒ‰åç§°/ç¼–ç /IP/æœºå™¨åæœç´¢ï¼ŒæŒ‰Token授æƒé¡¹ç›®è¿‡æ»¤</summary>
public class NodeSearchAction : McpActionBase
{
/// <summary>动作å</summary>
public override String Name => "node_search";
/// <summary>动作æè¿°</summary>
public override String Description => "æŒ‰å…³é”®å—æœç´¢èŠ‚ç‚¹ï¼ˆåŒ¹é…åç§°/ç¼–ç /IP/机器å),返回Token授æƒé¡¹ç›®èŒƒå›´å†…的匹é…节点。";
/// <summary>所属模å—</summary>
public override McpModuleType Module => McpModuleType.Node;
/// <summary>è¾“å…¥å‚æ•°JSON Schema</summary>
public override JsonElement InputSchema
{
get
{
var json = """
{
"type": "object",
"properties": {
"keyword": {"type": "string", "description": "æœç´¢å…³é”®å—(匹é…åç§°/ç¼–ç /IP/机器å)"},
"project_id": {"type": "integer", "description": "å¯é€‰ï¼ŒæŒ‰é¡¹ç›®è¿‡æ»¤"},
"page": {"type": "integer", "description": "页ç ,默认1"},
"page_size": {"type": "integer", "description": "æ¯é¡µæ¡æ•°ï¼Œé»˜è®¤20,最大100"}
},
"required": ["keyword"]
}
""";
using var doc = JsonDocument.Parse(json);
return doc.RootElement.Clone();
}
}
/// <summary>调用动作</summary>
public override Task<Object> InvokeAsync(JsonElement @params, McpContext context)
{
var keyword = GetString(@params, "keyword");
if (keyword.IsNullOrEmpty()) throw new McpException(-32602, "Invalid params: keyword is empty");
var projectId = GetInt32(@params, "project_id");
var page = GetInt32(@params, "page"); if (page <= 0) page = 1;
var pageSize = GetInt32(@params, "page_size"); if (pageSize <= 0) pageSize = 20; if (pageSize > 100) pageSize = 100;
var authorizedProjectIds = Stardust.Data.Platform.McpTokenResource.GetAuthorizedProjectIds(context.TokenId);
if (projectId > 0 && authorizedProjectIds != null && !authorizedProjectIds.Contains(projectId))
throw new McpException(-32003, $"Forbidden: project_id={projectId} is not authorized for this token");
// æž„é€ æŸ¥è¯¢è¡¨è¾¾å¼ï¼šå…³é”®å—åŒ¹é… Code/Name/IP/MachineName
var exp = new WhereExpression();
exp &= Node._.Code.Contains(keyword) |
Node._.Name.Contains(keyword) |
Node._.IP.Contains(keyword) |
Node._.MachineName.Contains(keyword);
// 项目过滤
if (projectId > 0)
exp &= Node._.ProjectId == projectId;
else if (authorizedProjectIds != null)
exp &= Node._.ProjectId.In(authorizedProjectIds);
var pageParam = new PageParameter { PageIndex = page, PageSize = pageSize };
var list = Node.FindAll(exp, pageParam);
var records = list.Select(n => new
{
id = n.ID,
project_id = n.ProjectId,
name = n.Name,
code = n.Code,
ip = n.IP,
category = n.Category,
enable = n.Enable,
version = n.Version,
machine_name = n.MachineName,
last_active = n.LastActive,
}).ToList();
return Task.FromResult<Object>(new
{
total = pageParam.TotalCount,
page,
page_size = pageSize,
records,
});
}
}
|