Skip to main content
Glama

Notemd MCP (Model Context Protocol) Server

==================================================
  _   _       _   _ ___    __  __ ___
 | \ | | ___ | |_| |___|  |  \/  |___ \
 |  \| |/ _ \| __| |___|  | |\/| |   | |
 | |\  | (_) | |_| |___   | |  | |___| |
 |_| \_|\___/ \__|_|___|  | |  | |____/
==================================================
   AI-Powered Backend for Your Knowledge Base
==================================================

Welcome to the Notemd MCP Server! This project provides a powerful, standalone backend server that exposes the core AI-powered text processing and knowledge management functionalities of the Notemd Obsidian Plugin.

English | 简体中文

Built with Python and FastAPI, this server allows you to offload heavy computational tasks from the client and provides a robust API to interact with your knowledge base programmatically.

Features

Source upgrade from Obsidian NotEMD 1.9.12

The current source branch includes a reliability upgrade after published 0.6.1. It does not replace an existing npm/PyPI release. To use these changes, clone this repository, run npm ci and python -m pip install -r requirements.txt, then configure your MCP client to run node with the absolute path to cli.js.

  • Markdown cleanup preserves labels, diagram families, nested/long/tilde fences, code, escaped currency and line endings. It removes only a complete outer Markdown response envelope. It does not parse or render Mermaid; unsupported syntax remains available for review.

  • Batch syntax repair stages a complete file, checks that the source has not changed, and replaces it only when needed. Symlink files are skipped; read-only files and write failures are reported without claiming success.

  • Retry waits yield to other requests and apply only to transient HTTP/transport failures. The public cancelled flag supports pre-cancellation; native Python task cancellation propagates. MCP request cancellation is not yet connected end to end.

  • Research HTML extraction uses selectolax's supported Lexbor backend, including compatibility with selectolax 1.x; search links, snippets and body extraction are covered by mocked-transport tests.

  • MCP stdout contains protocol messages only; Python/pip and task logs go to stderr. Configuration values and backend response bodies are excluded from bridge diagnostics. Google credentials travel in headers, not request URLs.

  • The bridge binds its backend to 127.0.0.1:8000 and verifies a per-process health identifier. Direct python main.py / installed notemd-mcp HTTP execution defaults to loopback; set NOTEMD_HOST and NOTEMD_PORT explicitly for a different binding. Remote HTTP access requires deployment-level authentication.

generate_diagram still returns Mermaid text. SVG/PDF rendering and Obsidian's diagnostics disclosure UI are host capabilities, not endpoints in this server. Backlink rename/delete operations retain their existing behavior; transactional writes, vault containment and partial-failure reporting for those operations remain separate work.

Verification: npm test, npm run test:python, python -m pip wheel . --no-deps --wheel-dir artifacts, then python scripts/verify-wheel.py artifacts/notemd_mcp-0.6.1-py3-none-any.whl. Tests use production modules and mock provider transport; no live LLM calls are needed. See the migration analysis and evidence.

  • AI-Powered Content Enrichment: Automatically processes Markdown content to identify key concepts and create [[wiki-links]], building a deeply interconnected knowledge graph.

  • Automated Documentation Generation: Generates comprehensive, structured documentation from a single title or keyword, optionally using web research for context.

  • Integrated Web Research & Summarization: Performs web searches using Tavily or DuckDuckGo and uses an LLM to provide concise summaries on any topic.

  • Diagram Workflows (Canonical + Compatibility Alias): Supports generate_diagram as the canonical flow plus generate_experimental_diagram as a legacy compatibility alias aligned with modern NotEMD command surfaces.

  • Translation & Extraction Utilities: Adds first-class translation, concept extraction, and verbatim original-text extraction operations for automation pipelines.

  • Knowledge Graph Integrity: Includes endpoints to automatically update or remove backlinks when files are renamed or deleted, preventing broken links.

  • Syntax Correction: Provides a utility to batch-fix common Mermaid.js and LaTeX syntax errors often found in LLM-generated content.

  • Highly Configurable: All major features, API keys, file paths, and model parameters are easily managed in a central config.py file.

  • Multi-LLM Support: Compatible with any OpenAI-compliant API, including local models via LMStudio and Ollama, and cloud providers like DeepSeek, Anthropic, Google, and more.

  • Interactive API Docs: Comes with automatically generated, interactive API documentation via Swagger UI.

Related MCP server: Enhanced Obsidian MCP Server

How It Works

The server is built on a simple and logical architecture:

  • main.py (API Layer): Defines all API endpoints using the FastAPI framework. It handles incoming requests, validates data using Pydantic, and calls the appropriate functions from the core logic layer.

  • notemd_core.py (Logic Layer): The engine of the application. It contains all the business logic for interacting with LLMs, processing text, performing web searches, and managing files within your knowledge base.

  • config.py (User-Defined Space): The central configuration hub. This is where you define your file paths, API keys, and tune the behavior of the server to fit your needs.

  • cli.js (MCP Bridge): A Node.js-based command-line interface that acts as a bridge to the Python server. It uses the @modelcontextprotocol/sdk to create a server that can be called by other tools. It starts the FastAPI server and then communicates with it via HTTP requests.

Getting Started

Follow these steps to get the Notemd MCP server up and running on your local machine.

Prerequisites

  • For Python execution: Python 3.10+ and pip or uv.

  • For NPX execution: Node.js 22.19+ and npx, plus Python on PATH.

Installation & Running

Choose the method that best fits your workflow.

Method 1: Using npx (Recommended for Quick Start)

npx downloads the published package, which may lag behind the source upgrade above. In the updated source, stdio mode reserves stdout for MCP protocol messages and sends backend logs to stderr.

# This single command will download the package and start the server.
npx notemd-mcp-server

Method 2: Local Installation with uv or pip

This method is for users who want to clone the repository and manage the files locally.

  1. Clone the repository:

    git clone https://github.com/Jacobinwwey/notemd-mcp.git
    cd notemd-mcp
  2. Install dependencies:

    • Using uv (Recommended):

      uv venv
      uv pip install -r requirements.txt
    • Using pip:

      python -m venv .venv
      # Activate the environment (e.g., source .venv/bin/activate)
      pip install -r requirements.txt
  3. Run the server:

    python main.py

Method 3: MCP Configuration

To integrate the published package with your Model Context Protocol (MCP) client, add the following to the mcpServers object in its configuration:

 {
   "mcpServers": {
     "notemd-mcp": {
       "description": "Notemd MCP Server - text processing for Markdown files.",
       "command": "npx",
       "args": [
         "-y",
         "notemd-mcp-server"
       ],
       "env": {
         "OPENAI_API_KEY": "your_openai_api_key_here",
         "DEEPSEEK_API_KEY": "your_deepseek_api_key_here"
       }
     }
   }
 }

Usage

The best way to explore and interact with the API is through the automatically generated documentation.

  • Navigate to http://127.0.0.1:8000/docs in your web browser.

You will see a complete, interactive Swagger UI where you can view details for each endpoint, see request models, and even send test requests directly from your browser.

API Endpoints

Endpoint

Method

Description

Request Body

Response

/process_content

POST

Takes a block of text and enriches it with [[wiki-links]].

{"content": "string", "cancelled": "boolean"}

{"processed_content": "string"}

/generate_title

POST

Generates full documentation from a single title.

{"title": "string", "cancelled": "boolean"}

{"generated_content": "string"}

/research_summarize

POST

Performs a web search on a topic and returns an AI-generated summary.

{"topic": "string", "cancelled": "boolean"}

{"summary": "string"}

/execute_custom_prompt

POST

Execute a user-defined prompt with given content.

{"prompt": "string", "content": "string", "cancelled": "boolean"}

{"response": "string"}

/translate_content

POST

Translate text/markdown into a target language.

{"content": "string", "target_language": "string", "cancelled": "boolean"}

{"translated_content": "string"}

/summarize_as_mermaid

POST

Summarize content as a Mermaid mindmap.

{"content": "string", "target_language": "string", "cancelled": "boolean"}

{"mermaid_summary": "string"}

/generate_diagram

POST

Canonical diagram generation endpoint.

{"content": "string", "diagram_intent": "string", "target_language": "string", "compatibility_mode": "string", "cancelled": "boolean"}

{"diagram": "string"}

/generate_experimental_diagram

POST

Legacy compatibility alias for diagram generation.

{"content": "string", "diagram_intent": "string", "target_language": "string", "cancelled": "boolean"}

{"diagram": "string"}

/preview_diagram

POST

Canonical preview diagram endpoint (no file side effects).

{"content": "string", "diagram_intent": "string", "target_language": "string", "compatibility_mode": "string", "cancelled": "boolean"}

{"diagram": "string"}

/preview_experimental_diagram

POST

Legacy preview alias for compatibility.

{"content": "string", "diagram_intent": "string", "target_language": "string", "cancelled": "boolean"}

{"diagram": "string"}

/extract_concepts

POST

Extract deduplicated core concept list.

{"content": "string", "cancelled": "boolean"}

{"concepts": ["..."]}

/extract_original_text

POST

Extract verbatim matches for user input from reference content.

{"reference_content": "string", "user_input": "string", "cancelled": "boolean"}

{"extracted_text": "string"}

/check_duplicates

POST

Return normalized duplicate terms detected in content.

{"content": "string"}

{"duplicates": ["..."], "count": 0}

/handle_file_rename

POST

Updates all backlinks in the vault when a file is renamed.

{"old_path": "string", "new_path": "string"}

{"status": "success"}

/handle_file_delete

POST

Removes all backlinks to a file that has been deleted.

{"path": "string"}

{"status": "success"}

/batch_fix_mermaid

POST

Scans a folder and corrects common Mermaid.js and LaTeX syntax errors in .md files.

{"folder_path": "string"}

{"errors": [], "modified_count": "integer"}

/health

GET

A simple health check to confirm the server is running.

(None)

{"status": "ok"}

Configuration

All configuration is handled in the config.py file. Here you can set API keys, file paths, and other settings.

Core Settings

The notemd_core.set_settings function in main.py initializes the core functionalities of the server using the following parameters, primarily sourced from config.py:

  • DEFAULT_PROVIDERS: A list of dictionaries, each defining an LLM provider with its name, apiKey, baseUrl, model, temperature, and optional apiVersion (for Azure OpenAI).

  • ACTIVE_PROVIDER: The name of the LLM provider to be used by default for all operations.

  • CHUNK_WORD_COUNT: The maximum number of words per chunk when processing content for wiki-linking.

  • MAX_TOKENS: The maximum number of tokens allowed for LLM interactions.

  • ENABLE_DUPLICATE_DETECTION: Boolean to enable/disable duplicate concept detection during wiki-linking.

File Paths Configuration

These settings define the directory structure for your knowledge base and logs:

  • VAULT_ROOT: The absolute path to your Obsidian vault or the root directory of your Markdown files.

  • CONCEPT_NOTE_FOLDER: The subfolder within VAULT_ROOT where generated concept notes will be stored.

  • PROCESSED_FILE_FOLDER: The subfolder where processed Markdown files will be moved.

  • CONCEPT_LOG_FOLDER: The subfolder for storing concept generation logs.

  • CONCEPT_LOG_FILE_NAME: The name of the log file for concept generation.

Search Configuration

Settings related to web research and summarization:

  • TAVILY_API_KEY: Your API key for Tavily, if SEARCH_PROVIDER is set to "tavily".

  • SEARCH_PROVIDER: Specifies the web search engine to use ("tavily" or "duckduckgo").

  • DDG_MAX_RESULTS: Maximum number of results to fetch from DuckDuckGo.

  • DDG_FETCH_TIMEOUT: Timeout in seconds for DuckDuckGo searches.

  • MAX_RESEARCH_CONTENT_TOKENS: Maximum tokens for content used in research.

  • ENABLE_RESEARCH_IN_GENERATE_CONTENT: Boolean to enable/disable web research when generating content from a title.

  • TAVILY_MAX_RESULTS: Maximum number of results to fetch from Tavily.

  • TAVILY_SEARCH_DEPTH: Search depth for Tavily ("basic" or "advanced").

Stable API Call Settings

These settings control the retry mechanism for LLM API calls:

  • ENABLE_STABLE_API_CALL: Boolean to enable/disable stable API calls with retries.

  • API_CALL_INTERVAL: Interval in seconds between API call retries.

  • API_CALL_MAX_RETRIES: Maximum number of retries for a failed API call.

Multi-Model and Task-Specific Settings

These settings allow for fine-grained control over which LLM provider and model are used for specific tasks:

  • ADD_LINKS_PROVIDER: The LLM provider to use for the process_content (add links) operation.

  • RESEARCH_PROVIDER: The LLM provider to use for the research_summarize operation.

  • GENERATE_TITLE_PROVIDER: The LLM provider to use for the generate_title operation.

  • TRANSLATE_PROVIDER: Provider for translate_content.

  • SUMMARIZE_TO_MERMAID_PROVIDER: Provider for summarize_as_mermaid.

  • EXTRACT_CONCEPTS_PROVIDER: Provider for extract_concepts.

  • EXTRACT_ORIGINAL_TEXT_PROVIDER: Provider for extract_original_text.

  • DIAGRAM_PROVIDER: Provider for generate_diagram.

  • ADD_LINKS_MODEL: Specific model to use for adding links (overrides provider's default if set).

  • RESEARCH_MODEL: Specific model to use for research (overrides provider's default if set).

  • GENERATE_TITLE_MODEL: Specific model to use for title generation (overrides provider's default if set).

  • TRANSLATE_MODEL, SUMMARIZE_TO_MERMAID_MODEL, EXTRACT_CONCEPTS_MODEL, EXTRACT_ORIGINAL_TEXT_MODEL, DIAGRAM_MODEL: Task-specific model overrides.

Post-processing Settings

  • REMOVE_CODE_FENCES_ON_ADD_LINKS: Boolean to remove code fences from content after adding links.

Language Settings

  • LANGUAGE: The default language for content processing.

  • AVAILABLE_LANGUAGES: A list of supported languages.

Custom Prompt Settings

These settings allow you to enable and define custom prompts for various operations:

  • ENABLE_GLOBAL_CUSTOM_PROMPTS: Boolean to enable/disable the use of custom prompts globally.

  • CUSTOM_PROMPT_ADD_LINKS: Custom prompt string for the process_content (add links) operation.

  • CUSTOM_PROMPT_GENERATE_TITLE: Custom prompt string for the generate_title operation.

  • CUSTOM_PROMPT_RESEARCH_SUMMARIZE: Custom prompt string for the research_summarize operation.

  • CUSTOM_PROMPT_TRANSLATE: Custom prompt string for translate_content.

  • CUSTOM_PROMPT_SUMMARIZE_TO_MERMAID: Custom prompt string for summarize_as_mermaid.

  • CUSTOM_PROMPT_GENERATE_DIAGRAM: Custom prompt string for generate_diagram.

  • CUSTOM_PROMPT_EXTRACT_CONCEPTS: Custom prompt string for extract_concepts.

  • CUSTOM_PROMPT_EXTRACT_ORIGINAL_TEXT: Custom prompt string for extract_original_text.

Release (npm + PyPI)

Use this one-line command to bump one shared version and publish both npm and PyPI in sync:

npm run release:sync-publish -- 0.6.1

Dry-run (no publish):

npm run release:sync-publish -- 0.6.1 --dry-run

Notes:

  • The command updates npm version (package.json + package-lock.json), and syncs Python/server versions in setup.py, main.py, and cli.js.

  • Make sure npm auth is ready (npm login or NPM_TOKEN) and PyPI auth is ready (~/.pypirc or TWINE_USERNAME + TWINE_PASSWORD).

  • It builds Python artifacts and runs twine check before upload.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Related MCP Connectors

Related MCP Servers