@voidly/mcp-server 1.0.1 → 1.1.0

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.
Files changed (2) hide show
  1. package/dist/index.js +90 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -187,6 +187,72 @@ async function getActiveIncidents() {
187
187
  result += `URL: https://voidly.ai/censorship-index\n`;
188
188
  return result;
189
189
  }
190
+ async function verifyClaim(claim, requireEvidence = false) {
191
+ const data = await fetchJson(`${VOIDLY_API}/v1/verify-claim?claim=${encodeURIComponent(claim)}&require_evidence=${requireEvidence}`);
192
+ let result = `# Claim Verification\n\n`;
193
+ result += `**Claim:** "${data.claim}"\n\n`;
194
+ // Verdict with emoji
195
+ const verdictEmoji = {
196
+ confirmed: '✅',
197
+ likely: '🟡',
198
+ unconfirmed: '❓',
199
+ no_data: '⚪',
200
+ insufficient_data: '⚠️',
201
+ };
202
+ result += `## Verdict: ${verdictEmoji[data.verdict] || ''} ${data.verdict.toUpperCase()}\n\n`;
203
+ result += `**Confidence:** ${(data.confidence * 100).toFixed(0)}%\n`;
204
+ result += `**Reason:** ${data.reason}\n\n`;
205
+ // Parsed components
206
+ result += `## Parsed Claim\n`;
207
+ if (data.parsed.country) {
208
+ result += `- Country: ${data.parsed.country} (${data.parsed.country_code})\n`;
209
+ }
210
+ if (data.parsed.service) {
211
+ result += `- Service: ${data.parsed.service}\n`;
212
+ }
213
+ if (data.parsed.date) {
214
+ result += `- Date: ${data.parsed.date}\n`;
215
+ }
216
+ if (data.parsed.date_range) {
217
+ result += `- Date Range: ${data.parsed.date_range.start} to ${data.parsed.date_range.end}\n`;
218
+ }
219
+ result += '\n';
220
+ // Matching incidents
221
+ if (data.incidents && data.incidents.length > 0) {
222
+ result += `## Supporting Incidents\n\n`;
223
+ data.incidents.forEach((inc, i) => {
224
+ result += `### ${i + 1}. ${inc.title}\n`;
225
+ result += `- ID: ${inc.id}\n`;
226
+ result += `- Status: ${inc.status}\n`;
227
+ result += `- Severity: ${inc.severity}\n`;
228
+ result += `- Confidence: ${(inc.confidence * 100).toFixed(0)}%\n`;
229
+ result += `- Started: ${inc.startTime.slice(0, 10)}\n`;
230
+ result += `- Permalink: ${inc.permalink}\n\n`;
231
+ });
232
+ }
233
+ // Evidence if requested
234
+ if (data.evidence && data.evidence.length > 0) {
235
+ result += `## Evidence Chain\n\n`;
236
+ data.evidence.forEach((ev, i) => {
237
+ result += `${i + 1}. **${ev.source.toUpperCase()}** (${ev.kind})\n`;
238
+ result += ` - Observed: ${ev.observedAt.slice(0, 10)}\n`;
239
+ result += ` - Confidence: ${(ev.confidence * 100).toFixed(0)}%\n`;
240
+ if (ev.permalink) {
241
+ result += ` - Verify: ${ev.permalink}\n`;
242
+ }
243
+ result += '\n';
244
+ });
245
+ }
246
+ // Citation
247
+ if (data.citation) {
248
+ result += `## Citation\n\n`;
249
+ result += `${data.citation}\n\n`;
250
+ }
251
+ result += `## Source\n`;
252
+ result += `Data: Voidly Research Claim Verification API\n`;
253
+ result += `License: CC BY 4.0\n`;
254
+ return result;
255
+ }
190
256
  // Create MCP server
191
257
  const server = new Server({
192
258
  name: 'voidly-censorship-index',
@@ -264,6 +330,24 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
264
330
  required: [],
265
331
  },
266
332
  },
333
+ {
334
+ name: 'verify_claim',
335
+ description: 'Verify a censorship claim with evidence. Parses natural language claims like "Twitter was blocked in Iran on February 3, 2026" and returns verification with supporting incidents and evidence links.',
336
+ inputSchema: {
337
+ type: 'object',
338
+ properties: {
339
+ claim: {
340
+ type: 'string',
341
+ description: 'Natural language censorship claim to verify (e.g., "Is YouTube blocked in China?", "Twitter was blocked in Iran on February 3, 2026")',
342
+ },
343
+ require_evidence: {
344
+ type: 'boolean',
345
+ description: 'Whether to include detailed evidence chain with source links (default: false)',
346
+ },
347
+ },
348
+ required: ['claim'],
349
+ },
350
+ },
267
351
  ],
268
352
  }));
269
353
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
@@ -293,6 +377,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
293
377
  case 'get_active_incidents':
294
378
  result = await getActiveIncidents();
295
379
  break;
380
+ case 'verify_claim':
381
+ if (!args?.claim) {
382
+ throw new Error('claim is required');
383
+ }
384
+ result = await verifyClaim(args.claim, args?.require_evidence || false);
385
+ break;
296
386
  default:
297
387
  throw new Error(`Unknown tool: ${name}`);
298
388
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voidly/mcp-server",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "MCP server for Voidly Global Censorship Index - enables AI systems to query real-time censorship data",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",