Twinning
Does this client stay within a declared Postgres or REST contract?
Developers testing agents, API clients or database workflows locally.
- Interface
- MCP server
- Access
- Open source
- Availability
- Available
- Runs on
- Runs locally
- Cairn roles
- AI connectors, Software factory
- Evidence roles
- Checks and support, What is missing
- Semantic context
- Source meaning
- Contribution
- Use a local MCP manager to exercise declared Postgres or REST contracts and inspect reports and refusals.
- Limit
- A twin tests its declared behavior; it does not establish production fidelity or validate an ontology.
What it does
- Start and stop Postgres and REST twins through a local stdio MCP manager.
- Inspect health, retained twins and reports from stopped twins.
- Compare Postgres snapshots by replaying a query set.
Checked REST example · November 2026
POST /v1/greet with a name and the configured demo header.
The local twin returned the declared greeting. Requests with a missing header, a wrong value type or an unknown route returned 401, 422 and 404. After stopping the twin, its report recorded all four requests.
Setup
Follow the platform checks, download a matching release and verify its checksum. The README includes client registration and a local test.
Read the current setup promptCoverage and freshness
The MCP manager supports Postgres and REST twin kinds. It models declared schemas and spec-defined routes rather than a general database or every behavior of a live service.
Limits
- The MCP manager does not provide MCP or Snowflake twin kinds.
- Prebuilt macOS and Linux archives include twinning and twinning-mcp. The Windows archive includes the CLI only.
- Only declared behavior is modeled. A local twin does not establish that a live API or database behaves identically.
- Optional refused-SQL capture can retain literal values locally. Keep capture disabled unless you need to inspect those statements.
Related tools and guides
Contact supportTwinning runs local twins from protocol specifications and schemas. Its MCP manager starts and manages Postgres and REST twins for agents and tests. Point your client at the local twin, supply test data, and inspect its results and refusals.
The twin implements the behavior supported by its configuration. Check the protocol coverage before relying on a result. The MCP manager controls twins through local stdio; it does not provide a hosted MCP endpoint.
Set up the local manager
We tested the v0.7.1 prebuilt bundle on Intel macOS on November 2, 2026. It contained twinning 0.7.1, twinning-mcp 0.1.0 and the MIT notice. Other platforms were not tested in this run. The README lists the available builds; the Windows archive contains the CLI only.
Release v0.7.1 · Current setup instructions
For the tested Intel macOS build, use a new directory and check the published checksum before extracting. Stop if a download, checksum or doctor check fails.
TWINNING_DIR=$(mktemp -d /tmp/twinning-demo.XXXXXX) TWINNING_ARCHIVE=twinning-v0.7.1-x86_64-apple-darwin.tar.gz TWINNING_RELEASE_URL=https://github.com/cmdrvl/twinning/releases/download/v0.7.1 mkdir "$TWINNING_DIR/bin" "$TWINNING_DIR/work" "$TWINNING_DIR/runtime" curl -fL "$TWINNING_RELEASE_URL/$TWINNING_ARCHIVE" -o "$TWINNING_DIR/$TWINNING_ARCHIVE" curl -fL "$TWINNING_RELEASE_URL/SHA256SUMS" -o "$TWINNING_DIR/SHA256SUMS" (cd "$TWINNING_DIR" && grep 'twinning-v0.7.1-x86_64-apple-darwin.tar.gz$' SHA256SUMS | shasum -a 256 -c -) && tar -xzf "$TWINNING_DIR/$TWINNING_ARCHIVE" -C "$TWINNING_DIR/bin" && "$TWINNING_DIR/bin/twinning-mcp" --workdir "$TWINNING_DIR/work" doctor
The archive SHA-256 matched the value below. Doctor reported health: ok (healthy (READY)).
5aee77f84f8bf57bd87355e4db8b8cc47afb412e87726cbd8e977ec0dc50e3bc
Print a Claude Desktop configuration snippet without changing your client configuration:
"$TWINNING_DIR/bin/twinning-mcp" --workdir "$TWINNING_DIR/work" setup --client claude-desktop --print
Review the printed paths before adding them to a client. If you choose Codex, this optional command writes a twins entry. Its stdio syntax was checked against Codex CLI 0.166.0 help; client registration was not part of the test.
codex mcp add twins --env TMPDIR="$TWINNING_DIR/runtime" -- \ "$TWINNING_DIR/bin/twinning-mcp" --workdir "$TWINNING_DIR/work"
Worked example: a local REST contract
This run used a synthetic greeting API. One request matched a declared response stub; three requests exercised refusals. All HTTP calls went to the loopback address returned by the manager. The results demonstrate this fixture, not a production API or general REST compatibility.
Save this fixture as demo-api.yaml in the work directory
openapi: 3.0.3
info:
title: Synthetic local greeting contract
version: "1.0.0"
servers:
- url: https://example.invalid/{basePath}
variables:
basePath:
default: v1
enum: [v1]
components:
securitySchemes:
DemoKey:
type: apiKey
name: X-DEMO-KEY
in: header
paths:
/greet:
post:
security:
- DemoKey: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name]
additionalProperties: false
properties:
name:
type: string
responses:
"200":
description: Synthetic greeting response.
content:
application/json:
schema:
type: object
required: [message]
properties:
message:
type: string
x-twinning:
response-stubs:
- id: synthetic_greeting
method: POST
path: /v1/greet
when:
body-json-equals:
name: Example
status: 200
body:
message: Hello, ExampleHave your MCP client initialize the local manager and list its tools. The tested handshake used protocol version 2025-03-26 and returned seven tools. Send these tools/call parameters to start the twin:
{
"name": "twin_start",
"arguments": {
"kind": "rest",
"spec_path": "demo-api.yaml",
"server_variables": { "basePath": "v1" }
}
}The response contains base_url and twin_id. Set BASE_URL to that returned loopback URL, then send the four requests below. The demo key only exercises the required-header shape; it does not validate production credentials.
curl -i -X POST "$BASE_URL/v1/greet" \
-H 'X-DEMO-KEY: demo-key' -H 'Content-Type: application/json' \
-d '{"name":"Example"}'
curl -i -X POST "$BASE_URL/v1/greet" \
-H 'Content-Type: application/json' -d '{"name":"Example"}'
curl -i -X POST "$BASE_URL/v1/greet" \
-H 'X-DEMO-KEY: demo-key' -H 'Content-Type: application/json' \
-d '{"name":123}'
curl -i "$BASE_URL/v1/no-such-route"Recorded results, in request order:
200 {"message":"Hello, Example"}
401 unauthorized
422 schema_validation_failed ($.name: expected string, received integer)
404 not_foundUse your returned twin_id to stop the twin before requesting its report:
{"name":"twin_stop","arguments":{"twin_id":"<returned twin_id>"}}
{"name":"twin_report","arguments":{"twin_id":"<returned twin_id>"}}The recorded child exited with code 0. Its report excerpt was:
{
"version": "twinning.rest-report.v0",
"outcome": "PASS",
"request_count": 4,
"outcomes": {
"auth_refusal": 1,
"response_stub": 1,
"schema_validation_refusal": 1,
"unmatched": 1
}
}Close the test MCP session after saving the report. In this run, the manager also exited with code 0 and its loopback listener was closed. Only this Intel macOS REST example was exercised; Postgres operations and other platforms need their own checks.
What it is for
Use a local twin to try requests and exercise error cases before connecting an agent to a real service. Keep test credentials and data separate from production, and confirm that the twin implements the behavior your test needs.
In Cairn’s software-factory role, this example contributes checks against a declared contract. Keep the fixture and report to inspect the run later; its PASS does not establish production behavior. Continue with the task guides to explore source records and other checks.
Background reading: Every API has two contracts.
Work with us
Twinning is MIT licensed and free to use. If you want twins built for your own APIs and databases, or want help wiring them into an agent workflow, start a conversation.
Support
Questions, bugs, or trouble with setup: email cairn@cmdrvl.com, or open an issue on GitHub.