CLAUDE LABEN
MCP — Claude が MCP の 2026-07-28 仕様へのサポートを広げました。ステートレスなコア・OAuth と OIDC による認可の強化・Apps と Tasks 向けのバージョン付き拡張が入っていますDESIGN — /design が8月17日にリサーチプレビューとして公開されました。アイデアやスクリーンショット、既存のデザインを渡すと Claude Design 上の編集可能なアートボードが返ってきますOUTPUT — 結論から先に述べる Concise 出力スタイルが追加されました。長い前置きを読み飛ばしたい場面で効きますPERMISSIONS — auto モードが既定になりました。許可と拒否のルールを、正規表現ではなく普通の文章として書けますLIMITS — 週次上限の50%増は8月31日まで延長されています。対象は Pro・Max・Team とシート課金の Enterprise で、残りは6日ですRESUME — 使用量の上限に達したセッションが、上限リセット後に自動で続きから再開するようになりました。あわせて認証情報の漏えい対策も強化されていますMCP — Claude が MCP の 2026-07-28 仕様へのサポートを広げました。ステートレスなコア・OAuth と OIDC による認可の強化・Apps と Tasks 向けのバージョン付き拡張が入っていますDESIGN — /design が8月17日にリサーチプレビューとして公開されました。アイデアやスクリーンショット、既存のデザインを渡すと Claude Design 上の編集可能なアートボードが返ってきますOUTPUT — 結論から先に述べる Concise 出力スタイルが追加されました。長い前置きを読み飛ばしたい場面で効きますPERMISSIONS — auto モードが既定になりました。許可と拒否のルールを、正規表現ではなく普通の文章として書けますLIMITS — 週次上限の50%増は8月31日まで延長されています。対象は Pro・Max・Team とシート課金の Enterprise で、残りは6日ですRESUME — 使用量の上限に達したセッションが、上限リセット後に自動で続きから再開するようになりました。あわせて認証情報の漏えい対策も強化されています
記事一覧/Claude Code
Claude Code/2026-08-25中級

settings.json のキー名を1文字間違えても、Claude Code は何も言わずに無視します

キー名を書き間違えた settings.json と正しい settings.json で claude doctor の出力を比べたところ、差分はゼロでした。何が検証され何が素通りするかを5通りで測り、書き間違いを自分で落とす検査を用意します。

Claude Code235settings.json6設定7トラブルシューティング40自動化80

Claude Code 2.1.237 に、キー名を1文字だけ書き間違えた settings.json を読ませてみました。claude doctor の出力を、正しく書いたものと diff にかけます。

差分はゼロでした。警告もエラーもありません。設定ファイルは読み込まれた顔をして、書き間違えた行の中身だけが静かに消えています。

個人開発で複数のサイトを無人のタスクに任せていると、設定ファイルを触る機会は思っていたより多くなります。その最中に、これが一番こわい形の失敗だと感じました。壊れていれば気づけます。黙って無視されると、効いているつもりのまま何日も過ぎてしまいます。

以下は Claude Code 2.1.237(linux-x64)で実際に測った結果です。

正しいキーと書き間違えたキーで、出力は1バイトも変わりません

用意したのは2つのディレクトリです。片方には、よくやる書き間違いを4種類まとめて入れました。

// A: .claude/settings.json(書き間違い版)
{
  "outputStile": "Concise",
  "cleanupPeriodDay": 3,
  "permissionmode": "plan",
  "permissions": { "denny": ["Bash(rm -rf *)"] }
}
// B: .claude/settings.json(正しい版)
{
  "outputStyle": "Concise",
  "cleanupPeriodDays": 3,
  "permissions": { "deny": ["Bash(rm -rf *)"] }
}

outputStileyi の取り違え、cleanupPeriodDay は複数形の s 落ち、permissionmode は先頭以外の大文字を忘れた形、permissions.dennyn の重ね過ぎです。いずれも JSON としては完全に妥当で、人間の目にも通り過ぎやすい間違いです。

それぞれのディレクトリで claude doctor を走らせ、出力を比べました。doctor は、そのディレクトリの設定ファイルを信頼確認なしで読んでくれるサブコマンドです。

cd A && claude doctor < /dev/null > ../doctorA.txt 2>&1
cd ../B && claude doctor < /dev/null > ../doctorB.txt 2>&1
diff ../doctorA.txt ../doctorB.txt && echo "差分なし"

結果は「差分なし」です。denny と書いた拒否ルールは、どこにも登場しないまま無かったことになります。危険なコマンドを止めるつもりで書いた行が、何の合図もなく外れている状態です。

doctor が反応するのは「型」だけでした

キー名は素通りするとして、では何なら拾ってくれるのか。書き間違いの種類を変えて5通り測りました。

書き間違いの種類実例doctor の反応終了コード
JSON の構文エラー末尾のカンマInvalid settings / Invalid or malformed JSON0
既知キーの型違反"cleanupPeriodDays": "three"Expected number, but received string0
既知キーの型違反(入れ子)"permissions": { "deny": "Bash(rm -rf *)" }Expected array, but received string0
既知キーに存在しない値"permissionMode": "planz"沈黙0
キー名そのものの間違いoutputStile ほか3件沈黙(正しい版と出力が完全一致)0

検証されているのは値の型です。数値のところに文字列を書けば Expected number, but received string と場所つきで指摘されますし、配列のところに文字列を書いた場合も同じように出ます。ここは信頼できます。

一方、permissionModeplanz という存在しない値を入れても何も言われませんでした。型としては文字列なので通ってしまう、という理屈でしょうか。列挙値の妥当性まで見てくれるわけではない、と読むのが安全です。

そして肝心のキー名は、どう間違えても無反応です。5通りすべてで終了コードは 0 でした。この点は後で効いてきます。

.mcp.json は同じ書き間違いを教えてくれます

黙るのが Claude Code 全体の性格なのかというと、そうではありませんでした。MCP サーバーの設定で同じ間違いをすると、はっきり警告が出ます。

// .mcp.json — command を commnad と書き間違えた
{ "mcpServers": { "demo": { "commnad": "node", "args": ["server.js"] } } }
$ claude mcp list
No MCP servers configured. Use `claude mcp add` to add a server.

MCP config diagnostics ⚠
[Contains warnings] Project config (shared via .mcp.json)
 └ [Warning] [demo] mcpServers.demo: Skipped — invalid MCP server config for "demo":
   command: expected string, received undefined

commnad という未知のキーそのものを名指ししてはいませんが、必須の command が欠けたことを検出して、そのサーバーを丸ごと Skipped にしたうえで知らせてくれます。必須項目があるスキーマなら、キー名の間違いは「欠落」として自然に浮かび上がる、ということです。

settings.json にはそもそも必須のキーがありません。全部が任意項目です。だから何を書いても、あるいは何を書き損じても、成立してしまいます。設計として理解はできるのですが、運用する側は自分で網を張るしかありません。

キー名の書き間違いを自分で落とす

公式が持っているキーの一覧を機械的に取り出す手段は見当たりませんでした。そこで、自分が実際に使っているキーだけを書いた小さなホワイトリストを持ち、それと突き合わせる方法にしました。全キーを網羅しようとすると更新が続かないので、意識的に狭く保っています。

# known_keys.txt — 自分が使っているキーだけを書く。増やすときは意識的に足す
outputStyle
permissionMode
cleanupPeriodDays
permissions
permissions.deny
permissions.allow
permissions.ask
env
model

検査スクリプトはこれだけです。

#!/usr/bin/env python3
"""settings.json のキー名の書き間違いを検出する。
claude doctor は未知キーを警告しないため、既知キーの一覧と突き合わせて自分で落とす。
使い方: python3 check_settings_keys.py <settings.json> <known_keys.txt>
"""
import difflib, json, sys, re
 
def flatten(obj, prefix=""):
    """ネストしたキーを permissions.deny のようなドット記法に潰す。
    検査対象はキー名だけなので、配列やフックの中身までは降りない。"""
    out = []
    if isinstance(obj, dict):
        for k, v in obj.items():
            path = f"{prefix}{k}"
            out.append(path)
            if isinstance(v, dict):
                out.extend(flatten(v, path + "."))
    return out
 
def normalize(k):
    """大文字小文字と区切り記号の違いを潰す。permissionmode と permissionMode を同一視する。"""
    return re.sub(r"[^a-z0-9]", "", k.lower())
 
def main(settings_path, known_path):
    with open(known_path, encoding="utf-8") as f:
        known = [l.strip() for l in f if l.strip() and not l.startswith("#")]
    known_norm = {normalize(k): k for k in known}
 
    try:
        with open(settings_path, encoding="utf-8") as f:
            data = json.load(f)
    except json.JSONDecodeError as e:
        print(f"NG {settings_path}: JSON として読めません ({e})")
        return 1
 
    typos, unknowns = [], []
    for key in flatten(data):
        if key in known:
            continue
        hit = known_norm.get(normalize(key))
        if hit is None:
            # 綴りが1〜2文字違うだけのキーも書き間違いとして拾う
            near = difflib.get_close_matches(normalize(key), known_norm.keys(), n=1, cutoff=0.8)
            hit = known_norm[near[0]] if near else None
        if hit:
            typos.append((key, hit))     # 綴りだけ違う = ほぼ確実に書き間違い
        else:
            unknowns.append(key)         # 知らないキー = 新しい設定かもしれないので区別する
 
    for wrong, right in typos:
        print(f"NG {settings_path}: '{wrong}' は '{right}' の書き間違いです")
    for key in unknowns:
        print(f"?? {settings_path}: '{key}' は一覧にありません(新しい設定なら一覧へ追加してください)")
 
    if not typos and not unknowns:
        print(f"OK {settings_path}")
    return 1 if typos else 0   # 書き間違いのみ失敗にする。未知キーは通す
 
if __name__ == "__main__":
    sys.exit(main(sys.argv[1], sys.argv[2]))

最初に書いた版には difflib の3行がありませんでした。大文字小文字と区切り記号を潰すだけの正規化だったので、先ほどの4件のうち permissionmode しか捕まえられません。outputStilecleanupPeriodDaypermissions.denny も、正規化した文字列としては別物だからです。

1文字の差を拾うには、近さで判定する必要がありました。difflib.get_close_matchescutoff=0.8 で足したところ、4件すべてが書き間違いとして名指しされます。

$ python3 check_settings_keys.py A/.claude/settings.json known_keys.txt
NG A/.claude/settings.json: 'outputStile' は 'outputStyle' の書き間違いです
NG A/.claude/settings.json: 'cleanupPeriodDay' は 'cleanupPeriodDays' の書き間違いです
NG A/.claude/settings.json: 'permissionmode' は 'permissionMode' の書き間違いです
NG A/.claude/settings.json: 'permissions.denny' は 'permissions.deny' の書き間違いです
$ echo $?
1

気になるのは誤検出です。一覧に載せていない正当なキーを足したときに落ちてしまうと、この検査はすぐ邪魔者になります。statusLineenableAllProjectMcpServers を追加して試しました。

$ python3 check_settings_keys.py H/.claude/settings.json known_keys.txt
?? H/.claude/settings.json: 'statusLine' は一覧にありません(新しい設定なら一覧へ追加してください)
?? H/.claude/settings.json: 'statusLine.type' は一覧にありません(新しい設定なら一覧へ追加してください)
?? H/.claude/settings.json: 'enableAllProjectMcpServers' は一覧にありません(新しい設定なら一覧へ追加してください)
$ echo $?
0

?? として見えるところまでは同じですが、終了コードは 0 のままです。書き間違いだけを失敗にして、知らないキーは通す。この線引きにしておくと、新しい設定を試した日に検査が止まる、という煩わしさを避けられます。

doctor の終了コードは 0 のままです

もうひとつ、自動化に組み込むときの落とし穴があります。先ほどの表のとおり、claude doctor は設定が壊れていても終了コード 0 を返します。構文エラーで設定が丸ごと読まれていない状態でも 0 です。

#!/usr/bin/env bash
# claude doctor は設定が壊れていても終了コード 0 を返す。出力を読んで自分で落とす。
set -uo pipefail
out="$(claude doctor < /dev/null 2>&1)"
echo "$out"
if grep -q 'Invalid settings' <<< "$out"; then
  echo "NG: settings が読み込まれていません(上の Invalid settings を参照)" >&2
  exit 1
fi
exit 0

正しい設定・末尾カンマの構文エラー・型違反の3つで試したところ、それぞれ 0 / 1 / 1 になりました。doctor の判断力はそのまま使えるので、足りないのは失敗として扱う部分だけです。

この2つを組み合わせると、settings.json に対する検査は次の形に落ち着きます。型と構文は doctor に任せ、キー名は自分の一覧で見る。どちらも終了コードで判定できるので、コミット前のフックにも無人タスクの前処理にも置けます。

設定ファイルが壊れて Claude Code そのものが立ち上がらなくなったときの切り分けは、壊れた settings.json で Claude Code が起動しなくなったとき に分けて書いています。今回の話はその手前、起動はするのに設定だけが効いていない状態への備えです。

最後は挙動で確かめる

正直なところ、この検査で守れるのは自分が知っているキーだけです。一覧に無いキーは ?? として素通りしますし、値の妥当性までは見ていません。permissionModeplanz と書いた設定は、この検査も doctor も通ります。

ですから、私はこの検査と併せて、新しい設定を足した日には1回だけ挙動で確かめる習慣を持つようにしました。拒否ルールを書いたのなら、実際にそのコマンドが止まるかを一度試す。出力スタイルを変えたのなら、次の応答の形が変わったかを見る。数十秒で済みますし、この確認だけが「書いた設定が本当に届いた」という証拠になります。

黙って落ちるものを見つける方法は、突き詰めると毎回同じでした。期待した件数・期待した反応を先に決めておいて、実際の数と突き合わせる。同じ考え方で一括処理の取りこぼしを止めた話は、空白ひとつで、80件の検査が0件になる で扱っています。

まず手元の settings.json を1つ選び、キーを書き出して眺めてみてください。複数形の s と、途中の大文字が残っているか。それだけでも、消えていた設定が1つ見つかるかもしれません。

私自身このスクリプトは、書き間違いを1つ見つけたところから育て始めたものです。お読みいただきありがとうございました。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Claude Code2026-07-01
Claude Code をアップデートしたら hook が発火しなくなった — ハイフン入り matcher の厳密一致化(v2.1.195)
Claude Code v2.1.195 でハイフンを含む hook matcher が部分一致から厳密一致に変わり、既存の PreToolUse フックが静かに発火しなくなりました。原因の切り分けと、壊れない matcher の書き方をまとめます。
Claude Code2026-06-13
モデルの自動アップグレードでクレジットを使い切らないために — enforceAvailableModels で実行モデルを固定する
6月15日の課金変更で月次クレジットは繰越なしに移行します。サブエージェントやフォールバックが意図せず上位モデルへ上がってクレジットを溶かさないよう、enforceAvailableModels で実行モデルを管理側から固定する設計と検証手順をまとめました。
Claude Code2026-05-18
Claude Code の Bash ツールで cd や export が引き継がれない時の対処
Claude CodeのBashツールでcdやexportが次のコマンドに反映されないのは、1回ごとに独立したシェルで起動する仕様のためです。&&で1行に束ねる、絶対パスを徹底する、環境変数をインラインで渡す、CLAUDE.mdに置くなど、実務で使える5つの対処パターンを整理しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →