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

mcp-cite-fragment

v1.0.0

Published

MCP server for verifying claims against source documents and generating citation links with W3C Text Fragments

Readme

Cite-Fragment MCP Server

AIが生成する調査レポートの主張をソース文書で裏付け、該当箇所に直接ジャンプできる引用リンクを生成するMCPサーバー。

W3C Text Fragments (#:~:text=) とPDFページリンク (#page=N) を活用し、引用の透明性を確保する。

解決する課題

AIがWeb検索結果を引用する際、ソースURLは提示されるが ページ内のどの箇所を参照しているかは不明瞭 である。ユーザーが事実確認するには長いページをスクロールして該当箇所を探す必要があり、ファクトチェックのコストが高い。

Before: [Source](https://example.com/article)
After:  [Source](https://example.com/article#:~:text=引用テキスト)
        クリックすると該当箇所が黄色ハイライトされた状態で表示される

提供ツール

| ツール | 用途 | 主な利用シーン | |---|---|---| | verify_claims | 複数の主張を一括でソース文書と照合 | 調査レポートの全主張を一度に検証 | | generate_text_fragment | 単一の引用テキストからFragment URLを生成 | 個別の引用リンク作成 | | check_fragment_url | 生成済みFragment URLの有効性検証 | ページ更新後のリンク切れ確認 | | highlight_pdf | PDF内の該当テキストに黄色ハイライト注釈を追加して保存 | レビュー用のPDF配布 |

verify_claims (推奨: 調査タスクのメインツール)

複数の主張を一括でソース文書と照合する。同一URLへの複数の主張はページを1回だけ取得する。

// 入力
{
  "claims": [
    {"url": "https://example.com/article", "claim": "actual text from the source", "lang": "en"},
    {"url": "https://example.com/article", "claim": "another claim from same page"},
    {"url": "https://example.jp/doc.pdf",  "claim": "PDF内のテキスト", "lang": "ja"}
  ]
}

// 出力
{
  "results": [
    {
      "claim": "actual text from the source",
      "url": "https://example.com/article",
      "status": "verified",
      "fragment_url": "https://example.com/article#:~:text=actual%20text%20from%20the%20source",
      "matched_text": "actual text from the source",
      "surrounding_context": "...preceding text actual text from the source following text..."
    },
    {
      "claim": "another claim from same page",
      "status": "not_found",
      "message": "引用テキストがページ内に見つかりません"
    },
    {
      "claim": "PDF内のテキスト",
      "status": "verified",
      "fragment_url": "https://example.jp/doc.pdf#page=5",
      "page_number": 5,
      "matched_text": "PDF内のテキスト",
      "surrounding_context": "...前後100文字の文脈..."
    }
  ],
  "summary": { "total": 3, "verified": 2, "not_found": 1, "fetch_failed": 0 }
}

出力フィールドの意味:

| フィールド | 意味 | |---|---| | status | verified = ソースに存在, not_found = 見つからない, fetch_failed = ページ取得失敗 | | matched_text | ソース上で実際にマッチしたテキスト(正規化前の原文) | | surrounding_context | マッチ箇所の前後100文字。主張が正確な引用か意訳かを判断するために使用 | | fragment_url | 該当箇所に直接ジャンプするURL(HTML: #:~:text=..., PDF: #page=N) |

generate_text_fragment

単一の引用テキストからFragment URLを生成する。

// 入力
{ "url": "https://example.com/article", "cited_text": "引用テキスト", "lang": "ja" }

// 出力 (成功)
{
  "fragment_url": "https://example.com/article#:~:text=引用テキスト",
  "detected_lang": "ja",
  "is_unique": true,
  "context_used": false,
  "match_count": 1,
  "matched_text": "引用テキスト",
  "surrounding_context": "...前後の文脈..."
}

// 出力 (エラー)
{
  "error": "NOT_FOUND",
  "message": "引用テキストがページ内に見つかりません",
  "suggestion": "引用テキストを短縮して再試行してください"
}

highlight_pdf

// 入力
{ "url": "https://example.jp/doc.pdf", "cited_text": "ハイライトするテキスト", "lang": "ja" }

// 出力
{
  "file_path": "/tmp/mcp-text-fragment/doc_highlighted.pdf",
  "page_number": 5,
  "match_count": 3,
  "detected_lang": "ja"
}

セットアップ

前提条件

  • Node.js 18+ (Intl.Segmenter の日本語対応に必要)
  • qpdf (暗号化PDFのハイライトに必要。オプション)
# macOS
brew install qpdf

# Ubuntu/Debian
apt-get install qpdf

Claude Code

claude mcp add --transport stdio cite-fragment -- npx -y mcp-cite-fragment

これだけで完了。次回の Claude Code セッションから verify_claims 等のツールが利用可能になる。

スコープの選択:

# ローカル (デフォルト) — このプロジェクトの自分だけ
claude mcp add --transport stdio cite-fragment -- npx -y mcp-cite-fragment

# プロジェクト共有 — .mcp.json に保存、チーム全員が利用可能
claude mcp add --transport stdio --scope project cite-fragment -- npx -y mcp-cite-fragment

# ユーザー全体 — すべてのプロジェクトで利用可能
claude mcp add --transport stdio --scope user cite-fragment -- npx -y mcp-cite-fragment

Claude Desktop

  1. Settings → Developer → Edit Config を開く
  2. claude_desktop_config.json に以下を追加:
{
  "mcpServers": {
    "cite-fragment": {
      "command": "npx",
      "args": ["-y", "mcp-cite-fragment"]
    }
  }
}

設定ファイルの場所:

| OS | パス | |---|---| | macOS | ~/Library/Application Support/Claude/claude_desktop_config.json | | Windows | %APPDATA%\Claude\claude_desktop_config.json | | Linux | ~/.config/Claude/claude_desktop_config.json |

  1. Claude Desktop を再起動

確認

# Claude Code の場合
claude mcp list
# cite-fragment: npx -y mcp-cite-fragment - ✓ Connected と表示されれば成功

ソースからビルド (開発者向け)

git clone https://github.com/ryo63-bot/mcp-cite-fragment
cd mcp-cite-fragment
npm install
npm run build

# ローカルビルドを直接指定して接続
claude mcp add --transport stdio cite-fragment -- node dist/index.js

Docker

docker compose up --build       # ビルド&起動
docker compose up -d            # バックグラウンド起動

Claudeへの指示例 (System Prompt)

Web検索で情報を引用する際、以下を実行すること:

1. 調査レポートを書き終えたら、全主張を verify_claims で一括検証する
2. status: "not_found" の主張はソースの原文を確認し、正確な表現に修正する
3. status: "verified" の主張は fragment_url をMarkdownリンクとして使用する
4. surrounding_context を確認し、主張が文脈的にも正確か検証する
5. PDFからの引用が重要な場合、highlight_pdf でハイライト付きPDFを保存する

書式例:
[Source](https://example.com/article#:~:text=引用テキスト)

対応コンテンツ

| コンテンツ種別 | Fragment形式 | 対応状況 | |---|---|---| | HTML (静的/SSR) | #:~:text=... | 対応 | | PDF | #page=N | 対応 | | PDF (暗号化) | #page=N + ハイライト | 対応 (qpdf必要) | | SPA / CSR (React等) | - | 非対応 (Phase 2) | | ログイン必須サイト | - | 非対応 |

言語対応

日本語と英語に最適化。言語は自動検出される(lang パラメータで明示指定も可能)。

| 処理 | 英語 | 日本語 | |---|---|---| | 正規化 | 小文字化 + 空白正規化 | 全角/半角統一 + カタカナ→ひらがな | | Context抽出 | スペース区切り3語 | Intl.Segmenter 6形態素 | | 長文閾値 | 60文字 → start,end形式 | 30文字 → start,end形式 | | 最小引用長 | 5文字 | 4文字 |

エラーコード

| コード | 意味 | 推奨対応 | |---|---|---| | NOT_FOUND | 引用テキストがソースに存在しない | ソースの原文を確認して再試行 | | FETCH_FAILED | ページの取得に失敗 (403, timeout等) | ソースURLのみ提示 | | INVALID_URL | https以外のURL | httpsのURLを使用 | | TEXT_TOO_SHORT | 引用テキストが最小長未満 | より長いテキストを使用 | | ENCODE_TOO_LONG | Fragment URL が2000文字超 | 引用テキストを短縮 |

アーキテクチャ

┌──────────────────────────────────────────────────────────┐
│  Claude (Claude Code / Claude Desktop)                   │
│                                                          │
│  verify_claims([{url, claim}, ...])                      │
└───────────────────┬──────────────────────────────────────┘
                    │ stdio (JSON-RPC)
┌───────────────────▼──────────────────────────────────────┐
│  Cite-Fragment MCP Server (Node.js 18+)                  │
│                                                          │
│  ┌─────────────────────────────────────────────────────┐ │
│  │  Tools                                              │ │
│  │  verify_claims | generate | check | highlight_pdf   │ │
│  └─────────────────────┬───────────────────────────────┘ │
│                        ↓                                 │
│  ┌─────────────────────────────────────────────────────┐ │
│  │  Core Pipeline                                      │ │
│  │                                                     │ │
│  │  fetcher ─→ extractor (HTML) ─→ detector            │ │
│  │         └→ pdf-extractor (PDF)      ↓               │ │
│  │                              normalizer (ja|en)     │ │
│  │                                     ↓               │ │
│  │                              matcher → context      │ │
│  │                                     ↓               │ │
│  │                              fragment → encoder     │ │
│  │                                                     │ │
│  │  pdf-highlighter (pdfjs-dist + pdf-lib + qpdf)      │ │
│  └─────────────────────────────────────────────────────┘ │
└───────────────────┬──────────────────────────────────────┘
                    │ HTTPS
              ┌─────▼─────┐
              │ Web / PDF  │
              └───────────┘

開発

npm run build        # TypeScriptコンパイル
npm run dev          # 開発モード (tsx)
npm test             # 全テスト (vitest)
npm run test:unit    # ユニットテストのみ
npm run test:integ   # 統合テストのみ
npm run lint         # ESLint
npm run format       # Prettier

ディレクトリ構成

src/
├── index.ts                  # エントリポイント (stdio接続)
├── server.ts                 # MCPサーバー定義 (4ツール登録)
├── types.ts                  # 型定義 (Lang, LangConfig, 入出力型)
├── tools/
│   ├── generate.ts           # generate_text_fragment 実装
│   ├── verify.ts             # verify_claims 実装 (ページキャッシュ付き)
│   ├── check.ts              # check_fragment_url 実装
│   └── highlight.ts          # highlight_pdf 実装
└── lib/
    ├── fetcher.ts             # HTML/PDF取得 (タイムアウト・サイズ制限)
    ├── extractor.ts           # HTML本文抽出 (Readability + linkedom)
    ├── pdf-extractor.ts       # PDFテキスト抽出 (pdf-parse, ページ単位)
    ├── pdf-highlighter.ts     # PDFハイライト注釈 (pdfjs-dist + pdf-lib)
    ├── detector.ts            # 言語自動検出 (ja/en)
    ├── matcher.ts             # テキスト検索・位置マッピング
    ├── fragment.ts            # Fragment URL組み立て・エンコード
    ├── boundary.ts            # ブロック境界検出
    ├── normalizer/
    │   ├── index.ts           # 言語ディスパッチ
    │   ├── english.ts         # 英語正規化 (小文字・空白)
    │   └── japanese.ts        # 日本語正規化 (全角半角・カナ変換)
    └── context/
        ├── index.ts           # 言語ディスパッチ
        ├── english.ts         # 英語context抽出 (スペース区切り)
        └── japanese.ts        # 日本語context抽出 (Intl.Segmenter)

ブラウザ対応

Text Fragments (#:~:text=) のブラウザ対応状況:

| ブラウザ | 対応状況 | |---|---| | Chrome / Edge | 80+ で対応 | | Firefox | 131+ で対応 | | Safari | 16.1+ で対応 |

PDF #page=N は主要ブラウザの内蔵PDFビューアすべてで対応。

ライセンス

Apache License 2.0