Skip to main content
Glama
jorgell23-sys

mdcx

mdcx

PyPI License DOI

ドキュメントコレクションを検証済みMarkdownに変換し、単一の暗号化ファイルにパッケージし、Model Context Protocolを通じてエージェントからクエリ可能にします。

問題

ドキュメントコレクションに関する質問に答えるエージェントには、2つの選択肢があります。ドキュメントをコンテキストウィンドウに受け取る方法です。これはコストがかかり、ウィンドウサイズに制限されます。あるいは、各項目の場所をすでに把握しているコンポーネントにクエリする方法です。

3Dでモデル化すべき最小パイプ径がどこに記載されているかを問う特定のクエリ1件を、実際の99ドキュメント・180MBのコレクションに対して、cl100k_baseトークナイザーを用いて測定しました:

モデルトークン

ローカルトークン

原本の読み取り

2,265,488

2,265,327

パッケージへのクエリ

435

2,688,861

435の内訳は、質問に20、取得された文章に274、回答に141です。

1行目がコレクション全体を要するのには具体的な理由があります。PDFはバイナリであり、検索できません。事前の変換なしには、99のドキュメントのどれが答えを持つのかを知る方法がないため、すべてを抽出して読む必要があるのです。

これは1回の測定値であり、平均ではありません。節約量は、回答が必要とするテキストの量に依存します。変わらないのは変化の形です。作業は消えるのではなく、課金され有限なコンテキストウィンドウから、課金されないCPUへと移ります。だからこそ、ローカル列は下がるのではなく上がるのです。

Related MCP server: md-mcp

3つの段階

変換。 各ドキュメントはMarkdownに変換され、変換を実行したエンジンとは独立したライブラリで読み取られた、原本が実際に公開するテキストと照合されます。構造化エンジンが省略したコンテンツは、失われたものとして報告されるのではなく、逐語的に追記されます。

開発中に使用したコレクション(99ドキュメント、1,144,553参照語)では、594語が回収されず、全体のカバレッジは99.948%でした。テキストを公開している184ドキュメントのうち、116件は正確に100%で、99.5%を下回るものはありませんでした。残りの4件は、ファイル内にテキストを一切含まないスキャン図面です。これらは光学文字認識で読み取られ、検証不能とマークされています。照合するためのテキスト原本が存在しないためです。

パッケージング。 コーパス、その検索インデックス、そしてすべての文章の出所が、AES-256-GCMで暗号化された単一の.mdcxファイルに収まります。このファイルのヘッダーはキーなしで読むことができます。8.8MBのMarkdownが、1つのファイルで3.9MBになります。

取得。 クエリは、それに答える文章を、その正確な出所とともに返します。チューニングに使用した20件の実クエリでは、正しいドキュメントが上位5件以内に現れたのは19件、上位10件以内では20件すべてでした。

インストール

このパッケージは、クエリと変換を分離しています。両者の要件は大きく異なるためです。

Command

インストール内容

Size

pip install mdcx

.mdcxパッケージのクエリと読み取り

~10 MB

pip install "mdcx[mcp]"

上記に加えてMCPサーバー

~50 MB

pip install "mdcx[convert]"

ドキュメント変換(Docling、PyTorch)

~1.4 GB

pip install "mdcx[all]"

OCRを含むすべて

~1.5 GB

変換が、重い依存関係を引き込むのです。.mdcxファイルを受け取り、クエリだけが必要な人は、DoclingもPyTorchもインストールしません。

コレクションの変換

pip install "mdcx[convert]"
mdcx-convert --input ./Documents --output ./Documents_md

出力は入力ディレクトリ構造を反映し、グローバルインデックスを追加し、各ファイルについて、その原本に対して達成されたカバレッジを記録します。

パッケージングとクエリ

mdcx pack --output ./Documents_md --target corpus.mdcx --key "..."
mdcx info corpus.mdcx
mdcx search corpus.mdcx "where is the minimum diameter stated" --key "..."
mdcx export corpus.mdcx --target ./restored --key "..."

infoはキーなしでヘッダーを読み取るため、開く前にファイルの発行者と完全性を確認できます。exportは元のフォルダを再構築します。離れられないフォーマットは、どれほど意図が良くても罠です。

MCPサーバーとして使う

サーバーにはPythonとこのパッケージが必要です。変換スタックは不要なので、フットプリントは約50MBです。

{
  "mcpServers": {
    "mdcx": {
      "command": "python",
      "args": ["-m", "mdcx.mcp_server"],
      "env": {
        "MDCX_FILE": "/path/to/corpus.mdcx",
        "MDCX_KEY": "package-key"
      }
    }
  }
}

あるいは、uvを使えば、事前インストールなしでサーバーが実行できます。これはPython MCPサーバーで一般的な構成です:

{
  "mcpServers": {
    "mdcx": {
      "command": "uvx",
      "args": ["--from", "mdcx[mcp]", "python", "-m", "mdcx.mcp_server"],
      "env": {
        "MDCX_FILE": "/path/to/corpus.mdcx",
        "MDCX_KEY": "package-key"
      }
    }
  }
}

3つのツールが公開されています。searchは質問に答える文章を、それぞれのソースドキュメントとポータブルパスとともに返します。infoはコーパスとその変換の忠実度を説明します。documentは、文章では不十分な場合に完全なドキュメントを返します。

サーバーはリッスンを開始する前にパッケージを検証するため、誤ったパスやキーは、最初のクエリ時ではなく即座に報告されます。

テスト

pip install pytest
python -m pytest tests/ -v

このスイートは敵対的な入力をカバーしています。空のファイルや破損したファイル、他の文字体系の名前、SQLインジェクション試行を含む不正なクエリ、切り詰めや改ざんが施されたパッケージ、そしてコンテンツ損失に対する圧縮などです。

パス

どの出力にも絶対パスは含まれません。すべてのドキュメントは@/で始まる疑似パスで識別され、それを含むフォルダまたはパッケージに対して解決されます。そのためコーパスは、ローカルディスク、ネットワーク共有、クラウドのどこに保存されても有効です。

署名

パッケージは署名することができ、発行者を単に宣言するのではなく証明できます。署名は暗号化された本体のダイジェストを対象とするため、出所と内容の両方を証明し、暗号化キーなしで検証されます。

mdcx keygen
mdcx pack --output ./Documents_md --target corpus.mdcx --key "..." \
          --issuer "Acme Ltd" --signing-key <private-key>
mdcx verify corpus.mdcx --public-key <public-key>

検証には本体が無傷であることも必要です。記録されたダイジェストのみを対象とする署名では、ヘッダーが無傷のまま内容が置き換えられたパッケージを受け入れてしまうからです。

発行者フィールドだけは自由テキストであり、何も証明しません。証明できるのは署名だけです。

暗号化

パッケージは保存時に暗号化され、開かれるとメモリ内で復号されます。平文がディスクに書き込まれることはありません。これにより、転送中のファイルが保護されます。これは、暗号化データを一切復号せずに検索することとは同じではありません。後者は、文書化された漏洩攻撃と、秒単位で測られるクエリごとのコストを伴う、別の分野です。

キーはscryptで導出されるため、推測は遅くなります。毎秒約8回の試行、各試行に32MBのメモリが必要で、GPUでの並列化を防ぎます。それでも、本当の強度はパスフレーズにあります。辞書にあるようなパスワードは1日で破られます。

著作者

Jorge Ellena G. が構想・指揮し、Claude(Anthropic)の支援を受けてプログラミングされました。

このパッケージにおけるすべての決定は、慣例ではなく測定に基づいて行われました。どの変換エンジンを使うか、どのライセンスが何を許可するか、検索をどのようにランク付けするか、どの最適化を受け入れ、どの最適化を捨てるか。いくつかは、まさに測定されたがゆえに捨てられました。検索候補プールの削減は10倍高速に見えましたが、実際には20件中19件から17件へと精度を下げました。そして、これらの測定は、それらが正当化する決定とともに記録されています。

引用

恒久的な識別子付きでZenodoにアーカイブされています。コンセプトDOIは常に最新バージョンに解決されます:

https://doi.org/10.5281/zenodo.22015991

ライセンス

Apache 2.0。このソフトウェアは、著作権表示が保持される限り、使用、変更、販売が可能です。

PyMuPDFは意図的に避けられました。そのAGPLライセンスは、このソフトウェアを使用するすべての人に対し、ネットワークサービスのみとして提供する場合も含め、自らのソフトウェアをAGPLのもとで公開することを要求するためです。

Related MCP Connectors

Related MCP Servers