Obsidian笔记服务器

一个安全、高性能的FastMCP服务器,通过模型上下文协议(MCP)提供对Obsidian库的认证访问,支持全文搜索、语义搜索和笔记管理。

  • by k1000
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 k1000/mcp_obsidian

使用说明

MCP黑曜石服务器

一种安全、高性能的FastMCP服务器,通过模型上下文协议(MCP)提供对黑曜石保险库的身份验证访问。

特性

  • 🔒 安全访问:具有速率限制的API密钥身份验证
  • ✏️ 完整的CRUD操作:读取、创建、更新和删除笔记
  • 🔍 强大的搜索功能:带标签和前体过滤的全文搜索
  • 🧠 RAG和语义搜索:具有本地或云嵌入的人工智能语义搜索
  • 🏷️ 标签管理:从笔记中提取、添加和删除标记
  • 🔗 链接跟踪:解析wiki风格的链接并查找反向链接
  • 📊 保险库统计信息:了解您的保险库
  • ⚡ 异步性能:内置异步I/O以获得最佳性能
  • ✅ 输入验证:全面的消毒和安全检查
  • 📝 日志记录和审计:详细的日志记录和审计跟踪
  • 🌐 本地首个RAG:使用Ollama进行完全本地、私有的语义搜索
  • ☁️ 云嵌入:可选的OpenAI、HuggingFace或Cohere集成
  • ✔️ 测试良好:全面的测试套件,覆盖率>80%

快速开始

安装

# Clone the repository
cd mcp_obsidian

# Install dependencies with uv
uv sync

# Install dev dependencies
uv sync --extra dev

配置

  1. 复制示例配置:
cp config/config.example.yaml config/config.yaml
cp .env.example .env
  1. 编辑 config/config.yaml 并设置vault路径:
vault:
  path: '/path/to/your/obsidian/vault'

auth:
  api_keys:
    - 'your-secure-api-key-here'
  1. 或者在中使用环境变量 .env:
OBSIDIAN_VAULT_PATH=/path/to/your/vault
OBSIDIAN_API_KEYS=your-api-key-here

运行服务器

# Run with default config
uv run python -m mcp_obsidian.server

# Or specify a config file
uv run python -m mcp_obsidian.server config/config.yaml

MCP客户端配置

要将此服务器与MCP客户端(如Claude Desktop)一起使用,请将以下内容添加到MCP设置文件中:

基本配置(无RAG)

位置: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)

{
  "mcpServers": {
    "obsidian": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/mcp_obsidian",
        "run",
        "python",
        "-m",
        "mcp_obsidian.server"
      ],
      "env": {
        "OBSIDIAN_VAULT_PATH": "/path/to/your/obsidian/vault",
        "OBSIDIAN_API_KEYS": "your-secure-api-key-here"
      }
    }
  }
}

RAG启用配置(带语义搜索)

使用Olama进行局部嵌入:

{
  "mcpServers": {
    "obsidian": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/mcp_obsidian",
        "run",
        "python",
        "-m",
        "mcp_obsidian.server"
      ],
      "env": {
        "OBSIDIAN_VAULT_PATH": "/path/to/your/obsidian/vault",
        "OBSIDIAN_API_KEYS": "your-secure-api-key-here",
        "OBSIDIAN_RAG__ENABLED": "true",
        "OBSIDIAN_RAG__PROVIDER": "ollama",
        "OBSIDIAN_RAG__PROVIDERS__OLLAMA__BASE_URL": "http://localhost:11434",
        "OBSIDIAN_RAG__PROVIDERS__OLLAMA__MODEL": "nomic-embed-text"
      }
    }
  }
}

对于OpenAI嵌入:

{
  "mcpServers": {
    "obsidian": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/mcp_obsidian",
        "run",
        "python",
        "-m",
        "mcp_obsidian.server"
      ],
      "env": {
        "OBSIDIAN_VAULT_PATH": "/path/to/your/obsidian/vault",
        "OBSIDIAN_API_KEYS": "your-secure-api-key-here",
        "OBSIDIAN_RAG__ENABLED": "true",
        "OBSIDIAN_RAG__PROVIDER": "openai",
        "OBSIDIAN_RAG__PROVIDERS__OPENAI__API_KEY": "sk-your-openai-api-key",
        "OBSIDIAN_RAG__PROVIDERS__OPENAI__MODEL": "text-embedding-3-small"
      }
    }
  }
}

使用配置文件

或者,您可以使用YAML配置文件:

{
  "mcpServers": {
    "obsidian": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/mcp_obsidian",
        "run",
        "python",
        "-m",
        "mcp_obsidian.server",
        "/path/to/config.yaml"
      ]
    }
  }
}

💡 如果将所有设置存储在 config/config.yaml (或设置 OBSIDIAN_CONFIG_PATH),你可以放下 env 完全阻塞——服务器将从配置文件中读取所有内容。

最小MCP配置(无参数/env)

您是否希望将Claude/VS Code MCP条目保持在最低限度?使用辅助启动器并省略两者 args 和 env:

{
  "mcpServers": {
    "obsidian": {
      "command": "/path/to/mcp_obsidian/scripts/run_server.sh"
    }
  }
}

scripts/run_server.sh 自动地 cds进入repo并开始 uv run python -m mcp_obsidian.server,通过 config/config.yaml 当它存在时。要将脚本指向另一个配置,请使用以下命令调用它 --config /path/to/custom.yaml (添加一个 args 仅当您需要从MCP客户端转发这些标志时才阻止)。

示例 config.yaml 与RAG:

vault:
  path: '/path/to/your/obsidian/vault'

auth:
  enabled: true
  api_keys:
    - 'your-secure-api-key-here'

rag:
  enabled: true
  provider: 'ollama'  # or 'openai', 'huggingface', 'cohere'

  providers:
    ollama:
      base_url: 'http://localhost:11434'
      model: 'nomic-embed-text'
      timeout: 30

    openai:
      api_key: 'sk-your-api-key'
      model: 'text-embedding-3-small'

  vector_store: 'chroma'
  vector_db_path: 'data/vector_db'

  chunking:
    strategy: 'smart'  # smart, fixed, or recursive
    chunk_size: 512
    chunk_overlap: 50
    split_on_headers: true

  search:
    hybrid_mode: true
    semantic_weight: 0.7
    keyword_weight: 0.3
    top_k: 20

  cache_embeddings: true
  batch_size: 32
  index_on_startup: false

RAG的先决条件

对于Ollama(当地):

  1. 安装Ollama:https://ollama.ai
  2. 拉式嵌入模型: ollama pull nomic-embed-text
  3. 启动Ollama: ollama serve

对于OpenAI:

  1. 从获取API密钥https://platform.openai.com
  2. 设置环境变量或配置

MCP工具

服务器提供以下MCP工具:

注释操作

read_note

读一下保险库里的便条。

参数:

  • path (str):注释的相对路径

退货: 带有注释元数据、内容、frontmatter、标签和链接的JSON

例子:

read_note(path="daily/2024-01-01.md")

create_note

在vault中创建新注释。

参数:

  • path (str):新音符的相对路径
  • content (str):Markdown内容
  • frontmatter (dict,可选):YAML frontmatter数据

例子:

create_note(
    path="meetings/team-standup.md",
    content="# Team Standup\n\nNotes here...",
    frontmatter={"date": "2024-01-01", "tags": ["meeting"]}
)

update_note

更新现有注释。

参数:

  • path (str):注释路径
  • content (str,可选):新内容
  • frontmatter (字典,可选):Frontmatter更新
  • append (bool):如果为True,则追加内容而不是替换

例子:

update_note(
    path="daily/2024-01-01.md",
    content="Additional notes...",
    append=True
)

delete_note

从vault中删除注释。

参数:

  • path (str):注释路径

例子:

delete_note(path="old-note.md")

搜索与发现

search_notes

搜索vault内容。

参数:

  • query (str):搜索查询字符串
  • tags (list[str],可选):按标签筛选
  • path_pattern (str,可选):按路径模式过滤
  • limit (int):最大结果(默认值:100)
  • offset (int):分页偏移量
  • case_sensitive (bool):区分大小写的搜索

例子:

search_notes(
    query="project planning",
    tags=["work", "important"],
    limit=50
)

list_notes

列出vault中的注释。

参数:

  • path_pattern (str,可选):用于过滤的球形图案
  • limit (int):最大结果
  • offset (int):分页偏移
  • sort_by (str):排序字段(名称、修改、创建、大小)
  • sort_desc (bool):降序排序

例子:

list_notes(
    path_pattern="projects/**/*.md",
    sort_by="modified",
    limit=100
)

get_backlinks

查找链接到特定笔记的所有笔记。

参数:

  • note_name (str):注释名称

例子:

get_backlinks(note_name="important-concept")

标签管理

add_tag_to_note

在笔记中添加标签。

参数:

  • path (str):注释路径
  • tag (str):要添加的标签(不带#前缀)
  • to_frontmatter (bool):添加到frontmatter vs内联

例子:

add_tag_to_note(
    path="note.md",
    tag="reviewed",
    to_frontmatter=True
)

remove_tag_from_note

从笔记中删除标签。

参数:

  • path (str):注释路径
  • tag (str):要删除的标签

例子:

remove_tag_from_note(path="note.md", tag="draft")

保险库信息

get_vault_stats

获取有关保险库的统计数据。

退货: JSON,包括总注释、大小、标签等

例子:

get_vault_stats()

RAG和语义搜索(可选)

备注:这些工具仅在配置中启用RAG时可用。

semantic_search

使用AI嵌入在vault笔记中执行语义搜索。

参数:

  • query (str):搜索查询文本
  • k (int,可选):要返回的结果数(默认值:10,最大值:100)
  • tags (list[str],可选):按标签筛选结果
  • path_pattern (str,可选):按路径模式过滤结果

退货: JSON,语义搜索结果包括相似性得分和匹配的文本块

例子:

semantic_search(
    query="machine learning concepts",
    k=20,
    tags=["ai", "notes"]
)

index_vault

索引vault注释以进行语义搜索。使用前必须调用 semantic_search.

参数:

  • force_reindex (bool,可选):强制对所有文档重新索引(默认值:False)
  • path_pattern (str,可选):仅索引与模式匹配的笔记
  • batch_size (int,可选):处理的批大小(默认值:32)

退货: 带索引统计的JSON(注释已索引,块已添加/更新)

例子:

# Index entire vault
index_vault()

# Force re-index specific folder
index_vault(force_reindex=True, path_pattern="projects/**/*.md")

get_index_stats

获取语义搜索索引的统计信息。

退货: JSON包含索引统计信息,包括:

  • 索引文件和注释总数
  • 嵌入维
  • 提供者名称(ollama、openai等)
  • 索引大小(MB)
  • 上次索引时间戳

例子:

get_index_stats()

delete_index

清除整个语义搜索索引。

警告: 这将永久删除所有索引嵌入,并且无法撤消。

退货: 带操作状态的JSON

例子:

delete_index()

RAG使用工作流程

  1. 启用RAG 在您的配置中(请参阅上面的MCP客户端配置部分)
  2. 启动服务器 启用RAG
  3. 为您的保险库建立索引:呼叫 index_vault() 创建嵌入
  4. 执行语义搜索:使用 semantic_search() 查找相关注释
  5. 监视器:检查 get_index_stats() 查看索引状态
  6. 维持:更新笔记时,根据需要重新索引

快速命令行索引(辅助脚本):

# Incremental index - discovers and indexes only NEW files (RECOMMENDED)
./scripts/index_incremental.sh [--config config/config.yaml]

# Full re-index - indexes ALL files (slower, use after config changes)
./scripts/index_full.sh [--config config/config.yaml]

# Index specific folder only (override the glob with --pattern)
./scripts/index_folder.sh --pattern "projects/**" [--config config/config.yaml]

# Check index stats
./scripts/index_stats.sh [--config config/config.yaml]

每个脚本只需包装相应的 uv run python -c ... 命令,因此如果愿意,您仍然可以手动运行这些命令。

示例工作流(通过MCP客户端):

# 1. Index the vault (first time or after major changes)
index_vault()

# 2. Check index status
get_index_stats()
# Returns: {"total_documents": 250, "total_notes": 50, "provider": "ollama", ...}

# 3. Perform semantic searches
semantic_search(query="What are my notes about Python async programming?", k=10)

# 4. Search with filters
semantic_search(
    query="project ideas",
    tags=["work", "ideas"],
    path_pattern="projects/**"
)

# 5. Incremental re-index (only new/modified files - FAST!)
index_vault(force_reindex=False)

配置参考

服务器配置

server:
  host: '0.0.0.0' # Server host
  port: 8000 # Server port
  log_level: 'INFO' # DEBUG, INFO, WARNING, ERROR, CRITICAL

保险库配置

vault:
  path: '/path/to/vault' # Absolute path to Obsidian vault
  note_extension: 'md' # Note file extension
  max_file_size_mb: 10 # Maximum file size
  allowed_extensions: # Allowed file types
    - 'md'
    - 'pdf'
    - 'png'

认证

auth:
  enabled: true
  api_keys: # List of valid API keys
    - 'your-key-here'
  rate_limit:
    enabled: true
    requests_per_minute: 60
    burst_size: 10

搜索配置

search:
  enabled: true
  max_results: 100
  cache_enabled: true
  cache_ttl_seconds: 300

发展

运行测试

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=src --cov-report=html

# Run specific test file
uv run pytest tests/test_vault.py

代码质量

# Format code
uv run black src tests

# Lint code
uv run ruff check src tests

# Type checking
uv run mypy src

安全最佳实践

  1. API密钥:使用随机生成的强API密钥(最少16个字符)
  2. 环境变量:将敏感数据存储在 .env file,永远不要提交到git
  3. 速率限制:启用速率限制以防止滥用
  4. 路径验证:验证所有路径以防止目录遍历
  5. 输入消毒:所有输入在处理前都经过消毒
  6. 审计日志:启用审核日志记录以跟踪所有操作

建筑

src/mcp_obsidian/
├── __init__.py           # Package initialization
├── models.py             # Pydantic data models
├── config.py             # Configuration management
├── auth.py               # Authentication & security
├── vault.py              # Core vault operations
├── obsidian_utils.py     # Obsidian-specific utilities
├── search.py             # Search functionality
├── logging_config.py     # Logging configuration
└── server.py             # MCP server implementation

故障排除

常见问题

问题:“保险库路径不存在”

  • 确保路径 config.yaml 是正确和绝对的
  • 检查文件权限

问题:“API密钥无效”

  • 验证配置中的API密钥是否与正在使用的密钥匹配
  • 检查是否启用了身份验证

问题:“超出费率限制”

  • 等待速率限制窗口重置
  • 调整配置中的速率限制设置

贡献

欢迎投稿!拜托:

  1. 分叉存储库
  2. 创建要素分支
  3. 为新功能编写测试
  4. 确保所有测试通过
  5. 提交拉取请求

许可证

MIT许可证-有关详细信息,请参阅许可证文件

支持

对于问题和疑问:

  • 在GitHub上打开一个问题
  • 检查现有文档
  • 查看配置示例

致谢