tokens-for-good 0.2.1 → 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.1",
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.1',
29
+ version: '0.2.2',
30
30
  });
31
31
 
32
32
  // --- No-key onboarding message ---
@@ -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.' } }] };