git-doc-mcp

git-doc-mcp

Turns any YAML manifest into a fully-functional MCP server without hosting infrastructure, enabling custom tools, resources, and prompts via declarative configuration.

Category
访问服务器

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.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选