Work context, packaged for LLMs

UCP is an open format that turns a sprawling issue thread into a small, verifiable package your agent can load: facts, decisions, conflicts, hashed sources.

microsoft/vscode#519 · 596 comments over ten years
raw thread~18,500 tokens
ucp package~1,200 tokens

15× smaller, with decisions, conflicts and provenance intact.

Install

Run the whole toolchain as one self-hosted service, or pick the piece you need.

One container: REST API on /v1, MCP over Streamable HTTP on /mcp.

docker run --rm -p 8080:8080 -e GITHUB_TOKEN=ghp_yourtoken \ ghcr.io/ucpcore/ucp-server:latest

Generate a package from a real issue

By default no LLM is involved: the structure alone carries the facts, decisions and timeline. Decorations go to stderr; stdout stays pure JSON, so piping is always safe.

Works on any public GitHub issue or Jira ticket. Every claim cites its sources; every source carries a sha256 hash. The output validates against the schema before it is written.

Connect Cursor or Claude Code in 60 seconds

MCP is the pipe. UCP is what flows through it. Start the server, point your agent at it, done.

Start the server

Generates and caches packages on demand.

docker run --rm -p 8080:8080 \ -e GITHUB_TOKEN=ghp_yourtoken \ ghcr.io/ucpcore/ucp-server:latest

Add it to mcp.json

Cursor and Claude Code speak Streamable HTTP natively.

{ "mcpServers": { "ucp": { "url": "http://localhost:8080/mcp" } } }

Your agent now has generate_context, list_contexts, get_context, get_context_markdown, and submit_usage_receipt. Ask it to load context for owner/repo#123 or PROJ-123. Prefer plain HTTP? The same server exposes POST /v1/generate and POST /v1/receipt.

Deploying beyond localhost? Set UCP_SERVER_API_KEY and send it as a Bearer header — see the MCP reference.

Close the loop with Usage Receipts

Most context formats are one-way: producer ships a package, the agent reads it, and nobody learns what actually helped. UCP adds a Usage Receipt — a small JSON object that records which claims were cited, which were ignored, and how the task ended. The reference server uses that signal to warm-rank the next package for your team.

Measured on real issues

Same token estimator on both sides (~4 chars/token). "Raw thread" is the text you would otherwise paste into the model: title, body, comments, linked-PR bodies.

IssueCommentsRaw threadUCP
microsoft/vscode#519first 200 of 596~18,500~1,200
rust-lang/rust#15862212~4,450~1,450
pallets/flask#59614~800~700
pallets/flask#59480~500~330

The win grows with thread size: a decade-long discussion collapses ~15× while keeping decisions, conflicts and provenance. On small issues the token count is similar, but the package is still structured, hashed and audience-aware. Reproduce with tools/benchmark_context.py; generated with ucp-gen 0.3.1, 2026-07-06.

What --llm adds

One call to any OpenAI-compatible endpoint extracts what exists only in prose. Guarantees hold: the package stays schema-valid, hallucinated citations are dropped, and if the endpoint is down you get the structural package with a warning.

conflict

On vscode#519, the enriched package records the dispute over whether Electron or VS Code's hard-coded styles are to blame, both positions citing specific hashed comments.

decision [rejected]

The request is not on the roadmap. Stated only in prose across a decade of comments, invisible to every structured GitHub field.

What's inside a package

One JSON document. Every consumer, human or model, gets the same predictable sections.

A canonical rendering algorithm turns any package into a deterministic prompt. Under a token budget, salience defines the truncation order (each claim MAY carry salience_method: producer, graph, ranking, or llm). Sources carry content_hash (sha256); consumers revalidate with since + context_diff when the upstream changes. A claim without sources is schema-invalid.