handoff-relay 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +434 -0
- package/dist/api/server.d.ts +16 -0
- package/dist/api/server.js +2578 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.js +5502 -0
- package/dist/client-CjWEJ02H.d.ts +144 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.js +2623 -0
- package/dist/mcp/server.d.ts +84 -0
- package/dist/mcp/server.js +2950 -0
- package/dist/relay-service-BjF5HNvN.d.ts +712 -0
- package/docs/advanced-manual-setup.md +196 -0
- package/docs/claude-code-setup.md +143 -0
- package/docs/codex-setup.md +135 -0
- package/docs/demo-video-script.md +49 -0
- package/docs/generic-mcp-setup.md +163 -0
- package/docs/launch-copy.md +70 -0
- package/docs/local-self-hosting.md +170 -0
- package/docs/packet-schema.md +116 -0
- package/docs/security-privacy.md +90 -0
- package/docs/troubleshooting.md +180 -0
- package/examples/hydration-receipts/reply-hydration.json +14 -0
- package/examples/packets/ask.json +73 -0
- package/examples/packets/reply.json +62 -0
- package/examples/packets/share.json +52 -0
- package/fixtures/clarification.json +7 -0
- package/fixtures/declined-packet.json +6 -0
- package/fixtures/normal-ask.json +72 -0
- package/fixtures/normal-share.json +51 -0
- package/fixtures/revoked-member.json +7 -0
- package/fixtures/secret-redaction.json +10 -0
- package/fixtures/stale-handoff.json +16 -0
- package/fixtures/superseded-packet.json +6 -0
- package/package.json +103 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Advanced Manual Setup
|
|
2
|
+
|
|
3
|
+
Use this path for automation, remote/self-hosted coordination servers, CI smoke tests, or explicit-auth MCP compatibility. Most users should start with:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx -y handoff-relay start --lan
|
|
7
|
+
npx -y handoff-relay invite alice
|
|
8
|
+
npx -y handoff-relay join http://<host>:3737/invite/<invite-token>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Plain `start` is still useful for local demos and CI smoke tests, but its loopback invite links are not the normal teammate handoff path.
|
|
12
|
+
|
|
13
|
+
The commands below intentionally expose low-level details: DB paths, server URLs, workspace IDs, member tokens, and approval secrets.
|
|
14
|
+
They document the strict approval-token flow. For profile-backed MCP sessions that treat explicit agent-chat instruction as approval, use `server mcp --profile default --agent-approvals` instead of explicit-auth mode.
|
|
15
|
+
|
|
16
|
+
## Start A Coordination Server
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx -y handoff-relay server start \
|
|
20
|
+
--db /srv/handoff/relay.db \
|
|
21
|
+
--host 10.0.0.10 \
|
|
22
|
+
--port 3737
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
For local-only testing:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx -y handoff-relay server start \
|
|
29
|
+
--db .relay/team.db \
|
|
30
|
+
--host 127.0.0.1 \
|
|
31
|
+
--port 3737
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Create A Workspace
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx -y handoff-relay workspace create \
|
|
38
|
+
--server-url http://10.0.0.10:3737 \
|
|
39
|
+
--name "Relay Demo" \
|
|
40
|
+
--handle sam \
|
|
41
|
+
--display-name "Sam" \
|
|
42
|
+
--json
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Save the returned:
|
|
46
|
+
|
|
47
|
+
- `workspace.id`
|
|
48
|
+
- `admin.token`
|
|
49
|
+
- `admin.approval_secret`
|
|
50
|
+
|
|
51
|
+
Member tokens authenticate API/MCP calls. Approval secrets stay outside MCP and are used only by the local approval-token command.
|
|
52
|
+
|
|
53
|
+
## Invite And Accept A Member
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npx -y handoff-relay member invite \
|
|
57
|
+
--server-url http://10.0.0.10:3737 \
|
|
58
|
+
--token <sam-token> \
|
|
59
|
+
--workspace <workspace-id> \
|
|
60
|
+
--handle alice \
|
|
61
|
+
--json
|
|
62
|
+
|
|
63
|
+
npx -y handoff-relay member accept \
|
|
64
|
+
--server-url http://10.0.0.10:3737 \
|
|
65
|
+
--invite <invite-token> \
|
|
66
|
+
--display-name "Alice" \
|
|
67
|
+
--json
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Explicit-Auth MCP Mode
|
|
71
|
+
|
|
72
|
+
Profile-backed MCP is the normal mode:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npx -y handoff-relay server mcp --profile default
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Explicit-auth compatibility mode keeps the older schemas that include `authToken` and `workspaceId`:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npx -y handoff-relay server mcp \
|
|
82
|
+
--server-url http://10.0.0.10:3737 \
|
|
83
|
+
--explicit-auth
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Use explicit-auth mode only when a script or test harness intentionally supplies auth fields. Do not put approval secrets in MCP config.
|
|
87
|
+
|
|
88
|
+
## Draft, Approve, And Send
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx -y handoff-relay share-with @alice \
|
|
92
|
+
--server-url http://10.0.0.10:3737 \
|
|
93
|
+
--token <sam-token> \
|
|
94
|
+
--workspace <workspace-id> \
|
|
95
|
+
--title "Auth refresh handoff" \
|
|
96
|
+
--summary "The retry path still returns 401 after refresh-token rotation." \
|
|
97
|
+
--finding "The retry path appears to skip persistence before the second request." \
|
|
98
|
+
--source-client codex \
|
|
99
|
+
--evidence-json '[{"kind":"test_failure","label":"test output","source":"pnpm test auth-refresh","excerpt":"expected 200 received 401"}]' \
|
|
100
|
+
--files src/auth/refresh.ts,refreshSession \
|
|
101
|
+
--tests "pnpm test auth-refresh" \
|
|
102
|
+
--tried "Checked token expiry math,Re-ran the refresh integration test" \
|
|
103
|
+
--hypothesis "Refresh persistence ordering issue." \
|
|
104
|
+
--json
|
|
105
|
+
|
|
106
|
+
npx -y handoff-relay approval-token <handoff-packet-id> \
|
|
107
|
+
--server-url http://10.0.0.10:3737 \
|
|
108
|
+
--token <sam-token> \
|
|
109
|
+
--approval-secret <sam-approval-secret> \
|
|
110
|
+
--action send \
|
|
111
|
+
--json
|
|
112
|
+
|
|
113
|
+
npx -y handoff-relay approve <handoff-packet-id> \
|
|
114
|
+
--server-url http://10.0.0.10:3737 \
|
|
115
|
+
--token <sam-token> \
|
|
116
|
+
--approval-token <send-approval-token> \
|
|
117
|
+
--json
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Review And Hydrate
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npx -y handoff-relay inbox \
|
|
124
|
+
--server-url http://10.0.0.10:3737 \
|
|
125
|
+
--token <alice-token> \
|
|
126
|
+
--workspace <workspace-id> \
|
|
127
|
+
--json
|
|
128
|
+
|
|
129
|
+
npx -y handoff-relay view <handoff-packet-id> \
|
|
130
|
+
--server-url http://10.0.0.10:3737 \
|
|
131
|
+
--token <alice-token> \
|
|
132
|
+
--json
|
|
133
|
+
|
|
134
|
+
npx -y handoff-relay accept <handoff-packet-id> \
|
|
135
|
+
--server-url http://10.0.0.10:3737 \
|
|
136
|
+
--token <alice-token> \
|
|
137
|
+
--json
|
|
138
|
+
|
|
139
|
+
npx -y handoff-relay approval-token <handoff-packet-id> \
|
|
140
|
+
--server-url http://10.0.0.10:3737 \
|
|
141
|
+
--token <alice-token> \
|
|
142
|
+
--approval-secret <alice-approval-secret> \
|
|
143
|
+
--action hydrate \
|
|
144
|
+
--json
|
|
145
|
+
|
|
146
|
+
npx -y handoff-relay hydrate <handoff-packet-id> \
|
|
147
|
+
--server-url http://10.0.0.10:3737 \
|
|
148
|
+
--token <alice-token> \
|
|
149
|
+
--client claude-code \
|
|
150
|
+
--approval-token <hydrate-approval-token>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Reply
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
npx -y handoff-relay reply <ask-packet-id> "Persist the rotated refresh token before retrying." \
|
|
157
|
+
--server-url http://10.0.0.10:3737 \
|
|
158
|
+
--token <alice-token> \
|
|
159
|
+
--summary "Likely refresh persistence ordering issue." \
|
|
160
|
+
--source-client claude-code \
|
|
161
|
+
--json
|
|
162
|
+
|
|
163
|
+
npx -y handoff-relay approval-token <reply-packet-id> \
|
|
164
|
+
--server-url http://10.0.0.10:3737 \
|
|
165
|
+
--token <alice-token> \
|
|
166
|
+
--approval-secret <alice-approval-secret> \
|
|
167
|
+
--action reply \
|
|
168
|
+
--json
|
|
169
|
+
|
|
170
|
+
npx -y handoff-relay approve <reply-packet-id> \
|
|
171
|
+
--server-url http://10.0.0.10:3737 \
|
|
172
|
+
--token <alice-token> \
|
|
173
|
+
--approval-token <reply-approval-token> \
|
|
174
|
+
--json
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Watch
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
npx -y handoff-relay watch \
|
|
181
|
+
--server-url http://10.0.0.10:3737 \
|
|
182
|
+
--token <member-token> \
|
|
183
|
+
--workspace <workspace-id>
|
|
184
|
+
|
|
185
|
+
npx -y handoff-relay watch \
|
|
186
|
+
--server-url http://10.0.0.10:3737 \
|
|
187
|
+
--token <member-token> \
|
|
188
|
+
--workspace <workspace-id> \
|
|
189
|
+
--desktop-notifications
|
|
190
|
+
|
|
191
|
+
npx -y handoff-relay watch \
|
|
192
|
+
--server-url http://10.0.0.10:3737 \
|
|
193
|
+
--token <member-token> \
|
|
194
|
+
--workspace <workspace-id> \
|
|
195
|
+
--webhook-url https://hooks.example.test/relay
|
|
196
|
+
```
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Claude Code Setup
|
|
2
|
+
|
|
3
|
+
Handoff runs as a local stdio MCP server near each user's Claude Code session. The shared workspace lives on the host machine or server; every teammate joins it into their own local profile.
|
|
4
|
+
|
|
5
|
+
## Team Setup
|
|
6
|
+
|
|
7
|
+
On Sam's machine, host a LAN-reachable workspace:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx -y handoff-relay start --lan
|
|
11
|
+
npx -y handoff-relay invite alice
|
|
12
|
+
npx -y handoff-relay doctor
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
On Alice's machine, run the invite command Sam sends her:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx -y handoff-relay join http://<sam-lan-ip>:3737/invite/<invite-token>
|
|
19
|
+
npx -y handoff-relay doctor
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Alice does not run `start` for Sam's workspace. `join` accepts the invite, stores Alice's local profile and credentials, and prints the profile-backed MCP command for her Claude Code config.
|
|
23
|
+
|
|
24
|
+
If Alice is not on the same network, host Handoff behind a reachable URL and use `start --public-url <url>` or the dedicated server path in [Local self-hosting](local-self-hosting.md).
|
|
25
|
+
|
|
26
|
+
Handoff cannot safely edit every Claude Code config shape automatically, so setup prints the profile-backed command and the `claude mcp add-json` command below. `doctor` reports `WARN` until a supported MCP config contains that profile-backed command.
|
|
27
|
+
|
|
28
|
+
For same-machine demos or CI smoke tests, plain `start` remains available, but its invite links are loopback-only.
|
|
29
|
+
|
|
30
|
+
## Add Handoff To Claude Code
|
|
31
|
+
|
|
32
|
+
Claude Code can add MCP servers with `claude mcp add-json`, and it can load MCP config JSON with `--mcp-config`.
|
|
33
|
+
|
|
34
|
+
Add with the CLI:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
claude mcp add-json handoff \
|
|
38
|
+
'{"type":"stdio","command":"npx","args":["-y","handoff-relay","server","mcp","--profile","default"]}'
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Or create `handoff.mcp.json`:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"mcpServers": {
|
|
46
|
+
"handoff": {
|
|
47
|
+
"command": "npx",
|
|
48
|
+
"args": ["-y", "handoff-relay", "server", "mcp", "--profile", "default"]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Start Claude Code with that config:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
claude --mcp-config ./handoff.mcp.json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Inside Claude Code, use `/mcp` to inspect server status.
|
|
61
|
+
|
|
62
|
+
## Invocation Pattern
|
|
63
|
+
|
|
64
|
+
Ask Claude to create a handoff packet, then review the returned draft before approving:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
Use Handoff to create a Relay Packet for @alice from this session.
|
|
68
|
+
Include files touched, commands run, known failures, current hypothesis, evidence excerpts, and suggested next steps.
|
|
69
|
+
Draft only. Show me the packet summary, claims, evidence, expiry, and redaction report before sending.
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
In strict mode, before Claude calls `relay_approve`, generate a human approval token in a terminal:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npx -y handoff-relay approval-token <packet-id> --action send
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Recipient side:
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
Check my Handoff inbox. Show me the Relay Packet before hydration.
|
|
82
|
+
If I approve, hydrate it into this Claude Code session.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Hydration also needs a human approval token:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npx -y handoff-relay approval-token <packet-id> --action hydrate
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Approval-token minting is deliberately outside MCP so Claude cannot draft and approve a packet with only a member token. Keep approval secrets out of MCP config.
|
|
92
|
+
|
|
93
|
+
For a smoother local workflow, profile-backed MCP can opt into agent-confirmed approvals:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npx -y handoff-relay server mcp --profile default --agent-approvals
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
With that flag, Claude may call `relay_approve` or `relay_hydrate` without a pasted token after it shows you the packet and you explicitly tell it to send or hydrate. The MCP process requests the short-lived approval token through the configured Handoff backend; remote profiles send the approval secret to that server API. Approval secrets still stay out of Claude config and tool schemas.
|
|
100
|
+
|
|
101
|
+
## Remote Or Self-Hosted
|
|
102
|
+
|
|
103
|
+
Profile mode is still preferred after `join` because the profile stores the server URL and credentials locally.
|
|
104
|
+
|
|
105
|
+
Explicit-auth compatibility mode remains available for automation:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"mcpServers": {
|
|
110
|
+
"handoff": {
|
|
111
|
+
"command": "npx",
|
|
112
|
+
"args": [
|
|
113
|
+
"-y",
|
|
114
|
+
"handoff-relay",
|
|
115
|
+
"server",
|
|
116
|
+
"mcp",
|
|
117
|
+
"--server-url",
|
|
118
|
+
"http://10.0.0.10:3737",
|
|
119
|
+
"--explicit-auth"
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## From A Local Checkout
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
pnpm install
|
|
130
|
+
pnpm build
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"mcpServers": {
|
|
136
|
+
"handoff": {
|
|
137
|
+
"command": "node",
|
|
138
|
+
"args": ["/absolute/path/to/handoff/dist/cli.js", "server", "mcp", "--profile", "default"],
|
|
139
|
+
"cwd": "/absolute/path/to/handoff"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Codex Setup
|
|
2
|
+
|
|
3
|
+
Handoff runs as a local stdio MCP server beside each user's Codex session. The shared workspace lives on the host machine or server; every teammate joins it into their own local profile.
|
|
4
|
+
|
|
5
|
+
## Team Setup
|
|
6
|
+
|
|
7
|
+
On Sam's machine, host a LAN-reachable workspace and install the Codex MCP entry:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx -y handoff-relay start --lan --install-mcp codex
|
|
11
|
+
npx -y handoff-relay invite alice
|
|
12
|
+
npx -y handoff-relay doctor
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
On Alice's machine, run the invite command Sam sends her:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx -y handoff-relay join http://<sam-lan-ip>:3737/invite/<invite-token> --install-mcp codex
|
|
19
|
+
npx -y handoff-relay doctor
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Alice does not run `start` for Sam's workspace. `join` accepts the invite, stores Alice's local profile and credentials, and wires Codex when `--install-mcp codex` is present.
|
|
23
|
+
|
|
24
|
+
If Alice is not on the same network, host Handoff behind a reachable URL and use `start --public-url <url>` or the dedicated server path in [Local self-hosting](local-self-hosting.md).
|
|
25
|
+
|
|
26
|
+
## Local Demo Setup
|
|
27
|
+
|
|
28
|
+
For a same-machine demo or CI smoke test, use loopback-only setup:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx -y handoff-relay start --install-mcp codex
|
|
32
|
+
npx -y handoff-relay invite alice
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Add Handoff To Codex
|
|
36
|
+
|
|
37
|
+
Codex stores MCP configuration in `~/.codex/config.toml` by default, and trusted projects can use `.codex/config.toml`. The CLI and IDE extension share this config.
|
|
38
|
+
|
|
39
|
+
If you did not use `--install-mcp codex`, add this TOML:
|
|
40
|
+
|
|
41
|
+
```toml
|
|
42
|
+
[mcp_servers.handoff]
|
|
43
|
+
command = "npx"
|
|
44
|
+
args = ["-y", "handoff-relay", "server", "mcp", "--profile", "default"]
|
|
45
|
+
startup_timeout_sec = 10
|
|
46
|
+
tool_timeout_sec = 60
|
|
47
|
+
enabled = true
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
In Codex, use `/mcp` to inspect active MCP servers.
|
|
51
|
+
|
|
52
|
+
`npx -y handoff-relay doctor` reports `WARN` when no supported MCP client config contains the profile-backed Handoff command. That warning means Handoff setup exists, but Codex has not been wired to use it yet.
|
|
53
|
+
|
|
54
|
+
## Invocation Pattern
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
Use Handoff to package the current investigation context for @alice.
|
|
58
|
+
Include files touched, commands run, known failures, current hypothesis, evidence excerpts, and suggested next steps.
|
|
59
|
+
Show me the Relay Packet and redaction report before sending.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Recipient flow:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
Use Handoff to check my inbox. Show me any Relay Packet before hydration.
|
|
66
|
+
Wait for my approval before calling relay_hydrate.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Strict approval tokens are generated outside MCP:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx -y handoff-relay approval-token <packet-id> --action send
|
|
73
|
+
npx -y handoff-relay approval-token <packet-id> --action hydrate
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The command uses your active Handoff profile and asks for a local confirmation phrase. Do not put approval secrets in Codex config.
|
|
77
|
+
|
|
78
|
+
For a smoother local workflow, profile-backed MCP can opt into agent-confirmed approvals:
|
|
79
|
+
|
|
80
|
+
```toml
|
|
81
|
+
[mcp_servers.handoff]
|
|
82
|
+
command = "npx"
|
|
83
|
+
args = ["-y", "handoff-relay", "server", "mcp", "--profile", "default", "--agent-approvals"]
|
|
84
|
+
startup_timeout_sec = 10
|
|
85
|
+
tool_timeout_sec = 60
|
|
86
|
+
enabled = true
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
With that flag, Codex may call `relay_approve` or `relay_hydrate` without a pasted token after it shows you the packet and you explicitly tell it to send or hydrate. The MCP process requests the short-lived approval token through the configured Handoff backend; remote profiles send the approval secret to that server API. Approval secrets still stay out of Codex config and tool schemas.
|
|
90
|
+
|
|
91
|
+
## Remote Or Self-Hosted
|
|
92
|
+
|
|
93
|
+
For normal local/LAN use, keep the profile-backed command. For automation against a self-hosted server, explicit-auth compatibility mode remains available:
|
|
94
|
+
|
|
95
|
+
```toml
|
|
96
|
+
[mcp_servers.handoff]
|
|
97
|
+
command = "npx"
|
|
98
|
+
args = [
|
|
99
|
+
"-y",
|
|
100
|
+
"handoff-relay",
|
|
101
|
+
"server",
|
|
102
|
+
"mcp",
|
|
103
|
+
"--server-url",
|
|
104
|
+
"http://10.0.0.10:3737",
|
|
105
|
+
"--explicit-auth"
|
|
106
|
+
]
|
|
107
|
+
startup_timeout_sec = 10
|
|
108
|
+
tool_timeout_sec = 60
|
|
109
|
+
enabled = true
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
In explicit-auth mode, MCP tool schemas include `authToken` and `workspaceId`. Prefer profile mode for day-to-day agent use.
|
|
113
|
+
|
|
114
|
+
## From A Local Checkout
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
pnpm install
|
|
118
|
+
pnpm build
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```toml
|
|
122
|
+
[mcp_servers.handoff]
|
|
123
|
+
command = "node"
|
|
124
|
+
args = [
|
|
125
|
+
"/absolute/path/to/handoff/dist/cli.js",
|
|
126
|
+
"server",
|
|
127
|
+
"mcp",
|
|
128
|
+
"--profile",
|
|
129
|
+
"default"
|
|
130
|
+
]
|
|
131
|
+
cwd = "/absolute/path/to/handoff"
|
|
132
|
+
startup_timeout_sec = 10
|
|
133
|
+
tool_timeout_sec = 60
|
|
134
|
+
enabled = true
|
|
135
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Short Video Demo Script
|
|
2
|
+
|
|
3
|
+
Use this script to record a 60-90 second launch demo. It keeps the story narrow: one human-approved context handoff plus one optional reply handoff, with no hosted service.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
Record a terminal at 120 columns or wider.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
cd handoff
|
|
11
|
+
pnpm install
|
|
12
|
+
pnpm build
|
|
13
|
+
rm -f .relay/demo-video.db .relay/demo-video.db-shm .relay/demo-video.db-wal
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Recording Flow
|
|
17
|
+
|
|
18
|
+
1. Show the product promise:
|
|
19
|
+
"Handoff packages selected agent-session context into a reviewable packet so another coding agent can continue from the right evidence."
|
|
20
|
+
|
|
21
|
+
2. Run the full local demo:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx -y handoff-relay demo two-user --db .relay/demo-video.db --json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
3. Point out the shape of the output:
|
|
28
|
+
- workspace-scoped member identities without raw tokens or approval secrets
|
|
29
|
+
- ask status ending in `closed_resolved`
|
|
30
|
+
- reply status ending in `hydrated`
|
|
31
|
+
- share status ending in `archived`
|
|
32
|
+
- audit receipts on the packets
|
|
33
|
+
|
|
34
|
+
4. Show the watcher notification command users run in a second terminal:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx -y handoff-relay watch --db .relay/demo-video.db --token <alice-token> --workspace <workspace-id> --once
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
5. Show optional native desktop and webhook notification flags:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx -y handoff-relay watch --db .relay/demo-video.db --token <alice-token> --workspace <workspace-id> --desktop-notifications
|
|
44
|
+
npx -y handoff-relay watch --db .relay/demo-video.db --token <alice-token> --workspace <workspace-id> --webhook-url https://hooks.example.test/relay
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Closing Line
|
|
48
|
+
|
|
49
|
+
"No passive team memory, no raw transcript dump, no autonomous agent chat. Just structured teammate handoffs with approval, redaction, permissions, and receipts."
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Generic MCP Setup
|
|
2
|
+
|
|
3
|
+
Handoff is a stdio MCP server. Any MCP client that can launch a command with arguments can use it.
|
|
4
|
+
|
|
5
|
+
## Team Setup
|
|
6
|
+
|
|
7
|
+
On Sam's machine, host a LAN-reachable workspace:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx -y handoff-relay start --lan
|
|
11
|
+
npx -y handoff-relay invite alice
|
|
12
|
+
npx -y handoff-relay doctor
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
On Alice's machine, run the invite command Sam sends her:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx -y handoff-relay join http://<sam-lan-ip>:3737/invite/<invite-token>
|
|
19
|
+
npx -y handoff-relay doctor
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Alice does not run `start` for Sam's workspace. `join` accepts the invite, stores Alice's local profile and credentials, and prints the same profile-backed MCP command for her MCP client.
|
|
23
|
+
|
|
24
|
+
Handoff can write MCP config for Codex and Cursor when you ask explicitly:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx -y handoff-relay start --lan --install-mcp codex
|
|
28
|
+
npx -y handoff-relay start --lan --install-mcp cursor
|
|
29
|
+
npx -y handoff-relay join <invite-link> --install-mcp codex
|
|
30
|
+
npx -y handoff-relay join <invite-link> --install-mcp cursor
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For Claude Code and other MCP clients, use the printed profile-backed command. `doctor` reports `WARN` until it detects a supported Codex, Claude Code, or Cursor config that already includes Handoff profile mode.
|
|
34
|
+
|
|
35
|
+
For same-machine demos or CI smoke tests, plain `start` remains available, but its invite links are loopback-only.
|
|
36
|
+
|
|
37
|
+
## Profile-Backed Config
|
|
38
|
+
|
|
39
|
+
Use profile mode for normal agent sessions:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"mcpServers": {
|
|
44
|
+
"handoff": {
|
|
45
|
+
"command": "npx",
|
|
46
|
+
"args": ["-y", "handoff-relay", "server", "mcp", "--profile", "default"]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
In this mode, Handoff injects the member token and workspace ID from the local profile. Normal MCP tool schemas omit `authToken` and `workspaceId`. Approval secrets are never exposed through MCP.
|
|
53
|
+
|
|
54
|
+
Strict approval remains the default. If you want the local agent session to treat your explicit chat instruction as approval, add `--agent-approvals`:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"handoff": {
|
|
60
|
+
"command": "npx",
|
|
61
|
+
"args": ["-y", "handoff-relay", "server", "mcp", "--profile", "default", "--agent-approvals"]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
With that flag, the MCP process requests and consumes short-lived approval tokens through the configured Handoff backend after the agent shows you the packet and you explicitly tell it to send, approve, or hydrate. Local database profiles keep that request local; remote profiles send the approval secret to the configured Handoff server API.
|
|
68
|
+
|
|
69
|
+
## Cursor
|
|
70
|
+
|
|
71
|
+
In Cursor, open Settings > Tools & MCP and add a new MCP server, or create `.cursor/mcp.json` for a project-scoped setup or `~/.cursor/mcp.json` for a global setup:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npx -y handoff-relay start --lan --install-mcp cursor
|
|
75
|
+
npx -y handoff-relay join <invite-link> --install-mcp cursor
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"handoff": {
|
|
82
|
+
"command": "npx",
|
|
83
|
+
"args": ["-y", "handoff-relay", "server", "mcp", "--profile", "default"]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Then ask Cursor Agent:
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
Use Handoff to package the current investigation context for @alice.
|
|
93
|
+
Show me the Relay Packet before sending.
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## LAN And Remote Profiles
|
|
97
|
+
|
|
98
|
+
For a same-network team setup:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx -y handoff-relay start --lan
|
|
102
|
+
npx -y handoff-relay invite alice
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
For remote/self-hosted setups, users should `join` an invite link from that server. The saved profile records the remote server URL, so the MCP command stays the same:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npx -y handoff-relay server mcp --profile default
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Explicit-Auth Compatibility
|
|
112
|
+
|
|
113
|
+
For advanced scripts and tests that intentionally pass auth through tool inputs:
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"mcpServers": {
|
|
118
|
+
"handoff": {
|
|
119
|
+
"command": "npx",
|
|
120
|
+
"args": [
|
|
121
|
+
"-y",
|
|
122
|
+
"handoff-relay",
|
|
123
|
+
"server",
|
|
124
|
+
"mcp",
|
|
125
|
+
"--server-url",
|
|
126
|
+
"http://10.0.0.10:3737",
|
|
127
|
+
"--explicit-auth"
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Explicit-auth mode exposes `authToken` and `workspaceId` in schemas. Do not put approval secrets in config.
|
|
135
|
+
|
|
136
|
+
## Tool Contract
|
|
137
|
+
|
|
138
|
+
- `relay_ask`: draft an ask packet; returns `pending_sender_approval`.
|
|
139
|
+
- `relay_share`: draft a share packet; returns `pending_sender_approval`.
|
|
140
|
+
- `relay_update_draft`: edit a draft before sender approval.
|
|
141
|
+
- `relay_configure_project_alias`: maps a clone/repo alias to a canonical project name.
|
|
142
|
+
- `relay_project_aliases`: lists workspace project/repo aliases.
|
|
143
|
+
- `relay_approve`: approves and sends ask/share packets, or approves reply packets. Requires a human approval token unless profile-backed MCP started with `--agent-approvals`.
|
|
144
|
+
- `relay_inbox`: lists packets addressed to the current member.
|
|
145
|
+
- `relay_status`: fetches a readable packet.
|
|
146
|
+
- `relay_view`: records a review view.
|
|
147
|
+
- `relay_accept`: records recipient acceptance before hydration.
|
|
148
|
+
- `relay_hydrate`: returns bounded context plus a hydration receipt. Requires a human hydration approval token unless profile-backed MCP started with `--agent-approvals`.
|
|
149
|
+
- `relay_reply`: drafts a reply packet; returns `pending_recipient_approval`.
|
|
150
|
+
- `relay_clarify`: requests more information or evidence from the sender after packet review.
|
|
151
|
+
- `relay_decline`: declines an addressed packet.
|
|
152
|
+
- `relay_archive`: archives a readable packet.
|
|
153
|
+
- `relay_search`: searches only permitted packet history and never hydrates results.
|
|
154
|
+
- `relay_history`: lists drafts, sent packets, open work, or closed packets with typed filters.
|
|
155
|
+
- `relay_audit`: lists packet audit receipts, or workspace receipts for admins.
|
|
156
|
+
|
|
157
|
+
In strict mode, generate approval tokens through the local CLI:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npx -y handoff-relay approval-token <packet-id> --action send
|
|
161
|
+
npx -y handoff-relay approval-token <packet-id> --action hydrate
|
|
162
|
+
npx -y handoff-relay approval-token <reply-packet-id> --action reply
|
|
163
|
+
```
|