DocumentMCP
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
MCP — Serveur documentaire
Un serveur Model Context Protocol complet, et les preuves qu'il fonctionne.
Tools · Resources · Prompts · Client · Tests · Guide 24 pages
Ce dépôt contient le projet fil rouge du cours Introduction to Model Context Protocol (Claude Academy), reconstruit, corrigé et documenté.
L'objectif n'est pas seulement d'avoir un serveur qui démarre : c'est de montrer comment on prouve qu'il fonctionne, sans modèle, sans clé API, et de documenter les pièges réels rencontrés en chemin.
📘 Le guide complet (24 pages, PDF) :
docs/MCP-Guide.pdf— architecture, les trois primitives, construction pas à pas, les trois niveaux de test, étude de cas illustrée et 14 pièges documentés.
Sommaire
Related MCP server: local-docs-mcp
🧩 Ce que fait le serveur
Un mini gestionnaire de documents, avec les trois familles de capacités du protocole.
Élément | Type | Qui décide | Rôle |
| tool | le modèle | lire un document |
| tool | le modèle | remplacer une chaîne (première occurrence) |
| tool | le modèle | chercher un mot-clé, renvoyer des extraits |
| resource directe | l'application | liste des ids, en JSON — pour l'autocomplete |
| resource templatée | l'application | contenu d'un document, en texte brut |
| prompt | l'utilisateur | instructions de réécriture en markdown |
Les documents sont stockés dans un dictionnaire en mémoire : le serveur repart de son état initial à chaque redémarrage.
🚀 Démarrage rapide
Linux / macOS
git clone https://github.com/thekiller-dev/mcp-server-course.git
cd mcp-server-course
python3 -m venv .venv
.venv/bin/pip install -r requirements.txtOu avec uv :
uv venv && uv pip install -r requirements.txtWindows (PowerShell)
python -m venv .venv
.venv\Scripts\pip install -r requirements.txtFish (Linux)
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
# ou, pour tout enchaîner d'un coup :
fish setup.fish⚠️ Version du SDK. Le cours utilise
FastMCP. Depuis la 2.x, le SDKmcpl'a renomméMCPServeret a changé plusieurs signatures : tout le code ci-dessous casse avecNo module named 'mcp.server.fastmcp'.requirements.txtépingle doncmcp[cli]<2.
🧪 Tester — les trois niveaux
Niveau 1 — sans clé API, sans navigateur (3 secondes)
.venv/bin/python test_server.pyCe script lance le serveur en sous-processus et parle le protocole en stdio, exactement comme le ferait Claude Desktop. Il vérifie les tools et leurs schémas, appelle un tool, lit les deux resources, récupère le prompt.
✅ connecté à DocumentMCP v1.30.0
TOOLS : read_doc_contents, edit_document, search_docs
RESOURCES : [('docs://documents', 'application/json')]
RESOURCE TEMPLATES : [('docs://documents/{doc_id}', 'text/plain')]
PROMPTS : format
🎉 tous les tests passentNiveau 2 — la boucle complète, racontée
.venv/bin/python demo_sans_cle.pyRejoue ce que ferait un modèle, tool call après tool call, en affichant chaque étape : lecture, édition, vérification de la persistance, erreur volontaire (l'exception revient comme résultat, sans casser la session), lecture des resources, récupération du prompt.
Niveau 3 — l'inspecteur
.venv/bin/mcp dev mcp_server.py # nécessite Node.js (npx)Le terminal affiche une URL du type http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=….
Ouvrez l'URL complète — sans le jeton, la connexion est refusée.
À essayer dans l'interface :
Onglet | Valeur | Ce que ça prouve |
Tools → |
| schéma dérivé du code |
Tools → | old | l'état persiste entre deux appels |
Tools → | old | une erreur reste une réponse |
Resources |
| sérialisation JSON automatique |
Resource Templates |
| parsing du gabarit d'URI |
Prompts |
| prompt calculé côté serveur |
Panneau de droite, onglet Protocol : chaque ligne est un message JSON-RPC réel.
Niveau 4 — un modèle aux commandes
export ANTHROPIC_API_KEY="sk-ant-..." # PowerShell : $env:ANTHROPIC_API_KEY = "..."
.venv/bin/python mcp_client.pyTrois questions suffisent à valider le découpage :
Question | Ce qui doit se passer | Primitive |
| Claude appelle | tool |
| aucun tool call, contenu injecté | resource |
| instructions récupérées puis envoyées | prompt |
La deuxième ligne est la plus importante : un tool call là où une resource suffit signale une architecture mal découpée.
🧠 Les trois primitives expliquées
La différence n'est pas technique, elle tient à qui décide.
Ça lit des données → resource (l'application décide)
Ça agit, ou ça peut échouer → tool (le modèle décide)
C'est une consigne destinée au modèle → prompt (l'utilisateur décide)Un tool : le schéma vient du code
@mcp.tool(
name="read_doc_contents",
description="Read the contents of a document and return it as a string.",
)
def read_document(
document_id: str = Field(description="Id of the document to read"),
) -> str:
if document_id not in docs:
raise ValueError(f"Doc with id {document_id} not found")
return docs[document_id]le type hint
strdevient"type": "string"dans le JSON Schema ;Field(description=…)devient la description du paramètre — c'est du prompt engineering, pas de la décoration ;raise ValueErrordevient un résultat d'erreur renvoyé au modèle, pas un crash.
Vous n'écrivez jamais de schéma JSON à la main : il ne peut donc pas dériver de l'implémentation.
Une resource : directe ou templatée
@mcp.resource("docs://documents", mime_type="application/json")
def list_docs() -> list[str]:
return list(docs.keys())
@mcp.resource("docs://documents/{doc_id}", mime_type="text/plain")
def fetch_doc(doc_id: str) -> str:
if doc_id not in docs:
raise ValueError(f"Doc with id {doc_id} not found")
return docs[doc_id]Le préfixe d'URI est libre : ce n'est pas une URL réseau, c'est un espace de noms. Le SDK
extrait {doc_id} et le passe en argument nommé.
Un prompt : la couche utilisateur
@mcp.prompt(name="format", description="Rewrite the document as clean markdown.")
def format_document(doc_id: str = Field(description="Id of the document")) -> str:
return f"""Please rewrite the following document into clean markdown.
Do not invent information.
<document id="{doc_id}">
{docs.get(doc_id, "Document not found")}
</document>"""📁 Structure du dépôt
mcp-server-course/
├── mcp_server.py # le serveur : 3 tools, 2 resources, 1 prompt
├── mcp_client.py # client + boucle agentique avec Claude (@mention, /format)
├── test_server.py # test de protocole — aucune clé API requise
├── demo_sans_cle.py # la boucle complète, rejouée et commentée
├── requirements.txt # mcp[cli]<2, anthropic
├── pyproject.toml # [tool.uv] package = false (voir « Pièges connus »)
├── setup.fish # installation + test en une commande (fish)
└── docs/
├── MCP-Guide.pdf # le guide de 24 pages
└── screenshots/ # preuves d'exécution (inspecteur, JSON-RPC)🔌 Brancher sur Claude Desktop / Claude Code
Claude Desktop — claude_desktop_config.json :
OS | Chemin |
Linux |
|
macOS |
|
Windows |
|
{
"mcpServers": {
"documents": {
"command": "uv",
"args": ["--no-project", "--with", "mcp", "mcp", "run",
"/chemin/absolu/vers/mcp-server-course/mcp_server.py"]
}
}
}Quittez complètement l'application puis relancez-la : la configuration n'est lue qu'au démarrage.
Claude Code :
claude mcp add documents -- python /chemin/absolu/vers/mcp_server.py⚠️ Pièges connus
Ces erreurs sont documentées parce qu'elles ont réellement été rencontrées.
Symptôme | Cause | Solution |
| binaire dans |
|
| chemin abîmé par un copier-coller ( | retaper la commande |
| Python du système au lieu du venv |
|
| SDK 2.x, |
|
|
|
|
terminal figé après | comportement normal du stdio |
|
| Node.js absent | Node 20+ via NodeSource, pas le |
| nodejs NodeSource + npm d'apt | ne pas installer |
inspecteur « Disconnected » | URL sans le jeton | ouvrir le lien complet |
le modèle ignore l'outil | description trop vague | dire quand l'utiliser, pas seulement ce qu'il fait |
La règle de tri : (1) le script de test répond-il ? (2) l'inspecteur exécute-t-il l'outil à la main ? (3) seulement ensuite, regarder les descriptions. 90 % des problèmes se règlent à l'étape 1.
🔭 Aller plus loin
Resource de synthèse —
stats://documentsrenvoyant en JSON le nombre de documents, le nombre total de mots et le document le plus long.Tool d'écriture complète —
create_document(document_id, content), avec erreur explicite si l'identifiant existe déjà.Transport HTTP —
mcp.run(transport="streamable-http"), connexion avecmcp.client.streamable_http, puis sortie du mono-utilisateur local.Persistance — remplacer le dictionnaire par des fichiers ou une base. La surface MCP ne bouge pas : c'est le signe d'une bonne séparation.
📚 Ressources
This server cannot be deployed
Maintenance
Related MCP Connectors
Markdown workspace for AI agents: read, write, organize, and share markdown documents.
Read, edit and improve shared documents and knowledge with people and agents.
Documents to Markdown and PDF, OCR, transcription, TTS, screenshots, domain checks, video frames.
- MontonOAuthdev.monton
Shared docs for people and their agents: markdown docs and HTML pages with comments and history.
Related MCP Servers
- FlicenseBqualityDmaintenanceProvides tools and resources for managing in-memory documents, allowing users to read, edit, and list document contents via the Model Context Protocol. It includes features for formatting documents to Markdown and accessing document-specific resources.3-
- FlicenseAqualityDmaintenanceEnables local document search and reading across formats like docx, pdf, md, and more, providing tools for listing, searching, and reading documents.3-
- FlicenseAqualityCmaintenanceEnables managing documents on the filesystem through natural language, with tools for read, create, edit, delete, and commands for summarize, format, rewrite, and convert.5-
- FlicenseNot gradedqualityDmaintenanceExposes a document store over MCP tools, resources, and prompts for reading, editing, summarizing, and formatting documents in a chat interface.-