Config Check
Validates Docker Compose files (docker-compose.yml) against the official SchemaStore schema, catching misspelled keys like port, depends_on conditions such as service_healthy, and invalid healthcheck settings.
Validates ESLint configuration files against their SchemaStore schema, including ESLint flat config, flagging invalid or misspelled options.
Validates GitHub Actions workflow files (.github/workflows/*.yml) against the official workflow schema, reporting errors such as runs_on instead of runs-on, with line numbers, paths and suggested corrections.
Provides schema lookup for Kubernetes manifests, resolving which SchemaStore schema applies to a given file so its contents can be validated.
Validates Python project configuration files such as pyproject.toml (build system, project metadata, dependencies, requires-python) against the official schema.
Validates Renovate configuration files against the official Renovate schema, catching invalid settings and keys before they take effect.
Validates pyproject.toml files, including the [tool.ruff] section, against the official schema so misconfigured settings such as an invalid line_length are reported.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Config Checkcheck my GitHub Actions workflow for schema errors and typos"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Config Check
Agents write config files all day and misspell them: runs_on for runs-on, strictNullCheck
for strictNullChecks, service_ready where Compose only knows service_started,
service_healthy and service_completed_successfully. Most of these fail late (a workflow GitHub
rejects after the push) or never (tsconfig ignores keys it does not know). Config Check validates
config files against the official JSON Schema for their file name from
SchemaStore, the catalog VS Code and JetBrains IDEs use, and reports
what an editor would underline in a form a model can act on:
Validate up to 20 files at once: JSON, JSON with comments, YAML (every document, merge keys) and TOML. The schema is chosen by file name (1,400+ kinds), by the file's own
$schema, or by name. Each error has its line, a readable path (jobs.test.steps[1].timeout), the allowed values and the key probably meant; a value that fails ananyOfgets one error for the alternative it nearly matched, not one per alternative.Warnings for what schemas let through: misspelt keys in settings that accept unknown keys (tsconfig's
compilerOptions), deprecated settings, and values that break their own setting's definition while another alternative lets the file pass (tsconfig's"include": "src").Look up any setting: its description, type, allowed values, default, deprecation and sub-settings, or search a schema's settings by words.
No key needed.
Built and maintained by Arhan Canli.
Install
Needs Node.js 20 or newer. No account or key.
Claude Code
claude mcp add config-check -- npx -y config-check-mcpClaude Desktop: download config-check-mcp-<version>.mcpb from the latest release and open it. The bundle is signed; verify it with gh attestation verify <file> --repo arhancanli/config-check-mcp.
Any other client (Windsurf, Zed, Cline, Continue and others), in its MCP config file:
{
"mcpServers": {
"config-check": {
"command": "npx",
"args": [
"-y",
"config-check-mcp"
]
}
}
}Docker
docker build -t config-check-mcp https://github.com/arhancanli/config-check-mcp.git && docker run -i --rm config-check-mcpHosted (Streamable HTTP): node src/server.mjs --http serves stateless MCP at POST /mcp (port from PORT, default 3000).
Related MCP server: VS Code Settings MCP Server
Example
An agent calls validate_config with:
{
"files": [
{
"path": "tsconfig.json",
"content": "{\n // JSON with comments, as tsconfig allows\n \"compilerOptions\": {\n \"target\": \"es2099\",\n \"moduleResolution\": \"nodenext\",\n \"strictNullCheck\": true,\n \"outdir\": \"dist\",\n \"importsNotUsedAsValues\": \"remove\",\n },\n \"include\": \"src\"\n}\n"
},
{
"path": ".github/workflows/ci.yml",
"content": "name: CI\non:\n push:\n branch: [main]\n pull_request:\njobs:\n test:\n runs_on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - run: npm test\n timeout: 10\n build:\n runs-on: ubuntu-latest\n needs: test\n steps:\n - name: Build\n"
},
{
"path": "docker-compose.yml",
"content": "services:\n web:\n image: nginx:latest\n port:\n - \"80:80\"\n depends_on:\n - db\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost\"]\n interval: 30\n db:\n image: postgres:16\n"
},
{
"path": "pyproject.toml",
"content": "[build-system]\nbuild-backend = \"hatchling.build\"\n\n[project]\nname = \"demo\"\nversion = \"0.1.0\"\nrequires-python = 3.11\ndependencies = \"requests>=2\"\n\n[tool.ruff]\nline_length = 100\n"
}
]
}and gets back (recorded from the live server on 2026-09-27):
{
"valid": 0,
"invalid": 4,
"files": [
{
"path": "tsconfig.json",
"schema": "tsconfig.json",
"schema_url": "https://www.schemastore.org/tsconfig.json",
"valid": false,
"warnings": [
{
"line": 6,
"path": "compilerOptions.strictNullCheck",
"message": "\"strictNullCheck\" is not a setting the schema knows; did you mean \"strictNullChecks\"?",
"did_you_mean": "strictNullChecks"
},
{
"line": 7,
"path": "compilerOptions.outdir",
"message": "\"outdir\" is not a setting the schema knows; did you mean \"outDir\"?",
"did_you_mean": "outDir"
},
{
"line": 8,
"path": "compilerOptions.importsNotUsedAsValues",
"message": "deprecated: Deprecated in favor of verbatimModuleSyntax."
},
{
"line": 10,
"path": "include",
"message": "must be array or null, not string (the schema's alternatives let the file pass, but this setting's own definition does not)"
}
],
"errors": [
{
"line": 4,
"path": "compilerOptions.target",
"message": "\"es2099\" is not an allowed value",
"allowed": [
"es3",
"es5",
"es6",
"es2015",
"es2016",
"es2017",
"es2018",
"es2019",
"es2020",
"es2021",
"es2022",
"es2023",
"es2024",
"es2025",
"esnext"
]
}
]
},
{
"path": ".github/workflows/ci.yml",
... (82 more lines)Tools
Tool | What it does |
| What a setting in a config file means and accepts, from its official schema: description, type, allowed values, default, deprecation and its sub-settings. setting is a dotted path (compilerOptions.module, jobs..runs-on, services..healthcheck); omit it for the top level. search finds settings by words instead (search: 'healthcheck interval'). |
| Which SchemaStore schema applies to a file (give its path or name) or matches words (kubernetes, eslint flat config): name, URL and the file names it covers, best match first. Use the name or URL as validate_config's or config_help's schema. |
| Checks config files against their official JSON Schema from SchemaStore (1,400+ kinds, chosen by file name: tsconfig.json, package.json, docker-compose.yml, .github/workflows/*.yml, pyproject.toml...). JSON, JSONC, YAML, TOML. Each error has its line, path, the allowed values and the key probably meant; also warns on likely misspelt and deprecated settings. |
How it behaves
Read-only: no tool changes anything outside this process. File contents never leave it; only schemas are downloaded.
Network: HTTPS only. SchemaStore's catalog comes from
www.schemastore.org(cached for a day); each schema, and every document it references, is fetched only from the hosts that catalog lists, level by level in parallel, with a deadline, an 8 MB cap per document and bounded retries. A schema the file names for itself ($schema,# yaml-language-server: $schema=, Taplo's#:schema) is used when it is on one of those hosts. Nothing is logged except unexpected failures (to stderr, without your inputs).Validation is Ajv, the validator SchemaStore tests its own schemas with, with ajv-formats. SchemaStore mixes drafts 04 to 2020-12 and schemas of one draft reference schemas of another, so each document is normalised (draft-04's boolean
exclusiveMaximum, 2020-12'sprefixItems) and compiled together, once per schema, cached for 6 hours.YAML is read as YAML 1.2, as GitHub and Compose read it (
yesis text,on:is a key), with merge keys. TOML dates are compared as their text.Results are compact JSON with a matching output schema. At most 40 errors and 20 warnings per file are listed; the rest are counted.
Benchmark
Not yet measured.
Performance
Measured 2026-09-27 from Dubai, home connection against the live upstream, Node 24.19.0 (bench/perf.json, scripts/perf.mjs in the factory).
Call | First call | Repeat | Result size |
validate_config: tsconfig, a workflow, a compose file and pyproject.toml with typical mistakes | 1705 ms | 8.2 ms | 2,846 chars |
validate_config: a clean workflow, and a manifest.json three schemas claim | 976 ms | 1.9 ms | 560 chars |
validate_config: YAML that does not parse | 6 ms | 0.5 ms | 169 chars |
config_help: tsconfig's compilerOptions.moduleResolution | 374 ms | 1.9 ms | 1,056 chars |
config_help: search a workflow's settings for 'timeout' | 344 ms | 2.7 ms | 372 chars |
find_schema: a file path and words | 229 ms | 1.6 ms | 313 chars |
First call: a fresh server process, including the TLS connection and the upstream's own time. Repeat: the same call again, answered from the in-process cache, so it shows this server's own overhead.
Tool definitions the model reads on every turn (name, description, input schema): 2,029 characters, against 1,105 for mcp-server-fetch reading SchemaStore (no config-validation MCP server exists; this is what agents use today). The full tool list, with the output schemas and annotations clients use to validate results, is 3,283 characters (1,104 for the alternative).
More MCP servers by Arhan Canli
Actions Check: Checks GitHub Actions workflows: outdated actions, old Node runtimes, retired runners, injection.
Cron Check: Explains cron expressions, lists next run times in any time zone, converts between cron dialects.
Domain Health: Email and domain checks: SPF lookup limits, DKIM keys, DMARC, DNS records, registration expiry.
End of Life: Is this version still supported? EOL dates, latest patch and upgrade target for 470+ products.
Internet Standards: RFC sections, status, obsoleted-by chains, errata and IANA registries for coding agents.
Kube Check: Checks Kubernetes manifests for your version: removed APIs, unknown fields, Pod Security, risks.
License Check: Open source license answers: SPDX ids, copyleft, and whether a dependency's license fits yours.
Package Truth: Checks packages exist before install: version, deprecation, vulnerabilities, licence. 7 ecosystems.
The whole collection, 9 more
License
MIT, Copyright (c) 2026 Arhan Canli.
Available Tools
3 toolsconfig_helpWhat does this config setting do?ARead-onlyIdempotent
What a setting in a config file means and accepts, from its official schema: description, type, allowed values, default, deprecation and its sub-settings. setting is a dotted path (compilerOptions.module, jobs..runs-on, services..healthcheck); omit it for the top level. search finds settings by words instead (search: 'healthcheck interval').
| Name | Required | Description | Default |
|---|---|---|---|
| schema | Yes | schema name, file name (tsconfig.json, .github/workflows/ci.yml) or schema URL | |
| search | No | ||
| setting | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| schema | Yes | |
| schema_url | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=true, destructiveHint=false, so safety is covered externally. The description adds that answers come from the 'official schema' and what facets are surfaced, but says nothing about auth, rate limits, or resolution behavior when a schema URL is fetched. With annotations carrying the safety profile, this is adequate but shallow.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly three dense sentences, front-loaded with the core purpose, then the setting-path semantics and the search alternative. Examples earn their space by showing path syntax; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return shape need not be re-explained, and the description still lists the facets exposed. Combined with the dotted-path and search guidance, an agent has enough to call this correctly; only sibling differentiation (find_schema) is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33%, so the description must compensate, and it does: it defines `setting` as a dotted path with three concrete examples (compilerOptions.module, jobs.*.runs-on, services.*.healthcheck), explains the omitted-setting default, and documents the `search` alternative with an example query. Only the `schema` parameter is left to the schema itself, which already describes it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: it explains what a config setting 'means and accepts' from its official schema, and enumerates what is returned (description, type, allowed values, default, deprecation, sub-settings). It does not, however, differentiate itself from the sibling find_schema, whose purpose overlaps (locating schema info).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description distinguishes its two access modes clearly – a dotted-path lookup with the `setting` parameter versus word-based discovery via `search` – and notes omitting `setting` returns the top level. It gives no guidance on when to prefer this over find_schema or validate_config, so usage is implied rather than explicitly routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_schemaWhich schema covers this file?ARead-onlyIdempotent
Which SchemaStore schema applies to a file (give its path or name) or matches words (kubernetes, eslint flat config): name, URL and the file names it covers, best match first. Use the name or URL as validate_config's or config_help's schema.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | a file path or name, or words |
Output Schema
| Name | Required | Description |
|---|---|---|
| schemas | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld, non-destructive, so the safety profile is covered. The description adds observable behavior beyond annotations: results are returned 'best match first' and include name, URL and covered file names. Useful, though no rate-limit or empty-result behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence, front-loaded with the core question and followed by output shape and downstream usage. Every clause earns its place, though the parenthetical examples make it slightly crowded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering safety, the description is nearly sufficient. It still volunteers the return fields (name, URL, covered file names), which is a bonus rather than a requirement, but pagination/limit behavior is unaddressed for an open-world lookup.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single query parameter is already documented as 'a file path or name, or words'. The description largely restates that (path/name or words), adding little syntax or format detail, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (find which SchemaStore schema applies to a file) and explicitly distinguishes itself from siblings by naming validate_config and config_help as downstream consumers. An agent can identify the tool's role without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains both accepted input styles (a file path/name, or words like kubernetes or eslint flat config) and the handoff pattern: feed the returned name or URL into validate_config or config_help. Clear context, though no explicit when-not-to-use exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_configCheck config files against their schemasARead-onlyIdempotent
Checks config files against their official JSON Schema from SchemaStore (1,400+ kinds, chosen by file name: tsconfig.json, package.json, docker-compose.yml, .github/workflows/*.yml, pyproject.toml...). JSON, JSONC, YAML, TOML. Each error has its line, path, the allowed values and the key probably meant; also warns on likely misspelt and deprecated settings.
| Name | Required | Description | Default |
|---|---|---|---|
| files | Yes | ||
| schema | No | use this schema for every file: a name, file name or URL |
Output Schema
| Name | Required | Description |
|---|---|---|
| files | Yes | |
| valid | Yes | |
| invalid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds genuine behavioral context the annotations don't: what each reported error contains (line, path, allowed values, suggested key) and that it also emits misspelling/deprecation warnings.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, followed by one supporting sentence on error detail; the parenthetical file-kind list is dense but earns its place as scope evidence. No filler sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be described, and annotations carry the safety profile. The main omission is batch constraints (maxItems 20, per-file size limits) that an agent calling with many files would benefit from knowing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 50% (the 'content' property is undocumented). The description partially compensates by explaining that the file path/name drives schema and format selection, but it never mentions the 'schema' override parameter that applies one schema to every file, leaving that behavior to the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Checks config files against their official JSON Schema from SchemaStore') plus the mechanism (schema chosen by file name) and supported formats. This is clearly distinguishable from config_help and find_schema, which cannot validate file contents.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is strongly implied by the purpose (validate a config file's content), and naming the supported file kinds hints at scope. However, there is no explicit when-to-use/when-not guidance and no routing to the sibling tools (e.g., use find_schema to obtain a schema, config_help for guidance).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
config_help - First observed
find_schema - First observed
validate_config
TDQS
Scored across 3 tools
Each tool targets a clearly distinct function: config_help explains settings, find_schema identifies the applicable schema, and validate_config checks a file. Their descriptions explicitly cross-reference each other, leaving no ambiguity about which tool to use.
All names use snake_case and are readable, but config_help breaks the verb_noun pattern set by find_schema and validate_config. The deviation is minor and does not impede understanding.
Three tools form a well-scoped set for config schema assistance: one to locate schemas, one to explain settings, and one to validate files. Each tool earns its place, and the count is neither thin nor bloated.
The surface covers the core lifecycle of schema discovery, setting explanation, and config validation. Minor gaps exist, such as no explicit schema browsing beyond search or auto-fix suggestions, but agents can work around them.
Maintenance
Related MCP Connectors
Validate oh-my-posh configurations and segment snippets against the official schema.
Deterministic validation for AI-generated artifacts: JSON Schema, OpenAPI response, SQL syntax.
MCP server (stdio): validate JSON against JSON Schema (draft-07 / 2020-12) via the AgentForge API
Validate JSON, YAML, XML and CSV with exact line/column errors and silent-corruption warnings.
Related MCP Servers
- FlicenseBqualityFmaintenanceEnables AI assistants to search documentation, read and update configuration files, and discover settings across your development workspace. Supports JSON, YAML, TOML, and Markdown files with seamless integration for GitHub Copilot and other MCP clients.5-
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to programmatically read, update, and manage Visual Studio Code settings across user and workspace scopes. It provides cross-platform support for automating VS Code configuration through the Model Context Protocol.672 npm-
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to list, find, fetch, and look up JSON Schema documents from the SchemaStore catalog.1 npmMIT
- AlicenseNot gradedqualityBmaintenanceValidates JSON values against JSON Schema (draft-07). Enables schema validation for structured data.3 npmMIT