Platform
An MCP server for GoCommerce
A Go package that exposes a GoCommerce store to AI agents over the Model Context Protocol. Nineteen tools, each calling the same domain service a REST request would — so an agent can do what an operator can, under the same rules, and every change it makes is written to an audit table.
- Platform module
- 3 settings
- 20 tests
- 2 API operations
- ext/mcp
What it does
In the package’s own words: “The agent never gets database access. Every tool calls the same domain service a REST request would, so there is one state machine and one place where an order becomes paid — whether a human, an application or an agent asked for it.”
It mounts one endpoint, POST /api/admin/x/mcp, behind the store’s admin authentication, and speaks JSON-RPC 2.0 — initialize, tools/list, tools/call and ping — at MCP revision 2024-11-05. For a desktop agent that launches the store as a subprocess, mcp.ServeStdio runs the same server over stdin and stdout.
Nine tools read: store_info, store_health, list_products, get_product, list_low_stock_variants, list_orders, get_order, list_customers and sales_report. Ten change things: update_variant_inventory, mark_order_paid, cancel_order, create_fulfillment, mark_order_delivered, create_product, update_product, set_variant_price, create_discount and refund_order.
Configuration
Nothing is required. The endpoint is authenticated by the store’s own admin credentials, so these settings decide what an agent may do; they live in Config only, with no panel card and no environment variable.
| Setting | Environment variable | Required | What it does |
|---|---|---|---|
ServerName | — | No | The name reported to the agent during initialize. Defaults to gocommerce. |
ReadOnly | — | No | Withholds all ten mutating tools. The package suggests it “while you are still deciding how much you trust the agent on the other end.” |
Tools | — | No | Extra tools — name, description, JSON Schema for the arguments, the rights they need, whether they mutate — wired explicitly in main(). There is no discovery, and two tools with one name stop the store starting. |
The module reads its Config struct, not the environment. The variable names are the ones the package’s own example or the reference binary uses; in your own main() you choose where each value comes from. Where a setting has a panel label, the admin’s settings drawer can hold it too, and a value typed there wins over Config.
Setting it up
- Install the modulePass mcp.New to gocommerce.New in your own main(), as below. The reference binary has no flag for it; examples/store/main.go installs it.
- Choose a credentialThe endpoint takes what the admin API takes. A static admin token carries every right; a signed-in operator needs agent.dispatch, which only the owner role holds until it is granted.
- Point the agent at itAn HTTP client posts JSON-RPC to /api/admin/x/mcp with the credential as a bearer token. A desktop agent over stdio needs mcp.ServeStdio(app, m) called in place of ListenAndServe.
- Read what it didEvery mutating call, including one refused for want of a right, is recorded. GET /api/admin/x/mcp/audit lists them, and the admin’s Agent activity screen shows the same list.
main.go
import (
"github.com/itswadesh/gocommerce/core"
"github.com/itswadesh/gocommerce/ext/mcp"
)
app, err := gocommerce.New(cfg, mcp.New(mcp.Config{
ServerName: "example-store",
// The ten mutating tools stay hidden until you switch this off.
ReadOnly: true,
})) The package doc’s example with the server name examples/store/main.go gives it, and ReadOnly switched on as a cautious start. cfg is your gocommerce.Config; the endpoint is then POST /api/admin/x/mcp. Import path github.com/itswadesh/gocommerce/ext/mcp.
How it works
-
The same services as REST
Each tool calls the domain service its REST route calls, so an agent cannot reach a state a person could not, and cannot skip a rule by coming in through a different door.
-
Rights, per tool
One route dispatches every tool, so each tool names the rights its REST equivalent needs — orders.refund for refund_order, catalog.write for set_variant_price — and they are checked against the signed-in operator on every call.
-
Errors an agent can use
A tool that fails returns its error as content with isError set: “that order is already shipped” is an answer. A call refused for want of a right comes back as a JSON-RPC error instead.
-
An audit table
The module owns one table, mcp_audit: the tool, its arguments, ok or error, and when. Every mutating call is written, including a refused one. The right to read it, agent.read, is separate from the right to act.
-
Read-only, visibly
tools/list marks each tool with readOnlyHint, an annotation from a later MCP revision that older clients ignore. Under ReadOnly the mutating tools are not listed at all.
-
Stdio for desktop agents
mcp.ServeStdio reads one JSON-RPC message per line from stdin and answers on stdout. It runs with the bootstrap credential, so every tool the Config allows is available.
What it does not do
Read these before an order depends on it. No store is known to run GoCommerce in production yet, so these come from the code, not from anyone’s experience.
- No flag, no quick startNeither the Docker quick start nor the reference binary installs it. Using it means a main() of your own.
- Tools onlyThe server advertises revision 2024-11-05 and answers initialize, ping, tools/list and tools/call. Resources, prompts and change notifications are not implemented.
- Plain POST, one message at a timeEach request is one POST answered with one JSON body. There is no server-sent event stream, no session id and no batching, so a client that needs any of those will not connect.
- The static token is not narrowedAn agent holding the static admin token has every right, and the per-tool checks do not apply to it. ReadOnly is the one switch that holds such an agent back.
- Reads leave no trailOnly mutating calls reach mcp_audit. What an agent read — customers, orders, sales — is not recorded by the module.
- No tools from other modules yetConfig.Tools takes extra tools, but no other module in the repository ships any today. Each one you want exposed is one you write.
FAQ
Questions about the MCP module
Which agents can use it?
Any MCP client that sends JSON-RPC over HTTP POST with a bearer token, or one that launches a program and talks over stdio — the second needs a main() that calls mcp.ServeStdio. The repository’s tests drive it with a scripted agent, not with a particular product.
Can the agent touch the database?
No. No tool runs SQL or holds a database handle; each calls a domain service, the same one a REST route calls. The only table the module writes is its own audit log.
How do I stop an agent refunding orders?
Run it with ReadOnly, which withholds every mutating tool, or give the agent a signed-in operator whose role lacks orders.refund — refund_order checks that right on every call. A static admin token ignores roles, so it is the wrong credential for a limited agent.
Does this mean agents can shop at the store?
No. This MCP server is for operating the store — catalogue, stock, orders, refunds. GoCommerce has no support for agentic commerce protocols such as ACP, UCP or AP2, which are about agents buying.
Source
Everything on this page is read from ext/mcp in the GoCommerce repository, MIT licensed. When this page and the code disagree, the code is right and this page is out of date.
Try it against a store of your own
The one-command stack gives you GoCommerce’s API and admin on your own machine in minutes. Add this module to it and try it on test orders before a real one depends on it.