MCP server
For every verified site, Sill runs a per-site Model Context Protocol (MCP) server at its edge, over Streamable-HTTP transport. MCP clients can connect to the site’s MCP endpoint to discover and invoke the site’s exposed skills.
Endpoint
Section titled “Endpoint”POST https://edge.sill.so/v1/mcp/{site_key}The transport is Streamable-HTTP, as defined in the MCP specification.
What it implements
Section titled “What it implements”initialize— the MCP handshake. Returns the server’s protocol version and capabilities.tools/list— returns the site’s exposed skills as MCP tools. The tool set is backing-filtered — only skills the site actually exposes through a wired backing appear here (the same set the agent card advertises).tools/callinvocations are recorded in the site’s signed audit envelope.
Example — initialize
Section titled “Example — initialize”A minimal MCP initialize request, posted to a verified site’s MCP endpoint:
POST /v1/mcp/SITE_KEY HTTP/1.1Host: edge.sill.soContent-Type: application/jsonAccept: application/json, text/event-stream
{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-03-26", "capabilities": {}, "clientInfo": { "name": "example-client", "version": "0.0.0" } }}Replace SITE_KEY with the site key issued for the verified domain.
Scope filtering (tools/list)
Section titled “Scope filtering (tools/list)”An agent can narrow the tools returned by tools/list to a declared subset by including an optional params._meta.sill_scope array of skill_id strings in the request. The server returns the intersection of (a) the site’s enabled, backed skills and (b) the declared scope. This lets an agent operating at least-privilege — for example a research-only client that never intends to check out — avoid learning the identifiers of skills it does not plan to call.
Scope filtering is a discovery-only signal. It does not gate tools/call. The mandate + policy pipeline remains the authorization surface for every invocation; an agent that calls a skill outside its declared scope hits that pipeline unchanged.
Request shape
Section titled “Request shape”// tools/list with declared scopeconst request = { jsonrpc: '2.0', id: 42, method: 'tools/list', params: { _meta: { sill_scope: ['browse_catalog', 'check_availability'], }, },};On a site with the seven default skills enabled, this request returns two tools (browse_catalog, check_availability) instead of all seven. _meta is the MCP-reserved extension namespace; the sill_ prefix on sill_scope marks it as Sill-defined so it will not collide with other server extensions.
Response shape
Section titled “Response shape”The response is a standard MCP tools/list result. The tools[] array is a subset of what an unscoped request would return; no new fields are added.
{ jsonrpc: '2.0', id: 42, result: { tools: [ { name: 'browse_catalog', description: '...', inputSchema: { /* ... */ } }, { name: 'check_availability', description: '...', inputSchema: { /* ... */ } }, ], nextCursor: null, },}Fail-open semantics
Section titled “Fail-open semantics”The filter is fail-open. Any of the following returns the site’s full enabled-skill list, byte-identical to the unscoped behavior:
paramsabsent, or not an object._metaabsent, or not an object.sill_scopeabsent, or not an array.sill_scopepresent but every entry is invalid (all dropped by validation — see below).
Validation rules
Section titled “Validation rules”Each entry in sill_scope is validated independently. Entries that fail validation are silently dropped; the request is never rejected on the basis of an invalid scope entry.
| Rule | Behavior |
|---|---|
Element type must be string | Non-strings dropped. |
skill_id shape: /^[a-z][a-z0-9_]*$/ | Non-matching entries dropped. |
| Maximum length: 64 characters per entry | Longer entries dropped. |
| Maximum array length: 32 entries | Entries beyond the first 32 truncated. |
The silent-drop discipline is deliberate. Surfacing a per-entry diagnostic would give a probing client a shape-fuzzing oracle for the skill_id validator; the operator-side signal is a structured log line, not a client-visible field.
Skills in sill_scope that are not in the site’s enabled set are silently ignored. The response does not distinguish “this skill exists but is disabled” from “this skill does not exist” — the same anti-fingerprinting posture the edge applies elsewhere.
Discovery-only, by design
Section titled “Discovery-only, by design”initializeis unchanged. No scope is captured at handshake time. The server does not persist per-session scope state; declarations are per-request.tools/callis unchanged. The declared scope has no effect on invocation. Merchant policy remains the authority on what a request is allowed to do.- No feature flag. The filter is additive and fail-open; clients that never send
_meta.sill_scopesee today’s behavior byte-for-byte.
Skill execution
Section titled “Skill execution”- Connector-wired skills (e.g. catalog browse against a wired commerce backend) dispatch through Sill’s connector layer.
- Skills without a wired backing fall back to discovery / observe-only.
- Money-movement skills require a signed mandate and dispatch only when payments are enabled. See the Transactional overview.
Scope of claim
Section titled “Scope of claim”- MCP server responses are not signed. The signed surface is the agent card pointer to the MCP endpoint, not the MCP responses themselves. (See the agent card.)
- The verified surface is live MCP discovery (
initialize+tools/list) and the auditedtools/callrecord. Full MCP skill execution is conditional on the skill’s backing, and money-movement skills additionally require the signed-mandate path.