MCP server for managing Obsidian notes and GitHub repositories, with support for reading, writing, and syncing notes
This server exhibits significant quality gaps across definition, schema, and error handling. While 15 tools are present, most lack proper input validation, comprehensive error guidance, and LLM-optimized descriptions. Naming follows verb_noun convention (positive), but descriptions are often generic or Chinese-language only, making them unsuitable for English-speaking LLM agents. Schemas are partially visible but lack robustness. The server mixes two distinct codebases (index.js with GitHub/Obsidian tools via SSE, server-v2.js with VPS tools via HTTP), creating inconsistency. No tool annotations (readOnlyHint/destructiveHint/idempotentHint) are present despite multiple DESTRUCTIVE operations (vps_shell, github_write_file, sync_note). Error responses provide minimal guidance, raw fetch failures and generic 'Error: ...' messages tell agents nothing about recovery steps. Parameters lack validation constraints (e.g., no enum for optional 'context' in github_read_lines, no bounds on 'timeout' in vps_shell). Output schemas are not documented. Security risks: vps_shell accepts arbitrary bash commands with no filtering or permission gates; GitHub token and repo are environment-injected (good), but the vps_shell tool is essentially a remote code execution endpoint.
在一篇筆記的末尾追加內容,不需要讀取原文
列出任意GitHub repo裡的文件結構
精準修改GitHub repo裡的文件內容,用搜索替換的方式
讀取任意GitHub repo裡的一個文件
只讀取文件的指定行範圍,或按關鍵詞搜索返回匹配行及上下文。比讀整個文件省很多token
寫入或更新任意GitHub repo裡的文件
列出一篇筆記裡的所有標題,用來預覽結構
Descriptions are primarily in Chinese with no English translations. LLM agents operating in English contexts cannot understand what tools do, making tool selection unreliable. Example: 'search_notes' description is '搜索octo的Obsidian筆記,按文件名或路徑關鍵詞查找'. English-language agents will fail to invoke this correctly.
vps_shell tool accepts arbitrary bash commands with no input validation, sandboxing, or permission gates. This is a critical remote code execution vulnerability. Agents can execute 'rm -rf /', delete data, modify system files, or exfiltrate secrets. No dry-run or confirmation pattern is implemented.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 44 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 48 | - | v1 |
列出octo的Obsidian某個資料夾下的所有筆記
讀取octo的一篇Obsidian筆記的完整內容
只讀取筆記裡某個標題下的內容,節省token
搜索octo的Obsidian筆記,按文件名或路徑關鍵詞查找
把内容同步到octo的Obsidian指定路徑,支援markdown格式
Read a file from the VPS
Execute a shell command on the VPS
Write content to a file on the VPS
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) are declared despite 6 WRITE and DESTRUCTIVE operations (sync_note, enrich_note, github_write_file, github_patch_file, vps_shell, vps_write_file). Agents cannot distinguish safe from risky tools without reading descriptions, and descriptions are in Chinese.
Error handling is minimal and unhelpful. Tools return generic 'Error: ...' messages with no guidance on recovery. Example in read_note: 'ok("找不到這個文件:" + path)' provides no hint that the agent should call search_notes or check list_notes. No error classification (retryable vs. fatal) is provided.
Parameter descriptions lack detail and constraints. Example: github_read_lines has 'start_line' ("起始行號(從1開始)") and 'end_line' ("結束行號(包含)") with no type info visible; 'context' defaults to 5 with no min/max bounds stated. Agents cannot validate input format or range before calling.
Output schemas are not documented. Tools return structured results (e.g., list of files, file content), but the LLM has no formal specification of return fields, types, or format. This forces agents to infer structure from examples, risking parsing errors.
Server uses two incompatible transports and tool registration patterns. index.js uses SSEServerTransport (deprecated since 2025-03-26); server-v2.js uses StreamableHTTPServerTransport (current). This creates confusion about which endpoint is canonical and prevents unified client integration.
github_read_lines tool name is ambiguous. 'read_lines' could mean 'retrieve a range' or 'search and return matches'. It actually does both (start_line/end_line OR search). This should be split into two tools: 'github_read_lines_by_range' and 'github_search_lines', or unified with a clear parameter relationship documented.
Parameter 'message' in sync_note and enrich_note defaults to 'veran was here'. This is a commit message default that appears to be a personal stub. It should default to a generic message like 'Update via MCP' or require explicit user input.
No pagination support on list_notes or github_list_files. If a folder contains 100+ items, the API will return all of them, bloating the response and wasting tokens. Tools should accept limit and cursor/offset parameters.
Tools accept arbitrary file paths without validation. Path traversal attacks are possible: calling read_note with path='../../etc/passwd' could read files outside the intended repository. All path parameters must be validated and normalized.