Learning objectives
By the end of this module, you will be able to:
- Distinguish package release numbers from protocol release numbers
- Install the maintained Python, WebMCP, or Rust package
- Parse and canonicalize a UVC token and a CSM-1 code
- Register browser VCP tools without loading remote scripts
3.1 — Choose the right surface
VCP-SDK 4.2.0 exposes three deliberately different surfaces:
| Package | Purpose | Scope |
|---|---|---|
value-context-protocol | Python implementation, maintained by the VCP project | Identity, semantics, adaptation, signed bundles, verification, enforcement, privacy helpers, and extensions |
@creedspace/vcp-sdk | TypeScript browser integration | WebMCP tool registration, hooks, and selected extensions. It is not a full TypeScript port of every protocol layer. |
vcp-core | Rust implementation, maintained by the VCP project | Identity, CSM-1, adaptation context, transport, trust, verification, hooks, and extensions |
Version boundary:
4.2.0is the published SDK release on PyPI, npm, and crates.io. VCP v3.1 is the current protocol source baseline. SDK 4.2.0 also contains explicitly identified v3.2 experimental adaptation features.
3.2 — Installation
Published 4.2.0. Install from PyPI, npm, or crates.io. Each block also shows the equivalent command to run from the root of a VCP-SDK checkout at the published commit (tag v4.2.0).
Python (Python 3.10 or newer):
python -m pip install value-context-protocol==4.2.0
# Or from a VCP-SDK checkout at tag v4.2.0
python -m pip install ./python TypeScript WebMCP integration:
npm install @creedspace/vcp-sdk@4.2.0
# Or from a VCP-SDK checkout at tag v4.2.0
npm install ./webmcp Rust:
cargo add vcp-core@4.2.0
# Or from a VCP-SDK checkout at tag v4.2.0
cargo build --manifest-path ./rust/Cargo.toml -p vcp-core Pin the exact version (4.2.0) or source commit in deployed applications. The publication-state record lists each registry receipt and the source commit.
3.3 — Parse and canonicalize in Python
Two kinds of VCP string appear here. A UVC token (the VCP/I identity
token) names a specific constitution. In family.safe.guide@1.2.0, family is the domain, safe the approach, guide the role, and 1.2.0 the version. A CSM-1 code, from Module 2, summarizes
what kind of constitution a bundle carries. Canonicalizing means reducing a
string to the one standard spelling the SDK compares against, which is why
the scopes in N5+F+E come back sorted.
from vcp import CSM1Code, Token
identity = Token.parse("family.safe.guide@1.2.0")
profile = CSM1Code.parse("N5+F+E")
print(identity.full) # family.safe.guide@1.2.0
print(identity.canonical) # family.safe.guide
print(profile.encode()) # N5+E+F (canonical scope order) Both parsers reject malformed input. Treat parse failure as a validation failure, rather than silently accepting a string as trusted VCP data.
3.4 — Encode adaptation context in Python
The Adaptation layer (VCP/A) can encode the situational and personal tiers from Module 1 into a compact wire string:
from vcp.adaptation import ContextEncoder
context = ContextEncoder().encode(
time="morning",
space="home",
company="children",
)
wire = context.encode()
print(wire) # ⏰🌅|📍🏡|👥👶 The example uses three of the nine situational dimensions in the VCP 3.1 context wire. The experimental v3.2 model adds four more, for 13 in all. Negotiate it explicitly when interoperability with a v3.1-only peer matters.
3.5 — Register browser tools in TypeScript
The TypeScript package registers VCP capabilities with document.modelContext when the browser supports WebMCP, a proposed browser interface that lets
a web page offer tools to AI agents:
import { registerVCPTools } from '@creedspace/vcp-sdk';
const registration = await registerVCPTools({
chatEndpoint: '/api/chat',
enableChat: false,
});
console.log(registration.registered);
// Call this when the component or page is destroyed.
registration.cleanup(); The call is safe during server rendering and returns an empty registration in unsupported browsers. Your application owns any optional polyfill and must bundle and pin it locally.
3.6 — Parse in Rust
use vcp_core::{Csm1Code, VcpToken};
fn main() {
let identity = VcpToken::parse(
"family.safe.guide@1.2.0"
).expect("valid identity");
let profile = Csm1Code::parse("N5+F+E")
.expect("valid CSM-1 code");
assert_eq!(identity.domain(), "family");
assert_eq!(profile.encode(), "N5+E+F");
} 3.7 — Verification is a separate gate
Parsing proves that data has the expected syntax. It does not prove issuer trust, signature validity, attestation validity, freshness, scope, revocation status, or content integrity. Signed bundles must pass the SDK's verification pipeline from Module 2 (its orchestrator) before their content is injected into a model.
The VCP-SDK repository includes a complete examples/python/05_full_pipeline.py example covering key generation, trust anchors, bundle verification, and guarded
injection.
Exercise
- Parse
family.safe.guide@1.2.0and print its domain, role, and version. - Change the CSM-1 scope order and confirm that encoding returns its canonical form.
- Pass malformed values and handle the resulting validation error without falling back to an unverified value.
Try it
Use the Playground to build a CSM-1 token
(the multi-line form mentioned in Module 2), then parse it with the Rust
SDK's Csm1Token::parse. SDK 4.2.0's parser accepts only the
seven required lines plus an optional R-line, adherence 1 to 5, and no R:none, so delete the LC: line first (and avoid
adherence 0 and an empty R-line). The Playground's own Parse Token tab
runs a later SDK build that accepts them. Its C: line holds a UVC
token that Token.parse and VcpToken::parse, from
the examples above, can read. Python's CSM1Code.parse reads
only one-line CSM-1 codes. The VCP/A context wire from 3.4 is a separate
format, which the Playground's Wire Decoder tab reads.