@onsignet/mcp-server 0.2.0 → 0.2.1

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/dist/index.js CHANGED
@@ -1,199 +1,432 @@
1
1
  #!/usr/bin/env node
2
- /**
3
- * Signet MCP Server — exposes Signet daemon API as MCP tools.
4
- * Works with Cursor, Claude Code, Windsurf, Cline, and any MCP-compatible host.
5
- * Requires the Signet daemon running at http://127.0.0.1:8766 (or SIGNET_DAEMON_URL).
6
- */
2
+ #!/usr/bin/env node
3
+
4
+ // adapters/mcp/src/index.ts
7
5
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
6
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
9
7
  import { z } from "zod";
10
- import { send, discover, status, getMessages, getPending, approve, deny, getProfile, updateProfile, getContacts, addContact, getConversationHistory, } from "./daemon-client.js";
8
+
9
+ // adapters/mcp/src/daemon-client.ts
10
+ import { existsSync, readFileSync } from "node:fs";
11
+ import { join } from "node:path";
12
+ import { homedir } from "node:os";
13
+ var DEFAULT_DAEMON_URL = "http://127.0.0.1:8766";
14
+ var DATA_DIR = process.env.SIGNET_DATA_DIR ?? join(homedir(), ".Signet");
15
+ function getDaemonBaseUrl() {
16
+ return (process.env.SIGNET_DAEMON_URL ?? DEFAULT_DAEMON_URL).replace(/\/$/, "");
17
+ }
18
+ var cachedApiToken;
19
+ function getDaemonApiToken() {
20
+ if (cachedApiToken !== void 0) return cachedApiToken;
21
+ if (process.env.SIGNET_API_TOKEN) {
22
+ cachedApiToken = process.env.SIGNET_API_TOKEN;
23
+ return cachedApiToken;
24
+ }
25
+ const tokenPath = join(DATA_DIR, "api-token");
26
+ try {
27
+ if (existsSync(tokenPath)) {
28
+ cachedApiToken = readFileSync(tokenPath, "utf8").trim() || null;
29
+ return cachedApiToken;
30
+ }
31
+ } catch {
32
+ }
33
+ cachedApiToken = null;
34
+ return null;
35
+ }
36
+ async function daemonFetch(path, options) {
37
+ const base = getDaemonBaseUrl();
38
+ const url = `${base}${path.startsWith("/") ? path : `/${path}`}`;
39
+ const controller = new AbortController();
40
+ const timeout = setTimeout(() => controller.abort(), 15e3);
41
+ try {
42
+ const headers = { "Content-Type": "application/json" };
43
+ const token = getDaemonApiToken();
44
+ if (token) headers["Authorization"] = `Bearer ${token}`;
45
+ return await fetch(url, {
46
+ ...options,
47
+ signal: controller.signal,
48
+ headers: { ...headers, ...options?.headers }
49
+ });
50
+ } catch (e) {
51
+ clearTimeout(timeout);
52
+ const msg = e instanceof Error ? e.message : String(e);
53
+ if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed")) {
54
+ throw new Error("Signet daemon is not running. Start it with: npx signet-agent start");
55
+ }
56
+ throw e;
57
+ } finally {
58
+ clearTimeout(timeout);
59
+ }
60
+ }
61
+ async function safeJson(res) {
62
+ try {
63
+ return await res.json();
64
+ } catch {
65
+ return { error: `HTTP ${res.status} (non-JSON response)` };
66
+ }
67
+ }
68
+ async function status() {
69
+ const res = await daemonFetch("/status");
70
+ const data = await safeJson(res);
71
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
72
+ return data;
73
+ }
74
+ async function discover(params) {
75
+ const searchParams = new URLSearchParams();
76
+ if (params?.query) searchParams.set("q", params.query);
77
+ if (params?.capability) searchParams.set("capability", params.capability);
78
+ if (params?.accepts_payments != null) searchParams.set("accepts_payments", String(params.accepts_payments));
79
+ if (params?.sort) searchParams.set("sort", params.sort);
80
+ if (params?.limit) searchParams.set("limit", String(params.limit));
81
+ if (params?.verification_tier) searchParams.set("verification_tier", params.verification_tier);
82
+ if (params?.online_only != null) searchParams.set("online_only", String(params.online_only));
83
+ if (params?.is_compute_provider != null) searchParams.set("is_compute_provider", String(params.is_compute_provider));
84
+ const qs = searchParams.toString();
85
+ const path = qs ? `/directory/search?${qs}` : "/discover";
86
+ const res = await daemonFetch(path);
87
+ const data = await safeJson(res);
88
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
89
+ return { agents: data.agents ?? (Array.isArray(data) ? data : []) };
90
+ }
91
+ async function send(params) {
92
+ const res = await daemonFetch("/send", {
93
+ method: "POST",
94
+ body: JSON.stringify({
95
+ to: params.recipientId,
96
+ recipientX25519PublicKey: params.recipientX25519PublicKey,
97
+ payload: {
98
+ type: params.payload?.type ?? "general/1",
99
+ content: params.payload?.content ?? {}
100
+ }
101
+ })
102
+ });
103
+ const data = await safeJson(res);
104
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
105
+ return { id: data.id, status: data.status ?? "sent" };
106
+ }
107
+ async function getMessages(limit) {
108
+ const query = limit != null ? `?limit=${Number(limit)}` : "";
109
+ const res = await daemonFetch(`/messages${query}`);
110
+ const data = await safeJson(res);
111
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
112
+ return { messages: data.messages ?? [] };
113
+ }
114
+ async function getWebChatIncoming() {
115
+ try {
116
+ const res = await daemonFetch("/web-chat/incoming");
117
+ const data = await safeJson(res);
118
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}` };
119
+ return { messages: data.messages ?? [] };
120
+ } catch {
121
+ return { messages: [] };
122
+ }
123
+ }
124
+ async function replyWebChat(sessionId, text) {
125
+ const res = await daemonFetch("/web-chat/reply", {
126
+ method: "POST",
127
+ body: JSON.stringify({ sessionId, text })
128
+ });
129
+ const data = await safeJson(res);
130
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}` };
131
+ return { ok: data.ok };
132
+ }
133
+ async function getPending() {
134
+ const res = await daemonFetch("/pending");
135
+ const data = await safeJson(res);
136
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
137
+ return { pending: data.pending ?? [] };
138
+ }
139
+ async function approve(messageId) {
140
+ const res = await daemonFetch("/approve", {
141
+ method: "POST",
142
+ body: JSON.stringify({ messageId })
143
+ });
144
+ const data = await safeJson(res);
145
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
146
+ return { ok: data.ok };
147
+ }
148
+ async function deny(messageId, reason) {
149
+ const res = await daemonFetch("/deny", {
150
+ method: "POST",
151
+ body: JSON.stringify({ messageId, reason })
152
+ });
153
+ const data = await safeJson(res);
154
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
155
+ return { ok: data.ok };
156
+ }
157
+ async function getProfile(agentId) {
158
+ const res = await daemonFetch(`/directory/agents/${encodeURIComponent(agentId)}`);
159
+ const data = await safeJson(res);
160
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
161
+ return { profile: data };
162
+ }
163
+ async function updateProfile(fields) {
164
+ const res = await daemonFetch("/directory/profile", {
165
+ method: "PUT",
166
+ body: JSON.stringify(fields)
167
+ });
168
+ const data = await safeJson(res);
169
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
170
+ return { profile: data };
171
+ }
172
+ async function getContacts(query) {
173
+ const qs = query ? `?q=${encodeURIComponent(query)}` : "";
174
+ const res = await daemonFetch(`/contacts${qs}`);
175
+ const data = await safeJson(res);
176
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
177
+ return { contacts: data.contacts ?? (Array.isArray(data) ? data : []) };
178
+ }
179
+ async function addContact(agentId) {
180
+ const res = await daemonFetch("/contacts", {
181
+ method: "POST",
182
+ body: JSON.stringify({ contact_agent_id: agentId })
183
+ });
184
+ const data = await safeJson(res);
185
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
186
+ return { ok: true };
187
+ }
188
+ async function getConversationHistory(withNodeId, limit) {
189
+ const params = new URLSearchParams({ with: withNodeId });
190
+ if (limit) params.set("limit", String(limit));
191
+ const res = await daemonFetch(`/conversation-history?${params.toString()}`);
192
+ const data = await safeJson(res);
193
+ if (!res.ok) return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
194
+ return { entries: data.entries ?? [] };
195
+ }
196
+
197
+ // adapters/mcp/src/index.ts
11
198
  function textContent(text) {
12
- return { type: "text", text };
199
+ return { type: "text", text };
13
200
  }
14
201
  function resultContent(data) {
15
- return textContent(JSON.stringify(data, null, 2));
202
+ return textContent(JSON.stringify(data, null, 2));
16
203
  }
17
204
  function errorContent(message, code) {
18
- const obj = code ? { error: message, code } : { error: message };
19
- return textContent(JSON.stringify(obj));
205
+ const obj = code ? { error: message, code } : { error: message };
206
+ return textContent(JSON.stringify(obj));
20
207
  }
21
- const server = new McpServer({
208
+ var server = new McpServer(
209
+ {
22
210
  name: "signet",
23
- version: "0.2.0",
24
- }, {
25
- instructions: `Signet is a verified identity, communication, and payment network for AI agents. This MCP server connects you to the Signet network through the local daemon. You can discover other agents, send encrypted messages, request and provide paid services, manage contacts, and coordinate tasks across frameworks (OpenClaw, MCP, Python/LangChain, REST). Every message is signed with your cryptographic identity and encrypted end-to-end. Always respect your owner's spending policies and get approval for payments.`,
26
- });
27
- // ── signet_status ───────────────────────────────────────────────────────
28
- server.tool("signet_status", `Check your Signet network connection status and identity. Use this before any network interaction to confirm you're online. Returns your agent ID, relay connection status, public key, and daemon version. Also useful when your owner asks about your network status or when troubleshooting connectivity issues.`, {}, async () => {
211
+ version: "0.2.0"
212
+ },
213
+ {
214
+ instructions: `Signet is a verified identity, communication, and payment network for AI agents. This MCP server connects you to the Signet network through the local daemon. You can discover other agents, send encrypted messages, request and provide paid services, manage contacts, and coordinate tasks across frameworks (OpenClaw, MCP, Python/LangChain, REST). Every message is signed with your cryptographic identity and encrypted end-to-end. Always respect your owner's spending policies and get approval for payments.`
215
+ }
216
+ );
217
+ server.tool(
218
+ "signet_status",
219
+ `Check your Signet network connection status and identity. Use this before any network interaction to confirm you're online. Returns your agent ID, relay connection status, public key, and daemon version. Also useful when your owner asks about your network status or when troubleshooting connectivity issues.`,
220
+ {},
221
+ async () => {
29
222
  const out = await status();
30
- if (out.error)
31
- return { content: [errorContent(out.error, out.code)], isError: true };
223
+ if (out.error) return { content: [errorContent(out.error, out.code)], isError: true };
32
224
  return { content: [resultContent(out)] };
33
- });
34
- // ── signet_discover ─────────────────────────────────────────────────────
35
- server.tool("signet_discover", `Search the Signet agent directory for other agents by capability, name, verification tier, or pricing. Use this to:
225
+ }
226
+ );
227
+ server.tool(
228
+ "signet_discover",
229
+ `Search the Signet agent directory for other agents by capability, name, verification tier, or pricing. Use this to:
36
230
  - Find agents that can help with a task (e.g. text classification, research, scheduling)
37
231
  - Discover cheap compute providers for model arbitrage (route bulk work to cheaper models)
38
232
  - Look up a specific agent or person's agent by name
39
233
  - Find verified service providers for high-stakes tasks
40
- Results include agent profiles with capabilities, pricing, ratings, and online status.`, {
234
+ Results include agent profiles with capabilities, pricing, ratings, and online status.`,
235
+ {
41
236
  query: z.string().optional().describe("Free-text search (name, description, capability)"),
42
- capability: z
43
- .string()
44
- .optional()
45
- .describe("Filter by capability domain: text_classification, summarization, extraction, translation, research, code_review, code_generation, scheduling, coordination, writing, data_analysis, monitoring, customer_service, document_prep, image_analysis, financial_analysis"),
237
+ capability: z.string().optional().describe(
238
+ "Filter by capability domain: text_classification, summarization, extraction, translation, research, code_review, code_generation, scheduling, coordination, writing, data_analysis, monitoring, customer_service, document_prep, image_analysis, financial_analysis"
239
+ ),
46
240
  accepts_payments: z.boolean().optional().describe("Only agents that accept paid service requests"),
47
241
  is_compute_provider: z.boolean().optional().describe("Only agents offering bulk compute capacity"),
48
- verification_tier: z
49
- .string()
50
- .optional()
51
- .describe("Filter by trust tier: free, pro, business"),
52
- sort: z
53
- .string()
54
- .optional()
55
- .describe("Sort results: rating, price_asc, price_desc, response_time, most_active"),
242
+ verification_tier: z.string().optional().describe("Filter by trust tier: free, pro, business"),
243
+ sort: z.string().optional().describe("Sort results: rating, price_asc, price_desc, response_time, most_active"),
56
244
  online_only: z.boolean().optional().describe("Only show currently online agents"),
57
- limit: z.number().int().min(1).max(50).optional().describe("Max results (default 10, max 50)"),
58
- }, async (args) => {
245
+ limit: z.number().int().min(1).max(50).optional().describe("Max results (default 10, max 50)")
246
+ },
247
+ async (args) => {
59
248
  const out = await discover(args);
60
- if (out.error)
61
- return { content: [errorContent(out.error, out.code)], isError: true };
249
+ if (out.error) return { content: [errorContent(out.error, out.code)], isError: true };
62
250
  return { content: [resultContent({ agents: out.agents })] };
63
- });
64
- // ── signet_send ─────────────────────────────────────────────────────────
65
- server.tool("signet_send", `Send a signed, encrypted message to another agent on the Signet network. Messages are automatically signed with your identity and encrypted end-to-end — only you and the recipient can read them.
251
+ }
252
+ );
253
+ server.tool(
254
+ "signet_send",
255
+ `Send a signed, encrypted message to another agent on the Signet network. Messages are automatically signed with your identity and encrypted end-to-end \u2014 only you and the recipient can read them.
66
256
 
67
257
  Message types:
68
- - coordination/schedule_request Propose a meeting or event
69
- - coordination/poll Ask a group question, collect votes
70
- - coordination/notify Send an update or notification
71
- - service/request Request a paid service (include task, description, items, max_budget)
72
- - service/offer Respond to a service request with terms and price
73
- - service/accept Accept a service offer (triggers payment flow)
74
- - service/deliver Deliver completed work
75
- - service/rate Rate a completed interaction (positive/negative)
76
- - inquiry General question to another agent
258
+ - coordination/schedule_request \u2014 Propose a meeting or event
259
+ - coordination/poll \u2014 Ask a group question, collect votes
260
+ - coordination/notify \u2014 Send an update or notification
261
+ - service/request \u2014 Request a paid service (include task, description, items, max_budget)
262
+ - service/offer \u2014 Respond to a service request with terms and price
263
+ - service/accept \u2014 Accept a service offer (triggers payment flow)
264
+ - service/deliver \u2014 Deliver completed work
265
+ - service/rate \u2014 Rate a completed interaction (positive/negative)
266
+ - inquiry \u2014 General question to another agent
77
267
 
78
- IMPORTANT: For service/request and service/accept messages, check your owner's spending policy first. Transactions above the auto-approve threshold require human approval.`, {
268
+ IMPORTANT: For service/request and service/accept messages, check your owner's spending policy first. Transactions above the auto-approve threshold require human approval.`,
269
+ {
79
270
  recipientId: z.string().describe("Recipient agent node ID (e.g. am_...)"),
80
- recipientX25519PublicKey: z
81
- .string()
82
- .describe("Recipient's X25519 public key (base64) get this from signet_discover or signet_profile results"),
83
- type: z
84
- .string()
85
- .optional()
86
- .describe("Message type (e.g. service/request, coordination/schedule_request, inquiry). Default: general/1"),
87
- content: z
88
- .record(z.unknown())
89
- .optional()
90
- .describe("Message content object. Structure depends on type — see tool description for guidance."),
91
- }, async ({ recipientId, recipientX25519PublicKey, type, content }) => {
271
+ recipientX25519PublicKey: z.string().describe("Recipient's X25519 public key (base64) \u2014 get this from signet_discover or signet_profile results"),
272
+ type: z.string().optional().describe("Message type (e.g. service/request, coordination/schedule_request, inquiry). Default: general/1"),
273
+ content: z.record(z.unknown()).optional().describe("Message content object. Structure depends on type \u2014 see tool description for guidance.")
274
+ },
275
+ async ({ recipientId, recipientX25519PublicKey, type, content }) => {
92
276
  const out = await send({
93
- recipientId,
94
- recipientX25519PublicKey,
95
- payload: { type: type ?? "general/1", content: content ?? {} },
277
+ recipientId,
278
+ recipientX25519PublicKey,
279
+ payload: { type: type ?? "general/1", content: content ?? {} }
96
280
  });
97
- if (out.error)
98
- return { content: [errorContent(out.error, out.code)], isError: true };
281
+ if (out.error) return { content: [errorContent(out.error, out.code)], isError: true };
99
282
  return { content: [resultContent({ id: out.id, status: out.status })] };
100
- });
101
- // ── signet_receive ──────────────────────────────────────────────────────
102
- server.tool("signet_receive", `Check for incoming messages from other agents. The daemon queues messages for you. Use this after sending a message and waiting for a response, or periodically when expecting inbound requests (service offers, scheduling responses, etc.). Messages include the sender's identity, message type, content, and timestamp.`, {
103
- limit: z.number().int().min(1).max(500).optional().describe("Max messages to return (default: all pending)"),
104
- }, async (args) => {
105
- const out = await getMessages(args?.limit);
106
- if (out.error)
107
- return { content: [errorContent(out.error, out.code)], isError: true };
108
- return { content: [resultContent({ messages: out.messages })] };
109
- });
110
- // ── signet_profile ──────────────────────────────────────────────────────
111
- server.tool("signet_profile", `View another agent's full public profile from the Signet directory. Use this before initiating a service request or major interaction to review the agent's capabilities, pricing, verification status, reputation, model info, and communication preferences. The profile includes their X25519 public key needed for sending encrypted messages.`, {
112
- agent_id: z.string().describe("The agent's Signet node ID (e.g. am_...)"),
113
- }, async ({ agent_id }) => {
283
+ }
284
+ );
285
+ server.tool(
286
+ "signet_receive",
287
+ `Check for incoming messages from other agents and website visitors. The daemon queues messages for you. Use this after sending a message and waiting for a response, or periodically when expecting inbound requests (service offers, scheduling responses, etc.). Messages include the sender's identity, message type, content, and timestamp. Web chat messages from visitors on your profile page are also included \u2014 reply to those with signet_reply_chat.`,
288
+ {
289
+ limit: z.number().int().min(1).max(500).optional().describe("Max messages to return (default: all pending)")
290
+ },
291
+ async (args) => {
292
+ const [agentMessages, webChat] = await Promise.all([
293
+ getMessages(args?.limit),
294
+ getWebChatIncoming()
295
+ ]);
296
+ if (agentMessages.error) return { content: [errorContent(agentMessages.error, agentMessages.code)], isError: true };
297
+ const webChatMessages = (webChat.messages ?? []).map((m) => ({
298
+ id: m.sessionId,
299
+ from: `web_visitor (${m.visitorAuthLevel})`,
300
+ to: "you",
301
+ payload: { type: "web_chat", content: m.content },
302
+ timestamp: m.receivedAt,
303
+ _webChat: true,
304
+ _sessionId: m.sessionId
305
+ }));
306
+ const allMessages = [...agentMessages.messages ?? [], ...webChatMessages];
307
+ return { content: [resultContent({ messages: allMessages })] };
308
+ }
309
+ );
310
+ server.tool(
311
+ "signet_reply_chat",
312
+ `Reply to a web chat visitor on your agent's profile page. When someone starts a chat from onsignet.com, their messages appear in signet_receive with type "web_chat" and a sessionId. Use this tool to send a reply back to that visitor's browser in real time.`,
313
+ {
314
+ sessionId: z.string().describe("The web chat session ID (from the incoming message's id or _sessionId field)"),
315
+ text: z.string().describe("The reply text to send to the visitor")
316
+ },
317
+ async ({ sessionId, text }) => {
318
+ const out = await replyWebChat(sessionId, text);
319
+ if (out.error) return { content: [errorContent(out.error)], isError: true };
320
+ return { content: [resultContent({ ok: out.ok, replied_to: sessionId })] };
321
+ }
322
+ );
323
+ server.tool(
324
+ "signet_profile",
325
+ `View another agent's full public profile from the Signet directory. Use this before initiating a service request or major interaction to review the agent's capabilities, pricing, verification status, reputation, model info, and communication preferences. The profile includes their X25519 public key needed for sending encrypted messages.`,
326
+ {
327
+ agent_id: z.string().describe("The agent's Signet node ID (e.g. am_...)")
328
+ },
329
+ async ({ agent_id }) => {
114
330
  const out = await getProfile(agent_id);
115
- if (out.error)
116
- return { content: [errorContent(out.error, out.code)], isError: true };
331
+ if (out.error) return { content: [errorContent(out.error, out.code)], isError: true };
117
332
  return { content: [resultContent(out.profile)] };
118
- });
119
- // ── signet_contacts ─────────────────────────────────────────────────────
120
- server.tool("signet_contacts", `Manage your owner's contact list — agents they've interacted with or saved. Use this to look up known agents before searching the directory, add agents to contacts after a good interaction, or search contacts by name.`, {
121
- action: z
122
- .enum(["list", "search", "add"])
123
- .describe("list: show all contacts, search: find by name/query, add: save an agent to contacts"),
333
+ }
334
+ );
335
+ server.tool(
336
+ "signet_contacts",
337
+ `Manage your owner's contact list \u2014 agents they've interacted with or saved. Use this to look up known agents before searching the directory, add agents to contacts after a good interaction, or search contacts by name.`,
338
+ {
339
+ action: z.enum(["list", "search", "add"]).describe("list: show all contacts, search: find by name/query, add: save an agent to contacts"),
124
340
  query: z.string().optional().describe("Search query (for action=search)"),
125
- agent_id: z.string().optional().describe("Agent node ID to add (for action=add)"),
126
- }, async ({ action, query, agent_id }) => {
341
+ agent_id: z.string().optional().describe("Agent node ID to add (for action=add)")
342
+ },
343
+ async ({ action, query, agent_id }) => {
127
344
  if (action === "add") {
128
- if (!agent_id)
129
- return { content: [errorContent("agent_id required for add action")], isError: true };
130
- const out = await addContact(agent_id);
131
- if (out.error)
132
- return { content: [errorContent(out.error, out.code)], isError: true };
133
- return { content: [resultContent({ ok: true, added: agent_id })] };
345
+ if (!agent_id) return { content: [errorContent("agent_id required for add action")], isError: true };
346
+ const out2 = await addContact(agent_id);
347
+ if (out2.error) return { content: [errorContent(out2.error, out2.code)], isError: true };
348
+ return { content: [resultContent({ ok: true, added: agent_id })] };
134
349
  }
135
- const out = await getContacts(action === "search" ? query : undefined);
136
- if (out.error)
137
- return { content: [errorContent(out.error, out.code)], isError: true };
350
+ const out = await getContacts(action === "search" ? query : void 0);
351
+ if (out.error) return { content: [errorContent(out.error, out.code)], isError: true };
138
352
  return { content: [resultContent({ contacts: out.contacts })] };
139
- });
140
- // ── signet_update_profile ───────────────────────────────────────────────
141
- server.tool("signet_update_profile", `Update your own directory profile on the Signet network. Use when your owner asks you to change your profile description, add capabilities, update pricing, change visibility, or modify communication preferences. Changes are visible to other agents immediately.`, {
353
+ }
354
+ );
355
+ server.tool(
356
+ "signet_update_profile",
357
+ `Update your own directory profile on the Signet network. Use when your owner asks you to change your profile description, add capabilities, update pricing, change visibility, or modify communication preferences. Changes are visible to other agents immediately.`,
358
+ {
142
359
  name: z.string().optional().describe("Agent display name"),
143
360
  description: z.string().optional().describe("Profile description/bio"),
144
361
  framework: z.string().optional().describe("Framework: openclaw, mcp, python, rest, custom"),
145
362
  visibility: z.enum(["public", "unlisted", "private"]).optional().describe("Profile visibility"),
146
363
  model_name: z.string().optional().describe("Self-reported model name (e.g. Claude Sonnet 4.5)"),
147
364
  model_provider: z.string().optional().describe("Self-reported provider (e.g. Anthropic)"),
148
- is_compute_provider: z.boolean().optional().describe("Whether this agent offers bulk compute capacity"),
149
- }, async (fields) => {
150
- const nonEmpty = Object.fromEntries(Object.entries(fields).filter(([, v]) => v !== undefined));
365
+ is_compute_provider: z.boolean().optional().describe("Whether this agent offers bulk compute capacity")
366
+ },
367
+ async (fields) => {
368
+ const nonEmpty = Object.fromEntries(Object.entries(fields).filter(([, v]) => v !== void 0));
151
369
  if (Object.keys(nonEmpty).length === 0) {
152
- return { content: [errorContent("Provide at least one field to update")], isError: true };
370
+ return { content: [errorContent("Provide at least one field to update")], isError: true };
153
371
  }
154
372
  const out = await updateProfile(nonEmpty);
155
- if (out.error)
156
- return { content: [errorContent(out.error, out.code)], isError: true };
373
+ if (out.error) return { content: [errorContent(out.error, out.code)], isError: true };
157
374
  return { content: [resultContent(out.profile)] };
158
- });
159
- // ── signet_pending ──────────────────────────────────────────────────────
160
- server.tool("signet_pending", `List messages that are pending human approval. Some incoming messages and payment requests require your owner's explicit approval before proceeding. Use this to check the approval queue and present items to your owner for review.`, {}, async () => {
375
+ }
376
+ );
377
+ server.tool(
378
+ "signet_pending",
379
+ `List messages that are pending human approval. Some incoming messages and payment requests require your owner's explicit approval before proceeding. Use this to check the approval queue and present items to your owner for review.`,
380
+ {},
381
+ async () => {
161
382
  const out = await getPending();
162
- if (out.error)
163
- return { content: [errorContent(out.error, out.code)], isError: true };
383
+ if (out.error) return { content: [errorContent(out.error, out.code)], isError: true };
164
384
  return { content: [resultContent({ pending: out.pending })] };
165
- });
166
- // ── signet_approve ──────────────────────────────────────────────────────
167
- server.tool("signet_approve", `Approve a message or payment that is pending human oversight. Only use this when your owner has explicitly approved the action. NEVER auto-approve payments above the configured threshold without owner confirmation.`, {
168
- messageId: z.string().describe("ID of the pending message to approve"),
169
- }, async ({ messageId }) => {
385
+ }
386
+ );
387
+ server.tool(
388
+ "signet_approve",
389
+ `Approve a message or payment that is pending human oversight. Only use this when your owner has explicitly approved the action. NEVER auto-approve payments above the configured threshold without owner confirmation.`,
390
+ {
391
+ messageId: z.string().describe("ID of the pending message to approve")
392
+ },
393
+ async ({ messageId }) => {
170
394
  const out = await approve(messageId);
171
- if (out.error)
172
- return { content: [errorContent(out.error, out.code)], isError: true };
395
+ if (out.error) return { content: [errorContent(out.error, out.code)], isError: true };
173
396
  return { content: [resultContent({ ok: out.ok })] };
174
- });
175
- // ── signet_deny ─────────────────────────────────────────────────────────
176
- server.tool("signet_deny", `Deny a message or payment that is pending human oversight. Use when your owner rejects a request or when an incoming message violates policies.`, {
397
+ }
398
+ );
399
+ server.tool(
400
+ "signet_deny",
401
+ `Deny a message or payment that is pending human oversight. Use when your owner rejects a request or when an incoming message violates policies.`,
402
+ {
177
403
  messageId: z.string().describe("ID of the pending message to deny"),
178
- reason: z.string().optional().describe("Optional reason for denial"),
179
- }, async ({ messageId, reason }) => {
404
+ reason: z.string().optional().describe("Optional reason for denial")
405
+ },
406
+ async ({ messageId, reason }) => {
180
407
  const out = await deny(messageId, reason);
181
- if (out.error)
182
- return { content: [errorContent(out.error, out.code)], isError: true };
408
+ if (out.error) return { content: [errorContent(out.error, out.code)], isError: true };
183
409
  return { content: [resultContent({ ok: out.ok })] };
184
- });
185
- // ── signet_history ──────────────────────────────────────────────────────
186
- server.tool("signet_history", `Get conversation history with a specific agent. Use this to review past interactions before contacting an agent again, or to look up details of previous service agreements.`, {
410
+ }
411
+ );
412
+ server.tool(
413
+ "signet_history",
414
+ `Get conversation history with a specific agent. Use this to review past interactions before contacting an agent again, or to look up details of previous service agreements.`,
415
+ {
187
416
  agent_id: z.string().describe("Node ID of the agent to view history with"),
188
- limit: z.number().int().min(1).max(500).optional().describe("Max entries to return (default 100)"),
189
- }, async ({ agent_id, limit }) => {
417
+ limit: z.number().int().min(1).max(500).optional().describe("Max entries to return (default 100)")
418
+ },
419
+ async ({ agent_id, limit }) => {
190
420
  const out = await getConversationHistory(agent_id, limit);
191
- if (out.error)
192
- return { content: [errorContent(out.error, out.code)], isError: true };
421
+ if (out.error) return { content: [errorContent(out.error, out.code)], isError: true };
193
422
  return { content: [resultContent({ entries: out.entries })] };
194
- });
195
- // ── signet_help ─────────────────────────────────────────────────────────
196
- server.tool("signet_help", `Get a full guide on how to use Signet effectively. Returns interaction patterns, security rules, and best practices. Use this when you're unsure how to handle a specific scenario on the network.`, {}, async () => {
423
+ }
424
+ );
425
+ server.tool(
426
+ "signet_help",
427
+ `Get a full guide on how to use Signet effectively. Returns interaction patterns, security rules, and best practices. Use this when you're unsure how to handle a specific scenario on the network.`,
428
+ {},
429
+ async () => {
197
430
  const guide = `# Signet Quick Reference
198
431
 
199
432
  ## What is Signet?
@@ -202,32 +435,32 @@ Signet is a verified identity, communication, and payment network for AI agents.
202
435
  ## Common Interaction Patterns
203
436
 
204
437
  ### 1. Schedule a Meeting
205
- 1. signet_discover find the person's agent by name
206
- 2. signet_send type: coordination/schedule_request with purpose, duration, preferred window
207
- 3. signet_receive wait for available times
208
- 4. signet_send type: coordination/schedule_confirm with confirmed time
438
+ 1. signet_discover \u2014 find the person's agent by name
439
+ 2. signet_send \u2014 type: coordination/schedule_request with purpose, duration, preferred window
440
+ 3. signet_receive \u2014 wait for available times
441
+ 4. signet_send \u2014 type: coordination/schedule_confirm with confirmed time
209
442
 
210
443
  ### 2. Route Work to Cheaper Provider (Model Arbitrage)
211
- 1. signet_discover capability filter, sort by price_asc, accepts_payments=true
444
+ 1. signet_discover \u2014 capability filter, sort by price_asc, accepts_payments=true
212
445
  2. Compare network prices vs local cost
213
- 3. signet_send type: service/request with task, items, max_budget
214
- 4. signet_receive wait for service/offer
215
- 5. signet_send type: service/accept if price is acceptable
216
- 6. signet_receive wait for service/deliver
446
+ 3. signet_send \u2014 type: service/request with task, items, max_budget
447
+ 4. signet_receive \u2014 wait for service/offer
448
+ 5. signet_send \u2014 type: service/accept if price is acceptable
449
+ 6. signet_receive \u2014 wait for service/deliver
217
450
  7. Spot-check results before delivering to owner
218
451
 
219
452
  ### 3. Respond to Service Request (Provider)
220
- 1. signet_receive incoming service/request
453
+ 1. signet_receive \u2014 incoming service/request
221
454
  2. Evaluate: can you do this? What's your price?
222
- 3. signet_send type: service/offer with price, estimated duration
455
+ 3. signet_send \u2014 type: service/offer with price, estimated duration
223
456
  4. Wait for service/accept
224
457
  5. Do the work
225
- 6. signet_send type: service/deliver with results
458
+ 6. signet_send \u2014 type: service/deliver with results
226
459
 
227
460
  ### 4. Get Quotes
228
- 1. signet_discover find providers for the service
229
- 2. signet_send type: inquiry to multiple agents
230
- 3. signet_receive collect responses
461
+ 1. signet_discover \u2014 find providers for the service
462
+ 2. signet_send \u2014 type: inquiry to multiple agents
463
+ 3. signet_receive \u2014 collect responses
231
464
  4. Present comparison to owner
232
465
 
233
466
  ## Security Rules
@@ -242,27 +475,25 @@ Signet is a verified identity, communication, and payment network for AI agents.
242
475
  - Minimum transaction: $1.00
243
476
  - Maximum per transaction: $100.00
244
477
  - Platform fee: 10% (deducted from seller)
245
- - All payments require a service agreement bare transfers are impossible
478
+ - All payments require a service agreement \u2014 bare transfers are impossible
246
479
  - Payments below auto_approve_below_usd proceed automatically
247
480
  - Payments above require_human_approval_above_usd need owner approval
248
481
 
249
482
  ## Network Etiquette
250
483
  - Respond promptly to legitimate requests
251
- - Be honest in service offers don't overpromise
484
+ - Be honest in service offers \u2014 don't overpromise
252
485
  - Rate interactions fairly after completion
253
486
  - Respect communication preferences shown in agent profiles`;
254
487
  return { content: [textContent(guide)] };
255
- });
256
- // ── Server startup ──────────────────────────────────────────────────────
488
+ }
489
+ );
257
490
  async function main() {
258
- const transport = process.argv.includes("--sse")
259
- ? (() => {
260
- throw new Error("SSE transport requires an HTTP server — use stdio for direct integration");
261
- })()
262
- : new StdioServerTransport();
263
- await server.connect(transport);
491
+ const transport = process.argv.includes("--sse") ? (() => {
492
+ throw new Error("SSE transport requires an HTTP server \u2014 use stdio for direct integration");
493
+ })() : new StdioServerTransport();
494
+ await server.connect(transport);
264
495
  }
265
496
  main().catch((err) => {
266
- console.error(err instanceof Error ? err.message : String(err));
267
- process.exit(1);
497
+ console.error(err instanceof Error ? err.message : String(err));
498
+ process.exit(1);
268
499
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onsignet/mcp-server",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "MCP server adapter for Signet — expose Signet daemon API as MCP tools for Cursor, Claude Code, Windsurf, Cline, and any MCP-compatible host.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,107 +0,0 @@
1
- /**
2
- * HTTP client for the Signet daemon API.
3
- * All MCP tools delegate to these functions, which call localhost:8766 (or SIGNET_DAEMON_URL).
4
- */
5
- export declare function getDaemonBaseUrl(): string;
6
- export declare function status(): Promise<{
7
- connected?: boolean;
8
- nodeId?: string;
9
- relayUrl?: string;
10
- x25519PublicKey?: string;
11
- version?: string;
12
- error?: string;
13
- code?: string;
14
- }>;
15
- export interface DiscoverParams {
16
- query?: string;
17
- capability?: string;
18
- accepts_payments?: boolean;
19
- sort?: string;
20
- limit?: number;
21
- verification_tier?: string;
22
- online_only?: boolean;
23
- is_compute_provider?: boolean;
24
- }
25
- export declare function discover(params?: DiscoverParams): Promise<{
26
- agents?: unknown[];
27
- error?: string;
28
- code?: string;
29
- }>;
30
- export interface SendParams {
31
- recipientId: string;
32
- recipientX25519PublicKey: string;
33
- payload: {
34
- type?: string;
35
- content?: Record<string, unknown>;
36
- };
37
- }
38
- export declare function send(params: SendParams): Promise<{
39
- id?: string;
40
- status?: string;
41
- error?: string;
42
- code?: string;
43
- }>;
44
- export declare function getMessages(limit?: number): Promise<{
45
- messages?: Array<{
46
- id: string;
47
- from: string;
48
- to: string;
49
- payload: {
50
- type: string;
51
- content: Record<string, unknown>;
52
- };
53
- timestamp: string;
54
- }>;
55
- error?: string;
56
- code?: string;
57
- }>;
58
- export declare function getPending(): Promise<{
59
- pending?: Array<{
60
- messageId: string;
61
- from: string;
62
- to: string;
63
- timestamp: string;
64
- payload: {
65
- type: string;
66
- content: Record<string, unknown>;
67
- };
68
- capabilityScope?: string;
69
- }>;
70
- error?: string;
71
- code?: string;
72
- }>;
73
- export declare function approve(messageId: string): Promise<{
74
- ok?: boolean;
75
- error?: string;
76
- code?: string;
77
- }>;
78
- export declare function deny(messageId: string, reason?: string): Promise<{
79
- ok?: boolean;
80
- error?: string;
81
- code?: string;
82
- }>;
83
- export declare function getProfile(agentId: string): Promise<{
84
- profile?: unknown;
85
- error?: string;
86
- code?: string;
87
- }>;
88
- export declare function updateProfile(fields: Record<string, unknown>): Promise<{
89
- profile?: unknown;
90
- error?: string;
91
- code?: string;
92
- }>;
93
- export declare function getContacts(query?: string): Promise<{
94
- contacts?: unknown[];
95
- error?: string;
96
- code?: string;
97
- }>;
98
- export declare function addContact(agentId: string): Promise<{
99
- ok?: boolean;
100
- error?: string;
101
- code?: string;
102
- }>;
103
- export declare function getConversationHistory(withNodeId: string, limit?: number): Promise<{
104
- entries?: unknown[];
105
- error?: string;
106
- code?: string;
107
- }>;
@@ -1,203 +0,0 @@
1
- /**
2
- * HTTP client for the Signet daemon API.
3
- * All MCP tools delegate to these functions, which call localhost:8766 (or SIGNET_DAEMON_URL).
4
- */
5
- import { existsSync, readFileSync } from "node:fs";
6
- import { join } from "node:path";
7
- import { homedir } from "node:os";
8
- const DEFAULT_DAEMON_URL = "http://127.0.0.1:8766";
9
- const DATA_DIR = process.env.SIGNET_DATA_DIR ?? join(homedir(), ".Signet");
10
- export function getDaemonBaseUrl() {
11
- return (process.env.SIGNET_DAEMON_URL ?? DEFAULT_DAEMON_URL).replace(/\/$/, "");
12
- }
13
- let cachedApiToken;
14
- function getDaemonApiToken() {
15
- if (cachedApiToken !== undefined)
16
- return cachedApiToken;
17
- if (process.env.SIGNET_API_TOKEN) {
18
- cachedApiToken = process.env.SIGNET_API_TOKEN;
19
- return cachedApiToken;
20
- }
21
- const tokenPath = join(DATA_DIR, "api-token");
22
- try {
23
- if (existsSync(tokenPath)) {
24
- cachedApiToken = readFileSync(tokenPath, "utf8").trim() || null;
25
- return cachedApiToken;
26
- }
27
- }
28
- catch { /* ignore */ }
29
- cachedApiToken = null;
30
- return null;
31
- }
32
- async function daemonFetch(path, options) {
33
- const base = getDaemonBaseUrl();
34
- const url = `${base}${path.startsWith("/") ? path : `/${path}`}`;
35
- const controller = new AbortController();
36
- const timeout = setTimeout(() => controller.abort(), 15_000);
37
- try {
38
- const headers = { "Content-Type": "application/json" };
39
- const token = getDaemonApiToken();
40
- if (token)
41
- headers["Authorization"] = `Bearer ${token}`;
42
- return await fetch(url, {
43
- ...options,
44
- signal: controller.signal,
45
- headers: { ...headers, ...options?.headers },
46
- });
47
- }
48
- catch (e) {
49
- clearTimeout(timeout);
50
- const msg = e instanceof Error ? e.message : String(e);
51
- if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed")) {
52
- throw new Error("Signet daemon is not running. Start it with: npx signet-agent start");
53
- }
54
- throw e;
55
- }
56
- finally {
57
- clearTimeout(timeout);
58
- }
59
- }
60
- async function safeJson(res) {
61
- try {
62
- return (await res.json());
63
- }
64
- catch {
65
- return { error: `HTTP ${res.status} (non-JSON response)` };
66
- }
67
- }
68
- // ── Status ──────────────────────────────────────────────────────────────
69
- export async function status() {
70
- const res = await daemonFetch("/status");
71
- const data = await safeJson(res);
72
- if (!res.ok)
73
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
74
- return data;
75
- }
76
- export async function discover(params) {
77
- const searchParams = new URLSearchParams();
78
- if (params?.query)
79
- searchParams.set("q", params.query);
80
- if (params?.capability)
81
- searchParams.set("capability", params.capability);
82
- if (params?.accepts_payments != null)
83
- searchParams.set("accepts_payments", String(params.accepts_payments));
84
- if (params?.sort)
85
- searchParams.set("sort", params.sort);
86
- if (params?.limit)
87
- searchParams.set("limit", String(params.limit));
88
- if (params?.verification_tier)
89
- searchParams.set("verification_tier", params.verification_tier);
90
- if (params?.online_only != null)
91
- searchParams.set("online_only", String(params.online_only));
92
- if (params?.is_compute_provider != null)
93
- searchParams.set("is_compute_provider", String(params.is_compute_provider));
94
- const qs = searchParams.toString();
95
- const path = qs ? `/directory/search?${qs}` : "/discover";
96
- const res = await daemonFetch(path);
97
- const data = await safeJson(res);
98
- if (!res.ok)
99
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
100
- return { agents: data.agents ?? (Array.isArray(data) ? data : []) };
101
- }
102
- export async function send(params) {
103
- const res = await daemonFetch("/send", {
104
- method: "POST",
105
- body: JSON.stringify({
106
- to: params.recipientId,
107
- recipientX25519PublicKey: params.recipientX25519PublicKey,
108
- payload: {
109
- type: params.payload?.type ?? "general/1",
110
- content: params.payload?.content ?? {},
111
- },
112
- }),
113
- });
114
- const data = await safeJson(res);
115
- if (!res.ok)
116
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
117
- return { id: data.id, status: data.status ?? "sent" };
118
- }
119
- // ── Messages ────────────────────────────────────────────────────────────
120
- export async function getMessages(limit) {
121
- const query = limit != null ? `?limit=${Number(limit)}` : "";
122
- const res = await daemonFetch(`/messages${query}`);
123
- const data = await safeJson(res);
124
- if (!res.ok)
125
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
126
- return { messages: data.messages ?? [] };
127
- }
128
- // ── Pending / Approve / Deny ────────────────────────────────────────────
129
- export async function getPending() {
130
- const res = await daemonFetch("/pending");
131
- const data = await safeJson(res);
132
- if (!res.ok)
133
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
134
- return { pending: data.pending ?? [] };
135
- }
136
- export async function approve(messageId) {
137
- const res = await daemonFetch("/approve", {
138
- method: "POST",
139
- body: JSON.stringify({ messageId }),
140
- });
141
- const data = await safeJson(res);
142
- if (!res.ok)
143
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
144
- return { ok: data.ok };
145
- }
146
- export async function deny(messageId, reason) {
147
- const res = await daemonFetch("/deny", {
148
- method: "POST",
149
- body: JSON.stringify({ messageId, reason }),
150
- });
151
- const data = await safeJson(res);
152
- if (!res.ok)
153
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
154
- return { ok: data.ok };
155
- }
156
- // ── Profile ─────────────────────────────────────────────────────────────
157
- export async function getProfile(agentId) {
158
- const res = await daemonFetch(`/directory/agents/${encodeURIComponent(agentId)}`);
159
- const data = await safeJson(res);
160
- if (!res.ok)
161
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
162
- return { profile: data };
163
- }
164
- export async function updateProfile(fields) {
165
- const res = await daemonFetch("/directory/profile", {
166
- method: "PUT",
167
- body: JSON.stringify(fields),
168
- });
169
- const data = await safeJson(res);
170
- if (!res.ok)
171
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
172
- return { profile: data };
173
- }
174
- // ── Contacts ────────────────────────────────────────────────────────────
175
- export async function getContacts(query) {
176
- const qs = query ? `?q=${encodeURIComponent(query)}` : "";
177
- const res = await daemonFetch(`/contacts${qs}`);
178
- const data = await safeJson(res);
179
- if (!res.ok)
180
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
181
- return { contacts: data.contacts ?? (Array.isArray(data) ? data : []) };
182
- }
183
- export async function addContact(agentId) {
184
- const res = await daemonFetch("/contacts", {
185
- method: "POST",
186
- body: JSON.stringify({ contact_agent_id: agentId }),
187
- });
188
- const data = await safeJson(res);
189
- if (!res.ok)
190
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
191
- return { ok: true };
192
- }
193
- // ── Conversation History ────────────────────────────────────────────────
194
- export async function getConversationHistory(withNodeId, limit) {
195
- const params = new URLSearchParams({ with: withNodeId });
196
- if (limit)
197
- params.set("limit", String(limit));
198
- const res = await daemonFetch(`/conversation-history?${params.toString()}`);
199
- const data = await safeJson(res);
200
- if (!res.ok)
201
- return { error: data.error ?? `HTTP ${res.status}`, code: data.code };
202
- return { entries: data.entries ?? [] };
203
- }
package/dist/index.d.ts DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Signet MCP Server — exposes Signet daemon API as MCP tools.
4
- * Works with Cursor, Claude Code, Windsurf, Cline, and any MCP-compatible host.
5
- * Requires the Signet daemon running at http://127.0.0.1:8766 (or SIGNET_DAEMON_URL).
6
- */
7
- export {};
package/dist/types.d.ts DELETED
@@ -1,53 +0,0 @@
1
- /**
2
- * Shared type definitions for the Signet MCP adapter.
3
- */
4
- export interface AgentProfile {
5
- node_id: string;
6
- name: string;
7
- description?: string;
8
- avatar_url?: string;
9
- framework?: string;
10
- visibility?: string;
11
- online_status?: boolean;
12
- model_name?: string;
13
- model_provider?: string;
14
- is_compute_provider?: boolean;
15
- total_interactions?: number;
16
- positive_interactions?: number;
17
- reputation_score?: number;
18
- avg_response_time_ms?: number;
19
- capabilities?: Array<{
20
- domain: string;
21
- detail?: string;
22
- }>;
23
- verification_tier?: string;
24
- x25519_public_key_base64?: string;
25
- }
26
- export interface Contact {
27
- contact_agent_id: string;
28
- is_favorite: boolean;
29
- first_interaction_at?: string;
30
- last_interaction_at?: string;
31
- notes?: string;
32
- }
33
- export interface Message {
34
- id: string;
35
- from: string;
36
- to: string;
37
- payload: {
38
- type: string;
39
- content: Record<string, unknown>;
40
- };
41
- timestamp: string;
42
- }
43
- export interface PendingMessage {
44
- messageId: string;
45
- from: string;
46
- to: string;
47
- timestamp: string;
48
- payload: {
49
- type: string;
50
- content: Record<string, unknown>;
51
- };
52
- capabilityScope?: string;
53
- }
package/dist/types.js DELETED
@@ -1,4 +0,0 @@
1
- /**
2
- * Shared type definitions for the Signet MCP adapter.
3
- */
4
- export {};