ml-skills-mcp
Click on "Install 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., "@ml-skills-mcpRun the architecture standards check on this repo and show me the findings"
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.
ml-skills
Architecture standards you can actually enforce — served as an MCP server, an HTTP API, a CLI and a library, so the same rules reach your coding agents, your website, your pipeline and your editor without being written down four times.
npx @mlmcps/ml-skills check . # a repo, with file:line findings
npx -p @mlmcps/ml-skills ml-skills-mcp # MCP over stdio, for agents
npx -p @mlmcps/ml-skills ml-skills-http # HTTP API + MCP Streamable HTTP + browser UIThe idea
Most "AI coding standards" projects ship a pile of markdown and hope. The problem is that prose is unenforceable, and an agent that reads a standard is under no obligation to follow it. So this package separates two things that usually get conflated:
What it is | Who owns it | |
Rules | The checks. "Pick one pagination style and use it everywhere." | Everyone. Shipped here. |
Decisions | The values those checks compare against. "Ours is cursor pagination with | You. Overridable, and the only part that is anyone's IP. |
You cannot buy the second column — a standard's value is precisely that it is your decision, consistently applied. What you can take off the shelf is the machinery: the rule catalogue, the checkers, and three transports to reach every tool you use. That is this package.
Nothing here can fail your build until you say so
Every standard ships marked proposed. A proposed standard reports at warn and cannot exit
non-zero, whatever its severity map says. You ratify it in .mlskills.json, and only then can it
break a pipeline.
That is deliberate. A gate that fails on day one gets disabled on day two, and a rule nobody agreed to is a preference wearing a uniform. Every report says out loud which standards were incapable of failing, because "no errors" means something very different when nothing was allowed to be one.
Related MCP server: Harness Engineering MCP
The eleven standards
Standard | Governs | Rules |
| HTTP API shape: versioning, errors, pagination, headers, leaks | 22 |
| SQL keys/money/time/FKs + Mongoose schema design | 36 |
| Layering, secrets, logging, timeouts, input validation | 25 |
| Images, probes, limits, pod security, CI pinning | 21 |
| Async states, tokens, data layer, accessibility | 19 |
| Injection, authz, crypto, cookies, traversal, headers | 22 |
| Whether a green suite means anything | 14 |
| Versioning, idempotency, the outbox, dead letters | 10 |
| Structured logs, correlation, traces, metrics | 10 |
| Backoff, jitter, breakers, graceful shutdown | 10 |
| Twelve-factor config, startup validation, secret hygiene | 10 |
199 rules. Read one in full: npx @mlmcps/ml-skills show security-patterns.
A few that earn their keep:
SEC021 flags
findById(req.params.id)with no ownership check nearby. Broken object-level authorisation is the most exploited API flaw there is, and it looks exactly like working code.OAS009 resolves
$reftransitively, so apasswordHashtwo schemas below a response root is still reported — the shape credential leaks actually have.EVT003 flags a publish inside a transaction with no outbox: the dual-write, where the transaction rolls back, the event does not, and the estate now believes something that never happened.
RES010 flags
catch { return [] }. The dependency is down, the page renders "no results", nothing alerts, and revenue drops for a week.TST001 flags a committed
.only, which silently stops the rest of the suite from running while the build stays green.
Adapters — reuse what already exists
Spectral, Semgrep, hadolint, ESLint and Trivy encode far more person-years of rule development than this package ever will, and several match on a real AST rather than on text. Reimplementing them would be worse and slower. So ml-skills runs them and normalises what they say:
ml-skills adapters # what is installed
ml-skills check . --with semgrep # built-in rules plus one adapter
ml-skills check . --with-all # plus everything installedAdapter | Standard it reports under | Covers |
|
| OpenAPI/AsyncAPI rulesets |
|
| Dockerfile |
|
| your project's own ESLint config — this adapter adds no rules |
|
| semantic patterns, registry rulesets |
|
| dependency CVEs, committed secrets, IaC misconfiguration |
|
| Postgres migration safety — parses SQL, reasons about lock levels |
|
| dialect-aware SQL linting |
|
| Java bytecode analysis (+ Find Security Bugs) — reads |
|
| Java source rules — reads the build's report |
|
| Java conventions — reads the build's report |
Java adapters read the report your build already produced rather than running a JVM. PMD, SpotBugs and Checkstyle are Maven and Gradle plugins, not standalone CLIs — invoking a second copy would be slower, need its own configuration, and could disagree with the one that gated the build. Their applicability is the report's existence, not our file walk: the build may have analysed sources we never saw.
ArchUnit has no adapter and needs none. It is a test library, so layering rules run in your existing suite and fail the build with no extra gate.
Findings merge into one list, sorted together, each tagged with its source:
Dockerfile
1 error INF001 base image "node:latest" uses the :latest tag
2 warn hadolint/DL3009 via hadolint Delete the apt-get lists after installing something
2 warn INF007 apt install without pinned package versionsExternal findings go through the same ratification gate. An installed tool cannot grant itself the authority to fail a build on a standard nobody has signed off. Severity precedence is: your config override, then the tool's own severity, then the ratification demotion.
{
"adapters": {
"semgrep": { "required": true, "config": "p/owasp-top-ten" },
"hadolint": { "severity": { "DL3059": "off" } },
"trivy": { "scanners": "vuln,secret" }
}
}Stack presets
ml-skills preset # list
ml-skills preset mern # write .mlskills.json
ml-skills preset java-springPreset | Adapters | Rules deferred |
| 5 | 65 |
| 9 | 70 |
A preset answers the question that matters once you accept the ecosystem is stronger than any one package: given ~3,000 rules across twenty tools, which of ours are still worth running?
Two rules govern them, both enforced by tests:
Never silence a rule without naming the tool that supersedes it. Every block carries a
$why. An unexplained"off"is indistinguishable from someone quietly disabling an inconvenient rule, so it is not allowed to exist.A preset never ratifies anything. Every skill stays
proposed. Deciding a standard may break a build is a human call, and a config file taking it on your behalf is how governance gets disabled the week after it lands.
Applying a preset over an existing config keeps your values and reports which it kept — a preset is a starting point, not an overwrite.
What each preset keeps
mern defers UI, testing and most security rules to eslint-plugin-react/-hooks/-jsx-a11y
(171 rules), eslint-plugin-jest/-testing-library (100) and Semgrep — then keeps the Mongoose
schema rules, because as of writing nothing in the JavaScript ecosystem checks Mongo schema
design. eslint-plugin-mongodb is 17 rules about query syntax; eslint-plugin-mongoose does not
exist. That is the load-bearing part of the preset.
java-spring defers bug-hunting to PMD, SpotBugs and Checkstyle, and migration safety to
squawk — which parses Postgres and reasons about lock levels ("requires ACCESS EXCLUSIVE;
blocking: reads, writes"), an analysis no pattern over text can reach. It keeps the contract and
design decisions: layering, entities leaving the API layer, timeouts, PII, transaction placement,
key type, cross-service foreign keys.
Both keep events-messaging, observability and resilience-patterns in full, because nothing
in either ecosystem checks the outbox pattern, correlation propagation, or backoff-with-jitter.
resilience4j is a library — using it does not mean it was configured correctly.
A tool that did not run is never a clean result
This is the rule the whole adapter layer is built around. A missing scanner reported as "no findings" is worse than no scanner, because the first one gets believed.
Not installed → status
missing, with an install hint.Crashed or timed out → status
failed, with the reason and the exact command to reproduce.Output unparseable → status
failed, not zero findings.Marked
requiredand absent → an error-severity finding, so the gate fails.Either way, the summary carries
adaptersNotRunand the report says so at the top level.
ml-skills own rules do not inspect a lockfile at all. A clean run says nothing about the CVEs in
your dependencies — only the Trivy adapter covers those, and adapter_status will tell an agent so
before it promises a security verdict.
Overlap is expected
hadolint's DL3025 and this package's INF012 both flag shell-form CMD. That is fine — two
tools agreeing is not a bug — but if the duplication is noisy, silence one side in config rather
than dropping the adapter.
Not over HTTP
Adapters run from the CLI and the stdio MCP server only. POST /v1/check never shells out: a
service that executed local binaries on request content would be a remote code execution surface,
and the HTTP face already refuses to accept a path for the same reason.
Behavioural evals
A standard is a behavioural intervention, not a document. evals/ tests whether it actually
changes what gets written:
ml-skills eval # all scenarios
ml-skills eval EV001 # oneEach scenario records the verbatim excuse an agent makes when the standard is absent, names the rule that counters it, and pairs it with the code that excuse produces plus the corrected version:
✓ EV001 events-messaging Publishing an event inside the transaction that may roll back
✓ counter rules exist
✓ fires on the rationalized code
✓ silent on the corrected code
✓ counter is documented in the skill
⏳ "I'll commit first and then publish, so the event only fires on success."
countered by EVT003 · behavioural check pendingThe method is borrowed, with thanks, from a-pavithraa/springboot-skills-marketplace (MIT). No code was copied — see NOTICE.md for the full provenance and the licences of every tool the adapters invoke. The difference is that there the counter is a sentence, so only a human or a model can judge whether it landed; here it is a rule, so three of the four checks run in CI.
The fourth never passes. Whether an agent reaches for the excuse when the standard is absent
needs a model run, and is reported as pending — never as passing. A harness that scored itself on
the three cheap checks and let the fourth be inferred would be measuring the wrong thing while
sounding confident about it, which is the failure this package exists to prevent.
Two things the harness enforces on the scenarios themselves, because they are what make it worth doing: the excuse must be verbatim and plausible (an excuse rewritten to look foolish tests nothing), and a rule that fires on the corrected code is a false positive on the compliant spelling — worse than a missing rule, because it teaches people the checker is noise.
Workflows — what to do, in what order
Rules say what is wrong. Assets show what right looks like. Neither says what to do first, and an agent handed eleven standards and ninety assets has no ordering — so it reads whatever appeared first in the diff and reports whatever it happened to notice.
workflow_list # the procedures, with their "not for" clauses
workflow_get review-java # the numbered stepsWorkflow | Steps | For |
| 4 | A diff, module or PR — checker first, contract pass before correctness |
| 6 | Assess the shape, choose the structure, apply the foundations |
| 5 | Name the persistence problem, then pick the pattern |
| 5 | Scan, then one migration at a time, each green before the next |
They own no content — they sequence the standards, references and assets that already exist. Each
is also an MCP prompt, so a client gets them as commands, and each carries a not-for clause,
because a procedure applied to a task it does not fit produces confident, irrelevant output rather
than an obvious failure.
Two tests keep them honest: steps must be numbered without gaps, and every asset or reference a workflow names must actually exist — a procedure that sends an agent looking for a missing file gets improvisation instead.
The shape is borrowed from
a-pavithraa/springboot-skills-marketplace,
whose SKILL.md files are procedures rather than rule lists. That comparison is where this gap
became obvious — see NOTICE.md.
Reference documents and runnable examples
Each skill's SKILL.md is a router, not a dump — it carries the decisions and the rule table, and
points at a reference loaded only when a change touches that ground:
Skill | Reference |
|
|
|
|
|
|
|
|
Every skill with a reference also ships complete, copyable implementations under assets/ —
not fragments:
| a schema passing every MNG rule; the query patterns |
| the transactional outbox and its relay; a consumer that survives redelivery |
| timeout + backoff + jitter + breaker composed; SIGTERM in the order that matters |
| structured logging with correlation and redaction; environment validated at boot |
Assets are partitioned by language — assets/java/, assets/node/, assets/shared/ — so adding a
language is a new directory rather than a reshuffle. Each asset's real destination
(src/main/java/..., db/migration/..., k8s/...) is derived from that, which matters because
a checker only selects a file whose path matches. See STRUCTURE.md.
Every asset is checked against the standard it demonstrates, by a test, at the path it would occupy in a real repository. An example that violates the rule it teaches is worse than no example — it is the strongest signal a reader gets, and it points the wrong way. Adding that check exposed four rule precision bugs:
Rule | Was wrong because |
| Fired on |
| Used proximity, but backoff is a helper defined once at the top of a module and used further down, so every correct implementation was reported |
|
|
| A logger implementation names every level by definition |
All four now use file scope or an exclusion rather than a proximity window.
Skill descriptions also carry a not-for line on all 11 skills. That clause is what stops a skill
loading on every task, and it matters more than the trigger list.
Two kinds of rule
Code rules live in lib/check/*.mjs and need real structure: the OpenAPI $ref walk, the SQL
DDL reader, the Kubernetes pod spec.
Declarative rules live in lib/rulesets/ and are data — a pattern, the files it applies to,
and the proximity conditions under which it matters:
{
id: 'RES001', skill: 'resilience-patterns', severity: 'error',
files: ['**/*.ts', '**/*.java'],
forbid: '\\b(?:retry|maxRetries)\\b',
near: { pattern: 'backoff|exponential|jitter', lines: 10 }, // suppress when mitigated
message: 'retry configured with no backoff strategy',
}near means "fine as long as that is close by"; requireNear means "only matters when that is
close by". Getting those the wrong way round makes a rule report the exact complement of what it
means, which is a mistake this package shipped once and now has a test for.
Your own rules, without forking
The rules that matter most to you are the ones nobody else can ship. Put them in .mlskills.json:
{
"customRules": [{
"id": "ACME001",
"skill": "backend-patterns",
"severity": "error",
"files": ["**/*.ts"],
"forbid": "from ['\"]moment['\"]",
"title": "No moment.js",
"why": "Frozen upstream. Use Temporal or date-fns.",
"message": "moment is banned — see ADR-014"
}]
}They run alongside the built-ins, appear in explain, and obey the same ratification gate: an org
cannot grant itself an error-severity rule on a standard it has not ratified. Malformed custom
rules throw at load rather than silently matching nothing — a rule that quietly matches nothing
reports a clean repo, which is the worst possible failure for a checker.
Use it
As an MCP server (agents)
Claude Code
claude mcp add ml-skills -- npx -y -p @mlmcps/ml-skills ml-skills-mcp --root .Cursor, VS Code, Windsurf, or any MCP client — in the client's MCP config:
{ "mcpServers": { "ml-skills": { "command": "npx",
"args": ["-y", "-p", "@mlmcps/ml-skills", "ml-skills-mcp", "--root", "."] } } }Remote / HTTP clients — run ml-skills-http and point the client at POST /mcp
(MCP Streamable HTTP).
One package, three binaries.
npx @mlmcps/ml-skillsruns the CLI because that bin matches the package name; the other two need-p:npx -p @mlmcps/ml-skills ml-skills-mcp. There is no separate@mlmcps/ml-skills-mcppackage to install.
Check which copy is running — the predictable failure when a team mixes a stale npx cache with a
fresh install — with --version, which prints the version and the resolved path:
npx -p @mlmcps/ml-skills ml-skills-mcp --versionThe server exposes three surfaces, because clients use different ones:
Surface | What |
Tools |
|
Resources |
|
Prompts |
|
check_repo reads from disk; check_content takes documents inline, for a file being drafted or a
client with no filesystem access. Both return the same verdicts.
Everything is read-only and makes no network calls — a standards checker that phoned home would not survive its first security review, and it has to run in the pipeline that has no egress.
In a website
npx -p @mlmcps/ml-skills ml-skills-http --port 8787Serves a browser UI at / (read the standards, paste a file, see the findings) and a JSON API:
| the standards, including full document text |
| the rule catalogue and per-rule rationale |
|
|
| which decisions are still shipped defaults |
| MCP Streamable HTTP |
| distinct, per this package's own infra standard |
const res = await fetch('https://standards.example.com/v1/check', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ files: [{ path: 'openapi.yaml', text: spec }] }),
});
const { summary, findings } = await res.json();The HTTP face deliberately does not accept a path to scan. A service that took a directory and walked it would be a directory-traversal oracle for anyone who could reach the port. Callers send content; disk access stays on the stdio transport, where the client already has the files.
In CI
- run: npx @mlmcps/ml-skills check . --json > standards.jsonExits 1 on any error-severity finding from a ratified standard, 0 otherwise.
As a library
import { check } from '@mlmcps/ml-skills';
const { findings, summary } = check(
[{ path: 'openapi.yaml', text }],
{ overrides: { 'openapi-contract': { status: 'standard' } } },
);check() is pure — content in, findings out, no filesystem and no network — which is why the same
function backs the agent, the website and the pipeline. It runs in a browser bundle unchanged.
Making it yours
npx @mlmcps/ml-skills init # writes .mlskills.json
npx @mlmcps/ml-skills ratify # what nobody has signed off yet{
"openapi-contract": {
"status": "standard", // now it can fail a build
"decisions": {
"pagination": "offset", // we disagree with the default, and that is fine
"paginationParams": ["offset", "limit"],
"versionPattern": "^/api/v[0-9]+/"
},
"severity": { "OAS002": "off" } // we do not care about summaries
},
"ui-patterns": { "status": "proposed" }
}Arrays replace rather than merge — an override of a list means instead of, not as well as.
Exclude paths with a top-level exclude (or per skill). Deliberately non-compliant fixtures are
the common case, and a checker you have to ignore is a checker nobody reads:
{ "exclude": ["test/fixtures/**", "**/*.generated.ts"] }This repo ships its own .mlskills.json doing exactly that, with all five standards ratified —
npx @mlmcps/ml-skills check . on this package reports zero findings, and the two rules it turns
off say in the file why.
Ratifying means three things: someone read the decision, someone agreed to it, and someone accepts that it can now break a build. See RATIFY.md for the checklist and the decisions that most need a human.
Honest limitations
Most built-in checks are text-based, not AST-based. Five standards have structural checkers; the rest are patterns over the right files with proximity conditions. For AST-level matching, run the Semgrep or ESLint adapter — that is what they are for.
Nothing built in inspects your dependencies. A clean run says nothing about CVEs in your lockfile. Use the Trivy adapter. Supporting TypeScript, JavaScript, Java and Kotlin with real parsers would be four dependencies and four things to keep current, and this package has none. What is checked is what survives being checked on text: import edges, forbidden calls, credential and log shapes. Type-level rules belong in your language's own linter, and this does not replace it.
The YAML reader is a subset. Block mappings, sequences, flow collections, block scalars and comments — enough for OpenAPI, k8s and compose. It does not resolve anchors or aliases, and says so in the findings rather than parsing them wrongly.
These checks find shapes, not semantics.
checkpassing does not mean the design is good; it means it does not violate the specific things you wrote down. Design review is still a human job.False positives exist and are reported as findings, not truths. Silence a rule with
"severity": { "RULE": "off" }rather than working around it.
Development
npm test # 83 tests, no dependencies, no network
npm run eval # behavioural eval scenarios
npm run serve # HTTP + web UI on :8787
npm run mcp # stdio MCP serverThe reference example in skills/openapi-contract/assets/endpoint.yaml is checked by the test
suite against its own standard. If a rule changes and the example stops passing, the build fails —
a standard whose own example violates it is worse than no standard.
MIT. @mlmcps/ml-skills.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP enforcement layer that intercepts AI agent actions and blocks rule violations before execution.
Zero-install security baseline for AI coding agents — OWASP/CWE-cited rules over MCP.
Compliance frameworks (SOC 2, ISO 27001, CMMC, NIST, more) delivered to AI agents as MCP tools.
Governance copilot for AI-assisted coding. 72 packs, 532 rules, proof bundles.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server that enables your agents to use coding rules from any or your GitHub repository. Instead of workspace rules files, you can now prompt agents to access the your coding rules from any repository.1113MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI coding environments to enforce engineering governance through MCP tools and resources for init, check, route, and review workflows.82MIT
- FlicenseNot gradedqualityDmaintenanceAutomatically enforces team coding standards in AI-assisted development by providing an MCP server that AI assistants can query for language-specific standards, style guides, and best practices.-
- FlicenseNot gradedqualityAmaintenanceAnalyzes repositories, explains architecture, calculates change impact, and enforces guardrails for AI Agents like Claude Code, Cursor, and Codex via MCP tools.-