tokens-for-good 0.2.3 → 0.2.5
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/package.json +1 -1
- package/src/mcp-server.js +31 -6
- package/src/platform.js +34 -0
package/package.json
CHANGED
package/src/mcp-server.js
CHANGED
|
@@ -26,7 +26,7 @@ updateState({ platform });
|
|
|
26
26
|
|
|
27
27
|
const server = new McpServer({
|
|
28
28
|
name: 'tokens-for-good',
|
|
29
|
-
version: '0.2.
|
|
29
|
+
version: '0.2.5',
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
// --- No-key onboarding message ---
|
|
@@ -191,15 +191,17 @@ server.tool('get_methodology', 'Get the full research methodology, verification
|
|
|
191
191
|
}
|
|
192
192
|
});
|
|
193
193
|
|
|
194
|
-
server.tool('submit_report', 'Submit a completed research report for an org you claimed.', {
|
|
194
|
+
server.tool('submit_report', 'Submit a completed research report for an org you claimed. IMPORTANT: Estimate your token usage for this research session and pass it as estimated_tokens (input + output tokens combined).', {
|
|
195
195
|
claim_id: z.number().describe('The claim ID from claim_org'),
|
|
196
196
|
report_markdown: z.string().describe('The full research report in markdown'),
|
|
197
197
|
model_used: z.string().optional().describe('The model that generated this report'),
|
|
198
|
-
|
|
198
|
+
estimated_tokens: z.number().optional().describe('Your estimated total token usage (input + output) for this research session'),
|
|
199
|
+
}, async ({ claim_id, report_markdown, model_used, estimated_tokens }) => {
|
|
199
200
|
if (!client) return { content: [{ type: 'text', text: 'Error: TFG_API_KEY not set.' }] };
|
|
200
201
|
|
|
202
|
+
const tokenUsage = estimated_tokens ? { total_tokens: estimated_tokens } : null;
|
|
201
203
|
try {
|
|
202
|
-
const result = await client.submitReport(claim_id, report_markdown,
|
|
204
|
+
const result = await client.submitReport(claim_id, report_markdown, tokenUsage, null, model_used);
|
|
203
205
|
markContributed();
|
|
204
206
|
const state = loadState();
|
|
205
207
|
const stats = result.contributor_stats;
|
|
@@ -277,10 +279,33 @@ server.tool('my_impact', 'See your personal contribution stats, tier, and histor
|
|
|
277
279
|
try {
|
|
278
280
|
const result = await client.getImpact();
|
|
279
281
|
const c = result.contributor;
|
|
280
|
-
const
|
|
282
|
+
const tokenStr = c.total_tokens > 0 ? `${(c.total_tokens / 1000).toFixed(0)}K tokens contributed` : 'No token data yet';
|
|
281
283
|
|
|
282
284
|
return {
|
|
283
|
-
content: [{ type: 'text', text: `Your Impact (@${c.github_handle}):\n\nTier: ${c.tier}\nOrgs researched: ${c.total_orgs}\
|
|
285
|
+
content: [{ type: 'text', text: `Your Impact (@${c.github_handle}):\n\nTier: ${c.tier}\nOrgs researched: ${c.total_orgs}\nTokens: ${tokenStr}\nAcceptance rate: ${c.acceptance_rate}%\nAutomation: ${c.has_schedule ? 'Active' : 'Not set up'}\n\nRecent:\n${result.claims?.slice(0, 5).map(cl => ` ${cl.organization?.name || 'Unknown'} - ${cl.status}`).join('\n') || 'None'}` }],
|
|
286
|
+
};
|
|
287
|
+
} catch (err) {
|
|
288
|
+
return { content: [{ type: 'text', text: `Error: ${err.message}` }] };
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
server.tool('get_badge', 'Get a markdown badge for your GitHub README showing your Tokens for Good contribution stats.', {}, async () => {
|
|
293
|
+
if (!client) return { content: [{ type: 'text', text: 'Error: TFG_API_KEY not set.' }] };
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
const result = await client.getImpact();
|
|
297
|
+
const c = result.contributor;
|
|
298
|
+
const tier = c.tier || 'new';
|
|
299
|
+
const orgCount = c.total_orgs || 0;
|
|
300
|
+
const label = `Tokens_for_Good`;
|
|
301
|
+
const message = `${orgCount}_org${orgCount !== 1 ? 's' : ''}_researched`;
|
|
302
|
+
const color = tier === 'gold' ? 'FFD700' : tier === 'silver' ? 'C0C0C0' : tier === 'bronze' ? 'CD7F32' : '54BC4B';
|
|
303
|
+
const badgeUrl = `https://img.shields.io/badge/${label}-${message}-${color}?style=flat`;
|
|
304
|
+
const linkUrl = `https://fierce-philanthropy-directory.laravel.cloud/contribute`;
|
|
305
|
+
const markdown = `[](${linkUrl})`;
|
|
306
|
+
|
|
307
|
+
return {
|
|
308
|
+
content: [{ type: 'text', text: `Add this badge to your GitHub README:\n\n\`\`\`markdown\n${markdown}\n\`\`\`\n\nPreview: ${markdown}\n\nTier: ${tier} | Orgs: ${orgCount}` }],
|
|
284
309
|
};
|
|
285
310
|
} catch (err) {
|
|
286
311
|
return { content: [{ type: 'text', text: `Error: ${err.message}` }] };
|
package/src/platform.js
CHANGED
|
@@ -90,6 +90,40 @@ Method: POST
|
|
|
90
90
|
Headers: X-TFG-Api-Key: ${apiKey}, Content-Type: application/json
|
|
91
91
|
Body: {"claim_id": <claim_id from step 1>, "report_markdown": "<full report>", "model_used": "claude-code-scheduled"}
|
|
92
92
|
|
|
93
|
+
### 5. Check next-action
|
|
94
|
+
After submitting, check if you need to do a peer review before continuing:
|
|
95
|
+
|
|
96
|
+
WebFetch URL: https://fierce-philanthropy-directory.laravel.cloud/api/research/next-action
|
|
97
|
+
Method: GET
|
|
98
|
+
Headers: X-TFG-Api-Key: ${apiKey}, Accept: application/json
|
|
99
|
+
|
|
100
|
+
If the response says action is "review", do the review:
|
|
101
|
+
|
|
102
|
+
**5a. Get the review:**
|
|
103
|
+
WebFetch URL: https://fierce-philanthropy-directory.laravel.cloud/api/research/review/next
|
|
104
|
+
Method: GET
|
|
105
|
+
Headers: X-TFG-Api-Key: ${apiKey}, Accept: application/json
|
|
106
|
+
|
|
107
|
+
**5b. Review the report** — score it 1-4 (4=great, 3=good with minor fixes, 2=needs redo, 1=bad actor)
|
|
108
|
+
|
|
109
|
+
**5c. Submit the review:**
|
|
110
|
+
WebFetch URL: https://fierce-philanthropy-directory.laravel.cloud/api/research/review/submit
|
|
111
|
+
Method: POST
|
|
112
|
+
Headers: X-TFG-Api-Key: ${apiKey}, Content-Type: application/json
|
|
113
|
+
Body: {"claim_id": <claim_id>, "score": <1-4>, "notes": "<review notes>", "updated_report": "<fixed report if score is 3>"}
|
|
114
|
+
|
|
115
|
+
### 6. Repeat (up to 3 orgs per session)
|
|
116
|
+
After completing each org (and any peer review), loop back to Step 1 and claim the next org.
|
|
117
|
+
Research up to 3 orgs total per session. After 3 orgs (or if no more are available), stop.
|
|
118
|
+
|
|
119
|
+
## Batch Flow Summary
|
|
120
|
+
\`\`\`
|
|
121
|
+
for i in 1..3:
|
|
122
|
+
claim org → research → submit report
|
|
123
|
+
check next-action → if review needed, do review
|
|
124
|
+
repeat
|
|
125
|
+
\`\`\`
|
|
126
|
+
|
|
93
127
|
### Rules
|
|
94
128
|
- Every factual claim needs an inline citation [Source Name](URL)
|
|
95
129
|
- Only use direct results from the org, not from similar orgs
|