obsidian_post_active
Append Markdown content to the active note in Obsidian using the Local REST API. Ideal for quickly adding notes or data without switching contexts.
Instructions
Append Markdown to the currently active note through Local REST API.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes |
Implementation Reference
- src/tools.ts:1215-1220 (handler)Registration and handler for obsidian_post_active tool. It calls obsidianRestRequest with POST method to /active/ endpoint, sending the content as text/markdown to append Markdown to the currently active note via the Obsidian Local REST API.
tool( "obsidian_post_active", "Append Markdown to the currently active note through Local REST API.", { content: z.string() }, async (args) => obsidianRestRequest(config, { method: "POST", path: "/active/", body: args.content, contentType: "text/markdown" }), ); - src/tools.ts:1218-1218 (schema)Schema for the tool: requires a single string parameter 'content' validated by Zod.
{ content: z.string() }, - src/tools.ts:1215-1220 (registration)Registration via the local 'tool' function on line 41-60, which wraps server.tool from the MCP SDK.
tool( "obsidian_post_active", "Append Markdown to the currently active note through Local REST API.", { content: z.string() }, async (args) => obsidianRestRequest(config, { method: "POST", path: "/active/", body: args.content, contentType: "text/markdown" }), ); - src/rest.ts:11-62 (helper)The underlying helper function that makes the actual HTTP POST request to the Obsidian Local REST API. It handles auth headers, content-type, timeout, and response parsing.
export async function obsidianRestRequest(config: ObsidianMcpConfig, options: RestRequestOptions): Promise<{ status: number; ok: boolean; contentType: string; body: unknown; }> { if (!config.restApiKey) throw new Error("OBSIDIAN_API_KEY is not configured"); if (config.restInsecureTls) process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; const url = new URL(options.path.replace(/^\/+/, ""), `${config.restUrl.replace(/\/+$/, "")}/`); const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), options.timeoutMs ?? 15000); try { const headers: Record<string, string> = { Authorization: `Bearer ${config.restApiKey}`, }; let body: string | undefined; if (options.body !== undefined) { if (typeof options.body === "string") { body = options.body; headers["Content-Type"] = options.contentType ?? "text/markdown"; } else { body = JSON.stringify(options.body); headers["Content-Type"] = options.contentType ?? "application/json"; } } const response = await fetch(url, { method: options.method ?? "GET", headers, body, signal: controller.signal, }); const contentType = response.headers.get("content-type") ?? ""; const text = await response.text(); let parsed: unknown = text; if (contentType.includes("application/json")) { try { parsed = JSON.parse(text); } catch { parsed = text; } } return { status: response.status, ok: response.ok, contentType, body: parsed }; } finally { clearTimeout(timeout); } } export async function getRestText(config: ObsidianMcpConfig, path: string): Promise<string> { const response = await obsidianRestRequest(config, { path }); if (!response.ok) throw new Error(`Obsidian REST returned ${response.status}: ${String(response.body)}`); return typeof response.body === "string" ? response.body : JSON.stringify(response.body); }