Skip to main content
Glama

NoteHarbor MCP

Ein Python-Beispiel zum Abfragen von Obsidian-Notizen über MCP und GraphQL und zur Erweiterung mit PostgreSQL/pgvector. Es enthält keine persönlichen Vaults, echten Dokumente oder API-Schlüssel.

Die Originale von NoteHarbor sind Markdown-Dateien. Es werden nur die für die Suche benötigten Daten separat erstellt, die Originale bleiben unverändert erhalten.

Kriterien dieses Projekts

  • Local first: Die ursprünglichen Markdown-Dateien bleiben lokal, externe Dienste sind optionale Verbindungsmöglichkeiten.

  • Source preserving: Suchergebnisse, Embeddings und Synchronisierungsergebnisse ersetzen nicht die Originale.

  • Privacy by boundary: Echte Vaults, persönliche Aufzeichnungen und API-Schlüssel bleiben außerhalb des öffentlichen Projekts.

  • Model neutral: Der Embedding-Generator und die Vektor-DB sind nicht an einen bestimmten Anbieter gebunden.

  • Small and replaceable: Adapter und Service-Schichten bleiben klein.

Related MCP server: Notes RAG MCP Server

Drei öffentliche Beispiele

  1. MCP: Werkzeuge upsert_vector, search_vectors

  2. GraphQL: Mutation indexChunk, Query vectorSearch

  3. PostgreSQL/pgvector: SQLAlchemy-Modelle, Repository-Port, Docker-Entwicklungsumgebung

Es handelt sich nicht um einen Produktionsdienst, sondern um ein Beispiel zur Veranschaulichung der Struktur. Das Standard-Repository arbeitet im Speicher; die Stelle für den Wechsel zu PostgreSQL/pgvector sowie SQL-Beispiele werden mitgeliefert.

Schnellstart

uv sync

MCP-Beispiel ausführen:

uv run noteharbor

PostgreSQL mit Docker starten

docker compose up -d postgres

Die docker-compose.yml definiert das pgvector/pgvector-Image und eine PostgreSQL-Entwicklungsdatenbank für Python MCP.

# PostgreSQL만
docker compose up -d postgres

# Python MCP까지
docker compose up --build python-mcp

POSTGRES_URL ist der Platzhalter für die Konfiguration, wenn eine echte DB-Verbindung hergestellt wird. Die aktuelle Standardausführung ist ein Mock.

GraphQL-Beispiel

Das GraphQL-Schema befindet sich in noteharbor/api/graphql_schema.py. Das Ergebnis von get_schema() kann in einen externen ASGI-Server eingebunden werden.

Beispieloperation:

mutation {
  indexChunk(
    sourcePath: "sample.md"
    content: "Obsidian knowledge"
    embedding: [1.0, 0.0]
  )
}

query {
  vectorSearch(embedding: [0.9, 0.1], limit: 5) {
    sourcePath
    content
    score
  }
}

CRUD- und ORM-Stil-Grenzen

Das Repository ist nicht nur für die Suche zuständig, sondern für den gesamten Lebenszyklus von NoteChunk, von der Erstellung bis zur Löschung.

  • Create/Upsert: MCP upsert_vector, GraphQL indexChunkVectorService.index_chunk()

  • Read: MCP get_chunk·list_chunks, GraphQL noteChunk·noteChunks

  • Update: MCP·GraphQL updateChunk → liest den vorhandenen Datensatz und übernimmt nur die geänderten Felder

  • Delete: MCP·GraphQL deleteChunk

  • Search: MCP search_vectors, GraphQL vectorSearch

Der aktuelle Adapter ist ein In-Memory-Mock zur Funktionsprüfung. Die tatsächliche Speicherung erfolgt hinter der SQLAlchemy-ORM-Grenze. Im echten PostgreSQL-Adapter wird MockPostgresVectorRepository durch die folgenden Session-Operationen ersetzt.

Wenn Sie den tatsächlichen ORM-Ablauf im Code sehen möchten, schauen Sie in noteharbor/infrastructure/postgres/sqlalchemy_repository.py. Dieser Adapter implementiert denselben VectorRepository-Port und verwendet Session.get, select, update, delete. Die Standardausführung ist weiterhin ein Mock, sodass Sie das Beispiel ohne PostgreSQL-Verbindung lesen und testen können.

session.get(NoteChunkModel, chunk_id)
session.scalars(select(NoteChunkModel).limit(limit)).all()
session.execute(update(NoteChunkModel).where(NoteChunkModel.id == chunk_id).values(...))
session.execute(delete(NoteChunkModel).where(NoteChunkModel.id == chunk_id))

Die API behandelt SQL nicht direkt, sondern übergibt CRUD und Suche in der Reihenfolge MCP/GraphQL → VectorService → VectorRepository → SQLAlchemy/pgvector.

Zweck

Dieses Repository ist ein Python-Architekturbeispiel, das eine einzelne Markdown-Quelle sowohl über MCP als auch über GraphQL mit demselben Vektorsuchdienst abfragt.

Der Fokus liegt darauf, austauschbare Punkte klar zu definieren, anstatt einen bestimmten Embedding-Anbieter oder eine bestimmte Vektor-DB festzulegen.

MCP / GraphQL API
  → VectorService
  → VectorRepository port
  → 현재: in-memory MockPostgresVectorRepository
  → 전환: PostgreSQL + pgvector

Verantwortung für Vektorisierung und Suche

Das aktuelle Python-Beispiel erzeugt keine Embeddings selbst. Die Mutation indexChunk und das Werkzeug upsert_vector empfangen extern erzeugte list[float]-Embeddings und speichern sie.

Die Gründe für die Trennung der Embedding-Erstellung sind folgende:

  • Um das Embedding-Modell nicht auf OpenAI, Voyage oder ein lokales Modell festzulegen

  • Um API-Schlüssel und persönliche Daten aus dem öffentlichen Beispiel auszuschließen

  • Um die Verantwortung der API-Schicht und des Suchspeichers zu trennen

  • Um im echten Dienst die Chunking- und Embedding-Batch-Pipeline durch einen separaten Worker zu ersetzen

Die Suche erfolgt in folgender Reihenfolge:

사용자 query embedding
  → GraphQL vectorSearch 또는 MCP search_vectors
  → VectorService.search()
  → Repository.search()
  → cosine similarity 계산
  → score가 높은 NoteChunk 반환

Der MockPostgresVectorRepository in repository.py reproduziert diesen Ablauf im Speicher. Im echten PostgreSQL-Adapter wird die Kosinus-Distanz mit embedding <=> :query_embedding berechnet und 1 - distance als Score zurückgegeben.

Warum PostgreSQL + pgvector?

NoteChunk ist nicht nur ein Wert mit Vektoren, sondern enthält auch den Quellpfad, die Chunk-Reihenfolge, den Text und Metadaten. Mit PostgreSQL und pgvector lassen sich relationale Bedingungen und Vektorähnlichkeitssuche in einem Speicher und innerhalb einer SQL-Grenze behandeln.

  • PostgreSQL: Verwaltung von Originalmetadaten, Status, Synchronisierungsinformationen und Transaktionen

  • pgvector: vector-Spalte, Kosinus-Distanz (<=>), HNSW-Index

  • Docker: Festlegung der pgvector-Ausführungsbedingungen in der Entwicklungsumgebung

  • SQLAlchemy-Repository: Austauschpunkt für den Speicher

Wenn der Suchumfang wächst, kann eine dedizierte Vektor-DB besser geeignet sein. Hier wird der Ablauf gezeigt, bei dem Dokumentinformationen und Vektorsuche in einem Speicher behandelt werden.

Quantisierungsumfang

Im aktuellen Python-Repo ist keine Quantisierungsimplementierung enthalten. Die Eingabe-Embeddings werden als Float-Werte direkt für die Suche verwendet; dies ist eine bewusste Entscheidung, um zuerst die modellneutrale Repository-Grenze zu zeigen.

Falls Quantisierung hinzugefügt wird, sollte ein separater EmbeddingQuantizer-Port eingerichtet und die Schritte float32 → INT8/float16 → Speichern/Wiederherstellen zwischen dem Indexierungs-Worker und dem Repository-Adapter platziert werden. Da die Quantisierungsmethode erst nach Messung von Suchqualität, Speicher und Latenz entschieden werden sollte, wird in diesem Beispiel nicht behauptet, dass sie implementiert ist.

Beziehung zwischen den beiden NoteHarbor-Beispielen

  • noteharbor-mcp: TypeScript-MCP-Werkzeuge und Ablauf für Embedding und INT8-Quantisierung

  • noteharbor-python: Python-MCP- und GraphQL-API sowie VectorService/Repository-Grenze

Beide Repos sind Beispiele, die dieselbe Idee in verschiedenen Sprachen und API-Ansätzen umsetzen; sie enthalten keine echten persönlichen Vaults oder Betriebsdaten.

Zusätzliche Technologien und Gründe für ihren Einsatz

Technologie

Grund für den Einsatz

uv

Schnelle Reproduktion von Python-Abhängigkeiten, virtuellen Umgebungen und Lock-Dateien; gleicher Installationspfad auch in Docker

FastMCP

Kurze und klare Verbindung zwischen Python-Funktionen und MCP-Werkzeugen

Pydantic

Validierung von Eingabemodellen und Konfiguration an der API-Grenze

SQLAlchemy

Grenze für den PostgreSQL-Adapter, damit das Repository nicht an eine bestimmte SQL-Ausführungsweise gebunden ist

psycopg

Zuständig für die PostgreSQL-Verbindung in Python

pgvector Python package

Darstellung des PostgreSQL-Vektor-Typs in SQLAlchemy-Modellen

Strawberry GraphQL

Beispiel, um denselben VectorService als GraphQL-Query/Mutation bereitzustellen

Docker Compose

Gemeinsame Reproduktion der Entwicklungsumgebung mit pgvector-aktiviertem PostgreSQL und Python MCP

Jede Technologie wurde ausgewählt, um die Rollen von API, Service, Speicher und Entwicklungsumgebung klar zu trennen.

Projektstruktur

.
├── noteharbor/
│   ├── mcp_server.py
│   ├── api/graphql_schema.py
│   ├── application/vector_service.py
│   ├── domain/
│   └── infrastructure/
│       ├── notion/mock_adapter.py
│       └── postgres/
│           ├── models.py
│           ├── repository.py
│           └── sqlalchemy_repository.py
├── tests/test_vector_repository.py
├── Dockerfile
├── docker-compose.yml
└── pyproject.toml

Lizenz

MIT

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides tools for ingesting documents into a local vector database and retrieving relevant information via semantic search, enabling retrieval-augmented generation for MCP clients.
    6
  • A
    license
    Not graded
    quality
    B
    maintenance
    Indexes local Markdown/text files into a SQLite database with vector embeddings and provides MCP tools for semantic search without cloud dependencies.
    GPL 3.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Provides MCP tools for semantic search over personal knowledge sources using pluggable embeddings and local vector indexing.
    1
    MIT

View all related MCP servers

Related MCP Connectors

  • Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.

  • Hosted MCP memory: save sessions/decisions once, search from Claude, Cursor, ChatGPT. EU-hosted FTS.

  • Token-efficient MCP memory for Markdown vaults. Tiered search, GraphRAG, AI memories.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kris-atelier/noteharbor-python'

If you have feedback or need assistance with the MCP directory API, please join our Discord server