Skip to content

Set up Render

Copy page

This walkthrough stands up Tapestry’s backend on Render — the services your projects connect to via .mcp.json. In self-host you run this once for your own deployment. See Platform dependencies for what’s needed.

Estimated time: 20–40 minutes for first provisioning, mostly waiting on builds.

The Render side hosts five Python web services plus one Postgres instance plus one cron, declared in render.yaml (the platform’s Blueprint file). The Blueprint is the source of truth — Render reads it and provisions everything declaratively.

ResourcePurposeSource
postgres (managed Postgres)Backing store for memory records, project registry, candidate registryrender.yaml
memory-mcp (web service)The Memory MCP — memory_read/write/recall/list/search/delete over HTTP + MCPservices/agent-context/
architecture-registryCandidate + Architecture registry endpointsservices/architecture-registry/
policy-servicePromotion policy evaluatorservices/policy/
project-registryProject + repo + machine registrationservices/project-registry/
self-observer (cron)6-hour scan that interprets signals into candidatesservices/self-observer/
  • A Render account (free tier is enough to start; the your own deployment may need a paid plan once traffic grows — see Render’s pricing)
  • A GitHub account that can read your deployment repo (the public repo holding the Blueprint)
  • A Grafana Cloud account with OTel credentials in hand — see Set up Grafana Cloud + OTel first; the Render services need OTEL_EXPORTER_OTLP_* env vars at provisioning time
  1. Open render.com and create an account if you don’t have one. The Render docs’ Getting Started page covers the basics.
  2. After signup, you land at dashboard.render.com. Bookmark it — every later step happens here.

Render reads the Blueprint directly from a connected GitHub repo. You need to authorize Render to access your deployment repo.

  1. In the dashboard, click your profile (top-right) → Account SettingsGitHubConfigure.
  2. Authorize Render against Lizo-RoadTown (your fork, or the upstream if you’re the upstream owner).

If you’re standing up your own deployment, fork the platform repo (Lizo-RoadTown/tapestry) first and edit the render.yaml service names if you want a different namespace.

Section titled “Step 3 — Validate the Blueprint locally (optional but recommended)”

Render provides a CLI for Blueprint validation. Per the Blueprint spec, the command (requires CLI v2.7.0+):

Terminal window
brew install render # or: curl -fsSL https://render.com/download-cli/linux | sh
render login
render validate render.yaml

If the file is valid, the command exits 0. If not, it prints the schema errors so you can fix them before pushing.

  1. In the Render dashboard, click New (top-right) → Blueprint. Render’s Infrastructure as Code page documents this workflow.
  2. Select the connected your deployment repo repo.
  3. Render reads render.yaml at the repo root and previews what it will create — five web services + one Postgres + one cron, matching the table above.
  4. Click Apply.

Render builds each service in parallel. First builds take 3–8 minutes per service (the Postgres comes up faster, services have to install pip dependencies). Subsequent deploys are incremental.

The Blueprint declares which env vars each service needs but does not set their values (secrets are operator-supplied). Per the render.yaml comments, you need to set these in the dashboard.

Shared across services — loom-shared-secrets env group

Section titled “Shared across services — loom-shared-secrets env group”
  1. In the dashboard, click Environment Groups (left sidebar) → New Environment Group → name it loom-shared-secrets.

  2. Add these key-value pairs:

    KeySource
    OTEL_EXPORTER_OTLP_ENDPOINTfrom Grafana Cloud setup
    OTEL_EXPORTER_OTLP_HEADERSfrom Grafana Cloud setup
    LOOM_JWT_PUBLIC_KEYRSA public key (PEM) — every service verifies tokens with it
  3. Attach the env group to each web service: open the service → EnvironmentLink Environment Group → select loom-shared-secrets.

A few keys must be set on individual services (not shared):

ServiceKeyPurpose
memory-mcpLOOM_JWT_PRIVATE_KEYRSA private key — only this service signs tokens
loom-project-observatory (if deployed)GRAFANA_CLOUD_API_URLServer-side Grafana query endpoint
loom-project-observatory (if deployed)GRAFANA_CLOUD_API_TOKENAuth for the query endpoint

Set these per-service: open the service → EnvironmentAdd Environment Variable.

Each service must show Live in the dashboard. Then check the health endpoints (every Python service in services/*/main.py exposes /health):

Terminal window
curl https://your-memory-host.example.com/health
curl https://your-registry-host.example.com/health
curl https://your-policy-host.example.com/health
curl https://your-project-registry-host.example.com/health

Each should return {"status": "ok", "service": "<name>"}.

For the cron, open self-observer in the dashboard and check the Logs tab. The first run executes within 6 hours of deployment (or you can manually trigger it via Manual DeployTrigger Job).

Step 7 — Confirm the Memory MCP is reachable

Section titled “Step 7 — Confirm the Memory MCP is reachable”

From a Claude Code session in any test project:

  1. Create or update the project’s .mcp.json:

    {
    "mcpServers": {
    "loom-memory": {
    "transport": {
    "type": "http",
    "url": "https://your-memory-host.example.com/mcp/memory/"
    }
    }
    }
    }
  2. Restart Claude Code.

  3. In a session, call memory_list — should return without error.

If you see MCP UNREACHABLE: HTTP 404, the service is still cold-starting (free-tier services sleep after 15 minutes of no traffic). Wait 30–60 seconds and retry. If persistent, see Memory troubleshoot.

Render’s free tier covers small projects but the platform’s services have constraints:

  • Free-tier web services sleep after 15 minutes idle (~60s cold-start when traffic resumes). For the Memory MCP this is a real UX cost — every fresh session hits a cold start. You typically upgrade memory-mcp to a paid plan (starter or above) once consumers are active.
  • Managed Postgres has its own pricing tiers; the free tier is fine for early use.
  • The cron schedule (every 6h) is well within free-tier limits.

See Render pricing for current rates.

Operator-only actions that need the dashboard (not the MCP)

Section titled “Operator-only actions that need the dashboard (not the MCP)”

Some Render operations are NOT available via the Render MCP — only the dashboard:

  • Plan changes (free → starter etc.) — operator does in dashboard
  • Service deletion — operator does in dashboard
  • Cron deletion — operator does in dashboard

This is by design; the Render MCP only supports updates that don’t change billing state. See feedback_render_mcp_cannot_change_service_plan_must_use_dashboard in the operator’s memory for the full list.