@tensorfeed/mcp-server 1.24.0 → 1.25.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  All notable changes to the [TensorFeed.ai MCP server](https://github.com/RipperMercs/tensorfeed-mcp). Free tools work without configuration; premium tools require a bearer token via the `TENSORFEED_TOKEN` env var. Buy credits at [tensorfeed.ai/developers/agent-payments](https://tensorfeed.ai/developers/agent-payments).
4
4
 
5
+ ## 1.25.0 - 2026-05-06
6
+
7
+ ### Added
8
+ - Tool annotations on every registered tool (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`). All `get_*`, `*_series`, `*_search`, `compare_*`, `provider_deepdive`, `cost_projection`, `whats_new`, `*_snapshot`, `probe_*`, `list_watches`, `premium_routing`, and `premium_agents_directory` tools are flagged read-only + idempotent + open-world. The four `create_*_watch` tools are flagged write + non-idempotent. `delete_watch` is flagged destructive + idempotent. Hosts and clients can now decide whether a tool is safe to batch, retry, or call autonomously without re-prompting the user. Required by the Anthropic Connectors Directory.
9
+
5
10
  ## 1.24.0 - 2026-05-06
6
11
 
7
12
  ### Added
package/dist/index.js CHANGED
@@ -56,14 +56,44 @@ const server = new McpServer({
56
56
  // covers any new endpoint that might forget it, plus protects against
57
57
  // drift between worker rules and what the MCP server should consider
58
58
  // safe. See ./sanitize.ts.
59
- function registerTool(name, description, paramsSchema, cb) {
59
+ // MCP tool annotation presets. These are HINTS for hosts/clients and agents
60
+ // so they can decide whether a tool is safe to call autonomously, batch, or
61
+ // retry. Required by the Anthropic Connectors Directory and used by client
62
+ // tool-pickers. See https://modelcontextprotocol.io/specification#tool-annotations
63
+ //
64
+ // readOnlyHint: true if the tool only reads, no side effects on the world
65
+ // destructiveHint: true if the tool may delete/destroy data
66
+ // idempotentHint: true if calling twice has the same effect as once
67
+ // openWorldHint: true if the tool interacts with external systems (HTTP/APIs)
68
+ //
69
+ // All TensorFeed tools hit the tensorfeed.ai HTTP API, so openWorldHint is
70
+ // always true here.
71
+ const READ_TOOL = {
72
+ readOnlyHint: true,
73
+ destructiveHint: false,
74
+ idempotentHint: true,
75
+ openWorldHint: true,
76
+ };
77
+ const CREATE_TOOL = {
78
+ readOnlyHint: false,
79
+ destructiveHint: false,
80
+ idempotentHint: false,
81
+ openWorldHint: true,
82
+ };
83
+ const DELETE_TOOL = {
84
+ readOnlyHint: false,
85
+ destructiveHint: true,
86
+ idempotentHint: true,
87
+ openWorldHint: true,
88
+ };
89
+ function registerTool(name, description, paramsSchema, cb, annotations = READ_TOOL) {
60
90
  const wrapped = (async (args, extra) => {
61
91
  const result = await cb(args, extra);
62
92
  return sanitizeToolResponse(result);
63
93
  });
64
94
  // Direct dispatch to the SDK's underlying registration. Do not call
65
95
  // registerTool() here or it will recurse forever.
66
- return server.tool(name, description, paramsSchema, wrapped);
96
+ return server.tool(name, description, paramsSchema, annotations, wrapped);
67
97
  }
68
98
  // ── Tool: get_ai_news ───────────────────────────────────────────────
69
99
  registerTool('get_ai_news', 'Get the latest AI news articles from TensorFeed.ai. Aggregates from 15+ sources including Anthropic, OpenAI, Google, TechCrunch, The Verge, arXiv, and more.', {
@@ -727,7 +757,7 @@ registerTool('create_price_watch', 'Register a webhook watch on a model price ch
727
757
  },
728
758
  ],
729
759
  };
730
- });
760
+ }, CREATE_TOOL);
731
761
  // ── Tool: create_status_watch (1 credit) ────────────────────────────
732
762
  registerTool('create_status_watch', 'Register a webhook watch on a service status transition (e.g. anthropic becomes down). Costs 1 credit. Watch lives 90 days.', {
733
763
  provider: z.string().describe('Provider name (e.g. anthropic, openai)'),
@@ -751,7 +781,7 @@ registerTool('create_status_watch', 'Register a webhook watch on a service statu
751
781
  },
752
782
  ],
753
783
  };
754
- });
784
+ }, CREATE_TOOL);
755
785
  // ── Tool: create_digest_watch (1 credit) ────────────────────────────
756
786
  registerTool('create_digest_watch', 'Register a scheduled digest webhook that fires daily or weekly with a curated summary of pricing changes (regardless of whether anything dramatic happened). Costs 1 credit. Watch lives 90 days. Set-and-forget for agents that want a periodic snapshot without subscribing to realtime transitions.', {
757
787
  cadence: z.enum(['daily', 'weekly']).describe('How often the digest fires'),
@@ -773,7 +803,7 @@ registerTool('create_digest_watch', 'Register a scheduled digest webhook that fi
773
803
  },
774
804
  ],
775
805
  };
776
- });
806
+ }, CREATE_TOOL);
777
807
  // ── Tool: create_leaderboard_rank_watch (1 credit) ──────────────────
778
808
  registerTool('create_leaderboard_rank_watch', 'Register a webhook that fires when a provider crosses a rank threshold on the cross-provider 7-day uptime leaderboard. Rank 1 = best (highest uptime). drops_below: was rank<=N, now rank>N (got worse). rises_above: was rank>=N, now rank<N (got better). changes: any rank movement. Costs 1 credit at registration. Watch lives 90 days.', {
779
809
  provider: z.string().describe('Provider name or slug (case-insensitive). e.g. claude, openai, gemini, bedrock, azure'),
@@ -800,14 +830,14 @@ registerTool('create_leaderboard_rank_watch', 'Register a webhook that fires whe
800
830
  },
801
831
  ],
802
832
  };
803
- });
833
+ }, CREATE_TOOL);
804
834
  // ── Tool: delete_watch ──────────────────────────────────────────────
805
835
  registerTool('delete_watch', 'Delete one of your active webhook watches by id. Free, requires TENSORFEED_TOKEN.', {
806
836
  watch_id: z.string().describe('The wat_... id from create_price_watch / create_status_watch / list_watches'),
807
837
  }, async ({ watch_id }) => {
808
838
  await fetchJSON(`/premium/watches/${watch_id}`, { method: 'DELETE', auth: true });
809
839
  return { content: [{ type: 'text', text: `Deleted watch ${watch_id}.` }] };
810
- });
840
+ }, DELETE_TOOL);
811
841
  // ── Tool: probe_latest (free) ───────────────────────────────────────
812
842
  registerTool('probe_latest', 'Last 24 hours of measured LLM endpoint latency and availability per provider (Anthropic, OpenAI, Google, Mistral, Cohere). TensorFeed pings each provider\'s chat completion endpoint every 15 min and records time-to-first-byte, total response time, and HTTP status. Returns per-provider success rate and ttfb/total p50/p95/p99 latency. The data is unique because we measure it ourselves, not self-reported by the providers. Useful when an agent needs to pick a provider whose SLA you can verify, or to detect ongoing incidents before they hit a status page. Free, no auth.', {}, async () => {
813
843
  const data = (await fetchJSON('/probe/latest'));
@@ -886,7 +916,7 @@ registerTool('mcp_registry_snapshot', 'Today\'s summary of the official Model Co
886
916
  content: [
887
917
  {
888
918
  type: 'text',
889
- text: `MCP Server Registry — ${s.date}\n` +
919
+ text: `MCP Server Registry, ${s.date}\n` +
890
920
  `Total servers: ${s.total_servers} (across ${s.total_versions} versioned entries)\n` +
891
921
  `Status: ${statusLine}\n${delta}\n\n` +
892
922
  `Top namespaces:\n${topNs}` +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tensorfeed/mcp-server",
3
- "version": "1.24.0",
3
+ "version": "1.25.0",
4
4
  "mcpName": "ai.tensorfeed/mcp-server",
5
5
  "description": "MCP server for TensorFeed.ai - AI news, status, model data, and premium endpoints (routing, cost projection, forecast, history series, news search, webhook watches with digest tier, enriched directory) for AI agents",
6
6
  "main": "dist/index.js",
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "ai.tensorfeed/mcp-server",
4
4
  "title": "TensorFeed",
5
5
  "description": "AI news, model pricing, service status, and machine-payable premium tools. AFTA-certified.",
6
- "version": "1.24.0",
6
+ "version": "1.25.0",
7
7
  "websiteUrl": "https://tensorfeed.ai/developers/agent-payments",
8
8
  "repository": {
9
9
  "url": "https://github.com/RipperMercs/tensorfeed-mcp",
@@ -14,7 +14,7 @@
14
14
  "registryType": "npm",
15
15
  "registryBaseUrl": "https://registry.npmjs.org",
16
16
  "identifier": "@tensorfeed/mcp-server",
17
- "version": "1.24.0",
17
+ "version": "1.25.0",
18
18
  "runtimeHint": "npx",
19
19
  "transport": {
20
20
  "type": "stdio"