소스 정보
- 저장소
- treylom/knowledge-manager
- 최근 소스 활동
- 2026년 8월 25일 19:26
- 감지된 SKILL.md 언어
- 영어
- 스타
- 227
- 포크
- 49
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/treylom/knowledge-manager --skill km-storage-abstraction명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
vault 통합 검색 — GraphRAG(있으면) → Obsidian CLI → (Obsidian MCP) → 텍스트 검색 4단계 자동 폴백. quick(즉답)/deep(분석) 자동 라우팅
6-phase workflow for content extraction, analysis, and export to Obsidian/Notion
Content extraction routing for KM - local documents (HWP/HWPX/PDF/DOCX/XLSX), web, and vault sources. Use when input is a local file or when km-workflow reaches Phase 2 with a non-URL input.
SKILL.md 표시 중
| name | km-storage-abstraction |
| description | Unified storage interface for Obsidian, Notion, and local file systems |
Unified interface for saving notes across different storage backends
function get_storage_backend(options = {}) {
config = Read("km-config.json") || {}
if (options.explicit_backend) return options.explicit_backend
if (options.project_scoped) return "local"
return config?.storage?.primary || "local"
}
For project-scoped file saves, the workflow must pass target_root. The backend may choose a tool, but it must not choose or redirect the destination root.
Priority: user-explicit destination/backend → host-provided primary project/workspace root → configured backend only outside project-scoped requests.
┌─────────────────────────────────────────────────────┐
│ 🛑 CRITICAL: target_root 보존 강제 │
│ │
│ Obsidian 도구는 연결 볼트와 target_root가 같을 때만! │
│ │
│ ❌ 잘못된 예: │
│ - 연결 볼트 확인 없이 MCP로 상대경로 저장 │
│ │
│ ✅ 올바른 예: │
│ - roots 동일 → MCP / 다름·미확인 → target_root Write│
└─────────────────────────────────────────────────────┘
| Feature | Obsidian | Notion | Local |
|---|---|---|---|
| Create | mcp_obsidian_create_note | mcp_notion_API-post-page | write_to_file |
| Search | mcp_obsidian_search_vault | mcp_notion_API-post-search | N/A |
| Read | mcp_obsidian_read_note | mcp_notion_API-get-block-children | read_file |
| Path format | Relative to vault | Database/Page ID | File system path |
| Wikilinks | Supported | Converted to mentions | Supported |
참고: Antigravity는 MCP 도구 이름에 싱글 언더스코어(
_)를 사용합니다.
| 작업 | 도구명 | 설명 |
|---|---|---|
| 노트 생성 | mcp_obsidian_create_note | 새 노트 생성 |
| 노트 검색 | mcp_obsidian_search_vault | Vault 내 키워드 검색 |
| 노트 읽기 | mcp_obsidian_read_note | 노트 내용 읽기 |
| 노트 목록 | mcp_obsidian_list_notes | 폴더 내 노트 목록 |
function canonical(path) {
return realpath(path)
}
function same_path(left, right) {
return canonical(left) === canonical(right)
}
function resolve_within(canonical_root, relativePath) {
current = canonical_root
for (component of dirname(relativePath).split('/')) {
next = join(current, component)
if (!exists(next)) mkdir(next)
current = canonical(next) // resolve every existing symlink component
assert(is_within(current, canonical_root))
}
return join(current, basename(relativePath))
}
function save_note(relativePath, content, options = {}) {
config = Read("km-config.json") || {}
backend = get_storage_backend(options)
target_root = options.target_root
if (options.project_scoped && !target_root) {
throw new Error("target_root is required for a project-scoped save")
}
canonical_target_root = target_root ? canonical(target_root) :
safe_relative_path = (relativePath)
((safe_relative_path) || (safe_relative_path)) {
()
}
target_candidate = options.
? (canonical_target_root, safe_relative_path)
:
() {
((target_candidate, canonical_target_root))
result = (target_candidate, content)
{ ...result, : target_candidate }
}
(backend) {
:
obsidian_root = config?.?.?. || ()
(options. && (!obsidian_root || !(obsidian_root, canonical_target_root))) {
result = ()
}
result = ({
: safe_relative_path,
: content
})
result. = options.
? target_candidate
: ((obsidian_root), safe_relative_path)
:
(options. && options. !== ) {
result = ()
}
({
: { : config... },
: { : [{ : { : (relativePath) } }] }
})
:
:
(options.) {
result = ()
} {
outputPath = config?.?.?. ||
fullPath =
result = (fullPath, content)
result. = fullPath
}
}
actual_saved_path = (result.)
((actual_saved_path))
(options. && !(actual_saved_path, canonical_target_root)) {
()
}
{ ...result, actual_saved_path }
}
function normalize_path(path) {
// Windows backslash → forward slash
path = path.replace(/\\/g, '/')
// Remove leading slash for relative paths
path = path.replace(/^\//, '')
return path
}
After every save operation:
□ Did the tool actually execute? (no JSON-only output!)
□ Did we receive a success response?
□ Is actual_saved_path canonicalized and does the file exist there?
□ For a project-scoped save, is actual_saved_path inside canonical_target_root?
□ Does the final report include target_root, relative path, and actual_saved_path?