Skip to content
Back to skills

Serve Via Ucp

ASecurity

Set up a merchant's own backend to serve UCP/MCP commerce to shopping agents — detect the stack, install portage-ucp (+ a platform adapter), write the initializer, mount the manifest/webhook endpoints, and verify the live manifest. Use when asked to expose a store over UCP, add AI-agent checkout to a store, integrate portage-ucp into an app, or self-host a /.well-known/ucp endpoint. Seller-side counterpart to shop-via-ucp. Enforces three guardrails — never write a permissive authenticator, ne...

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 11, 2026
ai-agentsrailsgitbackendsecurity

Works with

  • cli
  • mcp

Security analysis

A100/100

Pro scans all 6 files and shows the line behind each finding

Scanned October 11, 2026

npx -y skills add tomtom87/Portage --skill serve-via-ucp --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Serve Via Ucp?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Serve Via Ucp
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tomtom87-serve-via-ucp/badge)](https://www.skillsdirectory.com/skills/tomtom87-serve-via-ucp)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: serve-via-ucp
description: Set up a merchant's own backend to serve UCP/MCP commerce to shopping agents — detect the stack, install portage-ucp (+ a platform adapter), write the initializer, mount the manifest/webhook endpoints, and verify the live manifest. Use when asked to expose a store over UCP, add AI-agent checkout to a store, integrate portage-ucp into an app, or self-host a /.well-known/ucp endpoint. Seller-side counterpart to shop-via-ucp. Enforces three guardrails — never write a permissive authenticator, never commit credentials, always run doctor before declaring done.
---

# Serving commerce via UCP/MCP

You are setting up a merchant's own backend to be a UCP/MCP commerce server — the
seller side, not the shopper side (`shop-via-ucp` is the counterpart for acting as a
buyer's agent). The scripts in `scripts/` do the mechanical parts; you drive the
sequence and make the judgment calls a script can't (which adapter gem fits, what the
authenticator should actually check, whether the manifest looks right).

## Guardrails — apply these every time, no exceptions

1. **Never write a permissive authenticator or rate limiter.** The unconfigured
   defaults (`UnconfiguredAuthenticator`, `NullRateLimiter`) reject-by-default /
   never-limit on purpose (see portage-ucp's README, "Security hooks"). If you don't
   know what the real auth check should be, leave the TODO in place and say so — don't
   write `->(context) { true }` just to make `doctor.sh` stop complaining.
2. **Never commit credentials.** Every secret (webhook HMAC secret, PSP keys, platform
   admin tokens) is `ENV.fetch("...")` in the initializer, never a literal string —
   including in examples you write for the user. If a `.env` file is involved, confirm
   it's gitignored before touching it.
3. **Always run `doctor.sh` before declaring the setup done.** A manifest that responds
   over HTTP doesn't mean the setup is safe — `portage doctor` (see `portage-cli`)
   catches the specific footguns nothing else does: unconfigured auth/rate-limiting
   still in place, missing signing keys, missing payment handlers, a capability
   half-implemented (some actions overridden, others still raising
   `NotImplementedError`).

## Sequence

1. **Detect the stack** — `scripts/detect_stack.sh` (run from the app's root). Reports
   framework (Rails vs. plain Rack), which `portage-ucp*` gems are already bundled, and
   whether an `Adapter` subclass already exists. Read-only.
2. **Pick or write an Adapter.** If `detect_stack.sh` found none and no bundled
   platform gem fits (Shopify/Wix/WooCommerce/BigCommerce/Magento/Etsy/Instagram —
   see portage-ucp's README capability matrix for what each actually implements),
   scaffold one with `portage generate adapter Foo` (see portage-cli) rather than
   hand-rolling the boilerplate.
3. **Install** — `scripts/install.sh [adapter-gem-name]`. Adds `portage-ucp` (+ the
   adapter gem, if named) to the Gemfile, then either runs
   `rails generate portage:ucp:install` (Rails apps) or copies the same initializer
   template to `config/initializers/portage_ucp.rb` directly (plain Rack). Idempotent —
   safe to re-run.
4. **Fill in the initializer.** Every TODO in `config/initializers/portage_ucp.rb`
   (authenticator, rate_limiter, business, signing_keys, ...) needs a real value or a
   deliberate "leave unset" decision — this is the step guardrail 1 is about. Mount
   `Rack::ManifestEndpoint` and `Rack::WebhookEndpoint` per the routes the generator
   added (or portage-ucp's README, "Usage", if routing by hand).
5. **Run `doctor.sh [require-file] [adapter-class-name]`** (default require path:
   `config/environment`, i.e. Rails boot). Fix every finding it reports — this is
   guardrail 3. Don't proceed to verify.sh with known findings unaddressed unless the
   user explicitly accepts the risk.
6. **Boot the app** (however this app normally starts — this skill doesn't guess that
   part), then **verify.sh [base-url]** (default `http://localhost:3000`) — curls
   `/.well-known/ucp` and checks it nests `version`/`business`/`services`/
   `capabilities` under a top-level `ucp` object, with at least one advertised capability.
7. **Run the conformance kit** — `scripts/conformance.sh [spec-path]`. Fails loudly
   with a worked example if no spec includes `"a portage adapter"` yet (see
   portage-ucp-etsy's conformance spec in the Portage repo for a real one to copy the
   shape of); otherwise runs it. This is the same shared-examples kit
   `rake conformance` gates the bundled adapters on — see portage-ucp's
   `lib/portage/ucp/rspec.rb`.

## What "done" looks like

`doctor.sh` reports no findings (or the user explicitly accepted the remaining ones),
`verify.sh` confirms a well-formed live manifest, and `conformance.sh` passes against
the merchant's own `Adapter`. Report which of these three actually ran and passed —
don't claim the integration is safe on the strength of "the server responds."

Files in this skill

  • SKILL.md4.9 KB
  • scripts/conformance.sh1.1 KB
  • scripts/detect_stack.sh1.7 KB
  • scripts/doctor.sh684 B
  • scripts/install.sh2 KB
  • scripts/verify.sh1.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.