Status: pre-implementation working draft (Step 2 of 6 per the underlying standards playbook); zero conformant servers exist yet.
Canonical URL: https://webgcp.org/spec/v0.1/
Spec home: https://webgcp.org · Source repo: pending working-group convening (see §11.3); v0.1 markdown is the authoring artifact.
License: Spec text under CC-BY-4.0; schemas and fixtures under Apache-2.0
This is not from any standards body. It is a public proposal authored at webgcp.org, intended for eventual donation to a neutral foundation after interop is demonstrated.
Peer document: an implementation-shaped companion (BigQuery-backed reference instance, catalog-internal) accompanies this spec at standards/webgcp-standard.md in the maintaining catalog. The two are normative in different registers: this document specifies the protocol; the companion specifies the reference instance's conformance to it. Neither supersedes the other.
Editorial revision: v0.1-ed-2026-05-19 — non-normative only: §1.3 WebMCP-row accuracy refresh, §12 open-questions #5/#10 resolved, §16 review item ticked. The normative body, all /spec/v0.1 + /schemas/.../v0.1.json text/schemas, the conformance fixtures, and the .well-known/webgcp descriptor are byte-unchanged (RFC-errata-style; §10.4 normative immutability preserved).
| If you are a... | Start at... |
|---|---|
| Implementer who wants to ship a webGCP server | §4 (Conformance Levels), §5 (Normative Requirements), §6 (Wire Format), §9 (Conformance Tests) |
| Agent author who wants to consume webGCP | §3 (Mental Model), §6 (Wire Format), §7 (Bundle Contracts) |
| Standards reviewer / governance reader | §1 (Why), §2 (Design Principles), §10 (Versioning), §11 (Governance) |
| Architect comparing to MCP / WebMCP | §1.3 (Relationship to neighbors), §3 (Mental Model) |
| Skeptic | §1.4 (Known weaknesses) and §12 (Open questions) |
If you read nothing else, read §0 and §1.3.
v0.1 working draft. One L0-conformant reference instance is live as of 2026-05-16 at https://the-ai-news.web.app — server descriptor at /.well-known/webgcp, dynamic query endpoint at POST /webgcp/v0/query, conformance fixtures WGCP-L0-001 (happy path, 11 assertions) and WGCP-L0-002 (out-of-scope, 7 assertions) both pass against the live endpoint. L1–L4 are design targets; no L1+ implementation exists anywhere yet. A larger BigQuery-backed reference instance for L1+ conformance is in active build in the MyParallel catalog (M3a backend MCP server).
A ≥3-month production soak of the L0 reference instance is the gate to Step 3 of the underlying standards playbook — the clock started 2026-05-16; earliest Step 3 exit is 2026-08-16. Do not cite this document for L2+ production conformance claims until v0.2.
Anyone is invited to read, file issues, or build their own conformant server. Feedback is the input we need most. Per-section maturity flags throughout the document distinguish drafted target contract from running implementation.
The acronym GCP in webGCP stands for Graph Context Protocol. This document specifies the Context layer — manifests, bundle contracts, typed responses with provenance, applicability checking, L0–L4 conformance for an agent↔server query.
This disambiguation is load-bearing for v0.1 because at least one prior usage in adjacent literature expanded GCP as Graph Commerce Protocol. That usage is not what this document specifies. The two layers are different protocols at different concerns; sharing a domain (webgcp.org) and acronym is a coordination choice, not a merge.
webGCP is the protocol for an agent network that runs on top of an underlying substrate. It is crucial for implementers to distinguish the two:
MyParallel is the reference substrate. However, webGCP is fully store-agnostic. Any substrate that provides the four required properties can host a fully conformant webGCP server.
webGCP strictly divides agentic operations into two layers: Context and Commerce.
This v0.1 specification strictly covers the Context Layer. The Commerce layer is explicitly out of scope for this document and will be governed by future extensions and neighbor standards (e.g., AP2, x402).
While the reference instance may run both layers simultaneously, implementers evaluating this v0.1 specification should focus solely on Context-layer conformance. Any references to Commerce endpoints, receipt ledgers, or settlement wallets in examples are informative previews of v0.2+, not normative v0.1 requirements.
Agents in production today behave like this: an agent gets a task, decides it needs information, searches, retrieves, evaluates, decides it needs more, searches again, fragments the picture together, loops. Most of the token and latency budget is spent before the model attempts the task. This is the rediscovery tax.
The dominant fix has been better retrieval: better embeddings, better chunking, bigger context windows, smarter rerankers. None of these address the underlying problem, which is that agents are missing a typed contract for the knowledge they need. They ask for "relevant text" and get a probabilistic pile. They cannot say "give me a customer record, a policy, and the prior-ticket history, with provenance, within 500 ms, only if my caller has permission, and refuse if any required field is stale."
webGCP defines that contract.
A small set of typed objects, served at predictable URLs, with provenance on every field, can be the substrate for agent-ready knowledge across the web:
.well-known to make any compliant server reachable without prior coordination.The protocol is implementation-neutral. A compliant server can use BigQuery, Snowflake, Postgres+pgvector, a graph database, a knowledge engine like Pinecone Nexus, or a hand-rolled store. The protocol constrains the shapes agents see, not the stores operators use.
webGCP composes with, does not replace:
| Standard | What it does | What webGCP adds |
|---|---|---|
| MCP (Model Context Protocol, AAIF/Linux Foundation) | Standardizes how AI clients call tools and resources | A typed knowledge layer above tools — applicability, provenance, bundle contracts |
WebMCP (W3C Web ML CG draft; navigator.modelContext — imperative registerTool + declarative HTML; Chrome early-preview 2026; no centralized discovery, requires an open tab) |
Browser-side: how an open webpage exposes tools to an in-page agent | Server-side persistent knowledge, federation, and the discovery layer WebMCP deliberately omits — beyond the active page |
| x402 (payment) | How an agent settles for a tool/resource call | webGCP is settlement-agnostic; carries x402 references in receipts when present |
| AP2 (mandate / authorization) | How an agent proves it has authority to act | webGCP consumes AP2 assertions in the invoker identity field |
| Schema.org | Vocabulary for entities on the web | webGCP can carry Schema.org types in bundle fields; the protocol is vocabulary-neutral |
A webGCP server that also exposes its tools via MCP and its in-page surface via WebMCP is the expected pattern. Nothing in this spec prevents that.
Stated up front so reviewers don't have to find them:
the-ai-news.web.app (see §13.1 — Cloud Function webgcp-query in my-ai-00003, 8 fixture articles, both conformance fixtures pass). L1+ (vector search, multiple primitives, versioned artifacts, refresh SLAs) requires the larger MyParallel BQ-backed instance — myparallel.catalog (19 tables, 230 agencies + 29 skills with 3072-d embeddings) is live but its query endpoint (M3a) is undeployed.Drawn from what worked in prior standards and what failed.
canonical | derived | inferred. Inferred values never auto-promote..well-known/webgcp. Aggregators MAY exist; they are not the protocol.These come from MCP's first 18 months, WebMCP's W3C path, Schema.org's adoption arc, the OCI's container standard, and a few cautionary tales.
| Lesson source | What we took from it | Where it lands |
|---|---|---|
| MCP, governance maturation — every spec change required full core-maintainer review; bottlenecked the project | Build a contributor ladder and working-group delegation in from v0.1 | §11 |
| MCP, transport gaps surfaced only in production — stateful sessions fought load balancers | Define statelessness and idempotency as protocol-level requirements, not server-side conventions | §2.1 #2, §6.5 |
| MCP, security incidents (prompt injection, tool-name spoofing) — adoption ran ahead of governance | Treat retrieved content as untrusted input at the protocol level; mandate signed manifests; require typed failures rather than free-form errors | §5.10, §8.3 |
| Schema.org adoption — won by being lenient and useful, not by being strict | Conformance levels (L0 → L4) so small implementations can ship a useful subset | §4 |
| Schema.org — common vocabulary became a "dictionary" people drew from | Manifest fields and bundle field types are designed to be referenced selectively, not all-or-nothing | §5.2, §5.3 |
| OCI (Open Container Initiative) — "minimal and stable, enable innovation above and around it" | Core spec deliberately small; capabilities like graph traversal, agentic search, semantic-layer querying live in extensions | §2.1 #7 |
| OCI — backward compatibility was an explicit founding value | Once v1.0 ships, breaking changes require a major version | §10 |
| WebMCP at W3C — Community Group is fast; Recommendation track is slow | Don't pursue Recommendation status until interop is real. Community Group or Linux Foundation incubation is the right early target | §11 |
| Linked Data / Semantic Web — over-specified, under-adopted | We do not require RDF, SPARQL, or any specific ontology. Vocabulary is opt-in | §5.2 |
| JSON Schema — became ubiquitous by being usable, not by being blessed | Ship the schemas at stable URLs from day one; treat them as the authoritative artifact alongside the prose | §9 |
| HTTP, JSON, OAuth — won by being implementable in a weekend | Reference server in <1000 lines is a v0.1 release goal | §13 |
| HTTPS / RFC 8446 (TLS 1.3) — IETF rough-consensus-and-running-code | Two interoperable implementations required before any feature reaches "stable" | §10.3 |
| AAIF formation around MCP — donation came after adoption, not before | Don't form a foundation prematurely; donate when interop demands neutrality | §11 |
| Term | One-liner |
|---|---|
| Knowledge Base (KB) | A bounded collection of source material behind a retrieval interface. |
| Manifest | An agent-readable contract describing what a KB is for, when it applies, what inputs it needs, what it returns. |
| Bundle Contract | The typed shape an agent declares it needs in order to do its task. |
| Knowledge Artifact | A pre-compiled, persistent, task-shaped representation of source data. |
| Trace | The auditable record of a query: which KBs were consulted, what was retrieved, with what provenance and confidence. |
| Layer | Scope | Governed by |
|---|---|---|
| L-page — WebMCP | One webpage's in-page tools | W3C WebMCP CG |
| L-server — webGCP | One implementation's persistent registry of KBs and bundles | This document |
| L-network — Federation | Multiple webGCP servers discovering and querying each other | §8 of this document |
L-server is the heart of webGCP. L-page interop is at the seam with WebMCP (§7.6). L-network interop is federation (§8).
+-------------------------+
| Agent (any framework) |
+------------+------------+
| declares Bundle Contract,
| sends KL-Query
v
+------------+------------+
| webGCP Client SDK |
+------------+------------+
|
v
+----------------------------+----------------------------+
| webGCP Server |
| |
| [Manifest Registry] [Applicability Planner] |
| | | |
| v v |
| [Composable Retriever] -> KBs (artifacts, stores) |
| | |
| v |
| [Response Assembler] -> typed Bundle + Trace |
+----------------------------+----------------------------+
| optional federation
v
+------------+------------+
| Peer webGCP Servers |
+-------------------------+
Per §2.2, lessons from Schema.org and OCI: lenient cores get adopted; strict cores get bypassed. webGCP defines five conformance levels. A server claims the highest level it passes.
| Level | What it requires | Use case | v0.1 status |
|---|---|---|---|
| L0 — Reader | Single KB, single bundle contract, manifest, typed responses, provenance, ACL, typed failures, DNS-layer SVCB discovery at _webgcp.<host> (§5.1.1) |
Internal policy bot; the smallest useful deployment | fixtures live + passing (WGCP-L0-001, L0-002, L0-003 — webgcp.org self-conformant 2026-05-16) |
| L1 — Compiled | + Multiple KBs, multiple primitives (at least vector + direct lookup + one structured), versioned artifacts, refresh SLAs | Production single-org deployments | fixtures in progress |
| L2 — Governed | + PII classification, audit retention, signed manifests, right-to-delete, ACL inheritance | Regulated industries, enterprise rollouts | design target |
| L3 — Federated | + .well-known/webgcp discovery, cross-server trust, identity propagation, content-origin tagging |
Cross-org and partner integrations | design target |
| L4 — Composable | + Manifest changefeed, eval-gated publishing, deterministic conflict resolution, cross-KB transactions | Ecosystem-scale deployments and aggregators | design target |
Levels are cumulative: L2 implies L1 implies L0. Each level has a conformance suite (§9).
A server's .well-known/webgcp document MUST declare its level. Levels are self-declared and externally verifiable against the conformance suite.
The keywords MUST, MUST NOT, SHOULD, SHOULD NOT, MAY, REQUIRED, OPTIONAL in this document are to be interpreted as described in RFC 2119 and RFC 8174.
A webGCP server MUST publish a server descriptor at /.well-known/webgcp:
{
"spec_version": "0.1",
"conformance_level": "L1",
"server_id": "urn:webgcp:example.com",
"operator": "Acme Corp",
"endpoints": {
"query": "https://api.example.com/webgcp/v0/query",
"manifests": "https://api.example.com/webgcp/v0/manifests",
"schemas": "https://api.example.com/webgcp/v0/schemas"
},
"supported_features": ["bundle_contracts", "vector_hybrid", "direct_lookup"],
"contact": "webgcp@example.com",
"trust_roots": ["https://example.com/.well-known/webgcp/keys.json"]
}
The descriptor MUST be reachable over HTTPS. It MUST be served with Content-Type: application/json. It MUST be cacheable for at least one hour and no more than 24 hours.
A webGCP server MUST publish an SVCB record (DNS RR TYPE 64) at the name _webgcp.<host> for each <host> at which it serves the descriptor (§5.1):
_webgcp.<host>. 3600 IN SVCB 1 <host>.
webgcp-version, webgcp-conformance-level, and webgcp-descriptor-path once IANA registrations land.The DNS record gives agents a sub-millisecond binary signal — "does this domain host webGCP?" — without an HTTPS round-trip. It also lets ecosystem-scanning agents discover webGCP operators across a population of domains at the DNS layer.
Restricted-domain caveat. Operators who do not control authoritative DNS at their conformance hostname (notably: subdomains of .web.app, .firebaseapp.com, .netlify.app, .vercel.app, GitHub Pages .github.io, and similar managed-platform autodomains) MUST NOT claim plain L0 conformance. They MAY instead claim L0-restricted-domain and MUST set conformance_level: "L0-restricted-domain" in their /.well-known/webgcp descriptor, with a restricted_domain_reason field naming the platform. To clear this caveat and claim full L0, the operator attaches a domain whose DNS they control (custom domain via their registrar) and publishes the SVCB record there.
Why this is in L0 (not L1+). Per §2.2's "minimal stable core" + "rough consensus and running code" principles: the cheapest moment to add a new MUST is when the conformance suite is small. The SVCB profile is a 3-line DNS-layer signal; making it an L0 requirement today costs each implementer a single registrar action and gains the entire ecosystem a frictionless discovery path. Adding it after the spec has hundreds of implementations would require a v2.0 break.
Verification. The conformance fixture WGCP-L0-003 verifies the DNS record + the follow-up HTTPS descriptor fetch. Implementations may run it via DNS-over-HTTPS (DoH) against any compliant public resolver (e.g., https://dns.google/resolve?name=_webgcp.<host>&type=64 or https://cloudflare-dns.com/dns-query?name=_webgcp.<host>&type=64) — no dig-equivalent local tooling required.
Operator caveat (empirical, 2026-05-16). Google DoH (dns.google/resolve) has been observed to return an empty Answer array for SVCB queries even when the record is correctly provisioned at authoritative DNS. Cloudflare DoH (cloudflare-dns.com/dns-query) returns the record correctly. Implementations testing L0-003 SHOULD use Cloudflare DoH as the primary verifier. See SVCB-AT-SQUARESPACE.md for the full operator-facing guide, including the byte-level decoding of RFC 3597 generic-format storage (\# 14 00 01 06 ...) which is wire-equivalent to typed SVCB rendering.
RFC 3597 equivalence (normative). Resolvers MAY render the SVCB rdata in RFC 3597 generic format (\# <rdlength> <hex-octets>); this is wire-equivalent to the typed representation and conformant implementations MUST accept either form when verifying §5.1.1 compliance.
First publicly-deployed L0 host on SVCB (2026-05-16). webgcp.org itself is the first publicly-deployed host honoring §5.1.1. Its own spec-host descriptor at https://webgcp.org/.well-known/webgcp declares this_host_svcb_status: "live 2026-05-16". The L0-003 fixture verifies against itself — an agent doing _webgcp.webgcp.org DNS query gets the SVCB record, follows TargetName to webgcp.org, fetches /.well-known/webgcp, and confirms all 9 L0-003 assertions in sub-millisecond DNS + a single HTTPS GET. The spec is self-conformant.
Every KB MUST have a manifest. The manifest is the meta-knowledge layer: it describes what a KB is for, when it applies, what inputs it needs, and what authority its contents carry.
Manifests MUST validate against the JSON Schema at https://webgcp.org/schemas/manifest/v0.1.json (canonical URL once stub-published; the v0.1 shape is fully specified in the table below).
Required top-level fields:
| Field | Type | Purpose |
|---|---|---|
manifest_version |
string (semver) | Version of the manifest schema |
kb.id |
URN | Globally unique KB identifier |
kb.owner |
string | Contact / accountable party |
kb.status |
enum | active | deprecated | superseded |
purpose.summary |
string | One-paragraph description |
purpose.declared_capabilities |
string[] | Capability tags |
applicability.in_scope_when |
CEL expression[] | Predicates that make this KB applicable (§5.4.1–5.4.2) |
applicability.out_of_scope_when |
CEL expression[] | Predicates that make it inapplicable (§5.4.3) |
inputs.required |
field[] | Inputs that MUST be known before retrieval |
inputs.on_missing |
map | Per-input fallback strategy |
authority.canonical_sources |
URI[] | Systems of record this KB derives from |
authority.freshness_sla |
duration | Maximum acceptable age of derived facts |
governance.acl_policy_ref |
URN | Reference to the ACL policy |
governance.pii_class |
enum | none | pseudonymous | personal | sensitive |
versioning.manifest_semver |
string | This manifest's own version |
versioning.artifact_index_version |
string | The current artifact build's version |
Manifests MUST be content-addressed (SHA-256 over canonical form). A query MAY pin a manifest hash; if pinned, the server MUST refuse to serve under a different hash.
The full manifest schema will be published at https://webgcp.org/schemas/manifest/v0.1.json. Worked examples will be published at https://webgcp.org/examples/manifests/. (Both URLs are reserved as of v0.1; populated artifacts ship with the L1 conformance package — see §9.1.)
Every agent that issues a webGCP query MUST do so against a named bundle contract. Bundle contracts describe what the agent needs as a typed object.
Bundle contracts MUST validate against the JSON Schema at https://webgcp.org/schemas/bundle/v0.1.json (canonical URL once stub-published; the v0.1 shape is fully specified in the table below).
Each field in a bundle contract carries:
| Attribute | Type | Purpose |
|---|---|---|
name |
string | Dotted path within the bundle |
type |
TypeRef | Scalar, enum, object, list, or reference |
required |
bool | Drives completeness policy |
preferred_source_kb |
URN | Hint to the planner |
primitive_hint |
enum | direct_lookup | hierarchical_tree | vector_hybrid | graph_traversal | semantic_layer |
freshness_sla |
duration | Per-field freshness override |
authority_required |
enum | canonical | derived | any |
on_failure |
enum | hard_fail | fallback | annotate | abstain |
acl_class |
string | ACL category |
pii_class |
enum | PII classification |
Bundle contracts are versioned (semver) and content-addressed. Agents MUST pin a contract version.
A server MUST evaluate each KB's applicability.in_scope_when and out_of_scope_when against the query's filter before retrieving from that KB.
Predicate expressions MUST be written in CEL (Common Expression Language). CEL is chosen for its well-defined type system, deterministic evaluation, side-effect-free semantics, and wide implementation availability (Go, Java, C++, Rust, TypeScript, Python).
Each expression string is a single CEL expression that evaluates to bool. The evaluation environment exposes:
| Variable | Type | Source |
|---|---|---|
filter |
map(string, dyn) |
The query's filter object (§6.3) |
caller |
map(string, dyn) |
Caller identity claims (from auth context) |
now |
google.protobuf.Timestamp |
Server time at evaluation |
Implementations MUST support the CEL standard functions (string, math, list, map, timestamp). Implementations MUST NOT extend the environment with custom functions unless they also declare the extension in their manifest under applicability.cel_extensions[].
in_scope_when and out_of_scope_when are each an array of expression strings. Within a list, predicates compose as implicit AND — all must evaluate to true for the list to match:
in_scope_when: [A, B, C] → A && B && C
out_of_scope_when: [X, Y] → X && Y
To express OR within a single predicate, use CEL's || operator inside one expression string (e.g., filter.channel == "retail" || filter.channel == "wholesale").
A KB's applicability is evaluated as:
in_scope = all(in_scope_when) evaluates to true
out_scope = all(out_of_scope_when) evaluates to true
KB is applicable ⟺ in_scope AND NOT out_scope
If out_of_scope_when matches, the KB is excluded regardless of in_scope_when. This is not configurable — the exclusion always wins.
If in_scope_when is an empty array [], the KB is unconditionally in-scope (vacuous truth) unless excluded by out_of_scope_when.
If out_of_scope_when is an empty array [], no exclusion applies.
If a CEL expression references a key not present in filter, the expression MUST evaluate to false (not error). Implementations MUST use CEL's has() macro or null-safe access (filter.?key) to guard against missing keys, or MUST treat KeyNotFound errors as false at the evaluation boundary.
This means a KB with in_scope_when: ["filter.purchase_channel == 'retail'"] is out-of-scope for a query whose filter does not contain purchase_channel — safe default, no runtime crash.
Example 1 — simple channel gate:
{
"applicability": {
"in_scope_when": ["filter.purchase_channel == 'retail'"],
"out_of_scope_when": ["filter.region == 'SANCTIONED'"]
}
}
Query { "filter": { "purchase_channel": "retail", "region": "US" } } → KB is applicable (in-scope matches, out-of-scope does not).
Query { "filter": { "purchase_channel": "retail", "region": "SANCTIONED" } } → KB is excluded (out-of-scope wins).
Query { "filter": { "purchase_channel": "wholesale" } } → KB is not applicable (in-scope fails).
Example 2 — time-bounded applicability:
{
"applicability": {
"in_scope_when": [
"filter.product_line == 'solar'",
"now >= timestamp('2026-01-01T00:00:00Z')"
],
"out_of_scope_when": []
}
}
Both predicates must hold (implicit AND). The KB becomes applicable only for solar queries after 2026-01-01.
If a CEL expression fails to parse at manifest-load time, the server MUST reject the manifest (validation error). If a well-formed expression produces a runtime error during evaluation (e.g., type mismatch), the server MUST treat that predicate as false and SHOULD log a diagnostic.
If no KB is in-scope for a query, the server MUST return a typed out_of_scope failure (§6.7), not synthesize an answer from related-but-inapplicable KBs.
If a KB is in-scope but the query is missing required inputs declared in its manifest, the server MUST return a typed needs_input failure listing the missing inputs.
This is the protocol-level defense against the "franken-answer" failure mode: locally relevant evidence combined across incompatible applicability frames.
Every value in a response MUST be accompanied by _meta carrying at minimum:
| Field | Purpose |
|---|---|
source_kb |
URN of the originating KB |
source_uri |
Pointer to the specific record / passage |
retrieved_at |
ISO-8601 timestamp |
retriever_version |
Identifier for the retrieval code path |
authority |
canonical | derived | inferred |
confidence |
Float in [0,1] |
manifest_hash |
SHA-256 of the manifest at retrieval time |
Servers MUST NOT return values without _meta. Clients MUST NOT consume values without _meta.
A server MUST tag each value with one of:
authority.canonical_sourcesServers MUST NOT promote inferred values to canonical automatically. Promotion requires an explicit, audited step that is out of scope for the query path.
A server MUST declare in its descriptor which primitives it supports. The core set:
| Primitive | Description |
|---|---|
direct_lookup |
Point read by key |
vector_hybrid |
Vector + lexical (BM25 or equivalent) over passages |
hierarchical_tree |
TOC-with-summaries over long structured documents |
semantic_layer |
Typed query (e.g., SQL via metric layer) against structured data |
graph_traversal |
N-hop traversal over a property graph |
Additional primitives MAY be declared via extension URIs. An L1+ server MUST support at least three primitives including direct_lookup.
Every query MAY carry an Idempotency-Key header. If present:
409 Conflict with a typed failure if the same key is reused with a different query bodyThis is non-negotiable for any query whose response may drive a non-reversible action.
ACL MUST be enforced at retrieval, before any data reaches the response assembler or any model. Output-side redaction is permitted as defense in depth but is not a substitute.
Denied fields MUST be absent from the response, not present-but-redacted. A redactions_applied array MAY be returned in the trace metadata for audit purposes.
Content retrieved from KBs MUST be tagged with content_origin:
| Value | Meaning |
|---|---|
first_party |
Originated within the operator's own canonical sources |
third_party_trusted |
Sourced from a federation peer in the trust list |
third_party_untrusted |
Sourced from public or partner data not in the trust list |
Clients and downstream agents MUST treat third_party_untrusted content as untrusted for the purpose of tool authorization. Instructions embedded in retrieved content MUST NOT be interpreted as authoritative agent commands.
A conformant server MUST NOT:
_metainferred values to canonicalQueries are HTTP POST to the server's query endpoint. Request and response bodies are JSON. Streaming responses use Server-Sent Events (SSE) over HTTPS.
Servers MUST accept Bearer tokens. OIDC and OAuth 2.0 / 2.1 are supported. mTLS is required at L3+ for federation.
The invoker identity carries:
{
"subject": "agent:<id>",
"on_behalf_of": "user:<id>",
"auth_assertion": "<JWT>",
"mandate_ref": "<AP2 reference, optional>"
}
POST /webgcp/v0/query
Content-Type: application/json
Idempotency-Key: 7b3c...
{
"intent": "Triage a refund for ticket T-91823",
"bundle": {
"contract_uri": "urn:agent:support-refund-triage/v3",
"contract_hash": "sha256:..."
},
"filter": { ... domain-specific filters ... },
"invoker": { ... see 6.2 ... },
"scope": {
"allow_kbs": ["urn:webgcp:acme:*"],
"manifest_pins": [
{ "kb": "urn:webgcp:acme:policy/refund", "hash": "sha256:..." }
]
},
"provenance": { "required_fields": ["source_uri", "retrieved_at", "authority"] },
"confidence": { "min_per_field": 0.7 },
"budget": { "latency_ms_p95": 800, "max_tokens": 8000, "max_depth": 3 },
"trace": { "trace_id": "...", "parent_span_id": "..." }
}
{
"status": "ok",
"bundle": {
"<field>": {
"value": <any>,
"_meta": {
"source_kb": "urn:webgcp:acme:crm/customer",
"source_uri": "row://customers/C-104a9",
"retrieved_at": "2026-05-15T19:01:42Z",
"retriever_version": "v0.1.3",
"authority": "canonical",
"confidence": 1.0,
"manifest_hash": "sha256:..."
}
}
},
"completeness": "strict_satisfied",
"trace": { ... },
"content_origin_summary": { "first_party": 6, "third_party_trusted": 1, "third_party_untrusted": 0 }
}
Servers MUST support stateless operation. Any session-like behavior (caches, partial results, etc.) MUST be reconstructable from the request itself (idempotency key, trace ID) — not from server memory. This makes horizontal scaling and load balancing tractable, learning from MCP's transport-scalability pains.
Servers SHOULD honor standard HTTP cache semantics. Manifests have Cache-Control: public, max-age=3600 by default; bundle responses are non-cacheable by default unless the server can prove freshness.
Servers MUST return one of these structured failures rather than free-form errors. Each carries enough structure for the agent to act without parsing English.
status |
When | HTTP code |
|---|---|---|
out_of_scope |
No in-scope KB for the filter | 200 (typed result) |
needs_input |
Required inputs missing | 200 (typed result) |
acl_denied |
Invoker lacks permission | 403 |
conflict_unresolvable |
Sources conflict, no rule resolves | 200 (typed result) |
stale_canonical |
Canonical source missed freshness SLA | 200 (typed result) |
budget_exceeded |
Latency/token ceiling hit | 200 (typed result) |
manifest_mismatch |
Manifest pin failed | 409 |
degraded |
Bundle is degraded; some optional fields missing |
200 (typed result) |
kb_unavailable |
A required KB cannot be reached | 503 |
auth_required |
No valid invoker identity | 401 |
Free-form 4xx/5xx responses without a typed failure body are non-conformant.
A bundle contract is the most important artifact in this protocol from an agent author's point of view. It is the typed signature of what the agent needs to do its job.
The contract is the architecture. Stores follow.
The following bundle contracts will be maintained at https://webgcp.org/examples/bundles/ as canonical reference contracts. Each will come with a manifest, a fixture corpus, and a complete conformance test set. (URL reserved as of v0.1; populated artifacts ship with L1.)
These are not normative for the protocol. They are illustrative and serve as the public conformance corpus.
When a webGCP server has KBs that originate from a WebMCP-advertised webpage, the manifest MUST include a webmcp_origin block:
webmcp_origin:
page: "https://shop.example.com/products/widget"
registered_at: "2026-05-12T..."
webmcp_tools:
- "addToCart"
- "checkInventory"
This is how L-page surfaces appear in the L-server registry. WebMCP defines the in-page contract; webGCP carries it forward into persistent knowledge.
A webGCP server publishes itself at https://<host>/.well-known/webgcp (§5.1). Discovery is link-driven; no central registry is required.
A .well-known/webgcp/peers endpoint MAY list known peer servers. Aggregators / directories MAY exist as external services.
An agent (or planner) MAY issue a query whose scope spans multiple servers. The originating server fans out, validates incoming responses against their published manifests, and assembles the bundle.
Each field's _meta MUST identify the originating server. Cross-server fields are tagged content_origin: third_party_trusted (if the peer is in the trust list) or third_party_untrusted.
| Mechanism | Requirement |
|---|---|
| mTLS | REQUIRED for L3 federation |
| Signed manifests | REQUIRED; trust roots published at .well-known/webgcp/keys.json |
| Identity propagation | Invoker identity MUST travel as a signed assertion; each hop validates |
| Manifest pinning across boundaries | Originating server MUST record the peer's manifest hash at query time |
kb_unavailableFor every normative requirement (§5) and every conformance level (§4), a runnable test fixture will be published at https://webgcp.org/conformance/v0.1/. As of v0.1 (2026-05-16): L0 fixtures live + passing — WGCP-L0-001 (happy path, 11 assertions), WGCP-L0-002 (out-of-scope, 7 assertions), WGCP-L0-003 (DNS-layer SVCB, 9 assertions); 27 assertions total, all pass against webgcp.org's own descriptor + SVCB record (the spec is self-conformant). L1 fixtures in progress, L2–L4 not yet authored. A standard without runnable conformance tests is aspirational; this one will not stay aspirational past L1 completion.
Each test fixture is a JSON file containing:
L0 conformance is verified by a consolidated test suite. While this specification defines 11 distinct normative requirements (across §5.1 through §5.11), the conformance suite safely compresses these into three comprehensive fixtures:
WGCP-L0-001 (11 assertions): Collectively exercises the normative requirements for discovery, applicability gating, provenance tracking, and typed responses.WGCP-L0-002 (7 assertions): Exercises out-of-scope boundaries, rejection handling, and typed failure modes.WGCP-L0-003 (9 assertions): Exercises DNS-layer SVCB discovery (§5.1.1), descriptor fetch, and spec-host self-conformance.An implementation is L0-conformant when it passes all three fixtures, successfully validating all 27 assertions. The reference implementation currently passes all fixtures in production.
A server claims a conformance level by:
https://<host>/.well-known/webgcp/conformance.json with a signed timestampConformance is self-declared. External verification is possible because the tests are public.
| ID range | What it covers |
|---|---|
| WGCP-L0-* | Reader level |
| WGCP-L1-* | Compiled level |
| WGCP-L2-* | Governed level |
| WGCP-L3-* | Federated level |
| WGCP-L4-* | Composable level |
| WGCP-ADV-* | Adversarial / security tests (mandatory at all levels) |
At every level from L1 upward, the adversarial suite MUST pass to claim that level. The suite is specified below and authored in v0.1; the runnable fixtures land with the L1 conformance package. These are not aspirational; they test the security claims of the spec.
| Test | Verifies |
|---|---|
| WGCP-ADV-001 | Prompt injection in retrieved content does not authorize tool calls |
| WGCP-ADV-002 | ACL bypass via field aliasing fails |
| WGCP-ADV-003 | Manifest pin mismatch is rejected |
| WGCP-ADV-004 | Stale-canonical detection triggers |
| WGCP-ADV-005 | Cross-applicability blending is rejected |
| WGCP-ADV-006 | Inferred values are not promoted to canonical |
| WGCP-ADV-007 | Federation: untrusted peer's content is tagged correctly |
webGCP follows semver:
Each manifest, bundle contract, and conformance fixture carries its own semver and is content-addressed. The spec version and the artifact versions evolve independently.
Borrowed from IETF's rough-consensus-and-running-code tradition. Promotion of a feature from v0.x-draft to v1.0-stable requires:
No feature is stable on paper alone. As of v0.1, zero features have cleared this gate; the entire spec is v0.1-draft.
https://webgcp.org/spec/v0.1/ is immutable. Edits go to v0.2, v0.3, etc. The https://webgcp.org/spec/ redirects to the current version.
Schemas at https://webgcp.org/schemas/manifest/v0.1.json are immutable. Same convention.
This is the "stable URLs forever" principle (§2.1 #9) made operational.
Single-author / small-group governance, transparently. The v0.1 source-of-record is at https://webgcp.org/spec/v0.1/. A github.com/webgcp/ organization is pending and will host the issue tracker and conformance fixtures once a working group is convened (see §11.3). Until then, issues and feedback can be filed via the contact listed at https://webgcp.org/.well-known/webgcp (operator field).
Status as of v0.1: only level 1 (community participant) is staffed. Levels 2–5 will fill as activity warrants.
Drawn from MCP's stated 2026 governance maturation, applied early:
We will not staff levels 4–5 until level 1 has people in it.
Status as of v0.1: no WG is convened today. The list below is the planned topology for when activity warrants.
When activity warrants, working groups will form around:
A WG owns SEPs (Spec Enhancement Proposals) in its area. Core maintainers retain strategic oversight.
When two or more interoperable implementations exist and at least one external production deployment is using webGCP, we will approach a neutral foundation for donation. Most likely candidates, in order of fit:
Donation does not change technical direction. It changes governance neutrality. We will not donate before there is something worth giving.
These are tracked, not deferred. Each will get an ADR before v1.0.
_meta?webmcp_origin) is pinned to the W3C Web Machine Learning CG WebMCP draft as of 2026-02-10 (navigator.modelContext). WebMCP breaking changes (e.g. the observed navigator.ai.* → navigator.modelContext.* rename) are absorbed by re-pinning in the next webGCP version — never by mutating immutable v0.1 (§10.4). Any webmcp_origin API-name realignment is a v0.2 item.Implementer's companion: the construction sequence, gates, common pitfalls, and stack-substitution guide for building to L0 lives at https://webgcp.org/request-for-development/. Read it alongside this section — it's the "how" to this section's "what."
Two L0 reference instances are publicly deployed as of 2026-05-16:
webgcp.org — first publicly-deployed L0 host honoring §5.1.1 (SVCB)¶https://webgcp.org is the spec host AND the first publicly-deployed host honoring §5.1.1's DNS-layer SVCB MUST. Its own spec-host descriptor at https://webgcp.org/.well-known/webgcp declares this_host_svcb_status: "live 2026-05-16 — SVCB record provisioned at Squarespace DNS (TTL 14400)". The spec is self-conformant — the L0-003 fixture verifies against itself.
| Surface | URL |
|---|---|
| Spec-host descriptor | https://webgcp.org/.well-known/webgcp |
| SVCB record (sub-ms DNS discovery) | _webgcp.webgcp.org. IN SVCB 1 webgcp.org. (TTL 14400) |
| DoH verification (Cloudflare; primary) | https://cloudflare-dns.com/dns-query?name=_webgcp.webgcp.org&type=64 |
| Conformance fixtures it passes | L0-001 (11 assertions) + L0-002 (7 assertions) + L0-003 (9 assertions) — all live and passing |
Because webgcp.org is the spec host, not a knowledge server, its descriptor carries role: "specification_authority" instead of conformance_level: Lx. The §5.1.1 SVCB MUST applies to any host serving the descriptor — spec hosts included.
the-ai-news.web.app — first publicly-deployed L0-restricted-domain reference server¶https://the-ai-news.web.app — the first publicly-deployed Web Graph Context Protocol reference server, currently at L0-restricted-domain per §5.1.1's restricted-domain caveat (Firebase's .web.app zone does not allow operator-managed SVCB records). Full L0 conformance requires attaching a DNS-controllable custom domain.
| Surface | URL |
|---|---|
| Server descriptor | https://the-ai-news.web.app/.well-known/webgcp |
| Manifest | https://the-ai-news.web.app/webgcp/manifests/news-kb-v0.1.json |
| Bundle contract | https://the-ai-news.web.app/webgcp/bundles/news-article-retrieval-v0.1.json |
| Query endpoint | POST https://the-ai-news.web.app/webgcp/v0/query |
| Conformance fixtures | https://the-ai-news.web.app/webgcp/conformance/v0.1/WGCP-L0-001.json (happy path, 11 assertions) + /WGCP-L0-002.json (out-of-scope, 7 assertions); both pass against the live endpoint |
Implementation: ~280 lines of Python (Flask + functions-framework) deployed as Cloud Function Gen2 in GCP project my-ai-00003 / us-central1, backing service webgcp-query. Bundled fixture articles spanning the 8 manifest categories for deterministic demo; the function exposes a one-flag swap to live Firestore when the operator wants real-time data. Source maintained in the the-ai-news repository.
The-ai-news also runs a separate Commerce-layer stack (x402 USDC settlement, agent marketplace, graph-authority routing) — per §0.7, Context and Commerce are composing layers that share an operator but neither subsumes the other.
A larger BigQuery-backed instance is under active build in the MyParallel catalog. The substrate is live (myparallel.catalog, 19 tables, 230 agencies + 29 skills with 3072-d gemini-embedding-001 embeddings, backfilled 2026-05-16) but the query endpoint that exposes it via this protocol is in-development (M3a backend MCP server). When M3a ships, the MyParallel BQ instance becomes the L1 candidate — vector search via embed_text() UDF over catalog.entities.embedding, multiple retrieval primitives (vector + direct lookup + graph traversal), versioned artifacts. Public read access to the BQ dataset will be provided as a reference for the schema; the dataset is an implementation, not the standard.
A clean-room, vendor-neutral third reference implementation — currently unwritten — is intended for ease of adoption. Source will live at https://github.com/webgcp/reference-server and https://github.com/webgcp/reference-client once a GitHub organization is registered (pending working-group convening — see §11.3). Until then, the v0.1 draft is at https://webgcp.org/spec/v0.1/.
Goals:
docker compose up brings up a complete L0 server with one example KB and one bundle contractThe L0 instance at the-ai-news.web.app (§13.1) proves feasibility — one impl exists in production. The L1+ instance (§13.2) will prove the larger-data + retrieval-primitive picture. The third (clean-room) instance will prove the spec is implementable by an outside reader from text alone. Step 4 (second-implementer test) of the underlying standards playbook is met when a non-author ships a conformant server against this spec; until then the standard is single-implementer and remains v0.x-draft.
This spec draws on prior art from:
.well-known/mcp.json patternwebGCP is not original work in concept. Every individual idea is borrowed. The contribution is the typed integration of these ideas as one protocol, with stated conformance levels and runnable tests.
If you are reviewing this draft, the most useful feedback addresses:
navigator.modelContext, Chrome early-preview, no centralized discovery — the gap webGCP fills). Non-normative; normative body unchanged._meta set minimal-but-sufficient?File issues via the contact in https://webgcp.org/.well-known/webgcp (operator field), or — once a working group is convened (see §11.3) — at the github.com/webgcp/ issue tracker. Specific quotes and counter-proposals welcome; unstructured "I don't like X" less so.
End of v0.1 draft.