Files
obsidian-mcp/Tools/ListFilesTool.cs
T
zhengchen.tao 515763bc72
Build Docker Image / build (push) Failing after 1m22s
Initial public release
MCP (Model Context Protocol) server for reading and writing an Obsidian
vault, gated by OAuth-issued JWT bearer tokens. See README.md for setup.
2026-05-17 23:55:00 +08:00

55 lines
1.9 KiB
C#

using System.ComponentModel;
using ModelContextProtocol.Server;
using ObsidianMcp.Auth;
using ObsidianMcp.Services;
namespace ObsidianMcp.Tools;
[McpServerToolType]
public class ListFilesTool(VaultPathResolver resolver, IHttpContextAccessor http)
{
[McpServerTool]
[Description(
"List files and immediate subdirectories in a vault directory. " +
"Returns a flat list of names (not full paths). " +
"Use list_vault_tree for a recursive overview, or this tool to drill into one directory. " +
"Hidden directories (.obsidian, .git, .trash) and any path configured in Vault__Blacklist are excluded.")]
public List<string> ListFiles(
[Description("Vault-relative path to list. Defaults to root if omitted. " +
"e.g. 'Notes', 'Projects/logs'")] string? path = null)
{
ToolScopeGuard.EnsureScope(http, ScopePolicies.ReadObsidian);
string absDir;
if (string.IsNullOrWhiteSpace(path))
{
absDir = resolver.VaultRoot;
}
else
{
absDir = resolver.Resolve(path);
}
if (!Directory.Exists(absDir))
throw new DirectoryNotFoundException($"目录不存在:{path}");
var result = new List<string>();
// 子目录(排除隐藏目录;黑名单目录在尝试访问时由 VaultPathResolver 拦截)
foreach (var dir in Directory.GetDirectories(absDir).OrderBy(Path.GetFileName, StringComparer.OrdinalIgnoreCase))
{
var seg = Path.GetFileName(dir)!;
if (seg.StartsWith('.')) continue;
result.Add(seg + "/");
}
// 文件
foreach (var file in Directory.GetFiles(absDir).OrderBy(Path.GetFileName, StringComparer.OrdinalIgnoreCase))
{
result.Add(Path.GetFileName(file));
}
return result;
}
}