obsidian-mcp-server
Version:
MCP server for Obsidian vaults — read, write, search, and surgically edit notes, tags, and frontmatter via the Local REST API plugin. STDIO or Streamable HTTP.
56 lines • 2.48 kB
TypeScript
/**
* @fileoverview Path-policy enforcement for the Obsidian Local REST API service.
* Single chokepoint for OBSIDIAN_READ_PATHS / OBSIDIAN_WRITE_PATHS / OBSIDIAN_READ_ONLY —
* tools and resources call into the service, the service consults this policy
* before every upstream HTTP call. See issue #40 for the spec.
*
* The policy carries the active scope so error data echoes back which paths
* are allowed; the LLM (or operator) can self-correct without poking at logs.
*
* @module services/obsidian/path-policy
*/
import type { ServerConfig } from '../../config/server-config.js';
export type PathOp = 'read' | 'write';
export type PathForbiddenSubreason = 'outside_read_paths' | 'outside_write_paths' | 'read_only_mode';
/** Wire data shape thrown with `path_forbidden`. */
export interface PathForbiddenData {
activeScope: string[];
op: PathOp;
path: string;
reason: 'path_forbidden';
recovery: {
hint: string;
};
subreason: PathForbiddenSubreason;
}
/**
* Enforces folder-scoped read/write permissions on vault-relative paths.
* Constructed once from validated `ServerConfig`; read paths and write paths
* arrive already lower-cased, trimmed of trailing slashes, and deduplicated by
* the config parser, so matching is a straight prefix-or-equal compare.
*/
export declare class PathPolicy {
#private;
constructor(config: ServerConfig);
/** True when no path policy is active — every op falls through to the upstream. */
get isUnrestricted(): boolean;
/** Snapshot for startup-banner logging. */
describe(): {
readPaths: readonly string[] | 'full vault';
writePaths: readonly string[] | 'full vault' | 'denied (read-only)';
readOnly: boolean;
};
/** True when both READ_ONLY=true and WRITE_PATHS is non-empty (operator should know WRITE_PATHS is ignored). */
get readOnlyShadowsWritePaths(): boolean;
isReadable(path: string): boolean;
isWritable(path: string): boolean;
/** Throws `path_forbidden` if the path is not readable. */
assertReadable(path: string): void;
/** Throws `path_forbidden` if the path is not writable (write tools also implicitly need read access). */
assertWritable(path: string): void;
/** Drop reads outside scope. Used by `obsidian_search_notes` to silently filter. */
filterReadable<T extends {
filename: string;
}>(hits: readonly T[]): T[];
}
//# sourceMappingURL=path-policy.d.ts.map