Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Description from the maker (original English)
Fetch a SCITT receipt, its genesis and on-chain accumulator for @forestrie/mcp-verify to verify
These three are never merged into one score: opinions, measurements and popularity are different things.
We have not written a plain-language summary for this one yet. Below are the facts we read from the registry.
Pick the AI app you use, then copy the settings.
FORESTRIE_BASE_URL, FORESTRIE_RPC_URLYou need
Which app do you use?
Pick your app above. We remember it, so next time the button says “Install in …”.
Open Claude Desktop → Settings → Developer → Edit Config, and paste this into claude_desktop_config.json
{
"mcpServers": {
"resolve": {
"command": "npx",
"args": [
"-y",
"@forestrie/mcp-resolve"
],
"env": {
"FORESTRIE_BASE_URL": "your-value",
"FORESTRIE_RPC_URL": "your-value"
}
}
}
}Run this in your terminal
claude mcp add resolve --env FORESTRIE_BASE_URL=your-value --env FORESTRIE_RPC_URL=your-value -- npx -y @forestrie/mcp-resolveFill in the empty values before running it.
Paste into .cursor/mcp.json in your project, or ~/.cursor/mcp.json
{
"mcpServers": {
"resolve": {
"command": "npx",
"args": [
"-y",
"@forestrie/mcp-resolve"
],
"env": {
"FORESTRIE_BASE_URL": "your-value",
"FORESTRIE_RPC_URL": "your-value"
}
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
Paste into .vscode/mcp.json in your project
{
"servers": {
"resolve": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@forestrie/mcp-resolve"
],
"env": {
"FORESTRIE_BASE_URL": "your-value",
"FORESTRIE_RPC_URL": "your-value"
}
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
This one runs on your computer, and ChatGPT can only connect to servers on the internet. Pick another app.
Your choice stays on this device in a cookie; no account needed.
FORESTRIE_BASE_URL envFORESTRIE_RPC_URL envThese settings are generated from the maker’s registry entry. If the README says otherwise, follow the README.
Runs on your computer; the tool list appears in your AI app after you install it.
We check information anyone can see; we have not read the code. Checks that do not apply are left out of the count. · Checked Nov 6, 2026
The registry name was verified against the domain forestrie.dev (the registry checks domain ownership)
We have not read this repo from GitHub yet
We have not read this repo from GitHub yet
This one runs on your computer; there is no internet endpoint
Runs on your computer and uses local settings instead
Runs on your computer; we can only read tool lists from internet endpoints
Compared with every active server in this category in the registry. Stars count only when the publisher owns the repo.
It passed 1 of 1 applicable basic checks. We have not read the code. Before adding a key or token, see what access the server asks for and use a key with only the permissions you need.
The registry does not list a required key, though some servers ask you to sign in on first use.
It runs on your computer. Your AI app starts it when needed, and data does not pass through the maker’s servers (unless it calls an online service itself).
The GitHub repo last changed –, and the latest version (0.5.0) reached the registry 5 days ago.
Apps that support MCP, such as Claude Desktop, Claude Code, Cursor and VS Code. You also need Node.js on your computer.
In the same category: Spec Driven Development, Remote Desktop Commander, dotnet-mcp
Servers in the same category from other makers, sorted by stars.
Reading a card:★ GitHub starsiThree pillars: reviews · checks · usageiUpdated = latest version published to the registryi
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
MCP server for .NET symbols, XAML, source generators, and restricted workspace edit
Copied from the maker’s repo as written. PopNx MCP has not reviewed or endorsed it. HTML, images and scripts are removed. Links lead off this site.
Fetch a SCITT receipt, its log's genesis document and its on-chain accumulator, and hand them to @forestrie/mcp-verify to verify — including the split-view answer, from a chain read. An MCP server that fetches the material the verifier verifies: a receipt, a genesis document, an accumulator snapshot, a registration status, a service configuration. Every result says where its bytes came from and which of the four questions of the trust model they can support. Listed in the MCP registry as dev.forestrie/resolve.
The verifier runs entirely in your process with no network, no account, no key and no backend, and its own rule is that installing it can never imply a network dependency. So anything that fetches lives here.
{
"mcpServers": { "forestrie-resolve": { "command": "npx", "args": ["-y", "@forestrie/mcp-resolve"], "env": { "FORESTRIE_BASE_URL": "https://api-a.forest-2.forestrie.dev", "FORESTRIE_RPC_URL": "https:// " } } } }
Both environment variables are optional and both are yours. baseUrl is any SCRAPI base URL and rpcUrl is your own chain access; a call may pass either explicitly, and the environment values are used only when a call omits them. The package ships no default operator and no default chain provider, and names none.
Two public lanes exist and are examples, not defaults:
| Lane | Base URL | Service id |
|---|---|---|
| A | https://api-a.forest-2.forestrie.dev | canopy-dev-1 |
| B | https://api-b.forest-2.forestrie.dev | canopy-prod-1 |
Requires Node 20.11 or later.
Every value below is public, and the ones that change per release come from the verifier's own tarball. @forestrie/mcp-verify registers each release in a Forestrie log and ships the receipt under fixtures/self/ (docs/self-registration.md there), so the published package is a statement, a receipt, a genesis document and a log owner key that this package can fetch and verify against the live lane. The run below takes about four seconds and ends in split-view ok from a public RPC endpoint, with no key and no account.
| Coordinate | Value | Where it comes from |
|---|---|---|
| base URL | https://api-a.forest-2.forestrie.dev | lane A above (an example, not a default) |
| bootstrap log | e22c8d55-3f88-b2b5-f225-5d2c2441bcdd | the forest root; also decoded from the genesis document |
| publications log | da6f297c-4a0c-4c9a-b2ae-e701e558721d | the log the verifier registers releases on |
| content hash | sha256(fixtures/self/statement.cose) | the tarball; fixtures/self/manifest.json lists the same digest |
| entry id | fixtures/self/entry-id.txt | the tarball; query_registration returns it too |
| massif height | never typed | inside the receiptUrl that query_registration returns |
| log owner key | fixtures/self/log-key.xy.b64 (base64 text) | the tarball |
| chain | id 84532 (Base Sepolia), univocity 0xe22c8d553f88b2b5f2255d2c2441bcdd0d50cd58 | bound in the genesis document; fetch_genesis decodes it |
To have the tarball at hand in an empty directory:
npm i @forestrie/mcp-verify
ls node_modules/@forestrie/mcp-verify/fixtures/self/ shasum -a 256 node_modules/@forestrie/mcp-verify/fixtures/self/statement.cose
The sequence, with the arguments as JSON and the one-line result each call returned when run on 2026-09-22 against the published 0.5.0 bundle (its entry id is a0caa672b7030b000000000000000001; yours is whatever entry-id.txt says):
fetch_scitt_configuration {"baseUrl": "https://api-a.forest-2.forestrie.dev"} → fetched SCITT configuration (serviceId canopy-dev-1) from …/.well-known/scitt-configurationquery_registration {"baseUrl": …, "bootstrapLogId": "e22c8d55-3f88-b2b5-f225-5d2c2441bcdd", "logId": "da6f297c-4a0c-4c9a-b2ae-e701e558721d", "contentHash": " "} → registration complete; receipt at https://api-a.forest-2.forestrie.dev/logs/e22c8d55-…/da6f297c-…/14/entries/a0caa672b7030b000000000000000001/receipt — status: "receipt-available", the receiptUrl (with the massif height, 14, inside it) and entryId.fetch_receipt {"receiptUrl": " "} → fetched receipt (438 B) from …/receipt — receipt.sha256 equals the digest of the tarball's receipt.cbor; receiptLogId names the publications log.fetch_genesis {"baseUrl": …, "logId": "e22c8d55-3f88-b2b5-f225-5d2c2441bcdd"} → fetched genesis (160 B) from …/api/forest/e22c8d55-…/genesis: univocity 0xe22c8d553f88b2b5f2255d2c2441bcdd0d50cd58 on chain 84532 — byte-identical to the tarball's genesis.cbor. Keep it: the calls below pass it back as bytes, never fetched in the same call.verify_fetched_receipt {"receiptUrl": …, "entryId": " ", "payload": {"path": "…/fixtures/self/statement.cose"}, "trust": {"root": "known-log-key", "keyXy": {"b64": " "}}} → verify: PASS · root=known-log-key · sealing ok, split-view not answered at this root, append-authority not answered at this root, attribution ok"trust": {"root": "genesis", "genesis": {"path": "…/fixtures/self/genesis.cbor"}} → verify: FAILED at signature (delegation_invalid) · root=genesis · … This is expected, not tampering: the genesis root's offline walk resolves one delegation hop from the forest root, and the publications log is a grandchild. The result carries genesis_root_reaches_direct_delegates_only saying exactly that. Verify this receipt under a key or an accumulator, as in 5 and 7.verify_fetched_receipt {"receiptUrl": …, "entryId": …, "payload": …, "trust": {"root": "known-accumulator", "chain": {"genesis": {"path": "…/fixtures/self/genesis.cbor"}, "rpcUrl": "https://sepolia.base.org", "logId": "da6f297c-4a0c-4c9a-b2ae-e701e558721d"}}} → verify: PASS · root=known-accumulator · sealing ok, split-view ok, append-authority not answered at this root, attribution ok — anchor.blockNumber, anchor.matchedPeak and provenance.root.from.rpcUrl say which chain state answered. If the log has grown past the receipt's peak since, the same call looks back through published checkpoints and adds root_read_from_chain_history.fetch_accumulator {"chain": {…as in 7…}, "forReceipt": {"receipt": …, "payload": …, "entryId": …}} returns the snapshot as bytes to keep; later, @forestrie/mcp-verify's verify_receipt under `{"root": "known-accumulator", "accumulator":}` answers split-view again, offline.
The chain, and where to read it. Step 7 needs JSON-RPC access to chain 84532 (Base Sepolia). This package ships no provider and names none as a default; rpcUrl (or FORESTRIE_RPC_URL) is yours. The endpoints below are third-party public services, listed only as examples of what answered unauthenticated when this example was written; use your own provider for anything beyond a first try.
| Endpoint | On 2026-09-22 |
|---|---|
https://sepolia.base.org | answered |
https://base-sepolia-rpc.publicnode.com | answered |
https://base-sepolia.drpc.org | answered |
https://base-sepolia.gateway.tenderly.co | answered |
https://1rpc.io/base-sepolia | HTTP 400 |
https://rpc.ankr.com/base_sepolia | HTTP 403 |
https://base-sepolia.g.alchemy.com/v2/demo | HTTP 429 |
Two traps. keyXy: {"path": "log-key.xy.b64"} fails: that file is base64 _text_, and path inputs are read as raw bytes — pass its contents as b64. And the byte-field name is b64 in both servers (base64 is accepted here as an alias), so the shapes you learn from the verifier work here unchanged.
test/core/readme-example.test.ts asserts the coordinates in this section against the recorded lane-A fixtures, so a fixture re-capture cannot silently invalidate the example.
| Tool | Provenance | What it does | Supports |
|---|---|---|---|
fetch_scitt_configuration | fetched | GET {baseUrl}/.well-known/scitt-configuration | none |
query_registration | fetched | one registration-status request for a statement; never polls | none |
fetch_receipt | fetched | fetches a receipt, decodes it, and reports the log its certificate names | none on its own |
fetch_genesis | fetched | fetches the forest's genesis document, with its chain binding and bootstrap key | sealing, only for a copy you keep |
fetch_accumulator | chain-read | reads the log's published accumulator; looks back through history for a buried peak | split-view, sealing, append-authority |
fetch_checkpoint_history | chain-read | reads published checkpoints back, newest first, within your block budget | as fetch_accumulator |
fetch_ks256_attestation | chain-read | asks a contract KS256 root, at one block, whether it accepts a receipt's certificate | none on its own; mcp-verify consumes it |
verify_fetched_receipt | fetched, plus supplied or chain-read | fetches a receipt and verifies it under a root you supply or read from the chain | the verifier's own answers, unaltered |
fetch_ks256_attestation is for a forest whose root is a contract (a Safe). Such a root cannot be checked by ecrecover, so the verifier needs the contract's own answer, and getting it needs a chain read, which the verifier never makes. Give the tool the receipt and either the root address or a genesis you hold; it reads isValidSignature(digest, signature) at one block (default the latest, then pinned) and returns the answer as a canonical-CBOR attestation:
fetch_ks256_attestation {receipt: {b64: …}, genesis: {b64: …}, rpcUrl: …, block?: 123}
-> attestation {base64, byteLength, sha256}, fields {chainId, address, digest, signatureHash, blockNumber, blockHash, magic}, provenance, supports verify_receipt {receipt: …, …, ks256Attestation: {b64: }}
The result says the certificate is valid under the contract'
Only the beginning is shown; read the rest in the repo