subscribe
Set up a persistent watch for new AI tools matching a query. Receive daily notifications via email or webhook.
Instructions
Set up a persistent watch for new AI tools matching a query. Get notified daily when something new appears in the Unfragile graph. Requires at least one notification channel (email or webhook).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | What to watch for (e.g., 'new MCP server for Postgres', 'framework for building AI agents') | |
| type | No | Only watch for this artifact type | |
| No | Email address for notifications | ||
| webhook | No | Webhook URL for notifications (receives POST with new matches) |
Implementation Reference
- src/index.ts:763-765 (registration)Tool registration comment indicating this is Tool 9: Subscribe — create a monitor
); // Tool 9: Subscribe — create a monitor - src/index.ts:765-834 (handler)Full implementation of the 'subscribe' tool: registers with server.tool(), defines input schema (query, type, email, webhook), validates at least one notification channel, POSTs to /api/v1/monitor, and returns monitor details including ID, query, type filter, frequency, and expiration.
// Tool 9: Subscribe — create a monitor server.tool( "subscribe", "Set up a persistent watch for new AI tools matching a query. Get notified daily when something new appears in the Unfragile graph. Requires at least one notification channel (email or webhook).", { query: z.string().min(2).max(500).describe("What to watch for (e.g., 'new MCP server for Postgres', 'framework for building AI agents')"), type: z.enum(["agent", "api", "app", "benchmark", "cli", "dataset", "extension", "finetune", "framework", "mcp", "model", "platform", "product", "prompt", "repo", "skill", "template", "webapp", "workflow"]).optional().describe("Only watch for this artifact type"), email: z.string().email().optional().describe("Email address for notifications"), webhook: z.string().url().optional().describe("Webhook URL for notifications (receives POST with new matches)"), }, async ({ query, type, email, webhook }) => { log("subscribe", query); if (!email && !webhook) { return { content: [{ type: "text" as const, text: "Error: At least one notification channel required. Provide 'email' and/or 'webhook'." }], isError: true, }; } try { const headers: Record<string, string> = { "Content-Type": "application/json" }; if (API_KEY) headers["X-API-Key"] = API_KEY; const body: Record<string, unknown> = { query, notify: { email, webhook }, source: SOURCE, }; if (type) body.type = type; const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 15_000); try { const res = await fetch(`${API_BASE}/api/v1/monitor`, { method: "POST", headers, body: JSON.stringify(body), signal: controller.signal, }); const data = await res.json(); if (!res.ok) { throw new Error(data.error || `API error ${res.status}`); } const lines: string[] = []; lines.push(`# Monitor Created`); lines.push(`**ID:** ${data.id}`); lines.push(`**Watching for:** ${data.query}`); if (data.typeFilter) lines.push(`**Type filter:** ${data.typeFilter}`); lines.push(`**Frequency:** Daily`); if (email) lines.push(`**Email alerts:** ${email}`); if (webhook) lines.push(`**Webhook:** ${webhook}`); lines.push(`**Expires:** ${data.expiresAt.slice(0, 10)} (90 days)`); lines.push(`\n_Save the monitor ID to unsubscribe later._`); return { content: [{ type: "text" as const, text: lines.join("\n") }] }; } finally { clearTimeout(timeout); } } catch (err) { return { content: [{ type: "text" as const, text: `Error creating monitor: ${err instanceof Error ? err.message : String(err)}` }], isError: true, }; } } - src/index.ts:769-774 (schema)Input schema using Zod: query (string 2-500 chars), type (optional enum of artifact types), email (optional email string), webhook (optional URL string)
{ query: z.string().min(2).max(500).describe("What to watch for (e.g., 'new MCP server for Postgres', 'framework for building AI agents')"), type: z.enum(["agent", "api", "app", "benchmark", "cli", "dataset", "extension", "finetune", "framework", "mcp", "model", "platform", "product", "prompt", "repo", "skill", "template", "webapp", "workflow"]).optional().describe("Only watch for this artifact type"), email: z.string().email().optional().describe("Email address for notifications"), webhook: z.string().url().optional().describe("Webhook URL for notifications (receives POST with new matches)"), },