{"_id":"@crawlertoll/publisher","_rev":"2-b61c47b5c672f73d19821f55442a921d","name":"@crawlertoll/publisher","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@crawlertoll/publisher","version":"0.1.0","keywords":["crawlertoll","context-license","mcp","ai-agents","ai-licensing","publisher","well-known","attestation","ed25519"],"author":{"name":"Charthouse Ltd"},"license":"Apache-2.0","_id":"@crawlertoll/publisher@0.1.0","maintainers":[{"name":"charthouse","email":"c_steurer@icloud.com"}],"homepage":"https://context-license.org","bugs":{"url":"https://github.com/nhrzxxw9dn-web/crawlertoll-publisher-js/issues"},"bin":{"crawlertoll":"dist/cli.js"},"dist":{"shasum":"c64cd341f218e26aa32dfa925826411620abf91a","tarball":"https://registry.npmjs.org/@crawlertoll/publisher/-/publisher-0.1.0.tgz","fileCount":13,"integrity":"sha512-XeyHIZ2xiRwf7LD1HhZ6t/PWxR53sCoDx0l6j0GITTvzT3yOk3yRmGtY3o1sN/OtScycKWWpc/mjsq6x9rCeHg==","signatures":[{"sig":"MEUCIFfdGeF9rhmtiMsux2hXaEGg0/556xDxV9jOUFCyoctlAiEA5B0wkdyn9wl45OtNB8eQHy9fRJOdaR2XP5mq1xwBv8Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":115536},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./cli":{"types":"./dist/cli.d.ts","import":"./dist/cli.js"}},"gitHead":"e84b3fb7586d09def0cdfbb4e0f63ba32af79500","scripts":{"lint":"eslint src tests","test":"vitest run","build":"tsup src/index.ts src/cli.ts --format esm,cjs --dts --clean --shims","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run typecheck && npm test && npm run build"},"_npmUser":{"name":"charthouse","email":"c_steurer@icloud.com"},"repository":{"url":"git+https://github.com/nhrzxxw9dn-web/crawlertoll-publisher-js.git","type":"git"},"_npmVersion":"11.7.0","description":"Publisher SDK + CLI for the Context License standard. One-command install for /.well-known/context-license.json. CC0 spec, Apache 2.0 implementation.","directories":{},"_nodeVersion":"25.3.0","dependencies":{"cac":"^6.7.14","picocolors":"^1.1.1","canonicalize":"^2.0.0","@noble/hashes":"^1.7.1","@noble/ed25519":"^2.2.3","@inquirer/prompts":"^7.2.0","@crawlertoll/parser":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.6","vitest":"^3.0.5","typescript":"^5.7.3","@types/node":"^22.13.5"},"_npmOperationalInternal":{"tmp":"tmp/publisher_0.1.0_1779225972814_0.2772387773339866","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@crawlertoll/publisher","version":"0.1.1","description":"Publisher SDK + CLI for the Context License standard. One-command install for /.well-known/context-license.json. CC0 spec, Apache 2.0 implementation.","license":"Apache-2.0","author":{"name":"Charthouse Ltd"},"homepage":"https://context-license.org","repository":{"type":"git","url":"git+https://github.com/charthouse-ltd/crawlertoll-publisher-js.git"},"bugs":{"url":"https://github.com/charthouse-ltd/crawlertoll-publisher-js/issues"},"keywords":["crawlertoll","context-license","mcp","ai-agents","ai-licensing","publisher","well-known","attestation","ed25519"],"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","bin":{"crawlertoll":"dist/cli.js"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./cli":{"types":"./dist/cli.d.ts","import":"./dist/cli.js"}},"scripts":{"build":"tsup src/index.ts src/cli.ts --format esm,cjs --dts --clean --shims","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","lint":"eslint src tests","prepublishOnly":"npm run typecheck && npm test && npm run build"},"dependencies":{"@crawlertoll/parser":"^0.1.0","@inquirer/prompts":"^7.2.0","@noble/ed25519":"^2.2.3","@noble/hashes":"^1.7.1","canonicalize":"^2.0.0","cac":"^6.7.14","picocolors":"^1.1.1"},"devDependencies":{"@types/node":"^22.13.5","tsup":"^8.3.6","typescript":"^5.7.3","vitest":"^3.0.5"},"engines":{"node":">=20"},"publishConfig":{"access":"public"},"gitHead":"7a513d6669a221f96c6ac32adcde589414f824c8","_id":"@crawlertoll/publisher@0.1.1","_nodeVersion":"25.3.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-A2fMg0GsaPAGJMOTefpAwR2je33hQ3FrUHJP3yIc/LNtReT9MB2eOtKZRsUE0Z6rjrQ4fqUrpW6YS0fZ5oRLGQ==","shasum":"53f72e53bfca2df1af236121eddfb1425572debf","tarball":"https://registry.npmjs.org/@crawlertoll/publisher/-/publisher-0.1.1.tgz","fileCount":13,"unpackedSize":115831,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCevgCDjknIxv0MD8JUbYxArQ9zbv+cGe4EXLCiWqu74QIgCEaQeD8neUewtEvE3L5b/gd/N5QrhqsUq86dChlKcFo="}]},"_npmUser":{"name":"charthouse","email":"c_steurer@icloud.com"},"directories":{},"maintainers":[{"name":"charthouse","email":"c_steurer@icloud.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/publisher_0.1.1_1779370902033_0.5673350680960203"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-19T21:26:12.626Z","modified":"2026-05-21T13:41:42.332Z","0.1.0":"2026-05-19T21:26:13.051Z","0.1.1":"2026-05-21T13:41:42.180Z"},"bugs":{"url":"https://github.com/charthouse-ltd/crawlertoll-publisher-js/issues"},"author":{"name":"Charthouse Ltd"},"license":"Apache-2.0","homepage":"https://context-license.org","keywords":["crawlertoll","context-license","mcp","ai-agents","ai-licensing","publisher","well-known","attestation","ed25519"],"repository":{"type":"git","url":"git+https://github.com/charthouse-ltd/crawlertoll-publisher-js.git"},"description":"Publisher SDK + CLI for the Context License standard. One-command install for /.well-known/context-license.json. CC0 spec, Apache 2.0 implementation.","maintainers":[{"name":"charthouse","email":"c_steurer@icloud.com"}],"readme":"# @crawlertoll/publisher\n\nPublisher SDK + CLI for the **Context License** standard\n(`/.well-known/context-license.json`). One command from \"I have an API\" to\n\"my publisher is discoverable by AI agents under the open license spec\".\n\n- **Spec**: [context-license.org/v0.1](https://context-license.org/v0.1) (CC0 1.0)\n- **License**: Apache-2.0 (this implementation). The spec itself is CC0.\n- **Companion packages**:\n  [`@crawlertoll/parser`](https://www.npmjs.com/package/@crawlertoll/parser) (validator),\n  [`@crawlertoll/client`](https://www.npmjs.com/package/@crawlertoll/client) (buyer SDK)\n\n> **Status**: v0.1. CLI shipped, programmatic API stable for v1.x schema.\n> The Context License spec is open for public RFC through **2026-07-15** —\n> v0.2 of the spec will ship the resolution of three open issues\n> (pricing-model vocabulary, license-terms vocabulary, provenance schema).\n\n[![npm](https://img.shields.io/npm/v/%40crawlertoll%2Fpublisher.svg)](https://www.npmjs.com/package/@crawlertoll/publisher)\n[![license](https://img.shields.io/npm/l/%40crawlertoll%2Fpublisher.svg)](./LICENSE)\n\n---\n\n## Sixty seconds, one command\n\n```bash\nnpx @crawlertoll/publisher init\n```\n\nYou'll be asked six things — publisher name, domain, slug, contact email,\nfirst endpoint, and pricing. The CLI writes:\n\n- `public/.well-known/context-license.json` — schema-valid, ready to deploy\n- `keys/<slug>-priv.pem` — your Ed25519 signing key (mode 0600)\n- `keys/<slug>-pub.pem` — the matching public key (already embedded in the JSON)\n\nThen deploy the well-known file at\n`https://your-domain/.well-known/context-license.json` with\n`Content-Type: application/json` and `Access-Control-Allow-Origin: *`.\nYou're now a Context License publisher.\n\n---\n\n## Install\n\n```bash\n# As a CLI (npx is enough; install global if you'll use it often)\nnpm install -g @crawlertoll/publisher\n\n# As a programmatic dependency\nnpm install @crawlertoll/publisher\n```\n\nRequires **Node 20+** (Web Crypto must be globally available — Node 18 is EOL).\n\n---\n\n## Commands\n\n### `crawlertoll init`\n\nInteractive scaffolder. Walks through six prompts and produces a\nschema-valid `/.well-known/context-license.json` plus an Ed25519 keypair.\n\n```bash\nnpx @crawlertoll/publisher init\n```\n\nNon-interactive — useful for scripts, CI, and the\n[execution checklist](https://github.com/charthouse-ltd/context-license-spec#adopters):\n\n```bash\nnpx @crawlertoll/publisher init --yes \\\n  --name \"Acme News\" \\\n  --slug acme-news \\\n  --domain acme.example \\\n  --contact ai@acme.example \\\n  --endpoint-name search \\\n  --endpoint-url https://acme.example/mcp/search \\\n  --price-usd-cents 0.005 \\\n  --out-dir ./public \\\n  --keys-dir ./keys\n```\n\n### `crawlertoll validate <target>`\n\nValidate a local file, a URL, or a bare domain.\n\n```bash\n# Local file\ncrawlertoll validate ./public/.well-known/context-license.json\n\n# Bare domain — auto-resolves to /.well-known/context-license.json\ncrawlertoll validate matriculix.com\n\n# Explicit URL\ncrawlertoll validate https://medxcare.me/.well-known/context-license.json\n```\n\nExit codes: `0` valid, `1` invalid (schema errors on stderr), `2` could not fetch/read.\n\n### `crawlertoll keygen`\n\nStandalone Ed25519 keypair generation. Useful when bringing your own\nkeys or rotating.\n\n```bash\ncrawlertoll keygen --out-dir ./keys --stem prod\n# writes keys/prod-priv.pem (0600) and keys/prod-pub.pem\n\ncrawlertoll keygen --stdout  # print to stdout instead of writing files\n```\n\n### `crawlertoll sign`\n\nProduce a signed attestation envelope. The envelope is the per-response\nprovenance signal the buyer SDK's `verify()` checks.\n\n```bash\ncrawlertoll sign \\\n  --key keys/acme-news-priv.pem \\\n  --kid ct_sign_acme-news_2026-05 \\\n  --publisher acme-news \\\n  --endpoint search \\\n  --request req.json \\\n  --response resp.json \\\n  --out envelope.json\n\n# Or, if you already have SHA-256 hex hashes:\ncrawlertoll sign \\\n  --key keys/acme-news-priv.pem \\\n  --kid ct_sign_acme-news_2026-05 \\\n  --publisher acme-news --endpoint search \\\n  --request-hash 148f0e... --response-hash fdff36... \\\n  > envelope.json\n```\n\n### `crawlertoll verify`\n\nVerify a signed envelope against a public key.\n\n```bash\ncrawlertoll verify --envelope envelope.json --key keys/acme-news-pub.pem\n```\n\nExit codes: `0` valid, `1` invalid (reason on stderr), `2` file/key error.\n\n---\n\n## Programmatic API\n\nSame primitives as the CLI, exposed for embedding.\n\n### Build a license file from code\n\n```ts\nimport {\n  defineLicense,\n  serializeLicense,\n  generateEd25519Keypair,\n} from \"@crawlertoll/publisher\";\nimport { writeFile, mkdir } from \"node:fs/promises\";\n\nconst keys = await generateEd25519Keypair();\n\nconst result = defineLicense({\n  publisher: {\n    name: \"Acme News\",\n    slug: \"acme-news\",\n    domain: \"acme.example\",\n    contact: \"ai@acme.example\",\n  },\n  endpoints: [{\n    name: \"search\",\n    url: \"https://acme.example/mcp/search\",\n    transport: \"streamable-http\",\n    description: \"Full-text search across Acme's article corpus.\",\n    schema_org_types: [\"NewsArticle\"],\n  }],\n  pricing: { model: \"per_query\", currency: \"USD\", unit_price_micros: 5000 },\n  terms_of_use: \"https://acme.example/ai-terms\",\n  attestation: {\n    public_key_pem: keys.publicKeyPem,\n    kid: \"ct_sign_acme-news_2026-05\",\n    algorithm: \"ed25519\",\n  },\n});\n\nif (!result.ok) {\n  for (const e of result.errors) console.error(e.path, e.message);\n  process.exit(1);\n}\n\nawait mkdir(\"public/.well-known\", { recursive: true });\nawait writeFile(\n  \"public/.well-known/context-license.json\",\n  serializeLicense(result.value),\n);\n\n// Store keys.secretKeyPem somewhere safe — secret store, env var, KMS.\n```\n\n`defineLicense()` fills in sensible v1 defaults (`$schema`, `version`, `auth.schemes`,\n`quality_signals.last_updated`, etc.) and validates the result against the\ncanonical JSON Schema before returning. Required fields you must provide:\n`publisher`, `endpoints`, `pricing`, `terms_of_use`.\n\n### Sign attestation envelopes\n\n```ts\nimport { buildAndSign, pemToRawEd25519SecretKey } from \"@crawlertoll/publisher\";\nimport { readFile } from \"node:fs/promises\";\n\nconst secretKey = pemToRawEd25519SecretKey(\n  await readFile(\"keys/acme-news-priv.pem\", \"utf8\"),\n);\n\nconst envelope = await buildAndSign({\n  kid: \"ct_sign_acme-news_2026-05\",\n  publisher: \"acme-news\",\n  endpoint: \"search\",\n  requestHash: \"148f0e9b178ff35f30dcf4555498ce82f636fc83648b168dd81a44d6d5bb4cd2\",\n  responseHash: \"fdff36eb183b05bbd1df9009aeab6e2cf4e6722af4dc5016c57576da7ef8157d\",\n}, secretKey);\n\n// Return `envelope` alongside the response payload. Buyer SDK's verify()\n// will accept it.\n```\n\nThe signing scheme is **Ed25519 over the JCS-canonical envelope minus its\n`signature` field, domain-separated by `\"ct_att_v1:\"`**. Identical to\n[`@crawlertoll/client`'s `verify()`](https://www.npmjs.com/package/@crawlertoll/client)\n— envelopes signed here verify there and vice-versa.\n\n### Validate, in-process\n\n```ts\nimport { parse, fetchAndParse } from \"@crawlertoll/publisher\";\n\nconst result = parse(await readFile(\"./context-license.json\", \"utf8\"));\nconst live = await fetchAndParse(\"https://matriculix.com/.well-known/context-license.json\");\n```\n\nRe-exported verbatim from `@crawlertoll/parser`. Same types, same errors.\n\n---\n\n## What this SDK does NOT do (yet)\n\n- **Host your MCP server.** That's an MCP-server library's job. This SDK\n  emits the metadata file that *points* at the MCP server.\n- **Manage publisher onboarding to the Charthouse marketplace.** Listing\n  is opt-in via [crawlertoll.com/list](https://crawlertoll.com/list) once\n  the marketplace MVP is live (week-12 milestone).\n- **Talk to your payment processor.** The metadata declares which payment\n  rails you support (`x402`, `api_key`, etc.); your backend handles the\n  actual transaction.\n\n---\n\n## Conformance\n\nEvery release passes a 30-test vitest suite covering:\n\n- `defineLicense()` produces schema-valid output from a minimal spec, with\n  defaults applied\n- Schema-invalid input surfaces as structured `ValidationError[]`\n- Ed25519 keypair generation produces interoperable PEM\n- Sign↔verify roundtrips work, tamper detection works, wrong-key fails\n- `init --yes` produces a deployable file end-to-end\n- `validate` returns the correct exit codes for valid / invalid / missing\n\nRun yourself:\n\n```bash\ngit clone https://github.com/charthouse-ltd/crawlertoll-publisher-js\ncd crawlertoll-publisher-js\nnpm install\nnpm test\n```\n\n---\n\n## Project links\n\n- **Spec**: [context-license.org/v0.1](https://context-license.org/v0.1)\n- **Spec repo**: [github.com/charthouse-ltd/context-license-spec](https://github.com/charthouse-ltd/context-license-spec)\n- **Manifesto**: [github.com/charthouse-ltd/crawlertoll/blob/main/MANIFESTO.md](https://github.com/charthouse-ltd/crawlertoll/blob/main/MANIFESTO.md)\n- **Marketplace**: [crawlertoll.com](https://crawlertoll.com)\n\n## License\n\n[Apache-2.0](./LICENSE). The Context License spec itself is\n[CC0 1.0](https://context-license.org/v0.1) — fork the spec freely.\n\n## Trademark\n\nCrawlerToll™ is a trademark of Charthouse Ltd.\n","readmeFilename":"README.md"}