import { VaultResolver } from '../core/vault-resolver.js';
import { VaultManager } from '../core/vault-manager.js';
import { OperationRouter } from '../core/operation-router.js';
export class MCPTools {
constructor(
private vaultResolver: VaultResolver,
private vaultManager: VaultManager,
private operationRouter: OperationRouter
) {}
async listVaults(): Promise<any> {
const config = (this.vaultResolver as any).config;
const basePath = config.defaultVaultPath;
if (!basePath) {
return { vaults: [] };
}
const vaults = await this.vaultManager.discoverVaults(basePath);
return {
vaults: vaults.map((v) => ({
name: v.name,
path: v.path,
hasRestApi: v.hasRestApi,
pluginVersion: v.pluginVersion,
fileCount: v.fileCount,
})),
};
}
async getVaultInfo(vaultIdentifier: string): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
const info = await this.vaultManager.getVaultInfo(resolved.path);
return {
...info,
resolvedAs: resolved.resolvedAs,
};
}
async listFiles(
vaultIdentifier: string,
path?: string,
recursive?: boolean,
includeHidden?: boolean
): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
const files = await this.operationRouter.execute('list_files', resolved.path, {
path,
recursive,
includeHidden,
});
return { files };
}
async getFile(
vaultIdentifier: string,
filepath: string,
parseFrontmatter?: boolean
): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
const file = await this.operationRouter.execute('get_file', resolved.path, {
filepath,
parseFrontmatter,
});
return file;
}
async writeFile(
vaultIdentifier: string,
filepath: string,
content: string,
frontmatter?: any,
_createDirs?: boolean,
expectedModTime?: string
): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
// If frontmatter provided, prepend it
let finalContent = content;
if (frontmatter) {
const yaml = this.serializeFrontmatter(frontmatter);
finalContent = `---\n${yaml}\n---\n\n${content}`;
}
const modTime = expectedModTime ? new Date(expectedModTime) : undefined;
await this.operationRouter.execute('write_file', resolved.path, {
filepath,
content: finalContent,
expectedModTime: modTime,
});
return { success: true, path: filepath };
}
async appendContent(
vaultIdentifier: string,
filepath: string,
content: string
): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
await this.operationRouter.execute('append_content', resolved.path, {
filepath,
content,
});
return { success: true };
}
async searchFiles(
vaultIdentifier: string,
query: string,
path?: string,
caseSensitive?: boolean,
regex?: boolean,
contextLength?: number
): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
const results = await this.operationRouter.execute('search_files', resolved.path, {
query,
path,
caseSensitive,
regex,
contextLength: contextLength || 50,
});
return { results };
}
async getMetadata(vaultIdentifier: string, filepath: string): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
const metadata = await this.operationRouter.execute('get_metadata', resolved.path, {
filepath,
});
return metadata;
}
async executeCommand(
vaultIdentifier: string,
commandId: string,
args?: any
): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
const result = await this.operationRouter.execute('execute_command', resolved.path, {
commandId,
args,
});
return result || { success: true };
}
async openFile(vaultIdentifier: string, filepath: string): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
await this.operationRouter.execute('open_file', resolved.path, {
filepath,
});
return { success: true };
}
async getActiveFile(vaultIdentifier: string): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
const file = await this.operationRouter.execute('get_active_file', resolved.path, {});
return file || { content: null };
}
async openGraph(vaultIdentifier: string): Promise<any> {
const resolved = await this.vaultResolver.resolve(vaultIdentifier);
await this.operationRouter.execute('open_graph', resolved.path, {});
return { success: true };
}
private serializeFrontmatter(data: any): string {
const lines: string[] = [];
for (const [key, value] of Object.entries(data)) {
if (typeof value === 'string') {
lines.push(`${key}: "${value}"`);
} else if (Array.isArray(value)) {
lines.push(`${key}:`);
value.forEach((item) => lines.push(` - ${item}`));
} else {
lines.push(`${key}: ${value}`);
}
}
return lines.join('\n');
}
}