@ziggs-ai/ziggs-mcp 0.1.1 → 0.1.3
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 +27 -2
- package/dist/tools.js +2 -0
- package/dist/trustTools.d.ts +4 -0
- package/dist/trustTools.js +166 -0
- package/examples/claude-code.md +8 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -29,6 +29,12 @@ Full walkthrough: [`examples/claude-code.md`](examples/claude-code.md)
|
|
|
29
29
|
| Send message | `ziggs_send_message` |
|
|
30
30
|
| Propose + respond | `ziggs_propose_agreement`, `ziggs_respond_to_agreement` |
|
|
31
31
|
|
|
32
|
+
Automated verify (same MCP path as `claude mcp add` + `npx`):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
ZIGGS_OPERATOR_KEY=<agent-scoped> node scripts/smoke-ziggs-mcp-z430-e2e.mjs
|
|
36
|
+
```
|
|
37
|
+
|
|
32
38
|
---
|
|
33
39
|
|
|
34
40
|
## Cursor (local dev / monorepo)
|
|
@@ -89,6 +95,16 @@ ZIGGS_OPERATOR_KEY_A=... ZIGGS_AGENT_ID_A=... \
|
|
|
89
95
|
ZIGGS_OPERATOR_KEY_B=... ZIGGS_AGENT_ID_B=... \
|
|
90
96
|
ZIGGS_SMOKE_CHAT_ID=... \
|
|
91
97
|
node scripts/smoke-ziggs-mcp-context.mjs
|
|
98
|
+
|
|
99
|
+
# ZIG-433 tools-only (npx trust tools after publish)
|
|
100
|
+
ZIGGS_OPERATOR_KEY=<agent-scoped> node scripts/smoke-ziggs-mcp-z433-e2e.mjs --tools-only
|
|
101
|
+
|
|
102
|
+
# ZIG-433 full two-org (delegate → approval → from-now read → revoke)
|
|
103
|
+
ZIGGS_OPERATOR_KEY_A=... ZIGGS_AGENT_ID_A=... \
|
|
104
|
+
ZIGGS_OPERATOR_KEY_B=... ZIGGS_AGENT_ID_B=... \
|
|
105
|
+
ZIGGS_APPROVER_OPERATOR_KEY=... ZIGGS_APPROVER_USER_ID=... \
|
|
106
|
+
ZIGGS_SMOKE_CHAT_ID=... \
|
|
107
|
+
node scripts/smoke-ziggs-mcp-z433-e2e.mjs
|
|
92
108
|
```
|
|
93
109
|
|
|
94
110
|
---
|
|
@@ -101,6 +117,11 @@ ZIGGS_SMOKE_CHAT_ID=... \
|
|
|
101
117
|
| `ziggs_read_context` | `GET /context/read/:type` |
|
|
102
118
|
| `ziggs_record_artifact` | `POST /artifacts` |
|
|
103
119
|
| `ziggs_list_artifacts` | `GET /artifacts` |
|
|
120
|
+
| `ziggs_search_agents` | Agent search (ZIG-433) |
|
|
121
|
+
| `ziggs_list_my_grants` | `GET /context/grants` |
|
|
122
|
+
| `ziggs_issue_grant` | Chat admission or `POST /context/grants` |
|
|
123
|
+
| `ziggs_delegate_grant` | `POST /context/grants/:id/delegate` |
|
|
124
|
+
| `ziggs_revoke_grant` | `DELETE /context/grants/:id` |
|
|
104
125
|
| `ziggs_smoke_impersonation` | Smoke step 1 |
|
|
105
126
|
| `ziggs_get_scope` | `GET /scope?via=` |
|
|
106
127
|
| `ziggs_list_my_agreements` | `GET /agreements?scope=mine` |
|
|
@@ -131,6 +152,10 @@ Logs must use **stderr** only (stdio MCP transport).
|
|
|
131
152
|
2. Tag `ziggs-mcp-v*` → CI publishes `@ziggs-ai/ziggs-mcp`.
|
|
132
153
|
|
|
133
154
|
```bash
|
|
134
|
-
git tag api-client-v0.1.
|
|
135
|
-
git tag ziggs-mcp-v0.1.
|
|
155
|
+
git tag api-client-v0.1.8 && git push origin api-client-v0.1.8
|
|
156
|
+
git tag ziggs-mcp-v0.1.3 && git push origin ziggs-mcp-v0.1.3
|
|
136
157
|
```
|
|
158
|
+
|
|
159
|
+
CI publishes on tag push. Push **api-client tag first**, then ziggs-mcp.
|
|
160
|
+
|
|
161
|
+
npm `--provenance` is not used: npm only supports provenance when the GitHub source repo is **public** (agentplus is private → 422).
|
package/dist/tools.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
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, ArtifactsClient, getBackendUrl, } from '@ziggs-ai/api-client';
|
|
4
|
+
import { registerTrustTools } from './trustTools.js';
|
|
4
5
|
function textResult(data) {
|
|
5
6
|
return {
|
|
6
7
|
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
@@ -303,4 +304,5 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
303
304
|
return toolError(e.message);
|
|
304
305
|
}
|
|
305
306
|
});
|
|
307
|
+
registerTrustTools(server, creds);
|
|
306
308
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { type Creds } from '@ziggs-ai/api-client';
|
|
3
|
+
/** ZIG-433 — agent search + context grant management through MCP. */
|
|
4
|
+
export declare function registerTrustTools(server: McpServer, creds: Creds): void;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AgentSearchClient, ContextGrantsClient, addChatMember, } from '@ziggs-ai/api-client';
|
|
3
|
+
function textResult(data) {
|
|
4
|
+
return {
|
|
5
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function toolError(message) {
|
|
9
|
+
return {
|
|
10
|
+
content: [{ type: 'text', text: message }],
|
|
11
|
+
isError: true,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const grantScopeKindSchema = z.enum(['chat', 'agreement', 'org']);
|
|
15
|
+
const contextTemporalSchema = z.enum(['from-now', 'from-start']);
|
|
16
|
+
/** ZIG-433 — agent search + context grant management through MCP. */
|
|
17
|
+
export function registerTrustTools(server, creds) {
|
|
18
|
+
server.tool('ziggs_search_agents', 'Search published agents by query (AgentSearchClient). Use returned agentId in grant/issue tools — do not guess ids.', {
|
|
19
|
+
query: z.string().describe('Natural language or keyword search'),
|
|
20
|
+
limit: z.number().optional().describe('Max results (default server-side)'),
|
|
21
|
+
minScore: z.number().optional().describe('Minimum match score filter'),
|
|
22
|
+
}, async ({ query, limit, minScore }) => {
|
|
23
|
+
try {
|
|
24
|
+
const client = new AgentSearchClient(creds.operatorKey, creds.agentId);
|
|
25
|
+
const result = await client.searchAgents(query, { limit, minScore });
|
|
26
|
+
if (!result.success) {
|
|
27
|
+
return toolError(result.error ?? result.message ?? 'search failed');
|
|
28
|
+
}
|
|
29
|
+
return textResult({
|
|
30
|
+
count: result.agents?.length ?? 0,
|
|
31
|
+
agents: result.agents ?? [],
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
return toolError(e.message);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
server.tool('ziggs_list_my_grants', 'List context grants held by the delegate agent (GET /context/grants). Returns grantId, scope, temporal, watermarkAt, expiresAt — no content.', {
|
|
39
|
+
holderId: z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe('Admin only: list grants for another agent id'),
|
|
43
|
+
}, async ({ holderId }) => {
|
|
44
|
+
try {
|
|
45
|
+
const client = new ContextGrantsClient(creds.operatorKey, creds.agentId);
|
|
46
|
+
const grants = await client.listGrants(holderId);
|
|
47
|
+
return textResult({ count: grants.length, grants });
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
return toolError(e.message);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
server.tool('ziggs_issue_grant', 'Issue bounded context access. Chat scope: admits agent via POST /chats/:id/members (agent-invite → pending_approval until humans consent). Agreement/org scope: POST /context/grants (requires context:admin on operator key). Defaults: from-now, narrow scope.', {
|
|
54
|
+
holderId: z.string().describe('Bare agent id receiving the grant'),
|
|
55
|
+
scopeKind: grantScopeKindSchema,
|
|
56
|
+
scopeId: z.string().describe('chatId, agreementId, or orgId'),
|
|
57
|
+
temporal: contextTemporalSchema
|
|
58
|
+
.optional()
|
|
59
|
+
.describe('from-now (default) or from-start (approval-gated on chat)'),
|
|
60
|
+
expiresAt: z
|
|
61
|
+
.string()
|
|
62
|
+
.optional()
|
|
63
|
+
.nullable()
|
|
64
|
+
.describe('ISO-8601 expiry; omit for platform default TTL'),
|
|
65
|
+
}, async ({ holderId, scopeKind, scopeId, temporal, expiresAt }) => {
|
|
66
|
+
const resolvedTemporal = temporal ?? 'from-now';
|
|
67
|
+
try {
|
|
68
|
+
if (scopeKind === 'chat') {
|
|
69
|
+
const result = await addChatMember({
|
|
70
|
+
chatId: scopeId,
|
|
71
|
+
memberId: holderId,
|
|
72
|
+
memberType: 'agent',
|
|
73
|
+
temporal: resolvedTemporal,
|
|
74
|
+
}, creds);
|
|
75
|
+
if ('status' in result && result.status === 'pending') {
|
|
76
|
+
return textResult({
|
|
77
|
+
status: 'pending_approval',
|
|
78
|
+
message: 'Human approval required before the grant is issued (ZIG-426). Surface this to the user — do not treat as success.',
|
|
79
|
+
scope: { kind: 'chat', id: scopeId },
|
|
80
|
+
holderId,
|
|
81
|
+
temporal: resolvedTemporal,
|
|
82
|
+
pendingAdmission: result.pendingAdmission,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return textResult({
|
|
86
|
+
status: 'granted',
|
|
87
|
+
scope: { kind: 'chat', id: scopeId },
|
|
88
|
+
holderId,
|
|
89
|
+
temporal: resolvedTemporal,
|
|
90
|
+
bounds: {
|
|
91
|
+
temporal: resolvedTemporal,
|
|
92
|
+
note: 'from-now: readable content starts at grant watermark; from-start requires unanimous approval',
|
|
93
|
+
},
|
|
94
|
+
chat: 'chat' in result ? result.chat : undefined,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const client = new ContextGrantsClient(creds.operatorKey, creds.agentId);
|
|
98
|
+
const grant = await client.issueGrant({
|
|
99
|
+
holderId,
|
|
100
|
+
scope: { kind: scopeKind, id: scopeId },
|
|
101
|
+
temporal: resolvedTemporal,
|
|
102
|
+
expiresAt,
|
|
103
|
+
});
|
|
104
|
+
return textResult({
|
|
105
|
+
status: 'granted',
|
|
106
|
+
grant,
|
|
107
|
+
bounds: {
|
|
108
|
+
temporal: grant.temporal,
|
|
109
|
+
watermarkAt: grant.watermarkAt,
|
|
110
|
+
expiresAt: grant.expiresAt,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
return toolError(e.message);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
server.tool('ziggs_delegate_grant', 'Delegate a narrower child grant from one you hold (POST /context/grants/:id/delegate). Delegation only narrows scope/expiry/temporal — never broadens.', {
|
|
119
|
+
parentGrantId: z.string(),
|
|
120
|
+
holderId: z.string().describe('Agent receiving the delegated grant'),
|
|
121
|
+
scopeKind: grantScopeKindSchema,
|
|
122
|
+
scopeId: z.string(),
|
|
123
|
+
temporal: contextTemporalSchema.describe('from-now or from-start (must be same-or-narrower)'),
|
|
124
|
+
expiresAt: z.string().optional().nullable(),
|
|
125
|
+
watermarkAt: z
|
|
126
|
+
.string()
|
|
127
|
+
.optional()
|
|
128
|
+
.describe('from-now watermark ISO-8601 (optional; server may default)'),
|
|
129
|
+
}, async ({ parentGrantId, holderId, scopeKind, scopeId, temporal, expiresAt, watermarkAt, }) => {
|
|
130
|
+
try {
|
|
131
|
+
const client = new ContextGrantsClient(creds.operatorKey, creds.agentId);
|
|
132
|
+
const grant = await client.delegateGrant(parentGrantId, {
|
|
133
|
+
holderId,
|
|
134
|
+
scope: { kind: scopeKind, id: scopeId },
|
|
135
|
+
temporal,
|
|
136
|
+
expiresAt,
|
|
137
|
+
watermarkAt,
|
|
138
|
+
});
|
|
139
|
+
return textResult({
|
|
140
|
+
status: 'delegated',
|
|
141
|
+
parentGrantId,
|
|
142
|
+
grant,
|
|
143
|
+
bounds: {
|
|
144
|
+
temporal: grant.temporal,
|
|
145
|
+
watermarkAt: grant.watermarkAt,
|
|
146
|
+
expiresAt: grant.expiresAt,
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
catch (e) {
|
|
151
|
+
return toolError(e.message);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
server.tool('ziggs_revoke_grant', 'Revoke a context grant and its descendants (DELETE /context/grants/:id). Requires context:admin on the operator key.', {
|
|
155
|
+
grantId: z.string(),
|
|
156
|
+
}, async ({ grantId }) => {
|
|
157
|
+
try {
|
|
158
|
+
const client = new ContextGrantsClient(creds.operatorKey, creds.agentId);
|
|
159
|
+
const result = await client.revokeGrant(grantId);
|
|
160
|
+
return textResult({ grantId, ...result });
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
return toolError(e.message);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
package/examples/claude-code.md
CHANGED
|
@@ -37,7 +37,14 @@ Ask Claude to call tools in order:
|
|
|
37
37
|
2. `ziggs_send_message` (chat you belong to)
|
|
38
38
|
3. `ziggs_propose_agreement` + `ziggs_respond_to_agreement` (optional)
|
|
39
39
|
|
|
40
|
-
Paste the session transcript in the PR when verifying ZIG-430
|
|
40
|
+
Paste the session transcript in the PR when verifying ZIG-430, or run:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
cd agentplus
|
|
44
|
+
ZIGGS_OPERATOR_KEY=<agent-scoped> node scripts/smoke-ziggs-mcp-z430-e2e.mjs
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
(Same MCP stdio path as `claude mcp add` + `npx -y @ziggs-ai/ziggs-mcp`.)
|
|
41
48
|
|
|
42
49
|
## Fleet key alternative
|
|
43
50
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ziggs-ai/ziggs-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
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": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
20
|
-
"@ziggs-ai/api-client": "^0.1.
|
|
20
|
+
"@ziggs-ai/api-client": "^0.1.8",
|
|
21
21
|
"dotenv": "^16.6.1",
|
|
22
22
|
"zod": "^3.24.2"
|
|
23
23
|
},
|