ADR-002: s402 is a Pure Protocol Repo — mcp-server Moves to SweeFi
Status: Accepted Date: 2026-04-11 Supersedes: (none — refines the boundary that ADR-001 § Decision 1 named but did not enforce at the repo level)
Context
ADR-001 (2026-04-11) formalized four protocol boundaries, including S7: "the s402 protocol surface is chain-agnostic." That ADR treated the boundary as a rule about code inside the s402 package (typescript/src/). A follow-up read-only audit of sibling repos on 2026-04-11 revealed the boundary had already been broken in a less obvious way: the s402 repo itself contains a mcp-server/ folder whose src/sui-exact.ts imports @mysten/sui directly. The repo-level boundary test (typescript/test/boundary.test.ts) is scoped to typescript/src/ only and therefore does not detect the violation.
This is a repo-level S7 violation. The s402 npm package is chain-agnostic, but the mcp-server/ folder inside the same repo is not — and to a contributor reading ls s402/, the distinction is invisible. The same AI-drift risk ADR-001 was written to warn against (four consecutive sessions adding Sui-specific address validation to http.ts before a human caught it) can happen in any sibling directory of typescript/ just as easily as inside it.
The audit also surfaced that SweeFi already has the correctly-layered implementation:
sweefi/contracts/sources/contains Move modules for all five schemes (payment.move,stream.move,escrow.move,prepaid.move,seal_policy.move) plus supporting modules (mandate, identity, math, admin). 426 Move test functions across 10 modules.sweefi/packages/sui/src/s402/has client/facilitator/server TypeScript adapters for all five schemes (exact, stream, escrow, prepaid, unlock). 669 tests in@sweefi/sui.sweefi/packages/mcp/is@sweefi/mcpv0.1.4 with 35 tools and 222 tests. Beta-grade, published to npm, consumed by real users.- Testnet v11 is deployed at
0xb83e50365ba460aaa02e240902a40890bec88cd35bd2fc09afb6c79ec8ea9ac5with three schemes demo'd live (exact/stream/escrow). - Grand total: 1,775 tests (1,349 TypeScript + 426 Move).
- SweeFi already consumes
s402from npm as a versioned dependency ("s402": "^0.2.0").
SweeFi's own agent instructions (sweefi/.claude/CLAUDE.md) already codify the rule this ADR enforces, line-for-line:
Critical Boundaries — s402 is chain-agnostic. @sweefi/sui is chain-specific. NEVER put Sui logic in the s402 package.
The rule already exists in the ecosystem. This ADR simply makes the s402 repo obey it.
Decision
s402 is a pure protocol repo. The repository contains, and may only contain:
typescript/— thes402npm package (wire types, scheme interfaces, HTTP middleware, client/server/facilitator primitives, test utilities). Zero runtime dependencies. Zero chain-specific imports.python/— thes402pip package (mirror implementation, same surface).spec/— language-agnostic specification artifacts: conformance test vectors (spec/vectors/), Allium behavioral specs (spec/allium/).docs/— VitePress documentation site deployed tos402-protocol.org, including ADRs.demo-api/— a minimal chain-agnostic example consuming thes402package from npm. Allowed because it imports onlys402, never@mysten/suior any other chain SDK. It is a usage example, not an implementation.INVARIANTS.md,AGENTS.md,README.md,LICENSE,CONTRIBUTING.md,SECURITY.md— repo-level documentation.
The repository does not contain:
- Chain-specific adapters (
sui-*.ts,solana-*.ts,evm-*.ts, etc.) - Chain-specific imports (
@mysten/sui,@solana/web3.js,ethers,viem, etc.) - Move contracts, Anchor programs, Solidity contracts
- MCP server implementations
- Facilitator service implementations (beyond the abstract
s402Facilitatorclass intypescript/src/facilitator.ts)
All of the above live in downstream implementation repos:
- SweeFi (
projects/sweefi-project/sweefi/) — Sui implementation.@sweefi/suiis the adapter package,@sweefi/mcpis the canonical MCP server for Sui,@sweefi/facilitatoris the hosted facilitator service,@sweefi/solanais an alpha Solana adapter, and the Move contracts live undercontracts/. - Future implementations (SweeFi-EVM, SweeFi-CosmWasm, third-party forks) follow the same pattern: one chain per repo, each consuming
s402from npm.
Effective immediately
s402/mcp-server/is removed in full. The folder, its tests, itspackage.json, its README are all deleted in a single commit that references this ADR.- The published npm package
s402-mcp@0.1.1is deprecated vianpm deprecate s402-mcp "s402-mcp has moved to @sweefi/mcp — install @sweefi/mcp instead". This is a manual step performed by the npm account owner; it does not unpublish the old version, it only adds an install-time warning. Existing installations continue to work indefinitely. - Distribution pitches (Claude Code onboarding, Cursor tool list, MCP registry listing, README badges, Twitter threads, blog posts, HN submissions) are updated to point at
@sweefi/mcp, nots402/mcp-server. s402/README.mdadds a top-level "Reference implementations" section listing SweeFi with a link.- The scope coverage table in ADR-001 § Decision 1 is superseded by SweeFi's coverage state. ADR-001 itself remains unchanged (ADRs are append-only); ADR-002 is the current source of truth for "which schemes implement S8 where."
spec/allium/s8-facilitator-accountability.alliumhas itsImplements:header corrected to point at the@sweefi/suitarget adapters rather than the now-deleted mcp-server paths.- A CI guard is added to
typescript/test/boundary.test.ts(or a newtest/repo-boundary.test.ts) that fails if any file unders402/(outsidedemo-api/anddocs/) imports@mysten/sui,@solana/web3.js,ethers,viem, or any other known chain-specific SDK. This is stronger than the existingsrc/-only check and prevents a future side-door.
What s402 still provides
The protocol repo keeps everything that makes a protocol adoptable:
- The wire format (serialized HTTP 402 payment requirements and responses)
- The
s402ClientScheme,s402ServerScheme,s402FacilitatorSchemeinterfaces that any chain's adapter implements - The
verifySettlementinterface ons402ClientScheme(new in v0.3.0, per ADR-001 Decision 1) — chain-agnostic signature, chain-specific body lives in each adapter - The
DIGEST_MISMATCHerror code (new in v0.3.0) - 132 conformance test vectors any implementation must pass
- The S1-S8 invariants in
INVARIANTS.md - The ADR series
- The Allium behavioral specs
An adapter author in a new chain reads typescript/src/scheme.ts + spec/vectors/ + INVARIANTS.md and knows exactly what they have to implement. They never have to read, clone, or understand SweeFi-specific code.
Alternatives Considered
Alt A — Keep mcp-server as a "reference implementation," just move it to examples/. Rejected. The problem isn't the folder name or location — it's the @mysten/sui dependency. As long as any artifact in the s402 repo imports a chain-specific SDK, a new contributor's first grep -r '@mysten' s402/ surfaces Sui code inside the protocol repo, and the AI-drift cycle from the February 2026 S7 incident repeats. Moving the folder without removing the dependency is cosmetic; removing the dependency means rewriting mcp-server into something that doesn't actually run, i.e., deleting it.
Alt B — Refactor mcp-server to be chain-abstract with pluggable chain adapters loaded at runtime. Rejected. MCP servers need a concrete signing keypair, a concrete transaction builder, and a concrete RPC client — all chain-specific. A "chain-abstract MCP server" is either (a) a thin shell that still requires the user to install one of @sweefi/sui/@sweefi/solana/etc. as a peer dependency (in which case the shell adds no value over @sweefi/mcp which already does this), or (b) a dynamic loader that adds indirection for no gain. Either way, the right home is SweeFi (or future sibling implementation repos), not s402.
Alt C — Merge s402 and sweefi into one monorepo. Rejected. This is analogous to merging the TCP/IP spec repo with the Linux kernel repo: two different things with different release cadences, audiences, and governance models. s402 is meant to be adopted by many implementations from many authors; SweeFi is one specific Sui-native implementation that happens to be first. Coupling them makes the protocol look like "the SweeFi protocol" rather than a neutral specification — and destroys the credibility that lets third-party chain implementations adopt it.
Alt D — Leave mcp-server/ where it is and just stop adding to it. Rejected — this is the drift path. New contributors read the existing folder and assume it's load-bearing; AI sessions read the existing code and extend it; the violation calcifies into convention. The only durable fix is deletion plus this decision record explaining why the deletion is not a mistake.
Alt E — Split mcp-server into its own dedicated repo, s402-mcp-server, under the same GitHub org as s402. Rejected. A single-product npm package in its own repo still has the same boundary confusion: s402-mcp-server imports @mysten/sui, any reader assumes the s402 project endorses a Sui-first framing, and the neutrality of the protocol is still compromised. The correct home for a Sui-specific MCP server is a Sui-specific implementation repo. SweeFi already fills that role.
Consequences
Positive:
- The S7 boundary is enforceable at the repo level, not just at the package level. After deletion,
grep -r '@mysten' s402/returns zero results (excluding historical ADR mentions). The new CI guard prevents regression. - The two-repo structure mirrors the HTTP ecosystem pattern: one neutral spec repo, many chain-specific implementations. It makes the protocol legible to new contributors in a way a mixed repo never could.
@sweefi/mcpbecomes the single canonical Sui MCP server instead of one of two competing implementations. No more parallel drift, no more "which one should I install?" confusion.- Distribution becomes cleaner: MCP registry, Claude Code, Cursor, and NPM searches all resolve to one package that is actively maintained, thoroughly tested (222 tests, 35 tools), and production-grade.
- The s402 repo becomes smaller, more focused, and cheaper to audit. An auditor reading
s402/sees only the protocol — not a mixed bag of protocol + reference + product. - Future chain implementations (EVM, Solana, Cosmos) have an unambiguous pattern to follow: "write your own
@yourprotocol/chainpackage, consume s402 from npm, implement the three interfaces, pass the conformance vectors." No ambiguity about "should we add our adapter to the s402 repo?"
Negative:
- We lose the "clone s402 and run the MCP server in one command" one-click demo path. Replaced by
pnpm add @sweefi/mcp(or whatever install flow SweeFi documents), which is arguably better for real users but less convenient for read-only exploration. - Git history for
mcp-server/becomes archival-only. Future reads of old commits (e.g.,3a96c9d) will find files that no longer exist at HEAD. Mitigation: the deletion commit message explicitly references this ADR. - External contributors who fork
s402expecting to find a runnable example will need to be pointed at SweeFi ordemo-api/. The README update handles this. - The published
s402-mcp@0.1.1npm package becomes a deprecated island. Existing installations continue to work but receive no updates. Thenpm deprecatenotice handles communication; no migration path is planned for existing users (they install@sweefi/mcpmanually).
Risks & watch-fors:
- SweeFi must stay in sync with s402 protocol changes. When s402 adds a new scheme, interface method, or required field, SweeFi's adapters must implement it before their next release. Mitigation: SweeFi's CI runs the s402 conformance vectors against its adapters (
pnpm testreadsspec/vectors/from the installeds402package). If SweeFi falls behind a protocol change, its CI fails loudly. - Phantom
mcp-server/in old branches. Any in-flight branches or forks that still contain the folder will need rebasing. Mitigation: merge or close open branches before the deletion commit lands. At the time of this ADR, there are no open branches onmainreferencingmcp-server/. - Other future chain implementations need the same discipline. The next chain that joins s402 must be onboarded against this ADR explicitly so they don't ship a
s402/evm-mcp/ors402/solana-mcp/folder. Mitigation: CONTRIBUTING.md will link this ADR under "How to add a new chain implementation." - The
npm deprecatenotice can be missed. Users installings402-mcpvia a lock file pin will not see the notice. Mitigation: the deletion commit also updates thes402-mcp@0.1.1README.mdwith a "MOVED" banner (a final published version0.1.2that is effectively a redirect). This is a manual post-deletion republish step. - Cross-repo conformance tests do not yet exist. SweeFi's CI does not currently run s402 conformance vectors. This ADR creates the need; a follow-up must actually wire it up in SweeFi.
Follow-ups
- [ ] This session: Delete
s402/mcp-server/in a commit referencing this ADR - [ ] This session: Update
spec/allium/s8-facilitator-accountability.alliumImplements:header to point at SweeFi's plannedpackages/sui/src/s402/*/client.tspaths - [ ] This session: Add the "grep sibling repos before implementing" lesson to
s402/AGENTS.md - [ ] This session: Mirror the same rule to
sweefi/AGENTS.md - [ ] This session: Prepare
s402@0.3.0CHANGELOG entry +pnpm publish --dry-rungauntlet - [ ] Manual (Danny):
pnpm publishfroms402/typescript/to ship v0.3.0 - [ ] Manual (Danny):
npm deprecate s402-mcp "..."and optionally publish a finals402-mcp@0.1.2with a MOVED banner - [x] Next session (SweeFi): Back-port
verifySettlementinto all five scheme client classes insweefi/packages/sui/src/s402/*/client.ts. Bumps402dep from^0.2.0to^0.3.0. Done 2026-04-11. - [x] Next session (SweeFi): File
sweefi/docs/adr/010-facilitator-causal-binding.mdmirroring S8 in SweeFi's ADR style, referencing this ADR and s402 ADR-001 as the source. Done 2026-04-11. - [ ] Next session (SweeFi): Wire s402 conformance test vectors into SweeFi CI so protocol changes are caught automatically
- [ ] Follow-up: Add repo-level CI guard — fail if any file under
s402/(outsidedemo-api/anddocs/) imports a chain-specific SDK - [ ] Follow-up: Update
s402/README.mdwith a "Reference implementations" section linking SweeFi - [ ] Follow-up: Update
s402/CONTRIBUTING.mdwith a "How to add a new chain implementation" section linking this ADR - [ ] Follow-up: Update
s402-protocol.orgdocumentation site with a "Sui implementation" page that points at SweeFi rather than walking the reader throughmcp-server/