npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hillnote/mcp-server

v0.6.0

Published

MCP server for Hillnote - AI-powered document management

Readme

Hillnote MCP Server

NPM Version License: MIT MCP SDK Platform Node

Official Model Context Protocol (MCP) server for Hillnote, enabling AI assistants to interact with your document workspaces programmatically.

Platform Support: Supports macOS, Windows, and Linux.

Features

  • 📁 Multi-Workspace Support - Manage multiple document workspaces
  • 📝 Document Management - Full CRUD operations for documents
  • 🔍 Smart Search - Fuzzy search with intelligent ranking across titles, tags, and content
  • ✏️ Content Manipulation - Advanced content editing with validation and preview
  • 🎯 AI Recipes - Manage and execute AI prompt recipes
  • 🛠️ HTML Tools - Create interactive HTML-based utilities
  • 📋 Database & Task Management - Create databases with rows, columns, views, and kanban boards for task tracking
  • 🎨 Slide Presentations - Two-phase slide creation with storytelling guides and visual design tools
  • 🎨 Canvas Drawings - Create and edit Excalidraw canvas drawings with shapes, text, arrows, and more
  • 🏷️ Metadata Support - Rich document metadata with tags, emojis, and descriptions

Requirements

  • macOS, Windows, or Linux
  • Hillnote Desktop App
  • Node.js >= 18.0.0
  • MCP-compatible client (Claude Desktop, Cursor, VS Code, etc.)

Installation

Option 1: Install from NPM (Recommended)

# Install globally (IMPORTANT: Use -g flag!)
npm install -g @hillnote/mcp-server

# Verify installation worked
npm list -g @hillnote/mcp-server

# If using Homebrew Node.js, the files will be in:
# /opt/homebrew/lib/node_modules/@hillnote/mcp-server/

⚠️ Important: The -g flag is required for global installation. Without it, the package installs locally and won't work with the Claude Desktop configuration.

Option 2: Install from Source

# Clone the repository
git clone https://github.com/HillnoteApp/hillnote-mcp-server.git
cd hillnote-mcp-server

# Install dependencies (NO -g flag needed here)
npm install

Updating to Latest Version

NPM Installation

# Update to the latest version
npm update -g @hillnote/mcp-server

# Or reinstall to force latest version
npm install -g @hillnote/mcp-server@latest

# Check current version
npm list -g @hillnote/mcp-server

# After updating, restart your MCP client (Claude Desktop, Cursor, etc.)

Source Installation

# Navigate to your cloned repository
cd /path/to/hillnote-mcp-server

# Pull latest changes
git pull origin main

# Reinstall dependencies
npm install

# After updating, restart your MCP client

Version Check

To see what version you're currently running:

# For NPM installation
npm list -g @hillnote/mcp-server

# For source installation
cd /path/to/hillnote-mcp-server
cat package.json | grep version

Troubleshooting Updates

If you experience issues after updating:

  1. Clear npm cache:

    npm cache clean --force
  2. Uninstall and reinstall:

    npm uninstall -g @hillnote/mcp-server
    npm install -g @hillnote/mcp-server
  3. Restart your MCP client completely (not just reload - fully quit and reopen)

Configuration

The MCP server automatically discovers all your Hillnote workspaces from the app's configuration:

  • macOS: ~/Library/Application Support/Hillnote/workspaces.json
  • Windows: %APPDATA%/Hillnote/workspaces.json
  • Linux: ~/.config/Hillnote/workspaces.json

Configuration Examples

NPM Installation

If installed via NPM, use your global Node modules path:

{
  "mcpServers": {
    "hillnote": {
      "command": "hillnote-mcp"
    }
  }
}

Find your path with: npm root -g

Source Installation

If cloned from GitHub:

{
  "mcpServers": {
    "hillnote": {
      "command": "node",
      "args": ["/path/to/hillnote-mcp-server/index.js"]
    }
  }
}

Client-Specific Configuration

Location: ~/Library/Application Support/Claude/claude_desktop_config.json

Add the configuration above to this file.

Location: Settings → Features → MCP

Add the configuration above to the MCP servers section.

Install an MCP extension and add the configuration to your settings.json or extension configuration.

Available Tools

📁 Workspace Management

list_workspaces

Lists all available workspaces with document counts and metadata.

// No input required
// Returns: Array of workspace objects with path, name, overview, and documentCount

read_registry

Get complete workspace overview including all documents, folders, and relationships.

// Input: { workspace: "workspace-name" }
// Returns: Complete registry with documents and folder structure

📄 Document Operations

read_document

Read a specific document's content and metadata.

// Input: { workspace: "workspace-name", documentId: "doc-id" }
// Returns: Document content, metadata, and frontmatter

add_document

Create a new document with content and metadata.

// Input: {
//   workspace: "workspace-name",
//   name: "Document Name",
//   content: "Document content",
//   emoji: "📄",
//   description: "Brief description",
//   parent: "optional-folder-id"
// }
// Returns: { success: true, documentId: "new-id", fileName: "document-name.md" }

update_document

Update an existing document's content or metadata.

// Input: {
//   workspace: "workspace-name",
//   documentId: "doc-id",
//   content: "New content",
//   name: "New Name",
//   emoji: "📝",
//   description: "Updated description"
// }
// Returns: { success: true }

rename_document

Rename a document and update its file name.

// Input: { workspace: "workspace-name", documentId: "doc-id", newTitle: "New Title" }
// Returns: { success: true, newFileName: "new-title.md" }

delete_document

Delete a document from the workspace.

// Input: { workspace: "workspace-name", documentId: "doc-id" }
// Returns: { success: true }

🔍 Search

search_documents

Search documents with fuzzy matching and smart ranking.

// Input: {
//   query: "search term",
//   workspace: "optional-workspace",
//   fuzzy: true,
//   threshold: 0.6,
//   limit: 10
// }
// Returns: Ranked search results with snippets and scores

✏️ Content Manipulation

insert_content

Insert content at a specific position with validation.

// Input: {
//   workspace: "workspace-name",
//   documentId: "doc-id",
//   position: "start" | "end" | number | { line: number } | { after: "heading" },
//   text: "Content to insert",
//   validate: true,
//   preview: true
// }
// Returns: { success: true, preview: "...", validation: {...} }

replace_content

Replace text in a document with preview and occurrence info.

// Input: {
//   workspace: "workspace-name",
//   documentId: "doc-id",
//   searchText: "text to find",
//   replaceText: "replacement text",
//   all: false,
//   caseSensitive: false,
//   wholeWord: false,
//   useRegex: false
// }
// Returns: { success: true, replacements: 1, preview: "..." }

delete_content

Delete content between positions or patterns.

// Input: {
//   workspace: "workspace-name",
//   documentId: "doc-id",
//   startPos: 0 | { line: 5 } | { pattern: "## Section" },
//   endPos: 100 | { line: 10 } | { pattern: "## Next Section" }
// }
// Returns: { success: true, deletedChars: 95, preview: "..." }

append_to_section

Append content to a specific markdown section.

// Input: {
//   workspace: "workspace-name",
//   documentId: "doc-id",
//   sectionHeading: "## Notes",
//   content: "Additional notes"
// }
// Returns: { success: true }

🎯 AI Recipe Management

Recipes are AI prompt overrides that trigger custom instructions when a user's request matches specific topics.

list_recipes

List all AI prompt recipes in a workspace.

// Input: { workspacePath: "/path/to/workspace" }
// Returns: Array of recipe objects with metadata

get_recipe

Get a specific recipe by ID.

// Input: { workspacePath: "/path/to/workspace", recipeId: "recipe-id" }
// Returns: Complete recipe with trigger, instructions, and document references

create_recipe

Create a new AI prompt recipe.

// Input: {
//   workspacePath: "/path/to/workspace",
//   recipe: {
//     when_user_asks_about: "quarterly reports",
//     override_instructions: "Use the company template and include KPIs...",
//     required_documents: ["documents/template.md"],
//     optional_documents: ["documents/past-reports.md"],
//     output_format: "markdown"
//   }
// }
// Returns: { success: true, recipe: { id: "recipe_...", ... } }

update_recipe

Update an existing recipe.

// Input: {
//   workspacePath: "/path/to/workspace",
//   recipeId: "recipe-id",
//   updates: {
//     when_user_asks_about: "updated trigger",
//     override_instructions: "updated instructions"
//   }
// }
// Returns: { success: true }

get_recipe_documents

Load the content of documents referenced by a recipe.

// Input: { workspacePath: "/path/to/workspace", recipeId: "recipe-id", includeOptional: true }
// Returns: { recipe: {...}, documents: { required: [...], optional: [...] } }

📋 Database & Task Management

Databases are flexible folders containing markdown files (rows) with a database.json configuration. They can be used as task boards by adding status columns with kanban views.

create_database

Create a new database in a workspace.

// Input: {
//   workspace: "workspace-name",
//   name: "Project Tasks",
//   columns: [
//     { id: "title", name: "Title", type: "title" },
//     { id: "status", name: "Status", type: "status",
//       options: ["To Do", "In Progress", "Done", "Archived"],
//       optionColors: { "To Do": "gray", "In Progress": "amber", "Done": "emerald", "Archived": "purple" },
//       optionStates: { "To Do": "normal", "In Progress": "normal", "Done": "done", "Archived": "archive" }
//     },
//     { id: "priority", name: "Priority", type: "select", options: ["Low", "Medium", "High"] },
//     { id: "recurring", name: "Recurring", type: "recurring" }
//   ],
//   views: [
//     { id: "kanban", name: "Board", type: "kanban", groupBy: "status" },
//     { id: "table", name: "Table", type: "table" }
//   ],
//   defaultView: "kanban",
//   folderPath: "optional/subfolder"
// }
// Returns: { success: true, name: "...", path: "..." }

Column types: title, text, number, select, multiselect, status, checkbox, date, url, email, recurring

Status columns support optionStates mapping each option to "normal", "done" (strikethrough), or "archive" (dimmed) — enabling kanban board behaviour.

Recurring columns support auto-resetting tasks on daily/weekly/monthly/yearly schedules.

read_database

Read a database with optional filtering, sorting, and searching.

// Input: {
//   workspace: "workspace-name",
//   databasePath: "Project Tasks",
//   search: "optional search query",
//   filters: [{ column: "status", operator: "equals", value: "In Progress" }],
//   sort: { column: "priority", direction: "desc" },
//   viewId: "kanban",
//   limit: 50
// }
// Returns: Database config (columns, views) and matching rows

list_databases

List all databases in a workspace.

// Input: { workspace: "workspace-name" }
// Returns: Array of databases with metadata and row counts

delete_database

Delete a database and all its rows permanently.

// Input: { workspace: "workspace-name", databasePath: "Project Tasks" }
// Returns: { success: true }

add_rows

Add one or more rows to a database.

// Input: {
//   workspace: "workspace-name",
//   databasePath: "Project Tasks",
//   rows: [
//     { title: "Implement feature X", status: "To Do", priority: "High", _content: "Task details..." },
//     { title: "Fix bug Y", status: "In Progress", priority: "Medium" }
//   ]
// }
// Returns: { success: true, added: [...] }

update_rows

Update rows by ID (file path) or matching criteria.

// Input: {
//   workspace: "workspace-name",
//   databasePath: "Project Tasks",
//   updates: { status: "Done", priority: "Low" },
//   ids: ["/path/to/row.md"],       // by file path
//   where: { status: "In Progress" } // or by criteria
// }
// Returns: { success: true, updated: [...] }

delete_rows

Delete rows by ID or matching criteria.

// Input: {
//   workspace: "workspace-name",
//   databasePath: "Project Tasks",
//   ids: ["/path/to/row.md"],
//   where: { status: "Archived" }
// }
// Returns: { success: true }

add_column

Add a new column to a database.

// Input: {
//   workspace: "workspace-name",
//   databasePath: "Project Tasks",
//   column: { id: "assignee", name: "Assignee", type: "text" },
//   defaultValue: "Unassigned"
// }
// Returns: { success: true }

update_column

Update column properties (name, type, options, colors, states).

// Input: {
//   workspace: "workspace-name",
//   databasePath: "Project Tasks",
//   columnId: "status",
//   updates: { options: ["To Do", "In Progress", "Review", "Done"] }
// }
// Returns: { success: true }

delete_column

Remove a column from a database and all rows.

// Input: { workspace: "workspace-name", databasePath: "Project Tasks", columnId: "priority" }
// Returns: { success: true }

create_view

Create a saved view with filters, sorts, and display options.

// Input: {
//   workspace: "workspace-name",
//   databasePath: "Project Tasks",
//   view: {
//     name: "Active Tasks",
//     type: "kanban",        // table, kanban, gallery, chart
//     groupBy: "status",
//     filters: [{ column: "status", operator: "notEquals", value: "Archived" }],
//     sorts: [{ column: "priority", direction: "desc" }]
//   }
// }
// Returns: { success: true, viewId: "..." }

list_views

List all saved views for a database.

// Input: { workspace: "workspace-name", databasePath: "Project Tasks" }
// Returns: Array of view configurations

🎨 Slide Presentations

Slides use a two-phase workflow: write the story first, then add visual design.

get_slides_story_guide

Get the storytelling guide with 8 proven techniques (Hero's Journey, Sparklines, In Medias Res, etc.).

// No input required
// Returns: Story-writing guide with narrative techniques and structure advice
// Important: Do NOT use any visual layout markers (~split, ~inline, ~bg-, etc.) during this phase

get_slides_visual_guide

Get the visual design guide for adding layout markers, images, charts, and diagrams.

// Input: { documentPath: "documents/my-presentation.slides.md" }
// Returns: Visual design guide with layout markers, chart types, mermaid diagrams, and examples
// Note: Requires the .slides.md file to already exist (proves story has been drafted)

Important: When creating slides with add_document, the title MUST end with .slides.md (e.g., "My Presentation.slides.md"). The .slides.md extension is what makes it a slide presentation.

Example workflow:

// 1. Get the story guide first
get_slides_story_guide()

// 2. Create the slide presentation (story content only, no visual markers)
add_document({
  workspace: "workspace-name",
  name: "Quarterly Review.slides.md",  // Note: ends with .slides.md
  content: `---
type: slides
theme: minimal
---

# Quarterly Review

Q4 2024 Results

***

# Key Metrics

- Revenue: $1.2M
- Growth: 25%
- Users: 10,000+
`
})

// 3. Get the visual guide and enhance slides in batches of 3-5
get_slides_visual_guide({ documentPath: "documents/quarterly-review.slides.md" })
// Then edit the file to add ~split, ~inline, ~bg-, images, charts, etc.

🎨 Canvas Drawings

get_canvas_guide

Get the comprehensive guide for creating and editing Excalidraw canvas drawings in Hillnote.

// No input required
// Returns: Complete guide with element types, layout planning, spacing rules, colors, and best practices

Important: When creating a canvas with add_document, the title MUST end with .canvas.md (e.g., "Architecture Diagram.canvas.md"). Do NOT provide content — the system generates it automatically.

read_canvas

Read and parse a canvas file, returning a structured description of all elements.

// Input: { workspace: "workspace-name", canvasPath: "documents/my-drawing.canvas.md" }
// Returns: { canvasPath: "...", elementCount: 5, elements: [...] }

add_canvas_elements

Add shapes, text, arrows, and other elements to a canvas file.

// Input: {
//   workspace: "workspace-name",
//   canvasPath: "documents/my-drawing.canvas.md",
//   elements: [
//     { type: "rectangle", x: 0, y: 0, width: 200, height: 100, label: "Start", backgroundColor: "#a5d8ff" },
//     { type: "arrow", x: 200, y: 50, points: [[0, 0], [100, 0]] },
//     { type: "rectangle", x: 300, y: 0, width: 200, height: 100, label: "End", backgroundColor: "#b2f2bb" },
//     { type: "text", x: 0, y: 120, text: "My Diagram", fontSize: 28 }
//   ]
// }
// Returns: { success: true, added: 4, totalElements: 4, elementIds: [...] }

Supported element types: rectangle, ellipse, diamond, text, arrow, line

Element properties:

  • Position/size: x, y, width, height
  • Styling: strokeColor, backgroundColor, fillStyle (solid/hachure/cross-hatch), strokeWidth, roughness (0-2), opacity (0-100)
  • Text: text, fontSize, fontFamily (1=Virgil, 2=Helvetica, 3=Cascadia, 5=Excalifont), textAlign
  • Arrows/lines: points (e.g., [[0,0],[200,100]]), startArrowhead, endArrowhead
  • Shapes: label (centered text inside rectangle/ellipse/diamond)
  • Grouping: groupId

clear_canvas

Remove all elements from a canvas file, giving a blank slate.

// Input: { workspace: "workspace-name", canvasPath: "documents/my-drawing.canvas.md" }
// Returns: { success: true, message: "All elements cleared from canvas" }

Example workflow:

// 1. Get the canvas guide first
get_canvas_guide()

// 2. Create a new canvas
add_document({
  workspace: "workspace-name",
  name: "Architecture Diagram.canvas.md"  // Note: ends with .canvas.md, no content needed
})

// 3. Add elements to the canvas
add_canvas_elements({
  workspace: "workspace-name",
  canvasPath: "documents/architecture-diagram.canvas.md",
  elements: [
    { type: "text", x: 0, y: 0, text: "System Architecture", fontSize: 28 },
    { type: "rectangle", x: 0, y: 50, width: 200, height: 80, label: "Frontend", backgroundColor: "#a5d8ff" },
    { type: "arrow", x: 200, y: 90, points: [[0, 0], [100, 0]] },
    { type: "rectangle", x: 300, y: 50, width: 200, height: 80, label: "Backend", backgroundColor: "#b2f2bb" }
  ]
})

// 4. To redraw from scratch
clear_canvas({ workspace: "workspace-name", canvasPath: "documents/architecture-diagram.canvas.md" })
// Then add_canvas_elements again with new elements

🛠️ HTML Tool Management

add_html_tool

Create an interactive HTML tool in the workspace.

// Input: {
//   workspacePath: "/path/to/workspace",
//   toolName: "calculator",
//   description: "Scientific calculator",
//   category: "utilities",  // optional
//   files: [
//     { filename: "index.html", content: "<!DOCTYPE html>...", isEntryPoint: true },
//     { filename: "styles.css", content: "body { ... }" },
//     { filename: "script.js", content: "// JS code" }
//   ]
// }
// Returns: { success: true, path: "resources/html/calculator", entryPoint: "index.html", markdownLink: "[html:calculator](...)" }

edit_html_tool

Edit files in an existing HTML tool (create, update, or delete files).

// Input: {
//   workspacePath: "/path/to/workspace",
//   toolName: "calculator",
//   category: "utilities",  // optional
//   operations: [
//     { action: "update", filename: "index.html", content: "<!DOCTYPE html>..." },
//     { action: "create", filename: "utils.js", content: "// new file" },
//     { action: "delete", filename: "old-file.js" }
//   ],
//   updateMetadata: { description: "Updated calculator" }
// }
// Returns: { success: true, changes: { created: [...], updated: [...], deleted: [...] } }

add_tool_to_doc

Insert an HTML tool reference into a document.

// Input: {
//   workspacePath: "/path/to/workspace",
//   documentPath: "documents/my-doc.md",
//   toolName: "calculator",
//   displayName: "My Calculator",  // optional
//   position: "end"  // "end", "beginning", or "after:<text>"
// }
// Returns: { success: true, toolLink: "[html:My Calculator](...)" }

list_html_tools

List all HTML tools in a workspace.

// Input: { workspacePath: "/path/to/workspace", category: "utilities" }
// Returns: Array of HTML tools with metadata and markdown links

get_html_tool

Get a specific HTML tool's details and files.

// Input: { workspacePath: "/path/to/workspace", toolName: "calculator", category: "utilities" }
// Returns: Tool info with all file contents, entry point, and markdown link

read_html_file

Read the content of a specific file inside an HTML tool.

// Input: { workspacePath: "/path/to/workspace", filePath: "resources/html/calculator/index.html" }
// Returns: { filePath: "...", content: "..." }

write_html_file

Write or create a file inside an HTML tool folder.

// Input: { workspacePath: "/path/to/workspace", filePath: "resources/html/calculator/style.css", content: "body { ... }" }
// Returns: { success: true, filePath: "..." }

replace_in_html_file

Find and replace text in an HTML tool file.

// Input: {
//   workspacePath: "/path/to/workspace",
//   filePath: "resources/html/calculator/index.html",
//   searchText: "<title>Old Title</title>",
//   replaceText: "<title>New Title</title>"
// }
// Returns: { success: true, filePath: "..." }

Workspace Structure

Hillnote workspaces are typically stored in your Documents folder or custom locations:

~/Documents/YourWorkspace/
├── readme.md                 # Workspace overview
├── documents-registry.json   # Document metadata
├── ai_prompt_overrides.json # AI prompt recipes/overrides
├── documents/               # Markdown documents and databases
│   ├── document-1.md
│   ├── folder/
│   │   └── document-2.md
│   └── Project Tasks/       # Database (e.g., task board)
│       ├── database.json    # Database configuration (columns, views)
│       ├── implement-feature-x.md  # Row (task) with frontmatter
│       └── fix-bug-y.md    # Row (task) with frontmatter
└── resources/               # Assets and tools
    ├── images/             # Image attachments
    └── html/               # HTML tools
        └── tool-name/
            ├── index.html
            └── assets/

Document Format

Documents use Markdown with YAML frontmatter:

---
title: Document Title
tags: [tag1, tag2]
emoji: 📄
description: Brief description
created: 2024-01-01T00:00:00Z
modified: 2024-01-02T00:00:00Z
---

# Document Title

Your content here...

Development

Project Structure

mcp-server/
├── index.js                 # Main server entry point
├── config.json             # Server configuration
├── package.json            # Dependencies
├── src/
│   ├── tools/
│   │   ├── index.js       # Tool aggregator
│   │   ├── workspace.js   # Workspace tools
│   │   ├── document.js    # Document tools
│   │   ├── content.js     # Content manipulation
│   │   ├── search.js      # Search tools
│   │   ├── recipe.js      # Recipe management
│   │   ├── html-tool.js   # HTML tool management
│   │   ├── database.js    # Database, row, column, and view management
│   │   ├── slides.js      # Slide presentation guides (story + visual)
│   │   └── canvas.js      # Excalidraw canvas drawings
│   └── utils/
│       └── helpers.js     # Utility functions
└── README.md

Adding New Tools

  1. Create a new tool file in src/tools/
  2. Export tool definitions and handlers
  3. Import in src/tools/index.js
  4. Tools are automatically available to MCP clients

Running in Development

# Enable watch mode
npm run dev

# Run the server
npm start

Error Handling

All tools use structured error responses:

  • InvalidParams: Missing or invalid parameters
  • InternalError: Server-side errors
  • MethodNotFound: Unknown tool name

Security

  • File operations are sandboxed to workspace directories
  • No network requests are made
  • Path traversal protection included
  • Input validation on all operations

License

MIT - See LICENSE file

Support


Built with ❤️ by Rajath Bail