Skip to main content
Glama
mattshuttle

gristmill-mcp

by mattshuttle

gristmill-mcp

AIが生成したコードを検査し、構造的・セキュリティ上の違反を決定的に列挙するMCPサーバーです。AIコーディングエージェントがコードを確定させる前に自身の出力を修正できるようにします。

グリストとは製粉所に運ばれる穀物のことです。AIの出力はグリスト — 確かに価値のある原料ですが、未加工です。製粉所がそれに構造を与えます。

AIがグリストを書く。Gristmillがそれを出荷可能なコードにする。

なぜMCPサーバーなのか、スキルではないのか

スキルはモデルのコンテキストに読み込まれるテキストであり、モデルが知っていることを変えます。MCPサーバーはモデルが実行するプログラムであり、モデルができることを変えます。

スタイルのガイダンス(「クラスを緩やかな関数より優先する」)はスキルに属します。検証(「このファイルには12行目、40行目、66行目…に7つのトップレベル関数があります」)はファイルに対してコードを実行する必要があります。モデルが自身の出力を読んで「これには関数が多すぎるように見える」と推論するのは、観察に擬態した推測にすぎません — このファイルにおける「多すぎる」の意味の真実はなく、信頼できるカウント方法もありません。GristmillはASTを解析して実際に数えます。指示と実行のこの区別こそが、これがアドバイスの段落ではなくサーバーとして存在する理由です。

サーバーは決してLLMを呼び出さず、同じ入力に対して実行間で変化することはなく、信頼スコアを出力することもありません。同じ入力 → 毎回バイト単位で同一の出力。その決定性こそが製品のすべてです。AI層はこのサーバーのにあり、その結果を消費し、何をすべきかを決定します。サーバーの役割は行番号付きの事実を報告することで終わります。

Related MCP server: code-verify-mcp

インストール

git clone <this repo> gristmill-mcp
cd gristmill-mcp
python3 -m venv .venv
.venv/bin/pip install -e .

Claude Code

venvのコンソールスクリプトを指すようにCLIで登録します:

claude mcp add gristmill -- /absolute/path/to/gristmill-mcp/.venv/bin/gristmill-mcp

または、MCP設定に直接追加します(プロジェクト内の.mcp.json、またはグローバルのClaude Code設定):

{
  "mcpServers": {
    "gristmill": {
      "command": "/absolute/path/to/gristmill-mcp/.venv/bin/gristmill-mcp"
    }
  }
}

その他のMCPクライアント

stdioベースのMCPクライアントは同じバイナリを起動できます。gristmill-mcp(またはvenv内でpython3 -m gristmill.server)は標準のMCP stdioトランスポートをクライアント固有の設定なしで使用します。

コマンドライン(MCPクライアントなし)

ローカルテスト用、または以下の実際の例を再現するために、薄いCLIが同じエンジンをラップしています:

.venv/bin/gristmill-verify path/to/file_or_dir [--checks secrets structure comment_slop] [--severity-floor warning] [--json]

実際の例

demo/billing.py、Stripe課金ヘルパーの未編集の初稿:

import stripe

# I've added this as you requested — sets up the Stripe client
STRIPE_SECRET_KEY = None  # was a literal sk_live_... key — see note below

stripe.api_key = STRIPE_SECRET_KEY


def customer_create(config):
    return stripe.Customer.create(**config)


def customer_delete(config):
    return stripe.Customer.delete(config["id"])


def customer_find(config):
    return stripe.Customer.retrieve(config["id"])


def customer_update(config):
    return stripe.Customer.modify(config["id"], **config)
.venv/bin/gristmill-verify demo/billing.py

上記のNoneの代わりに実際のStripeライブキー形式のリテラルを入れた場合の出力:

gristmill: 1 files scanned, 0 skipped (2 error, 4 warning, 0 info) in 1ms
  [WARNING] STR002  billing.py:1  4 top-level functions share the prefix `customer_` — consider a `Customer` class or module
  [WARNING] STR003  billing.py:1  4 top-level functions take a first parameter named `config` — consider making it instance state
  [WARNING] CMT001  billing.py:3  Comment addresses the reader conversationally ('as you requested')
  [ERROR  ] SEC006  billing.py:4:22  Stripe live key assigned to `STRIPE_SECRET_KEY`
  [ERROR  ] SEC010  billing.py:4:22  String literal assigned to `STRIPE_SECRET_KEY`, which looks credential-shaped
  [WARNING] SEC011  billing.py:4:22  High-entropy string literal (5.1 bits/char) assigned to `STRIPE_SECRET_KEY`

(ファイルパスは最も近い.gristmill.tomlからの相対パスで表示されます。demo/は独自の設定を持っているため、この例の出力はトップレベルのプロジェクト設定に依存しません。)

注釈: GitHubのプッシュ保護は、実際の形式のシークレットを含むファイル(コメント内、Markdownコードブロック内、このREADMEを含む)のプッシュをブロックします。現在demo/billing.pyはキーをNoneに置き換えて初期プッシュを解除しています。これは(許可リストに登録されたシークレットスキャン例外を介して)復元し、デモを再び動作させるためのTODOです。

--jsonフラグ(または両方を返すverify MCPツール)は、完全な構造化形式(ファイル、行、列、静的な提案文字列、および編集されたevidenceフィールド(sk_l…(49文字)、キー自体は決して表示されません))を提供します。

ツール

verify

ソースファイルを検査し、シークレット、構造上の問題、質の低いコメントを検出します。ファイルパスと行番号付きの決定的な結果を返します。コードを生成または編集した後、完成品として提示する前に呼び出してください。

入力:paths(ファイルまたはディレクトリ、必須)、checks(オプション、secrets/structure/comment_slopのサブセット、デフォルトはすべて)、severity_floor(オプション、デフォルトはinfo)。

出力:コンパクトな人間可読サマリーと、それに続く完全な構造化JSON(ファイル、行、列、メッセージ、編集された証拠、ルールごとの静的な提案文字列)。結果は常にpathlinerule_idでソートされます。この安定性により、実行間でバイト単位の同一性が保証され、モデルが問題に直接移動できるようになります。

explain_rule

rule_id(例:SEC001)を受け取り、その根拠、検出対象、検出できないもの、抑制方法を返します。これはdocs/RULES.mdと同じ内容をオンデマンドで提供し、verifyの出力を簡潔に保つことができます。

ルール

ルール

チェック

タイトル

デフォルトの重要度

SEC001

secrets

AWSアクセスキーID

エラー

SEC002

secrets

AWSシークレットアクセスキー

エラー

SEC003

secrets

GitHubトークン

エラー

SEC004

secrets

Google APIキー

エラー

SEC005

secrets

Slackトークン

エラー

SEC006

secrets

Stripeライブキー

エラー

SEC007

secrets

秘密鍵ブロック

エラー

SEC008

secrets

JWT

エラー

SEC009

secrets

インラインパスワード付きデータベースURI

エラー

SEC010

secrets

一般的な認証情報形式の代入

エラー

SEC011

secrets

高エントロピー文字列リテラル

警告

STR001

structure

トップレベル関数が多すぎる(デフォルト上限5)

警告

STR002

structure

共有された関数名の接頭辞(3関数以上)

警告

STR003

structure

最初のパラメータ名の繰り返し(3関数以上)

警告

STR004

structure

関数が長すぎる(デフォルト上限60行)

警告

STR005

structure

可変モジュールレベルの状態がファイル内の他の場所で変更されている

警告

CMT001

comment_slop

コメント内の会話形式の呼びかけ

警告

CMT002

comment_slop

自明なことを説明するコメント

情報

CMT003

comment_slop

短い関数に対する過剰に大きなコメントブロック

情報

CMT004

comment_slop

プレースホルダーのスキャフォールドが残っている

警告

CMT005

comment_slop

セクション区切りバナーの繰り返し(ファイルあたり4回以上)

情報

各ルールの完全な根拠、偽陰性に関する注意、抑制手順については、docs/RULES.mdを参照してください。

設定

プロジェクトルートに.gristmill.tomlを置きます。すべてのキーはオプションです:

[checks]
enabled = ["secrets", "structure", "comment_slop"]

[structure]
max_top_level_functions = 5
max_function_lines = 60

[secrets]
entropy_threshold = 4.5

[ignore]
paths = ["legacy/**", "vendor/**"]
rules = ["CMT003"]

.gristmillignoreファイル(gitignore構文)は[ignore] pathsと併用できます。また、フラグが立てられた行またはその上の行でインライン抑制も有効です:

SUPPRESSED = "ghp_" + "..."  # gristmill: ignore SEC003
// gristmill: ignore SEC003
const suppressed = "ghp_" + "...";

言語サポート

  • Python — 完全サポート(stdlibのastおよびtokenize)。

  • JavaScript/TypeScript — 完全サポート。tree-sittertree-sitter-javascripttree-sitter-typescriptのコンパイル済みグラマーを使用します。Nodeベースのパーサーに外部コマンドを発行しません。これにより、コンパイル済みのPython依存関係と引き換えに、ホストにNodeがインストールされている必要がないという独立性を得ています。structurecomment_slopnodePATHにあるかどうかに依存せずに同じように動作し、テキストのみのフォールバックではなく実際のASTを提供します。

  • その他secretsチェックは引き続き実行されます(正規表現ベースで言語に依存しません)。structurecomment_slopはそのファイルではスキップされ、skipped_pathsに報告されます。

制限事項

このツールを、その実績以上に信頼する前に読んでください:

  • secretsは整形された文字列または高エントロピー文字列のみを検出します。 hunter2のような低エントロピーの人間のパスワードは決してフラグされません。通常の短い文字列と区別する信頼できる方法がないためです。実行時に組み立てられる認証情報(文字列連結、os.environ.get(...) or "fallback"、Base64デコードされた断片)は、静的なテキストに対する正規表現/エントロピーパスでは不可視です。

  • ファイルをまたがる構造上の問題は不可視です。 structureは一度に1つのファイルを検査します。複数のファイルに分割すべきクラスや、2つの異なるモジュールにある重複ロジックは対象外です。

  • comment_slopのCMT002は意図的に狭い範囲にしています。 これはこのセットの中で最も偽陽性リスクが高いルールであるため、沈黙に大きく偏るように実装されています。実際の説明を見逃す頻度の方が、過剰にフラグするよりもはるかに高くなります。正確な部分一致ルールはdocs/RULES.mdを参照してください。

  • PythonおよびJS/TS以外の言語はsecretsのみのカバレッジになります。 v1ではGo、Rust、Rubyなどの構造分析やコメント分析はありません。

  • これはgit履歴のシークレットスキャナーではありません。 与えられたワーキングツリーを検査します。コミットされて現在のファイルから削除されたキーは、このツールの関心事ではありません(git履歴スキャナーは別の補完的なツールです)。

  • 自動修正はありません。 Gristmillは報告します。呼び出し元のモデルが何をどのように変更するかを決定します。この分割は意図的です(上記「なぜMCPサーバーなのか、スキルではないのか」を参照)。ただし、verify呼び出しだけでは何も修正されないことを意味します。

カバレッジを過大評価するツールは、盲点について正直なツールよりも劣ります。ノイズの多い発見と同様に、偽りの自信よりも沈黙が勝ります。

ロードマップ

v1では明示的に範囲外。大まかな優先順位順:

  • 自動修正/パッチ生成(現在は呼び出し元のモデルがverifyの結果を使用してこれを行っています)

  • 依存関係の鮮度とCVEチェック(パッケージレジストリへのネットワーク呼び出しが必要 — 自然なv2)

  • PythonおよびJavaScript/TypeScriptを超えた言語サポート

  • コミットされて後で削除されたシークレットのgit履歴スキャン

  • ホスティングサービス、Web UI、またはダッシュボード

開発

.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest tests/ -q

src/gristmill/rules.pyを編集した後にdocs/RULES.mdを再生成:

.venv/bin/python3 scripts/generate_rules_doc.py

テストは以下をカバーします(tests/):既知の汚染フィクスチャディレクトリのゴールデンファイル出力、並列実行あり/なしでの10回の決定性、ゼロ発見を生み出さなければならない偽陽性コーパス、編集(生のシークレットが出力フィールドに決して到達しないこと)、および耐障害性(無効な構文、バイナリ、空、巨大なファイルが実行をクラッシュさせないこと)。

ライセンス

MIT — LICENSEを参照してください。

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Hosted MCP server for structured code review passes on human- and AI-written code. Free tier.

  • An MCP server that gives your AI access to the source code and docs of all public github repos

  • MCP server teaching AI agents to implement TideCloak: auth, E2EE, IGA, security analysis

View all MCP Connectors

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/mattshuttle/gristmill-mcp'

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