Install fracta
Follow Installation and Your First Agent. Confirm
fracta spawn --task hello --contract "say hi" returns cleanly before continuing.Complete pattern Setup
Walk through Setup once — it covers the Notion + Readwise OAuth flow (via
fracta config mcp auth login, with tokens exported as Kubernetes Secrets), the gateway ConfigMap entries for those two servers, and the catalog gotchas (Notion DB sharing, Readwise rate limits, extractor footprint). The current page does not repeat that material.What you will do
Add the three concept-extraction MCP servers, spawn one Claude worker with one prompt, and read back the result. The pipeline framing — “run the reading-garden pipeline” — lets Claude orchestrate the three strategies internally; you do not call them one at a time. The whole thing should fit in under 20 minutes once Setup is complete.Pick your deployment target. Examples on this page are written for Docker Compose; if you are running Kubernetes (the path Setup defaulted to), the equivalent operations are
kubectl apply-style — see Kubernetes deployment guide for the manifests. The pipeline framing in Step 2 onwards is deployment-agnostic.Strategy runner gateway plumbing. The Reading Garden strategies (
highlight-distill, notion-publish) call MCP tools inline via ctx.mcp.call_tool(...). Since v0.5.2 this is wired by default in the scaffold: the gateway ConfigMap (k8s) or configs/gateway.yaml (compose) ships with strategy.gateway_access: true, and the runner sidecar/service is started with --gateway-url http://gateway:8080 --agent-task default. If you upgraded from an older deploy, verify both flags before running the pipeline — without them the runner refuses with requires.mcp: true but ctx.mcp is None.Step 1 — Add the concept-extractor MCP servers
Setup wired upnotion and readwise (the two OAuth-gated knowledge sources). The Reading Garden pipeline also needs three small extractor MCP servers — KeyBERT, GLiNER, and spaCy — that turn raw highlight text into ranked concept candidates. They run as containers (no OAuth required), are first-party fracta images published to GHCR, and are catalogued at mcp-servers/concept-{keybert,gliner,spacy}/server.yaml in the fracta repo.
These three servers are local_process: not_supported in the catalog (they ship as containers only). Depending on your deployment target, bring them up alongside your gateway:
Docker Compose — append the sidecars to deployment/docker-compose.yml:
mcp_servers.servers: in your fracta.yaml so the gateway can route to them by compose-service DNS on the internal port 8000:
The URL shape follows the docker-compose convention from MCP server examples — compose-service DNS on the container’s internal port. In Kubernetes, swap the host for each server’s
service_url (e.g. http://concept-keybert.fracta.svc:8000/mcp) as documented in the catalog entry; see the Kubernetes runbook for the surrounding manifests. The container images ship from fracta-mcp-servers; fracta consumes the published GHCR tags only.notion, readwise, concept-keybert, concept-gliner, concept-spacy — all with status ok. If notion or readwise show auth_required, re-check Setup for the OAuth flow. If any of the extractors fail to reach ok, confirm the compose containers are healthy (docker compose ps) and that the gateway can resolve the service DNS from its own container.
Step 2 — Confirm Claude is your default runtime
The rest of this guide assumesfracta spawn without --runtime launches a Claude worker. Open your fracta.yaml and confirm it contains an agents: block roughly like the following — if Setup or fracta init already left this in place, you only need to verify it’s there:
agents: block is missing or default_runtime is set to something else, add or edit it now. See Runtime configuration for the full per-runtime adapter and authentication setup; the block above is the minimum needed for the rest of this guide. Any host that speaks MCP can drive this pipeline, but the prompt below is written for Claude and assumes its tool-use conventions.
Step 3 — Spawn the worker with the pipeline prompt
This is the one prompt. Copy it as-is, swap the three database IDs, and run:CONCEPTS_DS_ID, HIGHLIGHTS_DS_ID, and SOURCES_DS_ID with the three data_source_id values you captured in Setup — Step 2. Adjust the watermark_iso to whatever cutoff date you want — keeping it recent on the first run avoids long Readwise pulls (the API caps at 20 requests/minute).
Watch the run as it happens:
strategy_run call as a tool invocation, with the structured result returned to the worker. Detach with Ctrl-C whenever you want — the worker keeps running.
Step 4 — Read what the worker reports back
Once the worker reachescompleted (visible in fracta list), read its final semantic output:
epistemic_status header (evergreen for confidence > 0.8, budding for 0.4–0.8, seedling below), the supporting Highlights rendered as quote blocks, and backlinks to the source Documents. The exact rendering is fixed by the notion-publish strategy.
Step 5 — Spot-check the graph
The worker reported counts; verify them against the graph yourself. Spawn a short-lived agent to run a Cypher query through thegraph_query MCP tool:
Publication node:
sink should be notion and external_id should match the Notion page ID in the URL the worker reported.
Step 6 — Re-run for idempotency
Run the samefracta spawn command from Step 3 again, with the same concept_name and notion_database_id. The notion-publish strategy is idempotent — Step 3’s report should now read something like:
What just happened
The single prompt drove a three-stage CODE flow (Capture → Distill → Express) end-to-end:- Capture + Organize:
highlight-distillpulled fresh Readwise data through the gateway, staged it in a per-run DuckDB, and wrote typed nodes into the graph. - Distill:
cross-source-conceptsscored Concepts using recency × frequency × source diversity, writingconfidenceandmention_countback to the graph. - Express:
notion-publishrendered the highest-confidence Concept as a Notion page and recorded aPublicationnode tying the graph state to the external page (the basis for idempotent re-runs).
strategy_run was a deterministic Python pipeline executed by the gateway’s strategy runner — no LLM tokens were spent on the actual data work, only on deciding when to call the next stage.

