# Setting Up Relayfile

> Use when an agent or human needs to set up relayfile end-to-end so agents can read and write provider files through a local mount. Covers `relayfile setup`, dynamic integration discovery with `relayfile integration available/search`, Nango and Composio backend selection, Atlassian site selection and metadata, cloud login, OAuth/connect flows, mount verification, `RELAYFILE_LOCAL_DIR` handoff, wri…

- **Type:** Skill
- **Install:** `agentstack add skill-agentworkforce-relay-setting-up-relayfile`
- **Verified:** Pending review
- **Seller:** [AgentWorkforce](https://agentstack.voostack.com/s/agentworkforce)
- **Installs:** 0
- **Category:** [Communication](https://agentstack.voostack.com/c/communication)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [AgentWorkforce](https://github.com/AgentWorkforce)
- **Source:** https://github.com/AgentWorkforce/relay/tree/main/.claude/skills/setting-up-relayfile
- **Website:** https://agentrelay.com

## Install

```sh
agentstack add skill-agentworkforce-relay-setting-up-relayfile
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Setting Up Relayfile (Mount + Writeback for Agents)

## Overview

Relayfile mounts a provider (Notion, Linear, Slack, GitHub, and other adapter-backed integrations) as ordinary files on disk so an agent can read and write through the filesystem instead of calling APIs. This skill is the canonical setup recipe. Follow it top-to-bottom for first-time setup; jump to **Recovering from breakage** if a working mount has gone wrong.

## When to use this skill

- An agent needs read access to a provider (e.g., "summarize this Notion database").
- An agent needs to write back to a provider (e.g., "post a review on this Notion page", "update this Linear issue").
- A human is setting up a mount before delegating work to an agent.
- A mount stopped reflecting changes and you need to diagnose where.

## What you get

After setup, files appear under `//...`:

```text
~/relayfile-mount/notion/
├── databases/
│   ├── --/
│   │   ├── metadata.json     ← database schema (read-only)
│   │   └── pages/
│   │       ├── --.json     ← page metadata
│   │       └── --/
│   │           ├── content.md        ← page body (READ + WRITE)
│   │           └── blocks/.json  ← raw Notion block tree
└── pages/                            ← top-level pages (not in a database)
```

Read = `cat`. Write = overwrite, create, or remove files in writable adapter resource directories. The mount daemon picks up the change, queues a writeback, and the cloud delivers to the provider's API.

Current mounts are also self-describing. Start with `/LAYOUT.md`, then read provider-specific `/.layout.md` files and nearby `_index.json` files instead of hard-coding paths from memory. Entity filenames may use a `__` convention, and some providers expose alias views such as `by-title/`, `by-id/`, `by-name/`, or `by-state/`.

## Prerequisites

- Recent `relayfile` CLI on `$PATH`. Verify: `relayfile --help` should list `setup`, `integration`, `writeback`, and the `integration available` / `integration search` / `integration set-metadata` subcommands.
- A modern macOS or Linux shell with `jq` for JSON inspection. AWS CLI access is optional and only needed for internal cloud log diagnostics.
- Network access to `agentrelay.com/cloud` (cloud control plane), `api.relayfile.dev` (relayfile API), `connect.nango.dev` (Nango OAuth), and Composio connect endpoints when using `--backend composio`.

## Step 1 — Run setup (interactive happy path)

```bash
relayfile setup \
  --provider notion \
  --workspace my-agent \
  --local-dir ~/relayfile-mount \
  --no-open
```

What this does, in order:

1. **Cloud login.** Opens a localhost callback server, prints a URL to `agentrelay.com/cloud/api/v1/cli/login?...`. You complete the login in the browser; the cloud redirects back to `127.0.0.1:/callback` with an access token. The CLI stores cloud credentials in `~/.relayfile/cloud-credentials.json` and the active Relayfile workspace token in `~/.relayfile/credentials.json`.
2. **Workspace create.** POSTs `/api/v1/workspaces` with `{"name": "my-agent"}`. Returns `{ workspaceId: "rw_", relaycastApiKey, relayfileUrl, ... }`. The workspace ID is the prefix-style `rw_*` format — not a UUID.
3. **Integration connect.** By default, mints a Nango Connect URL like `https://connect.nango.dev/?session_token=nango_connect_session_` and opens it (or prints it, with `--no-open`). With `--backend composio`, the cloud resolves the provider to a Composio toolkit, finds or creates the Composio auth config when Composio supports automatic managed auth, and mints a Composio connect URL. You complete the provider auth there. The provider callback inserts a row into `workspace_integrations` and queues an initial sync. For Jira and Confluence, the CLI then lists the Atlassian sites covered by the OAuth grant and asks which site to bind when more than one is available.
4. **Initial sync.** The cloud nango-sync-worker pulls page metadata + content from the provider and writes it to relayfile. Takes ~30s for a small workspace.
5. **Mount.** Starts a local daemon that polls `api.relayfile.dev/v1/workspaces//sync/status` every 30s and reflects changes into `//`.

**Use `--no-open` if you're an agent**: the wizard otherwise tries to open a browser, which usually fails in headless environments and burns the OAuth state.

## Step 2 — Verify the mount is healthy

```bash
relayfile status my-agent
```

Healthy output:

```text
workspace rw_xxxxxxxx (my-agent)   mode: poll   lag: 4s

local mirror: /Users/you/relayfile-mount
daemon: running (pid 12345)

  notion       ready    214 files    last event 2s ago

pending writebacks: 0    failed: 0    dead-lettered: 0
```

What each row means:

- `lag: s` — how stale the mirror is relative to the cloud. >60s means investigate.
- `daemon: not running` — the mount poller exited. Start it with `relayfile mount my-agent ~/relayfile-mount &`.
- `pending writebacks` — local writes queued for upload. Should drain to 0 within ~30s.
- `failed` — lifetime counter of non-2xx responses from the cloud's PUT endpoint. **Informational; don't gate on this.**
- `dead-lettered` — count of writebacks that exhausted retries and got persisted under `/.relay/dead-letter/.json`. **Gate on this.**

If `dead-lettered > 0`, see **Recovering from breakage** below.

## Step 3 — Hand off to an agent

Two patterns, depending on where the agent runs:

### Pattern A: local agent (Claude Code, scripts, Cursor)

The agent reads files directly:

```bash
export RELAYFILE_LOCAL_DIR=~/relayfile-mount
# point Claude Code at the dir or `cd` in
```

Mental model for the agent: ordinary files. Use `Read`, `Write`, `Edit`, `Glob`, `Grep` — same as any project directory. Writes propagate within ~30s.

Before writing, read the relevant `_PERMISSIONS.md` or discovery files for the target subtree. If a path is denied, Relayfile preserves the local copy and records the denial in `/.relay/permissions-denied.log`.

### Pattern B: remote agent / SDK access (no disk mirror)

Use `@relayfile/sdk` against the workspace token:

```ts
import { RelayFileClient } from '@relayfile/sdk';

const token = process.env.RELAYFILE_TOKEN; // from ~/.relayfile/credentials.json
const client = new RelayFileClient({ token, server: 'https://api.relayfile.dev' });

// Read
const file = await client.getFile('rw_xxxxxxxx', '/notion/pages/xxx/content.md');

// Write — triggers writeback automatically
await client.putFile('rw_xxxxxxxx', '/notion/pages/xxx/content.md', {
  content: '# New body\n\n…',
  contentType: 'text/markdown',
});
```

The token issued by `relayfile setup` carries (as of May 2026): `fs:read`, `fs:write`, `sync:read`, `sync:trigger`, `ops:read`. The last two were added so agents can introspect the writeback pipeline (`relayfile pull`, `relayfile ops list`, `GET /v1/workspaces//ops/`).

## Step 4 — Verify writeback works (optional but recommended)

Skip-able if the agent only reads. Required if the agent will write.

1. Pick a throwaway page in the provider.
2. Write a marker:
   ```bash
   echo "[writeback test $(date -u +%FT%TZ)]" > ~/relayfile-mount/notion/pages//content.md
   ```
3. Wait 30s.
4. Open the provider's web UI; the marker should appear.
5. Run `relayfile writeback status` — `dead-lettered` should still be 0.

If the marker doesn't appear in step 4, see **Recovering from breakage**.

## Discover writeback contracts before writing

Do not guess writeback shapes and do not use a magic `new.json` filename. Current relayfile adapters ship discovery documents for writable resources:

A typical discovery surface looks like:

```text
/
├── .adapter.md                         ← adapter overview, operations, ID patterns
└── /
    ├── .schema.json                    ← full-record JSON Schema, draft 2020-12
    └── .create.example.json            ← minimal create payload
```

- First check which writeback contract the mounted workspace exposes. Run `find "$RELAYFILE_LOCAL_DIR" \( -name '.adapter.md' -o -name '.schema.json' -o -name 'new.json' \) | head -40`. If discovery files are absent and `new.json` templates are present, the mounted workspace is still on the pre-file-native adapter bundle; do not apply the create-by-filename flow until the cloud/adapter deployment has refreshed that workspace.
- Read the provider `.adapter.md` first. In mounted workspaces this may appear under the provider tree or under `/discovery//.adapter.md`; if unsure, run `find "$RELAYFILE_LOCAL_DIR" -path '*/.adapter.md'`.
- Read the resource `.schema.json` before writing JSON. It is JSON Schema draft 2020-12 for the full synced record. Fields with `"readOnly": true` are server-managed and must not be written. Common schema paths are resource-local, such as `/linear/issues/.schema.json`; packaged adapters also carry a discovery copy under `discovery//...`.
- For creates, start from the sibling `.create.example.json`. The create example intentionally omits read-only fields.
- For edits, write only mutable fields to a canonical `.json`; omitted fields are left alone.
- For creates, write a valid JSON document to any non-canonical filename in the resource directory, such as `draft-message.json` or `create issue.json`. The adapter creates the provider record at the real `.json` and rewrites the draft file as a receipt/pointer.
- For deletes, remove the canonical `.json` only when the resource's `.adapter.md` says delete is supported.

The `` pattern is resource-specific. A Linear issue ID is a UUID; a Slack message ID is a timestamp-like token; GitHub and many CRM IDs are integers. The `.adapter.md` ID pattern section is the source of truth for whether a filename routes to PATCH/DELETE or CREATE.

## Path conventions per provider

| Provider | Read paths                                                                                                          | Write paths                                                                                                                                        |
| -------- | ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Notion   | `/notion/pages/--/content.md`, `/notion/databases//pages/.../content.md`, `.json` (metadata)    | same paths overwrite the body / properties                                                                                                         |
| Slack    | `/slack/channels//messages/` plus `.adapter.md` / `.schema.json` discovery                                      | create by writing a valid message JSON to `/slack/channels//messages/.json`; edit/delete canonical message files when supported |
| Linear   | `/linear/issues/.json`, comments under issue resources, plus `.adapter.md` / `.schema.json` discovery           | create by writing a valid issue/comment JSON to a non-canonical filename; edit/delete canonical issue files when supported                         |
| GitHub   | `/github/repos///pulls//metadata.json`, `files.json`, plus `.adapter.md` / `.schema.json` discovery | create a review by writing the review JSON to a non-canonical file under the reviews resource                                                      |

`new.json` is not special in the file-native adapter contract. If a current `.adapter.md` and `.schema.json` are present, translate older examples using `/messages/new.json` or `/comments/new.json` to "write the create payload to any non-canonical filename in the resource directory." If the live mount only exposes `new.json`, treat that as an older deployment surface and follow the mounted template or wait for the workspace to refresh onto the new adapter version.

`/.relay/` is reserved — never write there. Anything you put under it gets ignored or treated as daemon state.

## Adding more integrations after setup

Do not guess provider names. Ask the CLI for the live catalog first; it pulls static Relayfile integrations plus dynamic Nango providers and Composio toolkits from the cloud, then caches the result locally.

```bash
relayfile integration available --refresh
relayfile integration search docker --backend composio --refresh
relayfile integration available --backend nango --search notion
```

Use `available` when you want to browse or filter the catalog. Use `search` when you already have a term. `--refresh` bypasses the local catalog cache and is worth using when a provider was just added in Nango or Composio. Add `--json` when an agent needs machine-readable output.

Then connect the provider, optionally selecting the backend:

```bash
relayfile integration connect linear --workspace my-agent
relayfile integration connect slack  --workspace my-agent
relayfile integration connect dockerhub --backend composio --workspace my-agent --no-open
relayfile integration list           --workspace my-agent
```

For Jira and Confluence, a single Atlassian OAuth grant can cover multiple sites. After a fresh `relayfile setup --provider jira|confluence` or `relayfile integration connect jira|confluence`, the CLI calls Cloud's accessible-resources endpoint. If there is one site, it auto-selects it; if there are multiple sites, it prompts for a numbered choice before waiting for initial sync. The selected site's `cloudId` and `baseUrl` are saved as integration metadata so Cloud knows which tenant to sync.

If the picker was skipped, the wrong site was chosen, or an operator needs to update provider metadata later, use `integration set-metadata`. The command replaces the provider metadata namespace, so include every key you want to keep:

```bash
relayfile integration set-metadata jira \
  cloudId=abc-123 \
  baseUrl=https://example.atlassian.net \
  --workspace my-agent \
  --yes
```

`set-metadata` accepts flat `KEY=VALUE` pairs only. Keys such as `site.cloudId` or `site[cloudId]` are rejected locally; nested metadata is not part of the v1 CLI contract. Re-running `relayfile integration connect jira` or `confluence` for an already-connected provider should not overwrite existing metadata unless it starts a fresh OAuth connect.

Backend rules:

- Nango is the default backend for the standard Relayfile providers such as Notion, Linear, Slack, and GitHub.
- Composio can be requested explicitly with `--backend composio` for supported providers and dynamic Composio toolkits.
- User-facing aliases are allowed where the cloud knows them. For example, `dockerhub` resolves to the Composio toolkit slug `docker_hub`; if discovery shows `docker_hub`, either spelling is acceptable for connect.
- For Composio, the cloud first lists existing auth configs for the toolkit. If none exists, it attempts to create a managed/default auth config automatically. If Composio cannot create managed auth for that toolkit, the command returns an actionable error; at that point the human must add a custom auth config in Composio Authentication Management and retry the same `relayfile integration connect ...` command.

Each provider gets its own subtree under `/`. Disconnect with `relayfile integration disconnect ` — leaves a marker at `.relay/disconnected/.json` and removes the provider's tree from the mirror.

## Common gotchas

### G1 — Cold-start 500 on workspace create

`POST /api/v1/workspaces` sometimes 500s on the first call after the cloud Lambda has been idle. Retry once before doing anything diagnostic. **Verified May 2026**: same call succeeded immediately on retry.

If it 500s twice in a row, check `aws logs tail /aws/lambda/clou-production-AgentRelayCloudWebServerUseast1Function- --since 5m --follow` for the actual stack trace.

### G2 — OAuth callback timing trap

The wizard prints the cloud-login URL, opens a localhost callback server, then waits. If you complete the login _after_ the wizard has timed out (or if you click the callback URL by hand later), the redirect-to-localhost won't load — that's expected. The login already completed; the wizard

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [AgentWorkforce](https://github.com/AgentWorkforce)
- **Source:** [AgentWorkforce/relay](https://github.com/AgentWorkforce/relay)
- **License:** Apache-2.0
- **Homepage:** https://agentrelay.com

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-agentworkforce-relay-setting-up-relayfile
- Seller: https://agentstack.voostack.com/s/agentworkforce
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
