tokens-for-good 0.2.0 → 0.2.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokens-for-good",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "Donate your spare AI tokens to research nonprofits for Fierce Philanthropy",
6
6
  "bin": {
@@ -1,12 +1,5 @@
1
1
  # Step 1: Research — Claude Code Instructions
2
2
 
3
- ## Inputs
4
-
5
- - **Org name:** `{{ORG_NAME}}`
6
- - **Org data:** From `orgs.json` — find the entry for this org (name, url, description, source)
7
- - **Writing style guide:** Read from `site/writing-style-guide.md`
8
- - **Research guidance:** Read from `site/research-guidance.md`
9
-
10
3
  ## Your Role
11
4
 
12
5
  You are a social impact research analyst working for Fierce Philanthropy. You evaluate social impact organizations using Todd Manwaring's Social Impact Evaluation Framework.
@@ -32,15 +25,7 @@ You recognize that the best social impact organizations follow a repeated cycle
32
25
 
33
26
  ## Instructions
34
27
 
35
- ### 1. Look Up the Organization
36
-
37
- Find the org in `orgs.json` by name. Extract:
38
- - Name
39
- - URL (primary website or portfolio link)
40
- - Description
41
- - Source (where we found them)
42
-
43
- ### 2. Research the Organization
28
+ ### 1. Research the Organization
44
29
 
45
30
  Using **WebSearch** and **WebFetch** tools, thoroughly research the organization. Search for:
46
31
 
@@ -54,7 +39,7 @@ Using **WebSearch** and **WebFetch** tools, thoroughly research the organization
54
39
  - Only direct results from this organization and independent measurements of it
55
40
  - Only measured results with citations — every factual claim traces to a specific source
56
41
 
57
- ### 3. Generate the Report
42
+ ### 2. Generate the Report
58
43
 
59
44
  Generate the COMPLETE report following this exact format and section order:
60
45
 
@@ -159,7 +144,7 @@ End with:
159
144
 
160
145
  Inline citations as `[Source Name](URL)`. Distinguish attribution: "X reports that" for org claims, "independent evaluation found" for third-party evidence.
161
146
 
162
- ### 4. Submit the Report
147
+ ### 3. Submit the Report
163
148
 
164
149
  Submit using the `submit_report` tool with the full markdown as `report_markdown`.
165
150
 
package/src/api-client.js CHANGED
@@ -19,6 +19,7 @@ export class ApiClient {
19
19
  'Content-Type': 'application/json',
20
20
  'Accept': 'application/json',
21
21
  },
22
+ signal: AbortSignal.timeout(30000),
22
23
  };
23
24
 
24
25
  if (body) {
@@ -70,10 +71,13 @@ export class ApiClient {
70
71
  }
71
72
 
72
73
  async getStatus() {
73
- // Status is public, no auth needed
74
74
  const response = await fetch(`${BASE_URL}/research/status`, {
75
75
  headers: { 'Accept': 'application/json' },
76
+ signal: AbortSignal.timeout(15000),
76
77
  });
78
+ if (!response.ok) {
79
+ throw new Error(`Status API error ${response.status}`);
80
+ }
77
81
  return response.json();
78
82
  }
79
83
 
package/src/mcp-server.js CHANGED
@@ -4,7 +4,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
4
4
  import { z } from 'zod';
5
5
  import { ApiClient } from './api-client.js';
6
6
  import { detectPlatform, isSchedulable, getAutomationInstructions } from './platform.js';
7
- import { loadState, updateState, isSnoozed, snoozeDays, hasContributedToday, markContributed } from './state.js';
7
+ import { loadState, updateState, isSnoozed, hasContributedToday, markContributed } from './state.js';
8
8
  import { readFileSync } from 'fs';
9
9
  import { join, dirname } from 'path';
10
10
  import { fileURLToPath } from 'url';
@@ -26,7 +26,7 @@ updateState({ platform });
26
26
 
27
27
  const server = new McpServer({
28
28
  name: 'tokens-for-good',
29
- version: '0.2.0',
29
+ version: '0.2.2',
30
30
  });
31
31
 
32
32
  // --- No-key onboarding message ---
@@ -327,10 +327,10 @@ After adding, tell them: "Done! Research will now run hands-free. Try saying 'Re
327
327
  };
328
328
  });
329
329
 
330
- server.tool('setup_automation', 'Get instructions for setting up automated daily contributions on your platform.', {
330
+ server.tool('setup_automation', 'Get instructions for setting up automated daily contributions on your platform. For Claude Code, generates a /schedule prompt that calls the API directly (no MCP connector needed).', {
331
331
  frequency: z.enum(['hourly', 'daily', 'weekly']).optional().describe('How often to contribute'),
332
332
  }, async ({ frequency }) => {
333
- const instructions = getAutomationInstructions(platform, frequency || 'daily');
333
+ const instructions = getAutomationInstructions(platform, frequency || 'daily', apiKey);
334
334
  return { content: [{ type: 'text', text: instructions }] };
335
335
  });
336
336
 
@@ -350,8 +350,7 @@ server.prompt('session_start', 'Check if you should research an org or complete
350
350
  const state = loadState();
351
351
 
352
352
  // Check for pending peer review first
353
- if (client) {
354
- try {
353
+ try {
355
354
  const review = await client.getNextPeerReview();
356
355
  return {
357
356
  messages: [{
@@ -362,7 +361,6 @@ server.prompt('session_start', 'Check if you should research an org or complete
362
361
  } catch {
363
362
  // No pending review, continue
364
363
  }
365
- }
366
364
 
367
365
  if (isSnoozed()) {
368
366
  return { messages: [{ role: 'user', content: { type: 'text', text: 'Tokens for Good is snoozed. No action needed.' } }] };
package/src/platform.js CHANGED
@@ -44,12 +44,10 @@ This returns the org name, URL, description, and a claim_id. You have 30 minutes
44
44
 
45
45
  ### 2. Research the org
46
46
  Use WebSearch and WebFetch to thoroughly research the organization:
47
- - Search for the org's website, impact pages, annual reports
48
- - Search for independent evaluations (RCTs, J-PAL, 3ie)
49
- - Search for third-party reviews (GiveWell, Charity Navigator)
50
- - Search for financial data (ProPublica Nonprofit Explorer)
51
-
52
- Use ONLY WebSearch and WebFetch tools. Do NOT use curl or Bash for web requests.
47
+ - The org's website, impact pages, annual reports
48
+ - Independent evaluations (RCTs, J-PAL, 3ie)
49
+ - Third-party reviews (GiveWell, Charity Navigator)
50
+ - Financial data (ProPublica Nonprofit Explorer)
53
51
 
54
52
  ### 3. Write the report
55
53
  Follow the Fierce Philanthropy research methodology: