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

git-doc-mcp

v0.2.3

Published

Turn any manifest URL into a fully-functional MCP server

Readme

git-doc-mcp - Turn Any Manifest into an MCP Server

npm version License: MIT Node.js TypeScript Linux macOS Windows

Write a manifest, host it anywhere, and users can instantly use it with their AI tools.

What is git-doc-mcp?

git-doc-mcp is a declarative MCP manifest system that lets anyone create and host MCP servers without running infrastructure. It turns any manifest URL into a fully-functional MCP server with custom tools, resources, and prompts - all defined in YAML.

Key features:

  • No hosting required - Use GitHub Pages, GitLab Pages, S3, any static hosting
  • Custom JavaScript actions - Define your own tool logic
  • Capability-scoped secrets - Fine-grained access control with URL pattern matching
  • Platform-agnostic - Works with GitHub, GitLab, S3, local files
  • TOFU manifest verification - Trust-on-first-use with fail-closed security
  • Three-layer isolation - Worker process + isolated-vm + URL validation
  • Cross-platform - Linux, macOS, Windows

Quick Start

1. Install

# Using npm
npm install -g git-doc-mcp

# Using npx (no install needed)
npx git-doc-mcp --manifest https://example.com/.mcp/manifest.yml

2. Configure with Claude Code

Add to ~/.claude/config.json:

{
  "mcpServers": {
    "my-repo": {
      "command": "npx",
      "args": ["git-doc-mcp", "--manifest", "https://example.com/.mcp/manifest.yml"]
    }
  }
}

3. Create Your Manifest

Create .mcp/manifest.yml in your repository:

schemaVersion: "1.0"
name: my-repo-mcp
version: 1.0.0
description: MCP server for my repository

tools:
  - name: fetch-file
    description: Fetch a file from the repository
    inputSchema:
      type: object
      properties:
        path: { type: string }
      required: [path]
    action: https://example.com/.mcp/actions/fetch-file.v1.js  # URL or local path
    actionHash: "sha256:..."
    annotations:
      readOnlyHint: true
      openWorldHint: true

Actions can reference HTTP(S) URLs or local file paths (relative to the manifest file's directory):

# Remote action (hosted)
action: https://raw.githubusercontent.com/owner/repo/main/.mcp/actions/fetch-file.v1.js

# Local action (for development)
action: ./actions/fetch-file.v1.js

Try It — Live Demo

This project uses its own manifest system to serve documentation. Add it to your AI tool to see git-doc-mcp in action:

Claude Code — add to your project's .mcp.json:

{
  "mcpServers": {
    "git-doc-mcp-docs": {
      "command": "npx",
      "args": [
        "git-doc-mcp",
        "--manifest",
        "https://raw.githubusercontent.com/Z-M-Huang/git-doc-mcp/main/.mcp/manifest.yml"
      ]
    }
  }
}

Claude Desktop — add to ~/.claude/claude_desktop_config.json:

{
  "mcpServers": {
    "git-doc-mcp-docs": {
      "command": "npx",
      "args": [
        "git-doc-mcp",
        "--manifest",
        "https://raw.githubusercontent.com/Z-M-Huang/git-doc-mcp/main/.mcp/manifest.yml"
      ]
    }
  }
}

This gives you 5 tools, 3 resources, and 3 prompts that fetch documentation from the project wiki:

| Tool | Description | |------|-------------| | list_topics | Browse documentation topics, filter by tag | | get_guide | Fetch a specific guide (e.g., Getting-Started, Manifest-Reference) | | search_docs | Search across all documentation by keyword | | get_example | Get complete working examples (GitHub tools, REST wrapper, etc.) | | get_action_api | Action scripting API reference (ctx.fetch, ctx.getSecret, etc.) |

The manifest source and action scripts serve as a reference for building your own.

Installation

npm

npm install -g git-doc-mcp

npx (no install)

npx git-doc-mcp --manifest <url-or-path>

Local Development

git clone https://github.com/Z-M-Huang/git-doc-mcp.git
cd git-doc-mcp
npm install
npm run build

Usage Examples

Public Manifest

npx git-doc-mcp --manifest https://raw.githubusercontent.com/owner/repo/main/.mcp/manifest.yml

Private Manifest with Authentication

npx git-doc-mcp --manifest https://private.example.com/.mcp/manifest.yml \
  --manifest-header "Authorization: Bearer $TOKEN"

Local Development

# Manifest and action scripts can all be local files
npx git-doc-mcp --manifest ./path/to/manifest.yml

When using a local manifest, action and resource.uri fields can reference local files with paths relative to the manifest's directory. Local actions are re-read from disk on each tool call, so edits take effect without restarting the server.

With Pre-approved Secrets

# Via CLI flag
npx git-doc-mcp --manifest https://example.com/.mcp/manifest.yml \
  --secret GITHUB_TOKEN=$GITHUB_TOKEN

# Via environment variable
export GIT_MCP_SECRET_GITHUB_TOKEN=$GITHUB_TOKEN
npx git-doc-mcp --manifest https://example.com/.mcp/manifest.yml

Hash Pinning (for CI/CD)

npx git-doc-mcp --manifest https://example.com/.mcp/manifest.yml \
  --manifest-hash sha256:abc123...

Rate Limiting

# Limit to 30 tool calls per minute
npx git-doc-mcp --manifest https://example.com/.mcp/manifest.yml \
  --rate-limit 30

Manifest Schema

schemaVersion: "1.0"           # Required - schema version
name: my-repo-mcp              # Required - server name
version: 1.0.0                 # Required - semantic version
description: Description       # Optional - shown to AI
instructions: Use when...      # Optional - helps AI understand when to use

secrets:                       # Optional - secrets needed
  - name: GITHUB_TOKEN
    description: GitHub token
    scope:
      - "https://api.github.com/*"
    required: false

tools:                         # Optional - tool definitions
  - name: fetch-file
    title: Fetch File          # Optional - human-readable title
    description: Fetch a file  # Required
    inputSchema:               # Required - JSON Schema
      type: object
      properties:
        path: { type: string }
      required: [path]
    action: https://...        # Required - URL or local file path to action script
    actionHash: sha256:...     # Required - SHA-256 hash of action content
    annotations:               # Optional - hints for AI
      readOnlyHint: true
      destructiveHint: false
      idempotentHint: true
      openWorldHint: true

resources:                     # Optional - static resources
  - name: readme
    uri: https://...           # URL or local file path
    description: README
    mimeType: text/markdown

prompts:                       # Optional - prompt templates
  - name: explain-code
    description: Explain code
    args:
      - name: path
        required: true
    messages:                    # Optional - MCP PromptMessage[]
      - role: user
        content:
          type: resource
          resource:
            uri: "https://example.com/{{path}}"
            mimeType: text/plain
      - role: user
        content:
          type: text
          text: "Explain the code above from {{path}}"

Prompt Messages

Prompts support the full MCP PromptMessage format with multi-message templates:

  • Without messages: A single user message is built from description + args (simple mode)
  • With messages: Messages are returned directly with {{argName}} substitution
  • Embedded resources: If a resource message omits resource.text, git-doc-mcp reads the URI and embeds the fetched content when the prompt is requested

Each message has a role (user or assistant) and content (either text or embedded resource):

messages:
  - role: user
    content:
      type: text
      text: "Analyze {{path}} for {{focus}}"
  - role: assistant
    content:
      type: text
      text: "I'll analyze the code structure first."
  - role: user
    content:
      type: resource
      resource:
        uri: "https://example.com/{{path}}"
        mimeType: text/plain

Action API

Actions are plain JavaScript files that export a default async function:

export default async function myAction(input, ctx) {
  const { fetch, getSecret, log, manifest } = ctx;

  log('info', `Running action for ${manifest.name}`);

  // Get a secret scoped to the target URL
  const url = 'https://api.example.com/data';
  const token = getSecret('API_KEY', url);

  const response = await fetch(url, {
    headers: token ? { 'Authorization': `Bearer ${token}` } : {}
  });

  // response.text is a property (not a method)
  // response.json() is a synchronous method
  const data = response.json();

  return {
    content: [{ type: 'text', text: JSON.stringify(data, null, 2) }]
  };
}

Context Methods

| Method | Description | |--------|-------------| | ctx.fetch(url, options) | Scoped fetch with SSRF protection and redirect validation | | ctx.getSecret(name, url) | Get a secret value if the URL matches the secret's scope pattern | | ctx.log(level, message) | Logging (levels: debug, info, warn, error) | | ctx.manifest | Manifest metadata ({ name, version }) |

Fetch Response

ctx.fetch returns a serialized response object (not a native Response):

| Property/Method | Type | Description | |-----------------|------|-------------| | response.ok | boolean | true if status is 200-299 | | response.status | number | HTTP status code | | response.statusText | string | HTTP status text | | response.text | string | Response body as a string (property, not method) | | response.json() | object | Parse body as JSON (synchronous method) | | response.headers | object | Response headers as key-value pairs |

Return Format

// Success
return {
  content: [{ type: 'text', text: 'Result' }]
};

// Error
return {
  content: [{ type: 'text', text: 'Error message' }],
  isError: true
};

CLI Reference

Options

| Option | Description | Default | |--------|-------------|---------| | --manifest <path> | URL or local path to manifest.yml | (required) | | --manifest-header <header> | Header for fetching manifest (repeatable) | | | --manifest-hash <hash> | Expected manifest hash for pinning | | | --action-code-header <header> | Header for downloading action scripts (repeatable) | | | --resource-header <header> | Header for fetching resources (repeatable) | | | --secret <name=value> | Pre-approved secret (repeatable) | | | --timeout <ms> | Worker timeout in milliseconds | 60000 | | --memory-limit <bytes> | Sandbox memory limit (8MB - 1GB) | 134217728 (128MB) | | --rate-limit <n> | Max tool calls per minute (0 = unlimited) | 0 | | --allow-http | Allow insecure HTTP URLs (HTTPS-only by default) | false | | --trust-changed | Accept manifest hash changes (TOFU override) | false |

Environment Variables

Secrets can be provided via environment variables prefixed with GIT_MCP_SECRET_:

export GIT_MCP_SECRET_GITHUB_TOKEN=ghp_abc123
export GIT_MCP_SECRET_API_KEY=sk-xyz789

The --secret CLI flag takes precedence over environment variables.

Examples

# Basic usage
git-doc-mcp --manifest ./manifest.yml

# With authentication headers
git-doc-mcp --manifest https://... \
  --manifest-header "Authorization: Bearer $TOKEN" \
  --action-code-header "Authorization: Bearer $TOKEN"

# Separate resource headers
git-doc-mcp --manifest https://... \
  --resource-header "Authorization: Bearer $RESOURCE_TOKEN"

# With secrets and rate limiting
git-doc-mcp --manifest https://... \
  --secret GITHUB_TOKEN=$TOKEN \
  --rate-limit 60

# Hash pinned (for CI/CD)
git-doc-mcp --manifest https://... --manifest-hash sha256:abc123...

# Accept manifest changes (TOFU override)
git-doc-mcp --manifest https://... --trust-changed

# Custom memory limit (256MB)
git-doc-mcp --manifest https://... --memory-limit 268435456

# Allow HTTP (not recommended for production)
git-doc-mcp --manifest http://localhost:8080/manifest.yml --allow-http

Comparison

| Feature | git-doc-mcp | Context7 | idosal/git-doc-mcp | |---------|---------|----------|----------------| | Hosting | Any static host | Hosted service | Needs separate server | | Custom actions | User-defined JS | Fixed tools | Limited actions | | Private repos | Auth headers | OAuth | Unknown | | Platform | Any (GitHub, GitLab, S3, etc.) | Any | GitHub only | | Local development | Local files | No | No | | Secret scoping | URL pattern matching | N/A | N/A | | Manifest integrity | TOFU + hash pinning | N/A | N/A |

Security Model

Trusted-Manifest System

Users explicitly configure manifest URLs they trust. This is consistent with the official GitHub MCP Server's approach — the user configures which server to use, so they trust the server author.

Three-Layer Isolation

Layer 1: Worker Process (Primary Boundary)
  - Separate Node.js child process
  - Sanitized environment (no inherited credentials)
  - Crash in action doesn't kill CLI

Layer 2: isolated-vm (Defense-in-Depth)
  - Configurable memory limit (default: 128MB)
  - CPU timeout: 30s
  - No direct filesystem/network access

Layer 3: Controlled API Surface
  - ctx.fetch with SSRF protection
  - ctx.getSecret with URL scope validation
  - Audit logging of all network calls

SSRF Protection

All HTTP(S) URLs are validated before fetch:

  • HTTPS-only by default (use --allow-http to override)
  • Private IP ranges blocked (10.x, 172.16-31.x, 192.168.x, localhost)
  • DNS resolution validated before connection
  • Every redirect URL re-validated
  • Cross-origin redirects strip sensitive headers (Authorization, Cookie)

Local file paths in action and resource.uri are read directly from disk and are not subject to SSRF validation. ctx.fetch inside action scripts remains HTTP(S)-only regardless of how the action was loaded.

Capability-Scoped Secrets

Secrets are scoped to specific URL patterns:

secrets:
  - name: GITHUB_TOKEN
    scope:
      - "https://api.github.com/*"
      - "https://raw.githubusercontent.com/*"

ctx.getSecret(name, url) only returns the secret value if the URL matches the scope pattern. Path-boundary-aware wildcard matching prevents /repos-private from matching a /repos/* scope.

TOFU (Trust-on-First-Use)

On first use, git-doc-mcp stores the manifest's SHA-256 hash. If the manifest changes:

Warning: Manifest content has changed since last use!
  Previous: sha256:abc123...
  Current:  sha256:def456...

To accept this change, re-run with: --trust-changed
For CI pinning, use: --manifest-hash sha256:def456...

The server exits with a non-zero code unless --trust-changed is provided. For CI/CD, use --manifest-hash for hard pinning.

Rate Limiting

Sliding-window rate limiter prevents excessive tool calls:

# 60 calls per minute
git-doc-mcp --manifest https://... --rate-limit 60

Audit Logging

All ctx.fetch calls are logged to ~/.git-doc-mcp/logs/audit.jsonl:

  • URL, HTTP status, duration
  • Redirect hops
  • Secret access (allowed/denied)
  • Action start/end with timing

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Build: npm run build
  5. Run tests: npm test
  6. Submit a pull request

Development Setup

npm install        # Install dependencies
npm run build      # Build all packages
npm test           # Run all tests (298 tests)

Project Structure

git-doc-mcp/
  packages/
    core/          # Manifest loading, sandbox, worker, MCP server
    cli/           # CLI entry point and serve command
    template/      # Example manifest and actions

Documentation

Full documentation is available on the GitHub Wiki:

License

MIT License - see LICENSE for details.