Skip to main content
Glama
pipinho13

MCP Notes Server

by pipinho13

MCP Notes Server — Your First MCP Server with Claude (Python)

A beginner-friendly, fully reproducible tutorial for building a Model Context Protocol (MCP) server in Python and connecting it to Claude.

The example server is a personal notes manager: Claude can create, list, read, search, update, and delete notes that are saved as Markdown files on your own computer.

📖 New to this? Follow the complete step-by-step guide in TUTORIAL.md. It explains every single command and shows the exact output you should see.


What is MCP?

MCP (Model Context Protocol) is an open standard that lets AI apps like Claude talk to external programs. You write a small server exposing:

  • Tools — actions Claude can take (e.g. "save a note")

  • Resources — read-only data Claude can pull in (e.g. "all my notes")

Claude is the client: when you ask it something, it can decide to call your tools. Build the server once, and any MCP-aware app can use it.

Do I need to write a client too? Usually no — the client is an existing app like Claude Desktop or Claude Code. You only write a server. This repo includes an optional client.py purely to show what a client does under the hood; see TUTORIAL.md §9.


Related MCP server: parchmark-mcp

Quickstart

Requires uv (the tutorial shows how to install it). Then, from this folder:

# 1. Set up the environment (installs Python 3.12 + the MCP SDK, pinned)
uv sync

# 2. Test the server in the visual MCP Inspector
uv run mcp dev notes_server.py

To connect it to Claude Desktop, add this to your claude_desktop_config.json (use the absolute path from pwd):

{
  "mcpServers": {
    "notes": {
      "command": "uv",
      "args": ["--directory", "/ABSOLUTE/PATH/TO/mcp_tutorial", "run", "notes_server.py"]
    }
  }
}

To connect it to Claude Code:

claude mcp add notes -- uv --directory "$(pwd)" run notes_server.py

Full details, expected output, and troubleshooting are in TUTORIAL.md.


Project structure

File

Purpose

notes_server.py

The MCP server: 6 tools + 1 resource

client.py

Optional standalone MCP client — chat with the server from your terminal (no Claude Desktop needed)

pyproject.toml

Project metadata, requires Python ≥ 3.10, depends on mcp[cli] and anthropic

uv.lock

Exact pinned versions of every dependency (commit this!)

.python-version

Pins the Python interpreter to 3.12 for reproducibility

.env.example

Template for your API key — copy to .env (git-ignored) and fill in

TUTORIAL.md

The complete step-by-step walkthrough

.gitignore

Excludes the virtual env and your personal notes from git


The tools

Tool

What it does

add_note(title, body)

Create a new note

update_note(title, body)

Replace an existing note's content

list_notes()

List all note titles

read_note(title)

Read one note

search_notes(query)

Find notes by title or content

delete_note(title)

Delete a note permanently

Plus a resource, notes://all, that returns every note concatenated.


Tested with

  • uv 0.11.19

  • Python 3.12.13 (pinned via .python-version)

  • mcp 1.27.2

Because uv.lock and .python-version are committed, anyone who runs uv sync gets the exact same environment.


License

MIT — see LICENSE. Use it, fork it, teach with it.

Available Tools

6 tools
add_noteA

Create a new note.

Args:
    title: A short name for the note, e.g. "Groceries".
    content: The body text of the note.
ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes
contentYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral transparency burden. It states the core mutating behavior (create), but it does not disclose whether the operation is idempotent, requires any permissions, or how existing notes might be affected. The described behavior is minimal beyond the basic create action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short, starts with the primary purpose, and then lists parameters with concise explanations. Every sentence contributes information, no filler or repetition, making it appropriately sized and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple creation tool, the description is nearly complete: it states the action and defines both parameters. With an output schema present, return value explanation is unnecessary. Minor gaps like storage behavior or prerequisites do not seem blocked for this basic tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, so the description's argument explanations are essential. It adds meaning by defining title as a short name with an example ('Groceries') and content as the body text, which a schema that only lists string types does not convey. This is useful contextual meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Create a new note' states a specific verb (create) and resource (note) with the qualifier 'new', making it clear this tool adds a note rather than modifies or retrieves one. This clearly distinguishes it from sibling tools like update_note, read_note, and delete_note.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when a new note is needed but provides no explicit when-to-use/alternatives guidance. There is no mention of when to prefer this over update_note or other siblings, leaving inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_noteA

Delete a note permanently.

Args:
    title: The title of the note to delete.
ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral disclosure burden. It does state that deletion is permanent, which is a crucial destructive trait, but it does not address error behavior, idempotency, permissions, or what happens when the title does not exist. This is a minimal but not rich disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single clear sentence with a brief Args section. It is front-loaded with the core behavior and contains no filler or redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter destructive tool, the description covers the essential information: the action, the permanence, and the identifying parameter. An output schema exists, so return values need not be explained. Minor gaps like error behavior remain, but they are not critical for a simple delete operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It defines 'title' as 'The title of the note to delete,' which clarifies that the title is the identifier for the note to be removed. However, this largely restates the parameter name and adds no nuance about matching, case sensitivity, or uniqueness.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Delete') and resource ('note') with the key qualifier 'permanently,' which clearly distinguishes it from sibling tools like read_note, update_note, and search_notes. The intent is immediately obvious and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to use this tool versus alternatives, nor are any exclusions or prerequisites mentioned. The only implicit signal is the tool name and the verb 'delete,' which does not constitute explicit usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_notesA

List the titles of all saved notes.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully discloses that the tool returns only titles, not full note content, and that it covers all saved notes. However, it omits any detail about ordering, pagination, or access/read-only semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with no filler. Every word contributes meaning and the description is immediately scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple zero-parameter listing tool with an output schema available, the description adequately conveys what the tool returns. The main missing element is explicit routing to sibling tools, but the low complexity makes this a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the schema is empty with 100% coverage, so the baseline of 4 applies. No additional parameter explanation is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb, 'List', and a specific resource, 'titles of all saved notes'. It clearly distinguishes itself from single-item operations like read_note and mutations like add_note/delete_note through the 'all saved notes' scope, though it does not explicitly name or contrast those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. It does not mention search_notes for targeted retrieval or read_note for full content, leaving the selection logic entirely to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_noteB

Read the full content of one note.

Args:
    title: The title of the note to read.
ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the core read behavior but does not mention behavior on missing titles, error handling, or whether any uniqueness or exact-match constraints apply. The description adds minimal context beyond the tool name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, front-loaded with the purpose, and includes only the necessary parameter explanation. Every part earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple one-parameter signature and the presence of an output schema, the description is nearly complete for calling the tool. It could mention what to do when the title does not exist or how to discover valid titles, but those are not required to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description explicitly defines the single parameter, saying 'title: The title of the note to read.' This adds a little meaning beyond the schema, which only says the property is a string named 'title.' It does not add constraints, exact-match expectations, or format details, but for one simple string parameter that is adequate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Read') and the resource ('one note'), and 'full content' distinguishes it from list/search operations. It does not explicitly name sibling tools, but the verb-resource-scope combination makes the purpose clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not say when to use this tool versus alternatives such as list_notes or search_notes. It only describes the operation itself; any usage context such as 'when you already know the note's title' is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_notesA

Find notes whose title or content contains the query (case-insensitive).

Args:
    query: The text to search for.
ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It discloses that the search is case-insensitive and matches title or content, which is valuable. It does not explicitly state it is a read-only operation (though 'Find' implies this), nor does it mention result ordering, pagination, or limits. The description is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two compact sentences plus a one-line argument definition. It front-loads the main purpose and includes the case-insensitivity detail early. No fluff or redundancy; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple search tool with one parameter and an output schema present, the description covers the essential context: what is searched and how (case-insensitively). It does not mention result limits or error behavior, but the output schema likely handles return format. With no annotations, some behavior context is missing, but it is reasonably complete for the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does: 'query: The text to search for.' clearly explains the meaning and usage of the only parameter, adding value beyond the bare schema which only provides the type. It could elaborate on formatting or examples, but for a single string parameter this is sufficient.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Find') and resource ('notes'), and specifies that it searches both title and content for a query. This clearly differentiates it from siblings like list_notes (which lists all), read_note (which fetches a single note), and add/update/delete (which are mutations).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: use this when you need to locate notes by text content/title rather than listing all notes. However, it does not explicitly name sibling tools or state when not to use it (e.g., 'for listing all notes, use list_notes'). The purpose is clear enough that an agent can infer the intent, but no explicit routing is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_noteA

Replace the content of an existing note.

Args:
    title: The title of the note to update.
    content: The new body text (overwrites the old content).
ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes
contentYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It explicitly discloses that content 'overwrites the old content', which is critical destructive behavior. It does not mention error behavior for nonexistent notes, permission requirements, or idempotency, but the overwrite warning is meaningful and prevents an agent from assuming additive behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short and front-loaded: the first sentence states the purpose, and the Args list is a compact structured format for parameters. Every sentence contributes value, with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple update tool, the description covers the core behavior and both parameters. It does not discuss the case where the title does not exist or what the output contains, but an output schema exists and the overall context is small. A minor gap is the lack of explicit error or idempotency details, which prevents a perfect score.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does: 'title' is clearly the note identifier, and 'content' is the replacement body text with overwrite semantics. These descriptions go beyond the schema's raw 'string' type, giving an agent enough meaning to supply correct values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Replace') and resource ('existing note'), which clearly differentiates it from siblings like add_note, read_note, or delete_note. The verb 'replace' unambiguously indicates an update operation, so an agent can tell what this tool does without inspecting the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'existing note' implies this tool is used for modifying notes that already exist, and the overwrite semantics hint that it is not for creating new notes. However, it does not explicitly name alternatives, state when not to use it, or call out add_note for creating notes. The usage guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.0
    • First observedadd_note
    • First observeddelete_note
    • First observedlist_notes
    • First observedread_note
    • First observedsearch_notes
    • First observedupdate_note

TDQS

A4/5.0

Scored across 6 tools

Disambiguation5/5

Each tool maps to a distinct operation: create, update, list, read, search, and delete. There is no overlap or ambiguity in their purposes.

Naming Consistency5/5

All tools follow a clear verb_noun pattern with the note resource. The only minor variation is pluralization for list_notes and search_notes, but this is consistent with typical collection-returning conventions.

Tool Count5/5

Six tools cover the full lifecycle of a notes domain without redundancy. The count is well-scoped and each tool earns its place.

Completeness5/5

The server provides complete CRUD coverage plus search, with no obvious gaps. Users can create, read, list, update, delete, and find notes effectively.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    C
    maintenance
    MCP server for managing ParchMark notes via Claude Code/Desktop. Provides tools to list, get, create, update, and delete notes through natural language.
    5
    -
  • A
    license
    A
    quality
    C
    maintenance
    A note-taking MCP server for Claude-based agents that provides persistent markdown files for easily referable notes, supporting create, read, update, append, and delete operations.
    5
    Apache 2.0