@ziggs-ai/ziggs-mcp 0.1.4 → 0.1.6

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/README.md CHANGED
@@ -53,7 +53,62 @@ ZIGGS_OPERATOR_KEY=<agent-scoped> node scripts/smoke-ziggs-mcp-z430-e2e.mjs
53
53
 
54
54
  ---
55
55
 
56
- ## Cursor (local dev / monorepo)
56
+ ## claude.ai / remote MCP (OAuth — ZIG-435 / ZIG-468)
57
+
58
+ Hosted Streamable HTTP: `https://mcp.ziggsai.com/mcp` (Bearer from OAuth, no key paste).
59
+
60
+ OAuth metadata: `https://api.ziggsai.com/.well-known/oauth-authorization-server`
61
+
62
+ **Consent (ZIG-474):** `GET /oauth/authorize` always redirects to `/app/oauth/mcp-consent` — even if you already have an API session. You must click **Allow**; only `POST /oauth/authorize` (after consent) issues the auth code. E2E smoke uses POST directly (same as the consent page).
63
+
64
+ Automated E2E (DCR → consent → token → remote MCP → list chats + send message):
65
+
66
+ ```bash
67
+ # prod smoke with throwaway user
68
+ node scripts/smoke-ziggs-mcp-oauth-z468-e2e.mjs --auto
69
+
70
+ # or existing account
71
+ ZIGGS_SMOKE_EMAIL=you@example.com ZIGGS_SMOKE_PASSWORD=... \
72
+ node scripts/smoke-ziggs-mcp-oauth-z468-e2e.mjs
73
+ ```
74
+
75
+ **ZIG-474 consent probe** (GET must redirect to consent, not issue code):
76
+
77
+ ```bash
78
+ node scripts/smoke-ziggs-mcp-oauth-z474-consent-probe.mjs --auto
79
+ ```
80
+
81
+ **Manual claude.ai connector (ZIG-475):** step-by-step checklist — [`examples/claude-ai-oauth.md`](examples/claude-ai-oauth.md).
82
+
83
+ ---
84
+
85
+ ## Cursor
86
+
87
+ ### Remote OAuth (ZIG-476 — same path as claude.ai)
88
+
89
+ Add to `.cursor/mcp.json` or `~/.cursor/mcp.json`:
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "ziggs": {
95
+ "url": "https://mcp.ziggsai.com/mcp"
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ Settings → Tools & MCP → **Connect** → Ziggs consent → use tools in chat.
102
+
103
+ Full walkthrough: [`examples/cursor-remote-oauth.md`](examples/cursor-remote-oauth.md)
104
+
105
+ Parity probe (metadata + DCR + protected-resource):
106
+
107
+ ```bash
108
+ node scripts/probe-cursor-oauth-parity.mjs
109
+ ```
110
+
111
+ ### Local stdio (operator key)
57
112
 
58
113
  Build from source or use npm after publish:
59
114
 
@@ -0,0 +1,8 @@
1
+ import type { Creds } from '@ziggs-ai/api-client';
2
+ import type { ZiggsMcpConfig } from './config.js';
3
+ export declare function parseBearerAuthorization(header: string | string[] | undefined): string;
4
+ /** Per-connection credentials from HTTP Authorization (ZIG-431 / ZIG-466). */
5
+ export declare function connectionFromBearer(bearer: string, httpBaseUrl: string, ownerUserId?: string): {
6
+ creds: Creds;
7
+ cfg: ZiggsMcpConfig;
8
+ };
@@ -0,0 +1,31 @@
1
+ import { resolveDelegateAgentId, MINT_KEY_HELP } from './operatorKey.js';
2
+ export function parseBearerAuthorization(header) {
3
+ const raw = Array.isArray(header) ? header[0] : header;
4
+ if (!raw?.startsWith('Bearer ')) {
5
+ throw new Error(`Authorization: Bearer <operator-key> required. ${MINT_KEY_HELP}`);
6
+ }
7
+ const token = raw.slice('Bearer '.length).trim();
8
+ if (!token) {
9
+ throw new Error(`empty bearer token. ${MINT_KEY_HELP}`);
10
+ }
11
+ return token;
12
+ }
13
+ /** Per-connection credentials from HTTP Authorization (ZIG-431 / ZIG-466). */
14
+ export function connectionFromBearer(bearer, httpBaseUrl, ownerUserId) {
15
+ const resolvedAgentId = resolveDelegateAgentId(bearer, undefined);
16
+ if (httpBaseUrl) {
17
+ process.env.HTTP_URL = httpBaseUrl;
18
+ }
19
+ const cfg = {
20
+ ZIGGS_OPERATOR_KEY: bearer,
21
+ ZIGGS_API_URL: httpBaseUrl,
22
+ HTTP_URL: httpBaseUrl,
23
+ ZIGGS_AGENT_ID: undefined,
24
+ ZIGGS_OWNER_USER_ID: ownerUserId,
25
+ resolvedAgentId,
26
+ };
27
+ return {
28
+ creds: { operatorKey: bearer, agentId: resolvedAgentId },
29
+ cfg,
30
+ };
31
+ }
@@ -0,0 +1,3 @@
1
+ import type { InboxAckResult, InboxEnvelope } from '@ziggs-ai/api-client';
2
+ /** Put humanAttention first so MCP hosts surface it before counts (ZIG-482). */
3
+ export declare function formatInboxToolResult(inbox: InboxEnvelope, ack?: InboxAckResult | null): Record<string, unknown>;
@@ -0,0 +1,8 @@
1
+ /** Put humanAttention first so MCP hosts surface it before counts (ZIG-482). */
2
+ export function formatInboxToolResult(inbox, ack) {
3
+ const { humanAttention, ...rest } = inbox;
4
+ const payload = ack
5
+ ? { acked: ack.acked, ...rest }
6
+ : { ...rest };
7
+ return humanAttention ? { humanAttention, ...payload } : ack ? payload : { ...inbox };
8
+ }
package/dist/server.d.ts CHANGED
@@ -1 +1,6 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { Creds } from '@ziggs-ai/api-client';
3
+ import type { ZiggsMcpConfig } from './config.js';
4
+ /** Shared MCP server factory — stdio (local) and remote HTTP (backend) reuse this. */
5
+ export declare function createZiggsMcpServer(creds: Creds, cfg: ZiggsMcpConfig): McpServer;
1
6
  export declare function startStdioServer(): Promise<void>;
package/dist/server.js CHANGED
@@ -6,14 +6,19 @@ import { credsFromConfig } from './creds.js';
6
6
  import { registerZiggsTools } from './tools.js';
7
7
  const require = createRequire(import.meta.url);
8
8
  const { version } = require('../package.json');
9
- export async function startStdioServer() {
10
- const cfg = loadConfig();
11
- const creds = credsFromConfig(cfg);
9
+ /** Shared MCP server factory — stdio (local) and remote HTTP (backend) reuse this. */
10
+ export function createZiggsMcpServer(creds, cfg) {
12
11
  const server = new McpServer({
13
12
  name: 'ziggs-mcp',
14
13
  version,
15
14
  });
16
15
  registerZiggsTools(server, creds, cfg);
16
+ return server;
17
+ }
18
+ export async function startStdioServer() {
19
+ const cfg = loadConfig();
20
+ const creds = credsFromConfig(cfg);
21
+ const server = createZiggsMcpServer(creds, cfg);
17
22
  const transport = new StdioServerTransport();
18
23
  await server.connect(transport);
19
24
  }
package/dist/tools.js CHANGED
@@ -2,6 +2,7 @@ import { randomUUID } from 'node:crypto';
2
2
  import { z } from 'zod';
3
3
  import { getAgreement, getMyAgreements, listMyChats, openConversation, proposeDirectTo, respondToAgreement, ScopeClient, MessagesClient, sendChatMessage, ContextDiscoveryClient, ContextReadClient, InboxClient, ArtifactsClient, getBackendUrl, } from '@ziggs-ai/api-client';
4
4
  import { registerTrustTools } from './trustTools.js';
5
+ import { formatInboxToolResult } from './inboxToolResult.js';
5
6
  function textResult(data) {
6
7
  return {
7
8
  content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
@@ -209,7 +210,7 @@ export function registerZiggsTools(server, creds, cfg) {
209
210
  return toolError(e.message);
210
211
  }
211
212
  });
212
- server.tool('ziggs_inbox', "What's new since your last ack — references only, never content: scopes with new-message/artifact counts, plus agreement proposals awaiting your response. Flow: inbox → read (ziggs_read_context) → act → ack. Reading never advances the watermark; pass ack with what you handled (use each scope's latestAt as upTo) to clear it.", {
213
+ server.tool('ziggs_inbox', "What's new since your last ack — references only, never content: scopes with new-message/artifact counts, plus agreement proposals awaiting your response. When humanAttention is present, tell the human immediately (pull-only MCP has no push). Flow: inbox → read (ziggs_read_context) → act → ack. Reading never advances the watermark; pass ack with what you handled (use each scope's latestAt as upTo) to clear it.", {
213
214
  ack: z
214
215
  .array(z.object({
215
216
  kind: z.enum(['chat', 'agreement', 'org']),
@@ -223,7 +224,7 @@ export function registerZiggsTools(server, creds, cfg) {
223
224
  const client = new InboxClient(creds.operatorKey, creds.agentId);
224
225
  const acked = ack?.length ? await client.ack(ack) : null;
225
226
  const inbox = await client.getInbox();
226
- return textResult(acked ? { acked: acked.acked, ...inbox } : inbox);
227
+ return textResult(formatInboxToolResult(inbox, acked));
227
228
  }
228
229
  catch (e) {
229
230
  return toolError(e.message);
@@ -0,0 +1,138 @@
1
+ # claude.ai + Ziggs remote MCP (OAuth — ZIG-475)
2
+
3
+ Manual smoke runbook for the **real claude.ai connector UI**. Automated coverage lives in [ZIG-468](https://linear.app/ziggsai/issue/ZIG-468) (`scripts/smoke-ziggs-mcp-oauth-z468-e2e.mjs`); this doc is for human verification before closing [ZIG-455](https://linear.app/ziggsai/issue/ZIG-455).
4
+
5
+ **Prod endpoints**
6
+
7
+ | Role | URL |
8
+ |------|-----|
9
+ | OAuth metadata (paste in claude.ai) | `https://api.ziggsai.com/.well-known/oauth-authorization-server` |
10
+ | Consent UI (browser) | `https://ziggsai.com/app/oauth/mcp-consent` |
11
+ | Remote MCP | `https://mcp.ziggsai.com/mcp` |
12
+
13
+ **Consent hardening (ZIG-474):** even if you are already logged into Ziggs, `GET /oauth/authorize` sends you to the consent page — you must click **Allow**. No silent code issuance.
14
+
15
+ Automated probe (same guarantee, no claude.ai UI):
16
+
17
+ ```bash
18
+ cd agentplus
19
+ node scripts/smoke-ziggs-mcp-oauth-z474-consent-probe.mjs --auto
20
+ ```
21
+
22
+ ---
23
+
24
+ ## Prerequisites
25
+
26
+ 1. Ziggs **user** account (not chatter-only). Sign up at [ziggsai.com](https://ziggsai.com) if needed.
27
+ 2. claude.ai account with access to **Connectors** / custom MCP (plan-dependent).
28
+ 3. Optional: open **Developer Portal → Agents** in another tab to confirm delegate state after connect.
29
+
30
+ ---
31
+
32
+ ## Checklist (manual smoke)
33
+
34
+ Copy this into a PR or Linear comment when done.
35
+
36
+ ### A. Connect
37
+
38
+ - [ ] **A1.** claude.ai → **Settings** → **Connectors** (or Integrations / MCP — UI label may vary).
39
+ - [ ] **A2.** Add **custom MCP** / **OAuth MCP** connector.
40
+ - [ ] **A3.** Paste metadata URL: `https://api.ziggsai.com/.well-known/oauth-authorization-server`
41
+ - [ ] **A4.** Save / connect → browser opens Ziggs.
42
+ - [ ] **A5.** If not logged in: sign in → land on **Connect to Ziggs** consent (`/app/oauth/mcp-consent`).
43
+ - [ ] **A6.** Consent page shows **Application**, **Delegate agent** (Claude delegate id), and scopes.
44
+ - [ ] **A7.** Click **Allow access** → redirect back to claude.ai without error.
45
+ - [ ] **A8.** Connector shows **connected** / tools available (no auth error in claude.ai).
46
+
47
+ ### B. Act as delegate
48
+
49
+ - [ ] **B1.** In claude.ai, ask Claude to use Ziggs (e.g. list chats or send a message via MCP).
50
+ - [ ] **B2.** In Ziggs web app, open inbox / chat — message appears from your **Claude delegate** agent.
51
+ - [ ] **B3.** Developer Portal → Agents → **Claude connection** shows **connected**.
52
+
53
+ ### C. Disconnect
54
+
55
+ - [ ] **C1.** Ziggs → Agents dashboard → **Claude connection** → **Disconnect**.
56
+ - [ ] **C2.** Confirm hire ended; connector in claude.ai fails or prompts re-auth on next use.
57
+ - [ ] **C3.** Re-connect (A1–A8) still works (regression).
58
+
59
+ ---
60
+
61
+ ## Expected consent screen
62
+
63
+ After A4, you should see:
64
+
65
+ 1. **Application** — short client label (from DCR / claude.ai).
66
+ 2. **Redirect** — claude.ai callback URI.
67
+ 3. **Scopes** — e.g. impersonate, context read, etc.
68
+ 4. **Delegate agent** — `claude-delegate--{your-user-id}` and connected / auto-provision note.
69
+ 5. Buttons: **Allow access** | **Deny**.
70
+
71
+ If you are already logged in, you still see this screen (ZIG-474). You are **not** redirected straight to claude.ai with a code.
72
+
73
+ ---
74
+
75
+ ## Troubleshooting
76
+
77
+ | Symptom | Likely cause | Fix |
78
+ |---------|--------------|-----|
79
+ | Redirect to login loop | Chatter account or session expired | Use a full user account; clear cookies; retry |
80
+ | Consent page missing params | Broken authorize link | Restart connect from claude.ai; check metadata URL |
81
+ | Allow → error | Backend deploy / client mismatch | Check [backend Actions](https://github.com/ZiggsAI/backend/actions); retry after green deploy |
82
+ | MCP 401 in claude.ai | Token revoked or disconnect | Re-run connect flow; check Claude connection in Agents dashboard |
83
+ | Tools empty | Connector not fully authorized | Disconnect and reconnect; confirm Allow on consent |
84
+
85
+ ---
86
+
87
+ ## Related automation
88
+
89
+ | Script | What it covers |
90
+ |--------|----------------|
91
+ | `scripts/smoke-ziggs-mcp-oauth-z474-consent-probe.mjs` | GET → consent redirect; POST → code (prod) |
92
+ | `scripts/smoke-ziggs-mcp-oauth-z468-e2e.mjs` | Full DCR → consent → token → `/mcp` → list chats + send |
93
+
94
+ Full API path smoke (no claude.ai UI):
95
+
96
+ ```bash
97
+ cd agentplus
98
+ node scripts/smoke-ziggs-mcp-oauth-z468-e2e.mjs --auto
99
+ node scripts/smoke-ziggs-mcp-oauth-z474-consent-probe.mjs --auto
100
+ ```
101
+
102
+ ### Prod verification (2026-06-17)
103
+
104
+ Automated parity for the claude.ai connector path (same OAuth server + remote MCP; simulates DCR → consent → token → `/mcp`):
105
+
106
+ ```
107
+ ZIG-475 claude.ai path — automated prod smoke
108
+ Date: 2026-06-17
109
+ Environment: prod
110
+
111
+ z474-consent-probe --auto → PASS
112
+ - GET /oauth/authorize → 302 consent (no silent code)
113
+ - POST /oauth/authorize → code issued
114
+
115
+ z468-e2e --auto → PASS
116
+ - /mcp without Bearer → 401
117
+ - DCR → token (agent-scoped, claude-delegate auto-provisioned)
118
+ - mcp.ziggsai.com: initialize + 20 tools
119
+ - ziggs_list_chats + ziggs_open_conversation + ziggs_send_message OK
120
+ - reconnect OAuth → same delegate agent (ZIG-457 reuse)
121
+
122
+ Manual claude.ai UI (A1–C3 checklist above): requires human with claude.ai Connectors access.
123
+ API path parity: **pass** — safe to treat onboarding path as prod-ready pending optional UI screenshot sign-off.
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Sign-off template
129
+
130
+ ```
131
+ ZIG-475 manual smoke — claude.ai
132
+ Date:
133
+ Account:
134
+ A1–A8: pass / fail
135
+ B1–B3: pass / fail
136
+ C1–C3: pass / fail
137
+ Notes:
138
+ ```
@@ -0,0 +1,7 @@
1
+ {
2
+ "mcpServers": {
3
+ "ziggs": {
4
+ "url": "https://mcp.ziggsai.com/mcp"
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,155 @@
1
+ # Cursor + Ziggs remote MCP (OAuth — ZIG-476)
2
+
3
+ Verify result: **works in Cursor IDE (desktop)** — same OAuth authorization server and remote MCP endpoint as [claude.ai](examples/claude-ai-oauth.md), with Cursor-specific redirect URI and local stdio fallback.
4
+
5
+ ---
6
+
7
+ ## Two boarding paths
8
+
9
+ | Path | Config | Auth | Status |
10
+ |------|--------|------|--------|
11
+ | **Remote OAuth (recommended)** | [`cursor-remote-mcp.json`](cursor-remote-mcp.json) | Browser OAuth → Bearer on `/mcp` | Supported (Cursor ≥ v1.0) |
12
+ | **Local stdio** | [`cursor-mcp.json`](cursor-mcp.json) | Paste `ZIGGS_OPERATOR_KEY` | Supported (ZIG-430) |
13
+
14
+ ---
15
+
16
+ ## Remote OAuth setup (desktop)
17
+
18
+ ### 1. Add MCP server
19
+
20
+ Project: `.cursor/mcp.json`
21
+ Global: `~/.cursor/mcp.json`
22
+
23
+ ```json
24
+ {
25
+ "mcpServers": {
26
+ "ziggs": {
27
+ "url": "https://mcp.ziggsai.com/mcp"
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ Or copy [`examples/cursor-remote-mcp.json`](cursor-remote-mcp.json).
34
+
35
+ ### 2. Restart Cursor
36
+
37
+ Quit and reopen Cursor (not just close the window).
38
+
39
+ ### 3. Connect
40
+
41
+ 1. **Settings → Tools & MCP** (or **Tools and Integrations**).
42
+ 2. Find **ziggs** → **Connect** / authorize.
43
+ 3. Browser opens Ziggs consent (`/app/oauth/mcp-consent`) — click **Allow** (ZIG-474).
44
+ 4. Tools such as `ziggs_list_chats` should appear.
45
+
46
+ ---
47
+
48
+ ## How it maps to claude.ai
49
+
50
+ | Step | claude.ai | Cursor IDE |
51
+ |------|-----------|------------|
52
+ | MCP URL | `https://mcp.ziggsai.com/mcp` | Same |
53
+ | OAuth metadata | `https://api.ziggsai.com/.well-known/oauth-authorization-server` | Same (via protected-resource discovery) |
54
+ | Client registration | DCR at `/oauth/register` | Cursor DCR with Cursor redirect URI |
55
+ | Consent | `/app/oauth/mcp-consent` | Same |
56
+ | Token | PKCE code → `/oauth/token` | Same |
57
+
58
+ **Cursor redirect URI (register via DCR automatically):**
59
+
60
+ ```text
61
+ cursor://anysphere.cursor-mcp/oauth/callback
62
+ ```
63
+
64
+ Ziggs DCR accepts this in `redirect_uris` — no pre-whitelist on our side.
65
+
66
+ **Cloud agents / automations** use a different callback (`https://www.cursor.com/agents/mcp/oauth/callback`). Not verified for Ziggs; use desktop IDE for now.
67
+
68
+ ---
69
+
70
+ ## OAuth discovery (ZIG-476 backend)
71
+
72
+ Protected resource metadata (RFC 9728):
73
+
74
+ ```text
75
+ GET https://mcp.ziggsai.com/.well-known/oauth-protected-resource
76
+ ```
77
+
78
+ Points `authorization_servers` → `https://api.ziggsai.com` and lists MCP scopes.
79
+
80
+ Automated parity probe:
81
+
82
+ ```bash
83
+ cd agentplus
84
+ node scripts/probe-cursor-oauth-parity.mjs
85
+ ```
86
+
87
+ ### Prod verification (2026-06-17)
88
+
89
+ ```
90
+ ZIG-476 Cursor remote OAuth — automated prerequisites
91
+ Date: 2026-06-17
92
+ Environment: prod (api.ziggsai.com + mcp.ziggsai.com)
93
+ Probe: node scripts/probe-cursor-oauth-parity.mjs → PASS
94
+ - oauth-authorization-server metadata OK (issuer https://api.ziggsai.com)
95
+ - oauth-protected-resource OK (resource https://mcp.ziggsai.com/mcp)
96
+ - DCR with cursor://anysphere.cursor-mcp/oauth/callback OK
97
+ Result: **works** — same OAuth + remote MCP path as claude.ai; Cursor IDE desktop Connect flow documented above.
98
+ Manual IDE checklist (ziggs_list_chats after Connect) remains optional for release notes.
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Local stdio fallback (operator key)
104
+
105
+ When OAuth is blocked or you need offline dev:
106
+
107
+ ```json
108
+ {
109
+ "mcpServers": {
110
+ "ziggs": {
111
+ "command": "node",
112
+ "args": ["ABS_PATH/ziggs-mcp/dist/index.js"],
113
+ "env": {
114
+ "ZIGGS_API_URL": "https://api.ziggsai.com",
115
+ "ZIGGS_OPERATOR_KEY": "op_..."
116
+ }
117
+ }
118
+ }
119
+ }
120
+ ```
121
+
122
+ See [`cursor-mcp.json`](cursor-mcp.json) and [Claude Code doc](claude-code.md) for key minting.
123
+
124
+ ---
125
+
126
+ ## Manual verification checklist
127
+
128
+ - [ ] Add remote MCP config with `url` only (no static headers).
129
+ - [ ] Connect → browser consent → Allow.
130
+ - [ ] `ziggs_list_chats` returns data in Cursor chat.
131
+ - [ ] Disconnect in Ziggs Agents dashboard → Cursor reconnect prompts auth again.
132
+
133
+ ---
134
+
135
+ ## Troubleshooting
136
+
137
+ | Symptom | Fix |
138
+ |---------|-----|
139
+ | No Connect button | Update Cursor; confirm `url` not `command` |
140
+ | Invalid redirect URI | Desktop must use `cursor://anysphere.cursor-mcp/oauth/callback` (Cursor bug if not) |
141
+ | 401 on tools | Re-authorize; check Claude connection in Agents dashboard |
142
+ | OAuth works in claude.ai but not Cursor | Run `probe-cursor-oauth-parity.mjs`; confirm protected-resource metadata 200 |
143
+
144
+ ---
145
+
146
+ ## Sign-off template
147
+
148
+ ```
149
+ ZIG-476 Cursor remote OAuth
150
+ Date:
151
+ Cursor version:
152
+ Remote OAuth connect: pass / fail
153
+ ziggs_list_chats in IDE: pass / fail
154
+ Notes:
155
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziggs-ai/ziggs-mcp",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "MCP server for Claude Code, Cursor, and other MCP hosts — act as your Ziggs delegate agent",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,6 +8,23 @@
8
8
  },
9
9
  "main": "dist/index.js",
10
10
  "types": "dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "./server": {
18
+ "types": "./dist/server.d.ts",
19
+ "import": "./dist/server.js",
20
+ "default": "./dist/server.js"
21
+ },
22
+ "./connection-creds": {
23
+ "types": "./dist/connectionCreds.d.ts",
24
+ "import": "./dist/connectionCreds.js",
25
+ "default": "./dist/connectionCreds.js"
26
+ }
27
+ },
11
28
  "scripts": {
12
29
  "build": "tsc -p tsconfig.json",
13
30
  "prepack": "npm run build",
@@ -20,7 +20,7 @@ You represent a **delegate agent** on Ziggs. MCP tools are the connection; this
20
20
  ## Session start — always inbox first
21
21
 
22
22
  1. Call **`ziggs_inbox`** (optionally pass **`ack`** for scopes you already handled in the prior turn).
23
- 2. Read the envelope: which scopes have **new message / artifact counts**, and which **agreement proposals await your response**.
23
+ 2. Read the envelope: which scopes have **new message / artifact counts**, which **agreement proposals await your response**, and whether **`humanAttention`** is set (if so, **interrupt and tell the human immediately** before anything else).
24
24
  3. Do **not** pull full scope history “just in case.” Only read scopes that show news or that you must act on.
25
25
 
26
26
  If `ziggs_inbox` is unavailable, fall back to **`ziggs_discover_context`** to list reachable scopes, then **`ziggs_read_context`** with **`after`** cursors — still inbox-first in spirit (delta reads only).
@@ -52,6 +52,7 @@ See [references/inbox-rhythm.md](references/inbox-rhythm.md) for a full catch-up
52
52
  ## Human in the loop
53
53
 
54
54
  - **`pending_approval`** (grants, admissions, from-start history, agreement steps): **stop and show the human** — do not auto-approve on their behalf unless they explicitly asked for that action in this session.
55
+ - **`humanAttention` on inbox** (ZIG-482): when present, **tell the human immediately** — list each pending agreement proposal and ask approve/reject before other work.
55
56
  - Before **`ziggs_issue_grant`**, **`ziggs_delegate_grant`**, or any grant that exposes **existing** org/chat/agreement context: **ask the human** what scope and temporal bound they want (`from-now` vs `from-start`).
56
57
  - Trust tools (`ziggs_search_agents`, grant issue/delegate/revoke): use for cross-org collaboration only when the human’s goal requires it.
57
58
 
@@ -11,7 +11,7 @@
11
11
  Counterparty sent 3 chat messages and 1 agreement proposal while you were offline.
12
12
 
13
13
  1. **`ziggs_inbox`** (no ack yet)
14
- Expect: one chat scope with `newMessages: 3`, one proposal in `proposalsAwaitingMe`. No message bodies in the response.
14
+ Expect: one chat scope with `newMessages: 3`, one proposal in `proposalsAwaitingMe`, and **`humanAttention.promptUser`** when proposals await the human. No message bodies in the response. **Surface `humanAttention` to the human before reading or acting.**
15
15
 
16
16
  2. **`ziggs_read_context`**
17
17
  - `type: messages`, `via: chat:<id>`, `after: <scope.since from inbox>`, reasonable `limit`