JSON Contracts

io.github.json-contracts由 GitHub 帳號 json-contracts 發布v0.1.2更新於 Oct 25, 2026

JSON contract registry and validator for structured LLM and agent outputs.

已驗證STDIO僅桌面開發者工具資料與分析

概覽

AI 產生的概覽

本機 MCP 伺服器,提供受 Git 管理的 JSON 契約與 JSON Schema 驗證,讓助理把自然語言轉換成符合 schema 的 JSON。

可以做什麼
列出並讀取本機資料夾中載入的 JSON 契約,包含 schema、規則、範例與雜湊值,並可在修改後重新載入。依輸入與情境取得建立契約,供助理自己的模型產生 JSON。帶著目前 JSON 取得編輯契約,讓模型回傳完整的更新物件。用契約 schema 驗證助理產生的 JSON,並回傳欄位層級錯誤。驗證失敗時取得附有確定性提示的修復契約。查看伺服器狀態與已載入契約以便排查設定。
適用情境
適用於應用程式或代理需要從自然語言穩定產出結構化 JSON,並希望把輸出結構、規則與範例放在受版本控制的檔案而非提示詞中的情境。適合已自行選擇模型、希望在旁加上驗證與修復指引的團隊。
執行需求
透過 npm 套件 json-contracts 以 stdio 在本機執行(npx 或全域安裝),需要 Node.js。需要一個存放 JSON 契約檔案的資料夾,由環境變數 JSON_CONTRACTS_DIR 指定(預設 ./json-contracts)。伺服器本身不需要 API 金鑰或 LLM 供應商存取權限。
安裝前請注意
伺服器本身不產生也不修復 JSON,由助理的模型完成,輸出品質取決於宿主模型。傳給工具的 context 會原樣回傳給模型,不要在其中放置機密資訊。契約檔案從 JSON_CONTRACTS_DIR 指定的資料夾讀取,請確保該資料夾可信並納入版本控制。設定 DEBUG=true 可能把完整使用者輸入寫入 stderr 記錄。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 JSON Contracts,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

JSON Contracts MCP Server

JSON Contracts is a local MCP contract server for natural-language-to-JSON workflows. It gives agents Git-controlled JSON contracts, rules, examples, and JSON Schema validation tools so any model can reliably convert natural-language requests into schema-valid JSON.

The MCP server does not call an LLM provider. The MCP server does not need API keys. The MCP server does not use BAML, LangChain, Markdown, or a DSL. The MCP server does not use MCP sampling. The MCP server does not generate JSON by itself.

The optional Studio is a separate package/repo for live demos and local contract testing. The MCP stdio server itself does not call LLM providers.

Your user provides natural language. Your agent chooses the model. Your agent performs the natural-language-to-JSON conversion. json-contracts provides the contract and validates the result.

Correct mental model

Not this:

text
json-contracts = generator

This:

text
json-contracts = schema contract registry + validator

Like TypeScript:

text
developer writes codeTypeScript validates it

With json-contracts:

text
agent writes JSONjson-contracts validates it

Architecture

text
User  ↓Agent using whatever model the user picked  ↓json-contracts MCP server  - lists available JSON contracts  - returns schemas, rules, examples, and instructions  - validates agent-produced JSON  - returns repair contracts when validation fails  ↓Agent generates or repairs JSON itself  ↓App consumes valid JSON

The MCP server never performs natural-language-to-JSON conversion itself. It only provides contracts, validation, and repair guidance.

Install

Install globally:

bash
npm install -g json-contractsjson-contracts --help

Or run without installing:

bash
npx -y json-contracts@latest

The npm package is json-contracts; the installed CLI binary is still json-contracts.

30-second setup

Create a starter contract folder and validate it:

bash
mkdir my-json-contractscd my-json-contractsnpx -y json-contracts@latest initnpx -y json-contracts@latest validate

Then add the MCP config below to your agent host. Point JSON_CONTRACTS_DIR at the json-contracts folder that init created.

Validate contracts in CI without starting MCP:

bash
npx -y json-contracts@latest validate --contracts ./json-contractsnpx -y json-contracts@latest lint --strict --contracts ./json-contracts

By default, the server starts as a local stdio MCP server and loads contracts from:

text
./json-contracts

MCP config

json
{  "mcpServers": {    "json-contracts": {      "command": "npx",      "args": ["-y", "json-contracts@latest"],      "env": {        "JSON_CONTRACTS_DIR": "./json-contracts"      }    }  }}

Adding a new behavior only requires adding a new .json file to the contracts folder. No MCP config change is required.

MCP host config snippets

Most MCP hosts use the same stdio shape. Adapt paths for your machine and point JSON_CONTRACTS_DIR at your app-owned contracts folder.

Claude Desktop
json
{  "mcpServers": {    "json-contracts": {      "command": "npx",      "args": ["-y", "json-contracts@latest"],      "env": {        "JSON_CONTRACTS_DIR": "/absolute/path/to/json-contracts"      }    }  }}
Cursor / Windsurf / VS Code MCP-compatible hosts
json
{  "mcpServers": {    "json-contracts": {      "command": "npx",      "args": ["-y", "json-contracts@latest"],      "env": {        "JSON_CONTRACTS_DIR": "./json-contracts"      }    }  }}
Continue or generic stdio MCP clients
json
{  "name": "json-contracts",  "command": "npx",  "args": ["-y", "json-contracts@latest"],  "env": {    "JSON_CONTRACTS_DIR": "./json-contracts"  }}

If npx startup is too slow or your host requires explicit executables, install globally and use:

json
{  "command": "json-contracts",  "args": []}

Adopt in your agent/app

Use json-contracts as a local contract/validation tool beside the model your app already uses.

1. Add the MCP server

If your agent host supports MCP, add the server config above and point JSON_CONTRACTS_DIR at the contracts folder your app owns.

If your app has its own agent runtime, connect to the same MCP stdio server and call the tools directly. The important part is the flow, not the host.

2. Write one contract per JSON behavior

Create files such as:

text
json-contracts/support-ticket.jsonjson-contracts/real-estate-lead.jsonjson-contracts/chart-generation.json

Each file contains:

  • schema for the final JSON shape
  • rules for app-specific mapping behavior
  • examples for model guidance
  • optional operations for create/edit behavior

3. Pass app/system variables as context

Do not hide runtime variables in the user prompt. Pass them as context:

json
{  "contract": "real-estate-lead",  "input": "I'm pre-approved for a 4 bedroom house in Durham NC up to 900k.",  "context": {    "current_datetime": "2026-05-03T00:00:00Z",    "email": "[email protected]",    "source": "website-lead-form"  }}

json-contracts passes context through unchanged. Contracts decide how to use it through rules/examples. The final JSON still must match the schema.

4. Give your agent this tool policy

Use this as the system/developer instruction for your agent:

text
When converting natural language into app JSON, use json-contracts.
Create flow:1. Call get_json_contract with contract, input, and context.2. Generate JSON using the returned schema, rules, examples, input, and context.3. Call validate_json.4. If invalid, call get_repair_contract, repair the JSON, and validate again.5. Return only validated JSON to the app.
Edit flow:1. Call get_edit_contract with contract, currentJson, input, and context.2. Return the complete updated object, not a patch.3. Call validate_json.4. Repair and validate again if needed.
Never skip validation. Never add fields that are not allowed by the schema. Do not copy context fields into output unless the schema allows them and the contract rules say to use them.

5. Runtime loop in your app

At request time, your app should do:

text
user input + app context  -> get_json_contract or get_edit_contract  -> your chosen model generates JSON  -> validate_json  -> if invalid: get_repair_contract -> model repairs -> validate_json  -> app consumes valid JSON

The MCP server does not call the model and does not mutate output. Your app/agent remains in control of model choice, provider keys, context, and business defaults.

Contract files

Each contract is one .json file in json-contracts/.

The contract name is derived from the filename:

text
json-contracts/support-ticket.json -> support-ticket

There is no manifest file and no manually maintained resources file. Git handles versioning.

Contract shape

json
{  "description": "Convert natural language into a support ticket object.",  "rules": [    "If the user says urgent, severity must be critical.",    "Summary must be under 80 characters.",    "Category must be authentication, billing, bug, feature_request, or other."  ],  "operations": {    "create": {      "enabled": true    },    "edit": {      "enabled": true,      "return": "full_object",      "rules": [        "Start from currentJson.",        "Apply only the user's requested change.",        "Preserve all unspecified fields exactly.",        "Return the complete updated JSON object."      ]    }  },  "schema": {    "type": "object",    "additionalProperties": false,    "properties": {      "summary": {        "type": "string",        "maxLength": 80      },      "severity": {        "type": "string",        "enum": ["low", "medium", "high", "critical"]      },      "category": {        "type": "string",        "enum": ["authentication", "billing", "bug", "feature_request", "other"]      }    },    "required": ["summary", "severity", "category"]  },  "examples": [    {      "input": "Urgent, users cannot log in after SSO update.",      "output": {        "summary": "Users cannot log in after SSO update",        "severity": "critical",        "category": "authentication"      }    }  ]}

Rules:

  • schema is required and must be valid JSON Schema. Omit $schema for the default 2020-12 validator, or set $schema to draft-07 or 2020-12 explicitly.
  • description is optional but recommended.
  • rules is optional and defaults to [].
  • examples is optional and defaults to []. Example output values must validate against schema.
  • operations is optional and defaults to enabled create and edit operations. Operation metadata belongs at the top level, not inside the JSON Schema.
  • name is optional, but the filename is the source of truth.
  • A version field is rejected; use Git for versioning.
  • Contract files are plain JSON.

Included example contracts

The default json-contracts/ folder includes examples from different app categories where teams commonly rebuild the same AI glue code:

ContractIndustry/app patternConverts natural language into
support-ticketSaaS supportTriage-ready support tickets.
create-filterInternal tools/API buildersAPI filter objects.
chart-generationBI/analytics toolsDashboard chart generation specs.
patient-intakeHealthcare intakeTriage and appointment-routing objects.
ecommerce-returnEcommerce supportReturn, refund, exchange, and warranty requests.
real-estate-leadReal estate CRMBuyer, renter, seller, and lease lead profiles.
legal-client-intakeLegal tech intakeMatter routing and conflict-check data.
expense-reportFinance/expense appsReimbursement and expense line items.

Each one uses the same MCP tools: read the contract, let the model create or edit JSON, validate it, and repair if needed. New apps should not need a new bespoke prompt framework just to get reliable JSON.

MCP resources

Every loaded contract is exposed dynamically as:

text
json-contract://{contractName}

Examples:

text
json-contract://support-ticketjson-contract://create-filterjson-contract://chart-generation

resources/list returns all loaded contracts. resources/read returns the normalized full contract JSON.

Stable MCP tools

list_contracts

Input:

json
{}

Output:

json
{  "contracts": [    {      "name": "support-ticket",      "description": "Convert natural language into a support ticket object.",      "contractHash": "sha256:...",      "schemaHash": "sha256:..."    }  ]}

read_contract

Input:

json
{  "contract": "support-ticket"}

Returns the selected contract's description, rules, operations, schema, examples, contractHash, and schemaHash.

Hashes are deterministic SHA-256 values over the normalized contract/schema payload. They are for logging, cache keys, and audit trails; contract files still use Git for versioning.

get_json_contract

Input:

json
{  "contract": "support-ticket",  "input": "Urgent, users cannot log in after SSO update.",  "context": {}}

Output:

json
{  "contract": "support-ticket",  "contractHash": "sha256:...",  "schemaHash": "sha256:...",  "operation": "create",  "instructions": [    "Convert the input into JSON.",    "Return JSON only.",    "Do not return markdown.",    "Do not include commentary.",    "Do not include extra keys.",    "Match the schema exactly.",    "Use enum values exactly.",    "Follow all rules.",    "Use examples as guidance."  ],  "description": "Convert natural language into a support ticket object.",  "rules": [    "If the user says urgent, severity must be critical.",    "Summary must be under 80 characters.",    "Category must be authentication, billing, bug, feature_request, or other."  ],  "operationRules": [],  "schema": {},  "examples": [],  "operationExamples": [],  "input": "Urgent, users cannot log in after SSO update.",  "context": {}}

The agent/model uses this contract to produce JSON. The MCP server does not produce it.

get_edit_contract

Input:

json
{  "contract": "create-filter",  "currentJson": {    "status": "open",    "limit": 50  },  "input": "we want the last 20 closed tickets",  "context": {}}

Output:

json
{  "contract": "create-filter",  "contractHash": "sha256:...",  "schemaHash": "sha256:...",  "operation": "edit",  "instructions": [    "Start from currentJson.",    "Apply only the user's requested change.",    "Preserve all unspecified fields exactly.",    "Return the complete updated JSON object, not a patch.",    "Return JSON only."  ],  "description": "Convert natural language into a structured API filter object.",  "rules": [    "Only include fields that are explicitly requested or clearly implied."  ],  "operationRules": [    "Preserve all unspecified fields exactly."  ],  "schema": {},  "examples": [],  "operationExamples": [],  "currentJson": {    "status": "open",    "limit": 50  },  "input": "we want the last 20 closed tickets",  "context": {}}

The agent/model uses this edit contract to return the complete updated JSON object. The MCP server first validates currentJson against the selected contract, and the agent should validate the edited object with validate_json afterward.

Context and system variables

context is an intentional pass-through object for app/system variables that should help the model interpret the user's input.

Examples:

json
{  "contract": "real-estate-lead",  "input": "I'm pre-approved for a 4 bedroom house in Durham NC up to 900k. We need a pool and a large backyard for dogs. We are looking to move this summer.",  "context": {    "current_datetime": "2026-05-03T00:00:00Z",    "email": "[email protected]"  }}

json-contracts does not interpret, normalize, or validate context against a separate schema. It returns the object unchanged in the contract payload so the model can use it with the contract rules and output schema.

Important behavior:

  • Put external variables in context, not by appending hidden text to input.
  • The final JSON must still match the contract schema.
  • Context fields should not appear in the final JSON unless the contract schema allows them.
  • Contracts can define how to use context through rules, examples, and schema shape.
  • Relative values such as "this summer" or "last week" should be resolved by the model using whatever date/time/location context the app provides.

validate_json

Input:

json
{  "contract": "support-ticket",  "json": {    "summary": "Users cannot log in after SSO update",    "severity": "critical",    "category": "authentication"  }}

Success:

json
{  "valid": true,  "contract": "support-ticket",  "json": {    "summary": "Users cannot log in after SSO update",    "severity": "critical",    "category": "authentication"  },  "errors": []}

Failure:

json
{  "valid": false,  "contract": "support-ticket",  "errors": [    {      "path": "/severity",      "message": "must be equal to one of the allowed values",      "keyword": "enum"    }  ]}

valid is never true unless Ajv validates the JSON against the contract schema.

get_repair_contract

Input:

json
{  "contract": "support-ticket",  "invalidJson": {    "summary": "Users cannot log in",    "severity": "urgent"  },  "validationErrors": []}

Output:

json
{  "contract": "support-ticket",  "contractHash": "sha256:...",  "schemaHash": "sha256:...",  "instructions": [    "Repair the JSON so it validates against the schema.",    "Return JSON only.",    "Do not return markdown.",    "Do not include commentary.",    "Do not include extra keys.",    "Preserve valid fields where possible."  ],  "schema": {},  "rules": [],  "examples": [],  "invalidJson": {},  "validationErrors": []}

The agent/model uses this repair contract to produce corrected JSON. The MCP server does not repair by calling a model. When validation errors are available, instructions also includes deterministic field-specific repair hints such as adding missing required fields, removing extra fields, or choosing allowed enum values.

status

Input:

json
{}

Output:

json
{  "server": "json-contracts",  "version": "0.1.0",  "contractsDir": "/absolute/path/to/json-contracts",  "loaded": 3,  "contracts": [    {      "name": "support-ticket",      "description": "Convert natural language into a support ticket object.",      "contractHash": "sha256:...",      "schemaHash": "sha256:..."    }  ],  "watchContracts": true,  "allowInvalidContracts": false}

Use this to debug host configuration, loaded contracts, and the exact contract/schema hashes in use.

reload_contracts

Input:

json
{}

Output:

json
{  "loaded": 3,  "contracts": ["support-ticket", "create-filter", "chart-generation"]}

Optional MCP prompts

The server also exposes reusable prompt helpers for MCP hosts that support prompts:

  • json_contract_prompt
  • edit_contract_prompt
  • repair_contract_prompt

These prompts only render contract text for the agent/model. They do not call a model and they do not generate JSON inside the MCP server.

Correct flow

User:

text
Create a support ticket: urgent, users cannot log in after SSO update.

Agent calls:

json
{  "tool": "get_json_contract",  "arguments": {    "contract": "support-ticket",    "input": "Urgent, users cannot log in after SSO update."  }}

MCP returns schema, rules, examples, instructions, and input.

Agent/model produces:

json
{  "summary": "Users cannot log in after SSO update",  "severity": "critical",  "category": "authentication"}

Agent calls:

json
{  "tool": "validate_json",  "arguments": {    "contract": "support-ticket",    "json": {      "summary": "Users cannot log in after SSO update",      "severity": "critical",      "category": "authentication"    }  }}

MCP returns:

json
{  "valid": true,  "contract": "support-ticket",  "json": {    "summary": "Users cannot log in after SSO update",    "severity": "critical",    "category": "authentication"  },  "errors": []}

If invalid, the agent calls get_repair_contract, uses its own model to repair, and calls validate_json again.

Edit flow

For existing JSON, the agent calls get_edit_contract with the current JSON plus a natural-language change request:

json
{  "tool": "get_edit_contract",  "arguments": {    "contract": "create-filter",    "currentJson": {      "status": "open",      "limit": 50    },    "input": "we want the last 20 closed tickets"  }}

The model returns the complete edited object:

json
{  "status": "closed",  "limit": 20}

Then the agent validates that final edited object with validate_json.

Contract validation and linting CLI

Use the CLI in CI or pre-commit checks without starting an MCP host:

bash
json-contracts validate --contracts ./json-contracts

validate loads every .json contract, checks the contract shape, validates the JSON Schema, and validates example outputs against the schema. It exits nonzero if any contract is invalid.

For advisory checks:

bash
json-contracts lint --contracts ./json-contractsjson-contracts lint --strict --contracts ./json-contracts

lint includes the same validation checks, then prints generic schema-quality warnings such as empty schemas, missing examples, object schemas without additionalProperties:false, or broad additionalProperties:true. --strict exits nonzero when warnings are found.

Both commands support machine-readable output:

bash
json-contracts validate --json --contracts ./json-contractsjson-contracts lint --json --strict --contracts ./json-contracts

Minimal app integration example

A tiny Node MCP client is included at examples/node-client. It shows the app-side loop:

text
get_json_contract -> your model -> validate_json -> optional get_repair_contract -> your model -> validate_json

It intentionally does not call an LLM provider. Replace its placeholder getModelJson() with your own model call.

Studio

The local web Studio is intentionally not bundled with this MCP package. It lives in a separate repo/package so the MCP server stays small, local, and focused.

Use the Studio when you want a browser UI for testing contracts, provider-backed demos, manual repair loops, or drafting new contract files.

For a quick demo with starter contracts:

bash
mkdir my-json-contractscd my-json-contractsnpx -y json-contracts@latest initnpx -y json-contracts-studio@latest

Repository:

text
https://github.com/json-contracts/json-contracts-studio

Pi local integration

This repo also includes a project-local Pi extension at .pi/extensions/json-contracts-mcp.ts. It starts the local MCP stdio server and exposes the server tools to Pi as jc_* tools for manual testing.

From this repo on Windows PowerShell:

powershell
npm run buildpi

Then try:

text
/jc-status

See docs/pi-integration.md for the full setup and test prompts.

Documentation site and content strategy

The docs/ folder can be published directly with GitHub Pages from the /docs branch folder setting.

Git-controlled behavior

The json-contracts/ folder is the product surface.

  • Add behavior by adding a new .json file.
  • Edit behavior by editing an existing .json file.
  • Review behavior through Git pull requests.
  • Roll back behavior through Git.

No provider keys, SDKs, sampling, or MCP config changes are required when contracts change.

Environment variables

VariableDefaultDescription
JSON_CONTRACTS_DIR./json-contractsFolder containing contract .json files.
MCP_TRANSPORTstdioTransport. v1 implements stdio.
PORT3000Reserved for future HTTP transport.
API_AUTH_TOKENunsetReserved for future HTTP Bearer auth.
DEBUGfalseEnables debug logging to stderr.
WATCH_CONTRACTStrueWatches local contracts and reloads on changes.
ALLOW_INVALID_CONTRACTSfalseIf true, invalid contracts are skipped with warnings.

Studio-only LLM provider variables are documented in the separate json-contracts-studio repo. The MCP stdio server does not use them.

In stdio mode, logs are written to stderr only. The server never writes logs to stdout.

Security notes

The MCP server in json-contracts:

  • never calls an LLM provider
  • never uses provider API keys
  • never performs MCP sampling
  • never executes anything from contract files
  • never uses eval
  • never imports or executes code from contract files
  • never logs full user input unless DEBUG=true
  • validates MCP tool inputs with Zod
  • enforces contract file, schema, and examples limits
  • rejects unsafe contract names and resource URIs
  • prevents path traversal

The optional separate Studio can call LLM providers only when you configure a key in its local UI or .env file; those provider calls are not part of the MCP stdio server.

Licensing and trademarks

Project owner: Harry Giunta.

Licensing model:

  • Runtime code, docs, examples, tests, and project infrastructure are licensed under Apache-2.0. See LICENSE and NOTICE.
  • Official starter contracts in json-contracts/ are licensed under Apache-2.0 OR MIT, at your option. See json-contracts/LICENSE.md.
  • Third-party or marketplace contract packs may use creator-selected licenses. They should include their own license file or license metadata and must not imply official status unless approved.

The project name json-contracts is subject to the trademark policy in TRADEMARKS.md. Copyright licenses do not grant trademark rights.

See CONTRIBUTING.md for contribution licensing and project guidelines.

Development

bash
npm installnpm testnpm run buildnpm run dev

Run the published package as an MCP stdio server:

bash
npx -y json-contracts@latest

Or from this repository:

bash
npm run dev

Docker

Docker support is optional. A sample Dockerfile is included for packaging the stdio server with its default contracts.

來源:README.md,提交 68e8536

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v0.1.2最新Sep 16, 2026

評分

已滿足適用檢查項的 40%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

    請在儲存庫或註冊中心條目中宣告授權條款。