@leonardocrdso/obsidian-mcp 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.js +55 -51
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -6506,6 +6506,7 @@ __export(exports_setup, {
|
|
|
6506
6506
|
loadSavedConfig: () => loadSavedConfig
|
|
6507
6507
|
});
|
|
6508
6508
|
import { writeFileSync, readFileSync, existsSync } from "fs";
|
|
6509
|
+
import { createInterface } from "readline";
|
|
6509
6510
|
import { homedir } from "os";
|
|
6510
6511
|
import { join } from "path";
|
|
6511
6512
|
function loadSavedConfig() {
|
|
@@ -6517,74 +6518,64 @@ function loadSavedConfig() {
|
|
|
6517
6518
|
return null;
|
|
6518
6519
|
}
|
|
6519
6520
|
}
|
|
6520
|
-
function
|
|
6521
|
-
|
|
6521
|
+
function mask(value) {
|
|
6522
|
+
if (value.length <= 8)
|
|
6523
|
+
return "*".repeat(value.length);
|
|
6524
|
+
return value.slice(0, 4) + "*".repeat(value.length - 4);
|
|
6522
6525
|
}
|
|
6523
|
-
function
|
|
6526
|
+
function createPrompt() {
|
|
6524
6527
|
const lines = [];
|
|
6525
6528
|
let waiting = null;
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
if (waiting) {
|
|
6535
|
-
const resolve = waiting;
|
|
6536
|
-
waiting = null;
|
|
6537
|
-
resolve(line.trim());
|
|
6538
|
-
} else {
|
|
6539
|
-
lines.push(line.trim());
|
|
6540
|
-
}
|
|
6529
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
6530
|
+
rl.on("line", (line) => {
|
|
6531
|
+
if (waiting) {
|
|
6532
|
+
const resolve = waiting;
|
|
6533
|
+
waiting = null;
|
|
6534
|
+
resolve(line);
|
|
6535
|
+
} else {
|
|
6536
|
+
lines.push(line);
|
|
6541
6537
|
}
|
|
6542
6538
|
});
|
|
6543
|
-
|
|
6544
|
-
if (
|
|
6539
|
+
rl.on("close", () => {
|
|
6540
|
+
if (waiting) {
|
|
6545
6541
|
const resolve = waiting;
|
|
6546
6542
|
waiting = null;
|
|
6547
|
-
resolve(
|
|
6548
|
-
buffer = "";
|
|
6543
|
+
resolve("");
|
|
6549
6544
|
}
|
|
6550
6545
|
});
|
|
6551
|
-
|
|
6546
|
+
const ask = (label, fallback) => {
|
|
6552
6547
|
const suffix = fallback ? ` [${fallback}]` : "";
|
|
6553
|
-
write(` ${label}${suffix}: `);
|
|
6548
|
+
process.stderr.write(` ${label}${suffix}: `);
|
|
6554
6549
|
if (lines.length > 0) {
|
|
6555
6550
|
const value = lines.shift();
|
|
6556
|
-
write(value + `
|
|
6551
|
+
process.stderr.write(value + `
|
|
6557
6552
|
`);
|
|
6558
|
-
return Promise.resolve(value || fallback || "");
|
|
6553
|
+
return Promise.resolve(value.trim() || fallback || "");
|
|
6559
6554
|
}
|
|
6560
6555
|
return new Promise((resolve) => {
|
|
6561
|
-
waiting = (value) => resolve(value || fallback || "");
|
|
6556
|
+
waiting = (value) => resolve(value.trim() || fallback || "");
|
|
6562
6557
|
});
|
|
6563
6558
|
};
|
|
6564
|
-
}
|
|
6565
|
-
function mask(value) {
|
|
6566
|
-
if (value.length <= 8)
|
|
6567
|
-
return "*".repeat(value.length);
|
|
6568
|
-
return value.slice(0, 4) + "*".repeat(value.length - 4);
|
|
6559
|
+
return { ask, close: () => rl.close() };
|
|
6569
6560
|
}
|
|
6570
6561
|
async function runSetup() {
|
|
6571
6562
|
const existing = loadSavedConfig();
|
|
6572
|
-
const
|
|
6573
|
-
write(`
|
|
6563
|
+
const { ask, close } = createPrompt();
|
|
6564
|
+
process.stderr.write(`
|
|
6574
6565
|
Obsidian MCP — Configuracao
|
|
6575
6566
|
|
|
6576
6567
|
`);
|
|
6577
|
-
const apiKey = await
|
|
6578
|
-
const host = await
|
|
6579
|
-
const port = await
|
|
6580
|
-
const protocol = await
|
|
6581
|
-
|
|
6568
|
+
const apiKey = await ask("API Key", existing?.apiKey ? mask(existing.apiKey) : undefined);
|
|
6569
|
+
const host = await ask("Host", existing?.host ?? "127.0.0.1");
|
|
6570
|
+
const port = await ask("Porta", existing?.port ?? "27124");
|
|
6571
|
+
const protocol = await ask("Protocolo", existing?.protocol ?? "https");
|
|
6572
|
+
close();
|
|
6582
6573
|
if (!apiKey || apiKey.includes("*")) {
|
|
6583
6574
|
if (existing?.apiKey && apiKey.includes("*")) {
|
|
6584
6575
|
saveConfig({ apiKey: existing.apiKey, host, port, protocol });
|
|
6585
6576
|
return;
|
|
6586
6577
|
}
|
|
6587
|
-
write(`
|
|
6578
|
+
process.stderr.write(`
|
|
6588
6579
|
API Key e obrigatoria.
|
|
6589
6580
|
|
|
6590
6581
|
`);
|
|
@@ -6594,13 +6585,13 @@ async function runSetup() {
|
|
|
6594
6585
|
}
|
|
6595
6586
|
function saveConfig(config2) {
|
|
6596
6587
|
writeFileSync(CONFIG_PATH, JSON.stringify(config2, null, 2));
|
|
6597
|
-
write(`
|
|
6588
|
+
process.stderr.write(`
|
|
6598
6589
|
Configuracao salva em ${CONFIG_PATH}
|
|
6599
6590
|
`);
|
|
6600
|
-
write(`
|
|
6591
|
+
process.stderr.write(`
|
|
6601
6592
|
Adicione ao Claude Code:
|
|
6602
6593
|
`);
|
|
6603
|
-
write(` claude mcp add obsidian -- npx @leonardocrdso/obsidian-mcp
|
|
6594
|
+
process.stderr.write(` claude mcp add obsidian -- npx @leonardocrdso/obsidian-mcp
|
|
6604
6595
|
|
|
6605
6596
|
`);
|
|
6606
6597
|
}
|
|
@@ -19608,9 +19599,10 @@ var STATUS_MESSAGES = {
|
|
|
19608
19599
|
};
|
|
19609
19600
|
function formatObsidianError(error2) {
|
|
19610
19601
|
if (error2 instanceof ObsidianApiError) {
|
|
19611
|
-
const
|
|
19602
|
+
const isInvalidTarget = error2.statusCode === 400 && error2.message.includes("invalid-target");
|
|
19603
|
+
const baseMessage = isInvalidTarget ? "O alvo (heading, block ou frontmatter) não foi encontrado no arquivo. Verifique se o nome existe exatamente como especificado, ou use createTargetIfMissing: true." : STATUS_MESSAGES[error2.statusCode] ?? "Erro inesperado na API do Obsidian.";
|
|
19612
19604
|
const parts = [`[${error2.statusCode}] ${baseMessage}`];
|
|
19613
|
-
if (error2.message)
|
|
19605
|
+
if (!isInvalidTarget && error2.message)
|
|
19614
19606
|
parts.push(`Detalhe: ${error2.message}`);
|
|
19615
19607
|
return parts.join(`
|
|
19616
19608
|
`);
|
|
@@ -19775,19 +19767,23 @@ function registerVaultTools(server, client) {
|
|
|
19775
19767
|
targetType: exports_external.enum(["heading", "block", "frontmatter"]).describe("Tipo do alvo: heading, block ou frontmatter"),
|
|
19776
19768
|
target: exports_external.string().describe("Identificador do alvo (nome do heading, ID do block, ou chave do frontmatter)"),
|
|
19777
19769
|
targetDelimiter: exports_external.string().optional().describe("Delimitador para separar conteúdo inserido (ex: '\\n')"),
|
|
19778
|
-
trimTargetWhitespace: exports_external.boolean().optional().describe("Remover espaços do target antes de comparar")
|
|
19770
|
+
trimTargetWhitespace: exports_external.boolean().optional().describe("Remover espaços do target antes de comparar"),
|
|
19771
|
+
createTargetIfMissing: exports_external.boolean().optional().describe("Criar o alvo se não existir no arquivo")
|
|
19779
19772
|
}, safeTool(async (params) => {
|
|
19780
19773
|
const headers = {
|
|
19781
19774
|
"Content-Type": "text/markdown",
|
|
19782
19775
|
Operation: params.operation,
|
|
19783
19776
|
"Target-Type": params.targetType,
|
|
19784
|
-
Target: params.target
|
|
19777
|
+
Target: encodeURIComponent(params.target)
|
|
19785
19778
|
};
|
|
19786
19779
|
if (params.targetDelimiter)
|
|
19787
19780
|
headers["Target-Delimiter"] = params.targetDelimiter;
|
|
19788
19781
|
if (params.trimTargetWhitespace !== undefined) {
|
|
19789
19782
|
headers["Trim-Target-Whitespace"] = String(params.trimTargetWhitespace);
|
|
19790
19783
|
}
|
|
19784
|
+
if (params.createTargetIfMissing !== undefined) {
|
|
19785
|
+
headers["Create-Target-If-Missing"] = String(params.createTargetIfMissing);
|
|
19786
|
+
}
|
|
19791
19787
|
await client.fetchVoid(`/vault/${client.encodePath(params.path)}`, {
|
|
19792
19788
|
method: "PATCH",
|
|
19793
19789
|
headers,
|
|
@@ -19922,19 +19918,23 @@ function registerActiveFileTools(server, client) {
|
|
|
19922
19918
|
targetType: exports_external.enum(["heading", "block", "frontmatter"]).describe("Tipo do alvo: heading, block ou frontmatter"),
|
|
19923
19919
|
target: exports_external.string().describe("Identificador do alvo"),
|
|
19924
19920
|
targetDelimiter: exports_external.string().optional().describe("Delimitador para separar conteúdo inserido"),
|
|
19925
|
-
trimTargetWhitespace: exports_external.boolean().optional().describe("Remover espaços do target antes de comparar")
|
|
19921
|
+
trimTargetWhitespace: exports_external.boolean().optional().describe("Remover espaços do target antes de comparar"),
|
|
19922
|
+
createTargetIfMissing: exports_external.boolean().optional().describe("Criar o alvo se não existir no arquivo")
|
|
19926
19923
|
}, safeTool(async (params) => {
|
|
19927
19924
|
const headers = {
|
|
19928
19925
|
"Content-Type": "text/markdown",
|
|
19929
19926
|
Operation: params.operation,
|
|
19930
19927
|
"Target-Type": params.targetType,
|
|
19931
|
-
Target: params.target
|
|
19928
|
+
Target: encodeURIComponent(params.target)
|
|
19932
19929
|
};
|
|
19933
19930
|
if (params.targetDelimiter)
|
|
19934
19931
|
headers["Target-Delimiter"] = params.targetDelimiter;
|
|
19935
19932
|
if (params.trimTargetWhitespace !== undefined) {
|
|
19936
19933
|
headers["Trim-Target-Whitespace"] = String(params.trimTargetWhitespace);
|
|
19937
19934
|
}
|
|
19935
|
+
if (params.createTargetIfMissing !== undefined) {
|
|
19936
|
+
headers["Create-Target-If-Missing"] = String(params.createTargetIfMissing);
|
|
19937
|
+
}
|
|
19938
19938
|
await client.fetchVoid("/active/", {
|
|
19939
19939
|
method: "PATCH",
|
|
19940
19940
|
headers,
|
|
@@ -19998,19 +19998,23 @@ function registerPeriodicTools(server, client) {
|
|
|
19998
19998
|
targetType: exports_external.enum(["heading", "block", "frontmatter"]).describe("Tipo do alvo: heading, block ou frontmatter"),
|
|
19999
19999
|
target: exports_external.string().describe("Identificador do alvo"),
|
|
20000
20000
|
targetDelimiter: exports_external.string().optional().describe("Delimitador para separar conteúdo inserido"),
|
|
20001
|
-
trimTargetWhitespace: exports_external.boolean().optional().describe("Remover espaços do target antes de comparar")
|
|
20001
|
+
trimTargetWhitespace: exports_external.boolean().optional().describe("Remover espaços do target antes de comparar"),
|
|
20002
|
+
createTargetIfMissing: exports_external.boolean().optional().describe("Criar o alvo se não existir no arquivo")
|
|
20002
20003
|
}, safeTool(async (params) => {
|
|
20003
20004
|
const headers = {
|
|
20004
20005
|
"Content-Type": "text/markdown",
|
|
20005
20006
|
Operation: params.operation,
|
|
20006
20007
|
"Target-Type": params.targetType,
|
|
20007
|
-
Target: params.target
|
|
20008
|
+
Target: encodeURIComponent(params.target)
|
|
20008
20009
|
};
|
|
20009
20010
|
if (params.targetDelimiter)
|
|
20010
20011
|
headers["Target-Delimiter"] = params.targetDelimiter;
|
|
20011
20012
|
if (params.trimTargetWhitespace !== undefined) {
|
|
20012
20013
|
headers["Trim-Target-Whitespace"] = String(params.trimTargetWhitespace);
|
|
20013
20014
|
}
|
|
20015
|
+
if (params.createTargetIfMissing !== undefined) {
|
|
20016
|
+
headers["Create-Target-If-Missing"] = String(params.createTargetIfMissing);
|
|
20017
|
+
}
|
|
20014
20018
|
await client.fetchVoid(`/periodic/${params.period}/`, {
|
|
20015
20019
|
method: "PATCH",
|
|
20016
20020
|
headers,
|