mcpField
S
SpecForge

SpecForge

Local
github.com/leaderiopDeveloper Tools39Updated today

About SpecForge

SpecForge is a deterministic spec checker for software teams and coding agents. It validates structured requirements, links tests to promises, and reports what remains unproven; checks use no AI.

Key features

  1. 01Deterministic .spec validation
  2. 02Finds broken references and missing rules
  3. 03Links tests to requirements
  4. 04Collects proof coverage
  5. 05Extensible domain rules

Use cases

  1. 01Validate agent-drafted specifications
  2. 02Track which requirements tests prove
  3. 03Review unresolved and unproven rules

MCP support

SpecForge provides MCP tools for clients to read and check project specifications.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

No install method listed yet

We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.

Repository
Packages
mcpbspecforge-mcp-0.1.0-rc1-aarch64-apple-darwin.mcpb
mcpbspecforge-mcp-0.1.0-rc1-x86_64-apple-darwin.mcpb
mcpbspecforge-mcp-0.1.0-rc1-aarch64-unknown-linux-gnu.mcpb
mcpbspecforge-mcp-0.1.0-rc1-x86_64-unknown-linux-gnu.mcpb

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

SpecForge. Turn your team's expertise into rules your AI can't skip. AI drafts, SpecForge checks, you sign.

Try it in 5 minutes · How it works · See it catch something · Docs

A spec says the refund behavior produces 'refund_isued', one letter short. specforge check fails with E003 unresolved reference, help: did you mean 'refund_issued'? After the one-letter fix: 0 errors, 0 warnings, 0 infos.

See it in 60 seconds, no agent needed. Install, create a project, drop one letter, check:

curl -fsSL https://raw.githubusercontent.com/leaderiop/SpecForge/main/install.sh | sh
mkdir sf-demo && cd sf-demo
specforge init --extensions @specforge/software          # spec/hello.spec, which checks clean
sed -i.bak 's/\[user_logged_in\]/[user_loged_in]/' spec/hello.spec   # drop one letter
specforge check
[E003] Error: unresolved reference 'user_loged_in' in entity 'authenticate_user'
 20 │   produces [user_loged_in]
    │ Help: did you mean 'user_logged_in'?

[W007] Warning: event 'user_logged_in' is not produced by any behavior

1 error, 1 warning, 0 infos

A reviewer reads. A check resolves.

The problem

You ask an AI agent to add refunds to your payment service. It writes clean code, the tests pass, the pull request looks fine. Two weeks later, finance finds a refund larger than the payment it refunded.

The rule was written down, in the spec: a Markdown file in docs/, next to the PRD. The agent read it three sessions ago, or never found it. Nothing failed, so nobody noticed.

This isn't a problem with the model. It's a problem with where your rules live. Today, the knowledge that matters sits in places that nothing enforces:

  • Specs in Markdown (PRDs, docs/*.md, spec-kit files) are prose. An agent can misread a rule or skip it, silently, and nothing checks that the spec is complete or that its parts agree.
  • Docs and wikis drift away from the code, and nothing breaks when they do.
  • Traceability (which requirement has a test, which rule is enforced where) is a spreadsheet someone updates by hand, until they stop.
  • Every session starts from zero. The agent re-reads dozens of files to rediscover what you meant, and still guesses.

The more work you give to AI, the worse this gets. It writes faster than anyone can review.

The idea: hard skills, not soft skills

There are two ways to teach an AI how your team works.

A soft skill is advice placed in the AI's context: a Markdown spec, a PRD, a skill file. It helps, but it's prose. The AI may follow it, or not.

A hard skill is a rule that a program enforces. The AI can't skip it, because the check fails.

An animated loop. A refund rule starts as advice in docs/refunds.md. The agent writes it as an invariant in spec/refund.spec. specforge check --strict fails: W003, invariant refund_within_capture is not enforced by any behavior, and the agent is blocked. specforge explain W003 says to reference it from the behaviors that must preserve it. The agent adds invariants [refund_within_capture] to issue_refund, the check passes with 0 errors, 0 warnings, 0 infos, and the agent goes from unsure to certain.

Soft skill
Markdown spec, PRD, skill file
Hard skill
SpecForge extension
Lives inThe AI's context window, as proseA compiler, as code
Can the AI ignore it?Yes, silentlyNo: the check fails
Same verdict twice?Not alwaysAlways. There's no AI inside
Knows what's missing?NoYes: broken links, unenforced rules, unproven promises
Shared how?Copied between filesVersioned and installed, like a library

SpecForge is a tool for hard skills. You (or more often, your agent) write down what must be true in small, structured .spec files. SpecForge checks them the way a compiler checks code: every reference must point to something real, every rule must be enforced by something, every promise must be proven by a test. Then it gives the checked result to your agent as context.

Think of it as a type checker for what you mean.

How it works

A loop of six steps around the checked spec: 1 describe (you), 2 draft (your agent), 3 check (SpecForge, which sends errors and fixes back to the draft), 4 build (your agent), 5 prove (your tests, via collect), 6 review (you).

  1. You describe what you want, in conversation, as you do today.
  2. Your agent drafts the spec: the operations, the rules that must always hold, the events, and for each one, what proves it.
  3. SpecForge checks the draft. Typos, rules nobody enforces, missing pieces: the check fails with the exact line and a fix hint, and the agent corrects it. No AI is involved in this step. Same input, same verdict, every time.
  4. Your agent builds against the checked spec. It asks SpecForge for the exact slice it needs, instead of re-reading your repository.
  5. Your tests prove the spec. Each test names what it proves. specforge collect runs them and records what is proven and what isn't.
  6. You review. Instead of reading every line the agent wrote, you read what was promised, what is proven, and what is still open.

See it catch something

Your agent drafts this for the refund feature:

invariant refund_within_capture "Refunds never exceed the captured amount" {
  risk high
  verify unit "rejects a refund larger than the captured amount"
}

invariant refund_needs_reason "Every refund records a reason" {
  guarantee "A refund without a reason is rejected"
  risk      medium
  verify unit "rejects a refund with no reason"
}

behavior issue_refund "Refund a captured payment" {
  category   command
  invariants [refund_within_capture]
  produces   [refund_isued]
  contract   "Given a captured payment, refunds up to the captured amount"
  verify unit "refunds the requested amount"
}

event refund_issued "A refund was issued" {
  verify unit "is emitted once per refund"
}

It reads fine. Here is what specforge check says:

specforge check on the draft reports E003 unresolved reference 'refund_isued' with the hint did you mean 'refund_issued', W003 invariant 'refund_needs_reason' is not enforced by any behavior, W007 event 'refund_issued' is not produced by any behavior, and E006 invariant 'refund_within_capture' is missing required field 'guarantee'. After the agent applies the fixes, the second run reports 0 errors, 0 warnings, 0 infos.

The same output as text
[E003] Error: unresolved reference 'refund_isued' in entity 'issue_refund'
    ╭─[ refunds.spec:15:15 ]
 15 │   produces   [refund_isued]
    │ Help: did you mean 'refund_issued'?

[W003] Warning: invariant 'refund_needs_reason' is not enforced by any behavior
[W007] Warning: event 'refund_issued' is not produced by any behavior
[E006] Error: invariant 'refund_within_capture' is missing required field 'guarantee'

2 errors, 2 warnings, 0 infos

Four problems a human reviewer would probably miss:

CodeWhat it foundWhy it matters
E003A one-letter typo in an event nameThe refund code would publish an event nobody listens to
W003A rule that nothing enforcesIn a doc, this rule would just sit there. Here, it's a warning until something enforces it
W007An event that nothing producesThe same typo, seen from the other side
E006A rule with a name but no guarantee"Refunds never exceed the captured amount" isn't checkable until it says what never exceeds what

Errors always fail the check. Warnings fail it too with specforge check --strict, which is what you run in CI.

The agent fixes all four and runs the check again: 0 errors, 0 warnings, 0 infos. The spec is now consistent, but nothing is proven yet. That's the tests' job: each test names the promise it proves, specforge collect runs them, and specforge review shows what's covered and what's still open.

specforge collect runs the tests: three pass, so issue_refund, refund_within_capture and refund_needs_reason become covered 1/1. refund_issued has no test for 'is emitted once per refund', so it stays uncovered 0/1: 3 of 4 covered, one promise still has no test.

Every rule you just saw came from an extension, not from SpecForge itself (see Hard skills are extensions).

Try it in 5 minutes

1. Install. SpecForge is a single binary with no dependencies.

curl -fsSL https://raw.githubusercontent.com/leaderiop/SpecForge/main/install.sh | sh
Other ways to install
# Homebrew (once the tap is published)
brew install leaderiop/tap/specforge

# Prebuilt binary via cargo-binstall
cargo binstall --git https://github.com/leaderiop/SpecForge specforge-cli

# From source (stable Rust toolchain)
git clone https://github.com/leaderiop/SpecForge && cd SpecForge
cargo install --path crates/surfaces/cli

Prebuilt archives for macOS, Linux and Windows are on the Releases page. Formal proofs (@specforge/formal) also need the z3 solver on your PATH; everything else works without it.

2. Create a project in your repository:

specforge init --extensions @specforge/software

This writes a specforge.json and a first file in spec/. In a Cargo or vitest project, it also turns on the matching test runner.

3. Connect your agent. SpecForge speaks MCP, so any MCP client can read and check your spec. Use an absolute path:

claude mcp add specforge -- specforge mcp /path/to/your/project

In Cursor, one click adds it for the open project (${workspaceFolder}):

Add SpecForge to Cursor

Other MCP clients
{
  "mcpServers": {
    "specforge": { "command": "specforge", "args": ["mcp", "/path/to/your/project"] }
  }
}

4. Ask your agent for a spec. For example:

Write a spec in spec/ for the refund feature: the behavior, the rules it must never break, the events it emits, and what proves each one. Validate it with the SpecForge tools and fix every error before you show it to me.

5. Read the result yourself.

specforge check     # is the spec consistent?
specforge review    # what is still unproven?

6. Link your tests. Each test says which entity it proves. In Rust (with the specforge-test crate):

use specforge_test::prelude::*;

#[specforge_test(behavior = "issue_refund", verify = "refunds the requested amount")]
fn refunds_the_requested_amount() { /* ... */ }

In vitest:

test('refunds the requested amount',
  { meta: { specforge: { behavior: 'issue_refund', verify: 'refunds the requested amount' } } },
  () => { /* ... */ })

Then run specforge collect. It asks once before running your test command, and records what each test proves. See the Rust and vitest guides.

Do I have to learn a new language?

You'll want to read it, because the spec is what you approve. You rarely need to write it: your agent writes and fixes the files, and the check tells it when it's wrong.

It's built to be easy to read. Each block is one thing, with a kind, a name, a title, and fields, like a filled-in form:

invariant refund_within_capture "Refunds never exceed the captured amount" {
  guarantee "The sum of refunds on a payment never exceeds the captured amount"
  risk      high
}

To write specs by hand, start with the authoring tutorial and the worked example.

How is this different from…

You already useIt's good atWhat SpecForge adds
Specs and PRDs in MarkdownDescribing intent for people and agentsSpecForge replaces them: the same intent as .spec files whose structure is validated. Broken references, missing pieces and unproven promises fail the check
CLAUDE.md, AGENTS.mdCoding rules for the agent: conventions, commands, styleNothing to replace. Keep your coding rules there; the spec, what the system must do, lives in SpecForge
TestsProving the code does somethingSaying which promise each test proves, and which promises have no test at all
Issue trackersTracking work in progressTracking what the system must do, and whether that's proven
Requirements tools (DOORS, Polarion)Traceability for regulated teamsPlain text in your repository, checked in CI, readable by agents, extensible by you
Code generatorsWriting code from a modelNothing. SpecForge never writes your code. Your agent does, from intent SpecForge has checked

Hard skills are extensions

SpecForge itself knows nothing about payments, software, or any other field. Every word in a spec (behavior, invariant, event) and every rule ("an invariant must be enforced by a behavior") comes from an extension. An extension is a hard skill packaged as code: a vocabulary, plus the rules that judge it.

Extensions plug into the SpecForge core, which parses, links and checks and knows no domain: software, product, governance, formal, test runners, and your own, such as pharma quality, medical devices or safety cases.

These ship inside the binary:

ExtensionWhat it lets you describe
@specforge/softwareBehaviors, the rules they must keep (invariants), events, types, and interfaces (ports)
@specforge/productFeatures, personas, journeys, milestones, releases, and your team's vocabulary
@specforge/governanceDecisions, constraints, and failure modes
@specforge/formalProperties and axioms that an SMT solver proves or refutes
@specforge/cargo-test, @specforge/vitestWhich of your tests prove which entities

Turn one on with specforge add @specforge/product. The full list is in the extension inventory. To write your own hard skill, see Extending SpecForge.

Where this is going

Software comes first because it's where AI writes the most today. But the engine has no built-in domain, on purpose. It's built for any field where expertise has rules and mistakes are expensive: regulated software (IEC 62304, GAMP 5), pharmaceutical quality (batch release, deviations), safety engineering. In those fields, "AI drafts, the hard skill checks, a qualified person signs" isn't a slogan. It's how the work has to be done. Extensions for these domains are in development; they aren't builtins yet.

Also planned: agents that edit the spec through typed operations, so nobody (human or AI) writes .spec text by hand.

What SpecForge is not

  • Not an AI. It makes no model calls. It's a deterministic compiler, written in Rust.
  • Not a code generator. It checks intent. Your agent writes the code.
  • Not a test framework. Your tests stay in cargo test or vitest. SpecForge runs them only after you approve the command, and records what they prove.

Learn more

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.