docs: import agentic-commerce doc files (allow to keep agentic-commer…#40
Conversation
…ce repo private for now)
There was a problem hiding this comment.
Pull request overview
Imports the agentic-commerce documentation set into this repo so the content can remain accessible even while the source repo stays private.
Changes:
- Adds Boson MCP server/client/GOAT plugin documentation plus example snippets.
- Adds High Value Asset Module (formerly Fermion) docs, including a local docker-compose example and TS scripts.
- Adds an “AI Agent Guide” (
AGENTS.md) and a large “E2E test suite” reference file.
Reviewed changes
Copilot reviewed 23 out of 25 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/agentic-commerce/src/fermion/README.md | High Value Asset Module MCP server overview + tool list + setup notes |
| docs/agentic-commerce/src/boson/mcp-server/README.md | Boson MCP server documentation (tools/resources/prompts, run modes) |
| docs/agentic-commerce/src/boson/mcp-client/README.md | Boson MCP client usage documentation |
| docs/agentic-commerce/src/boson/goat-sdk-plugin/examples/vercel.ts | Example snippet for using the GOAT SDK plugin with Vercel AI |
| docs/agentic-commerce/src/boson/goat-sdk-plugin/examples/anthropic.ts | Example snippet for using the GOAT SDK plugin with Anthropic |
| docs/agentic-commerce/src/boson/goat-sdk-plugin/README.md | GOAT SDK plugin overview + usage notes |
| docs/agentic-commerce/src/boson/README.md | Index of Boson subdirectories |
| docs/agentic-commerce/scripts/sign-transaction.ts | CLI helper script for signing transactions |
| docs/agentic-commerce/e2e/boson/tests/complete-marketplace-journeys.test.ts | Large e2e “reference” test file for end-to-end flows |
| docs/agentic-commerce/docs/fermion/setup-local-env.md | Local environment setup guide (docker-compose based) |
| docs/agentic-commerce/docs/fermion/interact-with-fermion-protocol.md | Walkthrough for interacting with the High Value Asset Module |
| docs/agentic-commerce/docs/fermion/example/sign-transaction.ts | Ethers-based example for signing a transaction |
| docs/agentic-commerce/docs/fermion/example/seller-entity-creation.ts | Example script to create/check a seller entity |
| docs/agentic-commerce/docs/fermion/example/runit.ts | CLI runner for the Fermion example scripts |
| docs/agentic-commerce/docs/fermion/example/ipfs-config.sh | IPFS container init script for local setup |
| docs/agentic-commerce/docs/fermion/example/docker-compose.yaml | Example docker-compose for local Fermion environment |
| docs/agentic-commerce/docs/fermion/example/create-offer.ts | Example script showing offer creation flow via MCP tools |
| docs/agentic-commerce/docs/fermion/example/create-mcp-client.ts | Example MCP client creation via Streamable HTTP transport |
| docs/agentic-commerce/docs/fermion/create-mcp-client.md | Guide for building an MCP client for the module |
| docs/agentic-commerce/README.npm.md | NPM-facing README for @bosonprotocol/agentic-commerce |
| docs/agentic-commerce/README.md | Repo README copy for @bosonprotocol/agentic-commerce |
| docs/agentic-commerce/AGENTS.md | Comprehensive AI agent guide / integration reference |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import { ReturnTypeMcp } from "../../../src/common"; | ||
| import { mcpServerUrl } from "../../common/constants"; | ||
| import { provider } from "../../common/protocol-utils"; | ||
| import { | ||
| getSignatureData, | ||
| resultIsSuccessful, | ||
| signAndSendTransactionData, | ||
| } from "../../common/test-utils"; | ||
| import { | ||
| ensureMintedAndAllowedTokens, | ||
| initCoreSDKWithFundedWallet, | ||
| storeProductV1Metadata, | ||
| } from "./boson-utils"; | ||
| import { MOCK_ERC20_ADDRESS } from "./constants"; | ||
| import { BosonMCPClient } from "./mcp-client"; | ||
| import minimalOfferMetadata from "./metadata/minimalOffer.json"; |
There was a problem hiding this comment.
This e2e test file is not runnable in the current repo snapshot: it imports ../../common/*, ./boson-utils, ./constants, ./mcp-client, and ./metadata/minimalOffer.json, but those paths don’t exist under docs/agentic-commerce/e2e/. Either add the missing support files/fixtures or remove/relocate this test so it doesn’t look like a runnable reference while being incomplete.
| // One of the pre-funded accounts in the Local Environment | ||
| // (https://github.com/fermionprotocol/contracts/blob/main/e2e/accounts.ts) | ||
| privateKey: "0xa2e78cd4c87191e50d6a8f1610b1cf160b17216e9090dde7a92960a34c310482" | ||
| }; | ||
|
|
||
| // The roles the Seller Entity should have to be able to create offers without any need for other entities | ||
| const sellerRoles = [eEntityRole.Seller, eEntityRole.Verifier, eEntityRole.Custodian]; | ||
|
|
||
| export async function createSellerEntity() { |
There was a problem hiding this comment.
This example hard-codes a private key in the repository. Even if it’s intended only for a local Hardhat environment, committing private keys trains unsafe patterns and may trigger secret scanners. Prefer reading from an env var (e.g. PRIVATE_KEY) and/or using a clearly fake placeholder value in the committed example.
| // One of the pre-funded accounts in the Local Environment | |
| // (https://github.com/fermionprotocol/contracts/blob/main/e2e/accounts.ts) | |
| privateKey: "0xa2e78cd4c87191e50d6a8f1610b1cf160b17216e9090dde7a92960a34c310482" | |
| }; | |
| // The roles the Seller Entity should have to be able to create offers without any need for other entities | |
| const sellerRoles = [eEntityRole.Seller, eEntityRole.Verifier, eEntityRole.Custodian]; | |
| export async function createSellerEntity() { | |
| // Provide one of the pre-funded local private keys through the environment | |
| // instead of committing it to the repository. | |
| privateKey: process.env.PRIVATE_KEY | |
| }; | |
| // The roles the Seller Entity should have to be able to create offers without any need for other entities | |
| const sellerRoles = [eEntityRole.Seller, eEntityRole.Verifier, eEntityRole.Custodian]; | |
| export async function createSellerEntity() { | |
| if (!context.privateKey) { | |
| throw new Error("Missing PRIVATE_KEY environment variable"); | |
| } |
| let contentJson; | ||
| try { | ||
| contentJson = JSON.parse(contentText); | ||
| } catch (e) { | ||
| console.error( | ||
| `Unable to parse JSON from ${contentText}. Error: ${e.toString()}`, | ||
| ); | ||
| } | ||
| if (!contentJson.success) { | ||
| throw new Error(`Unsuccessful return from tool: ${contentText}`); | ||
| } | ||
| return contentJson as T; |
There was a problem hiding this comment.
getContent() logs JSON parse errors but then continues; if parsing fails, contentJson stays undefined and contentJson.success will throw a less-informative error. Throw immediately on parse failure (or return a structured error) so callers get a clear failure mode.
|
|
||
| ## Create an mcp-client | ||
|
|
||
| Creating an MCP client is straightforward using the typescript_sdk and the example given in their GitHub repo (See [MCP typescript_sdk](https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#writing-mcp-clients)). |
There was a problem hiding this comment.
The docs refer to the “typescript_sdk” name, which is confusing/incorrect in this context (the project is typically referred to as the MCP TypeScript SDK). Consider renaming this to “TypeScript SDK” and keeping the wording consistent with the linked repository name.
| Creating an MCP client is straightforward using the typescript_sdk and the example given in their GitHub repo (See [MCP typescript_sdk](https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#writing-mcp-clients)). | |
| Creating an MCP client is straightforward using the TypeScript SDK and the example given in the GitHub repo (see [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#writing-mcp-clients)). |
| const context = { | ||
| // EnvironmentType of the Local Environment | ||
| envName: "local" as EnvironmentType, | ||
| // ConfigId of the Local Environment | ||
| configId: "local-31337-0" as ConfigId, | ||
| // One of the pre-funded accounts in the Local Environment (https://github.com/fermionprotocol/contracts/blob/main/e2e/accounts.ts) | ||
| privateKey: | ||
| "0xa2e78cd4c87191e50d6a8f1610b1cf160b17216e9090dde7a92960a34c310482", | ||
| // Local Environment RPC Node | ||
| rpcNode: "http://localhost:8545", | ||
| // ERC20 token deployed on Local Environment | ||
| exchangeToken: "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1", | ||
| }; |
There was a problem hiding this comment.
This example also hard-codes a private key in context.privateKey. Even for local-only demos, it’s safer to require an env var (e.g. PRIVATE_KEY) and keep committed examples free of secrets to avoid copy/paste into real environments.
| const createOfferResult = await tools.create_offer.execute( | ||
| { | ||
| price: "1", | ||
| sellerDeposit: "0", | ||
| buyerCancellationPenalty: "0", | ||
| quantityAvailable: 99, | ||
| validFromDateInMS: Date.now(), | ||
| validUntilDateInMS: Date.now() + 1000 * 60 * 60 * 24, // 1 day | ||
| voucherRedeemableFromDateInMS: Date.now(), | ||
| voucherRedeemableUntilDateInMS: 0, | ||
| disputePeriodDurationInMS: 1000 * 60 * 60 * 24 * 7, // 7 day | ||
| voucherValidDurationInMS: 1000 * 60 * 60 * 24 * 7, // 7 day | ||
| resolutionPeriodDurationInMS: 1000 * 60 * 60 * 24 * 7, // 7 day | ||
| metadataUri, | ||
| metadataHash, | ||
| }, |
There was a problem hiding this comment.
The create_offer tool call omits configId and signerAddress. Per the MCP server docs in this PR, state-changing tools require both, so this example will fail against the real server. Include configId and the signer’s address in the arguments (and keep it consistent with the metadata storage call).
| environment: | ||
| - ENV_NAME=local | ||
| - CONFIG_ID=local-31337-0 | ||
| - PRIVATE_KEY=0x316b234f5fea007dcc40404188b588fb90cb9bb1e33fc163e212eab2f8565293 # ACCOUNT_9 from ./contracts/accounts.js |
There was a problem hiding this comment.
meta-tx-gateway is configured with a real-looking PRIVATE_KEY value committed into the example compose file. Even for local-only keys, this is risky and encourages copying secrets into source control. Replace with a placeholder and document how to provide it via env / .env at runtime.
| - PRIVATE_KEY=0x316b234f5fea007dcc40404188b588fb90cb9bb1e33fc163e212eab2f8565293 # ACCOUNT_9 from ./contracts/accounts.js | |
| # Provide META_TX_GATEWAY_PRIVATE_KEY at runtime, e.g. via shell env or a local .env file. | |
| # Example .env entry (do not commit real keys): META_TX_GATEWAY_PRIVATE_KEY=0xYOUR_LOCAL_PRIVATE_KEY | |
| - PRIVATE_KEY=${META_TX_GATEWAY_PRIVATE_KEY} |
| import { createMcpClient } from "./create-mcp-client"; | ||
| import { checkSellerEntity } from "./seller-entity-creation"; | ||
| import { ReturnTypeMcp } from "../../../src/common/mcp-server/mcpTypes"; | ||
| import { signTransaction } from "./sign-transaction"; | ||
|
|
There was a problem hiding this comment.
This script imports ReturnTypeMcp from ../../../src/common/mcp-server/mcpTypes, but docs/agentic-commerce/src/common doesn’t exist in this repo snapshot. To keep the example runnable/portable, avoid importing internal types from the main codebase here; define a minimal local type for the tool result or use the MCP SDK’s public types.
| .description("Sign a transaction using a private key") | ||
| .command("createMcpClient") | ||
| .action(async () => { await createMcpClient() }); | ||
|
|
||
| program | ||
| .name("runit") | ||
| .description("Sign a transaction using a private key") | ||
| .command("createSellerEntity") | ||
| .action(async () => createSellerEntity()); | ||
|
|
||
| program | ||
| .name("runit") | ||
| .description("Sign a transaction using a private key") | ||
| .command("createOffer") | ||
| .action(async () => createOffer()); | ||
|
|
||
| if (require.main === module) { | ||
| program.parse(); |
There was a problem hiding this comment.
The CLI wiring here looks inconsistent with the usage comments in the other example files (they suggest npx ts-node runit.ts -- createOffer, but Commander subcommands are typically invoked as npx ts-node runit.ts createOffer). Consider updating either this command registration or the usage comments so users can run the examples without trial-and-error, and avoid repeating .name()/.description() for each subcommand on the same program instance.
| .description("Sign a transaction using a private key") | |
| .command("createMcpClient") | |
| .action(async () => { await createMcpClient() }); | |
| program | |
| .name("runit") | |
| .description("Sign a transaction using a private key") | |
| .command("createSellerEntity") | |
| .action(async () => createSellerEntity()); | |
| program | |
| .name("runit") | |
| .description("Sign a transaction using a private key") | |
| .command("createOffer") | |
| .action(async () => createOffer()); | |
| if (require.main === module) { | |
| program.parse(); | |
| .description("Sign a transaction using a private key"); | |
| program | |
| .command("createMcpClient") | |
| .action(async () => { | |
| await createMcpClient(); | |
| }); | |
| program | |
| .command("createSellerEntity") | |
| .action(async () => createSellerEntity()); | |
| program | |
| .command("createOffer") | |
| .action(async () => createOffer()); | |
| if (require.main === module) { | |
| const argv = process.argv.includes("--") | |
| ? process.argv.filter((arg, index) => !(arg === "--" && index > 1)) | |
| : process.argv; | |
| program.parse(argv); |
| import { viem } from "@goat-sdk/wallet-viem"; | ||
| import { generateText } from "ai"; | ||
| import { createWalletClient, http } from "viem"; | ||
| import { privateKeyToAccount } from "viem/accounts"; | ||
| import { polygonAmoy } from "viem/chains"; | ||
|
|
||
| import { getOnChainTools } from "../adapters/vercel-ai"; | ||
| import { bosonProtocolPlugin } from "../boson-protocol.plugin"; |
There was a problem hiding this comment.
These examples import getOnChainTools and bosonProtocolPlugin via relative paths (../adapters/vercel-ai, ../boson-protocol.plugin), but those modules don’t exist in this repo snapshot, so the example is not runnable. If this repo is intended to host runnable docs, switch the imports to the published package entrypoints (as described in the plugin README) or include the missing adapter/plugin sources here.
| import { viem } from "@goat-sdk/wallet-viem"; | |
| import { generateText } from "ai"; | |
| import { createWalletClient, http } from "viem"; | |
| import { privateKeyToAccount } from "viem/accounts"; | |
| import { polygonAmoy } from "viem/chains"; | |
| import { getOnChainTools } from "../adapters/vercel-ai"; | |
| import { bosonProtocolPlugin } from "../boson-protocol.plugin"; | |
| import { getOnChainTools } from "@goat-sdk/adapter-vercel-ai"; | |
| import { viem } from "@goat-sdk/wallet-viem"; | |
| import { bosonProtocolPlugin } from "@bosonprotocol/goat-sdk-plugin"; | |
| import { generateText } from "ai"; | |
| import { createWalletClient, http } from "viem"; | |
| import { privateKeyToAccount } from "viem/accounts"; | |
| import { polygonAmoy } from "viem/chains"; |
…ce repo private for now)