rate_connection
Rate a connection after meeting through Mingle. Choose useful, neutral, or not_useful to improve future matching for everyone.
Instructions
Rate a connection you made through Mingle. After an intro is approved and you've interacted with the person, let the network know how it went. This helps improve matching for everyone.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| intro_id | Yes | Intro ID of the connection to rate | |
| rating | Yes | How useful was this connection? | |
| comment | No | Optional: brief note on why |
Implementation Reference
- src/index.ts:455-484 (registration)Registration of the 'rate_connection' tool on the MCP server via server.tool(), defining name, description, and schema.
server.tool( "rate_connection", "Rate a connection you made through Mingle. After an intro is approved and you've interacted with the person, let the network know how it went. This helps improve matching for everyone.", { intro_id: z.string().describe("Intro ID of the connection to rate"), rating: z.enum(["useful", "neutral", "not_useful"]).describe("How useful was this connection?"), comment: z.string().optional().describe("Optional: brief note on why"), }, async (args) => { try { const result = await api(`/api/feedback/${args.intro_id}`, { method: "POST", body: JSON.stringify({ rating: args.rating, comment: args.comment, }), }); if (result.error) return { content: [{ type: "text" as const, text: result.error }], isError: true }; const digest = await fetchDigest(); return { content: [{ type: "text" as const, text: withDigest({ rated: true, introId: args.intro_id, rating: args.rating }, digest), }], }; } catch (e: any) { return { content: [{ type: "text" as const, text: `Network error: ${e.message}` }], isError: true }; } } ); - src/index.ts:458-462 (schema)Zod schema defining input parameters: intro_id (string), rating (enum: useful/neutral/not_useful), comment (optional string).
{ intro_id: z.string().describe("Intro ID of the connection to rate"), rating: z.enum(["useful", "neutral", "not_useful"]).describe("How useful was this connection?"), comment: z.string().optional().describe("Optional: brief note on why"), }, - src/index.ts:463-483 (handler)Handler function that POSTs feedback to /api/feedback/{intro_id}, then returns result with digest via fetchDigest() and withDigest().
async (args) => { try { const result = await api(`/api/feedback/${args.intro_id}`, { method: "POST", body: JSON.stringify({ rating: args.rating, comment: args.comment, }), }); if (result.error) return { content: [{ type: "text" as const, text: result.error }], isError: true }; const digest = await fetchDigest(); return { content: [{ type: "text" as const, text: withDigest({ rated: true, introId: args.intro_id, rating: args.rating }, digest), }], }; } catch (e: any) { return { content: [{ type: "text" as const, text: `Network error: ${e.message}` }], isError: true }; } } - src/index.ts:39-68 (helper)fetchDigest() helper that fetches network state digest from /api/digest/{agentId} and returns pending intros, matches, etc.
async function fetchDigest(): Promise<any> { try { const d = await fetch(`${API}/api/digest/${agentId}`, { headers: { "X-Agent-Id": agentId, "X-Public-Key": keys.publicKey }, }).then(r => r.json()); const rawMatches = d.matches || []; const classified = classifyMatches(rawMatches, prefs.mode); const surfaceNow = classified.filter((m: any) => m.surfacing === "surface_now"); const queued = classified.filter((m: any) => m.surfacing === "queue"); return { pendingIntros: (d.introsReceived || []).length, introsReceived: (d.introsReceived || []).map((i: any) => ({ introId: i.intro_id, from: sanitize(i.requested_by), message: sanitize(i.message), })), matches: { total: rawMatches.length, surfaceNow: surfaceNow.length, queued: queued.length, topMatch: surfaceNow[0] ? { name: sanitize(surfaceNow[0].name), score: surfaceNow[0].score, mutual: surfaceNow[0].mutual, why: surfaceNow[0].needMatch || surfaceNow[0].offerMatch } : null, }, networkSize: d.networkSize || 0, cardStatus: d.hasCard ? "active" : "none", mode: prefs.mode, lastChecked: new Date().toISOString(), }; } catch { return { pendingIntros: 0, matches: { total: 0, surfaceNow: 0, queued: 0, topMatch: null }, networkSize: 0, cardStatus: "unknown", lastChecked: new Date().toISOString() }; } - src/index.ts:72-74 (helper)withDigest() helper that injects the _digest side-channel into any tool result text.
function withDigest(resultObj: any, digest: any): string { return JSON.stringify({ ...resultObj, _digest: digest }, null, 2); }