Skip to main content
Glama
ah-oh

handbook-mcp-server

by ah-oh

handbook-mcp-server

An MCP (Model Context Protocol) server for the Handbook API by ah-oh.com. Enables full management of handbook entries directly from Claude Desktop, Claude Code, VS Code Copilot, and other MCP-compatible clients.


Features

Tool

Description

handbook_list_entries

List all handbook entries

handbook_get_entry

Retrieve a single entry by ID (including markdown content)

handbook_create_entry

Create a new entry

handbook_update_entry

Update an existing entry

handbook_delete_entry

Delete an entry

handbook_get_overview

Compact overview of all entries per app

handbook_search_tags

Search tags across all entries


Related MCP server: MCP Audio Server

Prerequisites

  • Node.js >= 18

  • Bearer Token for the Handbook API


Installation

Option A: Install from npm

npm install -g @ah-oh/handbook-mcp-server

Option B: Build from source

git clone https://github.com/ah-oh/handbook-mcp-server.git
cd handbook-mcp-server
npm install
npm run build

Configuration

Environment Variables

Variable

Required

Default

Description

HANDBOOK_API_TOKEN

Yes

Bearer token for the Handbook API

HANDBOOK_API_URL

No

https://handbook.ah-oh.com/handbook-api

Base URL of the API

TRANSPORT

No

stdio

Transport mode: stdio or http

PORT

No

3000

Port for HTTP transport


Usage

Claude Desktop

Add the following to your claude_desktop_config.json:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "handbook": {
      "command": "node",
      "args": ["/absolute/path/to/handbook-mcp-server/dist/index.js"],
      "env": {
        "HANDBOOK_API_TOKEN": "your-bearer-token"
      }
    }
  }
}

If installed globally via npm:

{
  "mcpServers": {
    "handbook": {
      "command": "handbook-mcp-server",
      "env": {
        "HANDBOOK_API_TOKEN": "your-bearer-token"
      }
    }
  }
}

Claude Code

claude mcp add handbook -- node /path/to/handbook-mcp-server/dist/index.js \
  --env HANDBOOK_API_TOKEN=your-bearer-token

VS Code (Copilot / Continue)

In .vscode/mcp.json:

{
  "servers": {
    "handbook": {
      "command": "node",
      "args": ["/path/to/handbook-mcp-server/dist/index.js"],
      "env": {
        "HANDBOOK_API_TOKEN": "your-bearer-token"
      }
    }
  }
}

HTTP Mode (Remote)

TRANSPORT=http HANDBOOK_API_TOKEN=your-token PORT=3000 npm start

The server will listen on http://localhost:3000/mcp.


Examples

Once the MCP server is connected, you can ask Claude things like:

  • "Show me all handbook entries"

  • "Create a new entry titled 'Onboarding Guide' for the app szales"

  • "Update the entry with ID 65c4e1f5... – set the content to ..."

  • "Which tags start with 'meet'?"

  • "Give me an overview of all entries for the app sethub"

  • "Delete entry 65c4e1f5..."


Publishing to the MCP Registry

The official MCP Registry makes your server discoverable by all MCP clients. Here's the step-by-step guide:

Step 1: Replace placeholders

Replace ah-oh everywhere in the project with your GitHub username:

# macOS
find . -type f \( -name "*.json" -o -name "*.md" \) \
  -exec sed -i '' 's/ah-oh/my-github-user/g' {} +

# Linux
find . -type f \( -name "*.json" -o -name "*.md" \) \
  -exec sed -i 's/ah-oh/my-github-user/g' {} +

This affects the following files:

  • package.json – fields name, mcpName, repository, homepage, bugs

  • server.json – fields name, repository, packages[0].identifier

  • README.md – links and install command

Step 2: Publish to npm

# Log in to npm (one-time)
npm login

# Publish the package
npm publish --access public

Note: The MCP Registry only hosts metadata, not the code itself. Your package must first be available on npm (or PyPI, Docker Hub, etc.).

Step 3: Install the mcp-publisher CLI

curl -L \
  "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" \
  | tar xz mcp-publisher && sudo mv mcp-publisher /usr/local/bin/

# Verify
mcp-publisher --help

Step 4: Log in to the registry

mcp-publisher login github

This opens the browser for GitHub OAuth. You'll get access to the namespace io.github.ah-oh/*.

Alternative (custom domain, e.g. com.ah-oh/*):

# Generate an Ed25519 keypair
openssl genpkey -algorithm Ed25519 -out key.pem

# Host the public key at https://ah-oh.com/.well-known/mcp-registry-auth
# Then:
mcp-publisher login http --domain=ah-oh.com --private-key=HEX_KEY

Step 5: Publish

# Dry run first
mcp-publisher publish --dry-run

# Publish for real
mcp-publisher publish

Your server will then be discoverable at registry.modelcontextprotocol.io and automatically picked up by downstream registries (GitHub, VS Code, etc.).

Step 6 (Optional): Automation via GitHub Actions

The project includes a ready-made workflow file at .github/workflows/publish.yml. It automatically publishes to npm and the MCP Registry on every git tag (v*).

Setup:

  1. Go to npmjs.com → Access Tokens → Create a new token

  2. In GitHub → Repository → Settings → Secrets and Variables → Actions → Add NPM_TOKEN as a secret

  3. Tag a release and push:

git tag v1.0.0
git push origin v1.0.0

The pipeline takes care of the rest.

Updating the version

For new versions:

  1. Bump the version in package.json and server.json

  2. Create and push a new tag:

npm version patch   # or minor / major
git push origin v$(node -p "require('./package.json').version")

Project Structure

handbook-mcp-server/
├── .github/workflows/
│   └── publish.yml          # CI/CD: npm + MCP Registry
├── src/
│   ├── index.ts             # Entry point (stdio + HTTP)
│   ├── constants.ts         # API URL, limits
│   ├── types.ts             # TypeScript interfaces
│   ├── schemas/
│   │   └── handbook-entry.ts # Zod validation schemas
│   ├── services/
│   │   ├── api-client.ts    # HTTP client for the Handbook API
│   │   └── formatting.ts    # Markdown formatting
│   └── tools/
│       └── handbook-entry.ts # Tool registrations
├── dist/                    # Compiled JS files
├── package.json
├── tsconfig.json
├── server.json              # MCP Registry metadata
└── README.md

Development

# Install dependencies
npm install

# Build TypeScript (one-time)
npm run build

# TypeScript watch mode
npm run dev

# Start server (stdio)
npm start

# Start server (HTTP)
TRANSPORT=http npm start

API Reference

Based on the Handbook OpenAPI specification.

All endpoints require Bearer token authentication. The MCP server handles auth headers automatically – you only need to set HANDBOOK_API_TOKEN.


License

MIT

Available Tools

6 tools
handbook_create_entryCreate Handbook EntryA

Create a new handbook entry.

Args:

  • title (string): Entry title

  • content (string, optional): Markdown content

  • active (boolean): Whether the entry is active

  • app (string): App identifier (e.g. 'szales', 'sethub')

  • tags (string[], optional): Tags

  • importId (string, optional): Import ID

Returns: The created HandbookEntry.

ParametersJSON Schema
NameRequiredDescriptionDefault
appYesThe app associated with this entry (e.g. 'szales', 'sethub')
tagsNoTags for the entry, e.g. ['meeting', 'project']
titleYesTitle of the handbook entry
activeYesWhether the entry is active
contentNoContent of the entry in markdown format
importIdNoOptional import ID for entries imported from sethub language content

TDQS

A3.6/5.0
Behavior3/5

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

Annotations indicate readOnlyHint=false and destructiveHint=false, which are consistent with a creation operation. The description adds the return type ('Returns: The created HandbookEntry') but does not disclose other behavioral traits like required permissions or side effects.

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

Conciseness4/5

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

The description is structured with a clear first sentence and a parameter list, and includes a return statement. It is not overly verbose, though the parameter list is redundant with the schema.

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

Completeness3/5

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

The description covers the tool's purpose and parameters. With no output schema, it mentions the return type but lacks detail on the returned object's structure. For a creation tool, this is adequate but not fully complete.

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 100%; all parameters have descriptions in the schema. The description enumerates the parameters with types and optionality but adds little semantic value beyond what the schema already provides.

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 starts with 'Create a new handbook entry,' clearly stating the verb and resource. It distinguishes from siblings such as handbook_update_entry (update) and handbook_list_entries (list), as those are separate tools.

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?

No explicit guidance on when to use this tool versus alternatives. The sibling tools are listed, but the description does not indicate prerequisites, context, or when not to use this tool.

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

handbook_get_entryGet Handbook EntryA
Read-onlyIdempotent

Retrieve a single handbook entry by its ID, including full content in markdown.

Args:

  • id (string): The MongoDB ObjectId of the entry

Returns: Full HandbookEntry object with content.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe ID of the handbook entry to retrieve

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already confirm read-only, idempotent, non-destructive. Description adds that content is in markdown and returns a full object, which is useful context. No contradictions.

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?

Two concise, well-structured sentences. First line states purpose, then docstring-style breakdown. No wasted words.

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?

Covers purpose, parameter, and return value well. Simple tool with one param and no output schema, so description is adequate. Could mention error handling briefly.

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 has 100% coverage, baseline 3. Description adds 'MongoDB ObjectId' detail not in schema, providing format guidance beyond the schema's generic 'ID'.

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?

Description clearly states 'Retrieve a single handbook entry by its ID' with a specific verb and resource. Distinguishes from siblings like handbook_list_entries and handbook_create_entry.

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?

No explicit when-to-use or when-not-to-use guidance. While it's implied for retrieving a specific entry, it doesn't contrast with siblings like handbook_search_tags or handbook_list_entries.

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

handbook_get_overviewGet Handbook OverviewA
Read-onlyIdempotent

Get a lightweight overview of all handbook entries for a specific app. Returns only title, ID, app and tags (no full content).

Args:

  • app (string): App identifier (e.g. 'szales', 'sethub')

Returns: HandbookOverviewResponse with an array of overview entries.

ParametersJSON Schema
NameRequiredDescriptionDefault
appYesThe app to get overview entries for (e.g. 'szales', 'sethub')

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnly, openWorld, idempotent, non-destructive. The description adds the lightweight nature and specifies which fields are returned (title, ID, app, tags), enhancing transparency beyond annotations.

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?

Highly concise: two short paragraphs covering purpose, arguments, and return type with zero waste. Front-loaded with key information.

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

Completeness5/5

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

Despite no output schema, the description explains the return structure (array of overview entries). For a simple overview tool with one parameter, it is completely sufficient.

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 coverage is 100% with an adequate parameter description. The tool description repeats the parameter example, adding marginal value; baseline 3 is appropriate.

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 clearly states it gets a lightweight overview of handbook entries for a specific app, returning only title, ID, app, and tags. It distinguishes from siblings like handbook_get_entry (which likely returns full content) and other CRUD tools.

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 lightweight overview is needed rather than full content, but does not explicitly contrast with siblings or state when not to use it.

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

handbook_list_entriesList Handbook EntriesA
Read-onlyIdempotent

Retrieve all handbook entries. Returns a list with title, ID, app, active status and tags for every entry.

Returns: Array of HandbookEntry objects.

Use when: you need an overview of all existing entries or want to find an entry ID.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, so the safety profile is clear. The description adds that it returns a list of objects with specific fields, but does not disclose any additional behavioral traits (e.g., pagination, rate limits).

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 very concise, with two paragraphs. The first sentence states the purpose, the second lists return fields, and the third gives usage guidance. Every sentence is valuable 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?

Given no parameters and rich annotations, the description is adequate. It explains the return fields and when to use it. However, it could mention whether results are paginated or ordered, but for a simple list tool, it is mostly complete.

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?

There are no parameters (0), so the schema coverage is 100%. The baseline for 0 parameters is 4. The description does not need to add parameter semantics, and it correctly omits any.

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 clearly states 'Retrieve all handbook entries' with a specific verb and resource. It distinguishes itself from siblings like handbook_get_entry (single entry) and handbook_search_tags by focusing on listing all entries, and explicitly mentions its use for an overview.

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

Usage Guidelines4/5

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

The description explicitly says 'Use when: you need an overview of all existing entries or want to find an entry ID.' This provides clear guidance, though it does not mention when not to use it or list alternatives directly.

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

handbook_search_tagsSearch Handbook TagsA
Read-onlyIdempotent

Search for tags across all handbook entries.

Args:

  • searchQuery (string): Search string to filter tags (e.g. 'meet')

Returns: HandbookTagsResponse with an array of matching tag strings.

ParametersJSON Schema
NameRequiredDescriptionDefault
searchQueryYesSearch query to filter handbook tags (e.g. 'meet')

TDQS

A3.7/5.0
Behavior3/5

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

Annotations already indicate readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the tool's safety profile is clear. The description adds return structure ('HandbookTagsResponse with array of matching tag strings') but does not disclose other behaviors like case sensitivity, pagination, or limits.

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

Conciseness4/5

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

The description is short and front-loaded with the main purpose. The Args/Returns section adds some redundancy but is not excessively long. Could be slightly more concise.

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 tool with one parameter and no output schema, the description covers the essential aspects. It lacks details on pagination or result limits, but given the low complexity, it is fairly complete.

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 coverage is 100% and includes a description for searchQuery. The description repeats the param info without adding new meaning, so baseline of 3 applies.

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 clearly states 'Search for tags across all handbook entries.' It uses a specific verb ('Search') and resource ('tags'), and the scope is explicit. Sibling tools deal with handbook entries (list, get, create, etc.), so this tool is well-differentiated.

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 for tag searching but does not explicitly state when to use this tool versus alternatives (e.g., filtering entries instead). No guidance on when not to use it or prerequisites.

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

handbook_update_entryUpdate Handbook EntryA
Idempotent

Update an existing handbook entry by ID.

Args:

  • id (string): ID of the entry to update

  • title (string): Updated title

  • content (string, optional): Updated markdown content

  • active (boolean): Active status

  • app (string): App identifier

  • tags (string[], optional): Updated tags

  • importId (string, optional): Import ID

Returns: The updated HandbookEntry.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe ID of the handbook entry to update
appYesThe app associated with this entry
tagsNoUpdated tags
titleYesUpdated title
activeYesWhether the entry is active
contentNoUpdated content in markdown format
importIdNoOptional import ID

TDQS

A3.6/5.0
Behavior3/5

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

The description correctly indicates a mutation (update) but adds no additional behavioral context beyond the annotations; no information about preconditions, error behavior, or effects on related data.

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

Conciseness4/5

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

The description is structured with a clear statement and Args/Returns sections, but the Args section essentially duplicates the schema, making it slightly longer than necessary.

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

Completeness3/5

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

The description lacks details about the return value format and potential errors; while annotations and schema cover basics, the description could be more complete for proper usage.

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?

All parameters are already well-documented in the input schema; the description merely lists them without additional semantics, providing no added value.

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 clearly states the action (update) and the resource (handbook entry), and references the identifier (ID), making it easy to distinguish from create and list tools.

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 does not provide explicit guidance on when to use this tool versus the sibling tools; it only implies update through the verb, but lacks comparison or context.

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. Dates show when Glama detected each change.

  1. 6 tool updatesv1.0.1
    • First observedhandbook_create_entry
    • First observedhandbook_get_entry
    • First observedhandbook_get_overview
    • First observedhandbook_list_entries
    • First observedhandbook_search_tags
    • First observedhandbook_update_entry

TDQS

A3.9/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: listing all entries, retrieving by ID, creating, updating, getting an app-specific overview, and searching tags. No overlapping functionality.

Naming Consistency5/5

All tools follow a consistent 'handbook_verb_noun' pattern using snake_case, making it easy to predict tool names.

Tool Count5/5

Six tools is appropriate for a handbook management server, covering core CRUD operations plus overview and tag search without being excessive.

Completeness3/5

CRUD is missing delete functionality, and there is no tool to toggle an entry's active status independently, leaving a notable gap in lifecycle management.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

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/ah-oh/handbook-mcp-server'

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