@agents-trust/mcp 0.1.1 → 0.1.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/dist/api.js CHANGED
@@ -74,7 +74,7 @@ export class AgentsTrustApi {
74
74
  }
75
75
  if (response.status === 402 && paid) {
76
76
  if (this.settings.enablePayments !== true)
77
- throw new Error('Payments disabled. The wallet owner must configure AGENTS_TRUST_ENABLE_PAYMENTS=true for one authorization per process.');
77
+ throw new Error('Payments disabled. The wallet owner must configure AGENTS_TRUST_ENABLE_PAYMENTS=true for one authorization per process' + (this.settings.walletKey ? '.' : ' and supply AGENTS_TRUST_WALLET_PRIVATE_KEY.'));
78
78
  if (this.authorizationUsed)
79
79
  throw new Error('Payment authorization already used in this process. Check your wallet and receipt before granting another process permission.');
80
80
  if (!this.settings.walletKey)
@@ -105,8 +105,20 @@ export class AgentsTrustApi {
105
105
  throw new Error('Payment could not complete. Budget remains reserved; check your wallet and receipt before another call.');
106
106
  }
107
107
  }
108
- if (!response.ok)
109
- throw new Error(`Agents Trust returned HTTP ${response.status}. No automatic retry was made.`);
108
+ if (!response.ok) {
109
+ let detail;
110
+ try {
111
+ const body = await response.json();
112
+ const code = typeof body?.error?.code === 'string' ? body.error.code : '';
113
+ const message = typeof body?.error?.message === 'string' ? body.error.message : '';
114
+ detail = [code, message].filter(Boolean).join(': ').replace(/\s+/g, ' ').slice(0, 200);
115
+ }
116
+ catch {
117
+ detail = '';
118
+ }
119
+ const retry = this.authorizationUsed && paid ? ' No automatic retry was made.' : '';
120
+ throw new Error(`Agents Trust returned HTTP ${response.status}${detail ? ` (${detail})` : ''}.${retry}`);
121
+ }
110
122
  try {
111
123
  const body = await response.json();
112
124
  return {
package/dist/server.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { z } from 'zod';
3
3
  import { AgentsTrustApi } from './api.js';
4
+ const RESULT = 'Returns JSON {data, payment_attempt_id, request_id}; payment_attempt_id is set only after a paid answer.';
5
+ const PAYMENT = 'Paying needs the wallet owner to set AGENTS_TRUST_ENABLE_PAYMENTS=true and AGENTS_TRUST_WALLET_PRIVATE_KEY (Base USDC); one paid call per process, capped by AGENTS_TRUST_MAX_CALL_USDC (default 0.01). Otherwise it returns an error and sends nothing. Errors and empty results are free; paid calls are never retried.';
4
6
  export function createServer(settings = {}, request = fetch) {
5
7
  const api = new AgentsTrustApi(settings, request);
6
- const server = new McpServer({ name: 'agents-trust', version: '0.1.0' });
8
+ const server = new McpServer({ name: 'agents-trust', version: '0.1.2' });
7
9
  const run = async (action) => {
8
10
  try {
9
11
  let text = JSON.stringify(await action());
@@ -19,19 +21,33 @@ export function createServer(settings = {}, request = fetch) {
19
21
  }
20
22
  };
21
23
  server.registerTool('recommend', {
22
- description: 'Find APIs for your task, with URLs, prices and call details. Payment requires owner opt-in and consumes the process’s single authorization, up to the configured USDC limit.',
24
+ title: 'Recommend paid APIs for a task',
25
+ description: [
26
+ 'Find which paid x402 API to call for a task described in plain words, ranked with evidence. Each pick has the endpoint URL, provider price and payment network, a ready request template, liveness, delivery evidence and risk flags.',
27
+ 'Use it when you do not yet know which API to call; use inspect instead when you already have one exact endpoint URL, and receipt to confirm settlement after paying.',
28
+ 'Weather, crypto prices and web search are free demo needs; other needs cost 0.01 USDC.',
29
+ PAYMENT, RESULT,
30
+ 'Returns fewer picks, or none, when evidence is insufficient.',
31
+ ].join(' '),
23
32
  inputSchema: {
24
- need: z.string().refine(s => Array.from(s).length >= 2 && Array.from(s).length <= 300 && /[\p{L}\p{N}].*[\p{L}\p{N}]/u.test(s), 'Use 2–300 characters with at least two letters or digits.'),
25
- limit: z.number().int().min(1).max(5).optional(),
26
- live: z.literal(1).optional(),
27
- max_price_usd: z.number().finite().min(0).optional().describe('Maximum provider price; separate from the recommendation fee.'),
28
- chain: z.string().regex(/^[a-z0-9-]{2,16}:[A-Za-z0-9_=-]{1,64}$/).optional(),
29
- view: z.enum(['legacy', 'compact', 'evidence']).optional(),
33
+ need: z.string().refine(s => Array.from(s).length >= 2 && Array.from(s).length <= 300 && /[\p{L}\p{N}].*[\p{L}\p{N}]/u.test(s), 'Use 2–300 characters with at least two letters or digits.')
34
+ .describe('The work you need done, in plain words, e.g. "weather forecast for Berlin" or "translate text to German". 2–300 characters with at least two letters or digits.'),
35
+ limit: z.number().int().min(1).max(5).optional().describe('Maximum number of picks, 1–5. Default 3.'),
36
+ live: z.literal(1).optional().describe('Only 1 is accepted, which is also the default: prefer endpoints with recent liveness evidence.'),
37
+ max_price_usd: z.number().finite().min(0).optional().describe('Highest provider price per call in USD you accept. Separate from the 0.01 USDC recommendation fee; the provider\'s own quote at call time is authoritative.'),
38
+ chain: z.string().regex(/^[a-z0-9-]{2,16}:[A-Za-z0-9_=-]{1,64}$/).optional().describe('Only return providers that accept payment on this network, as a CAIP-2 id, e.g. eip155:8453 for Base.'),
39
+ view: z.enum(['legacy', 'compact', 'evidence']).optional().describe('Response detail: compact (smallest, pick essentials and request template), evidence (adds ranking, liveness, delivery and payment evidence per pick) or legacy (default, original field layout).'),
30
40
  },
31
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
41
+ annotations: { title: 'Recommend paid APIs for a task', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
32
42
  }, args => run(() => api.recommend(args)));
33
43
  server.registerTool('inspect', {
34
- description: 'Read stored evidence for one exact API endpoint URL, without calling or paying that provider. The Inspect fee is 1% of the endpoint\'s lowest quoted price, with a 0.001 USDC floor. Read the actual quote. Payment requires owner opt-in and shares the process\'s single authorization and USDC limits with Recommend.',
44
+ title: 'Inspect evidence for one endpoint',
45
+ description: [
46
+ 'Read the stored evidence for one exact x402 endpoint URL: price, payment networks, liveness, delivery history and risk flags. It never calls or pays the endpoint itself.',
47
+ 'Use it before paying an endpoint you already know, for example one returned by recommend; use recommend instead to find candidates for a task.',
48
+ 'Demo endpoints are free; other indexed endpoints cost 1% of the endpoint\'s lowest quoted price, minimum 0.001 USDC. An unindexed URL returns ENDPOINT_NOT_INDEXED without payment.',
49
+ PAYMENT, RESULT,
50
+ ].join(' '),
35
51
  inputSchema: {
36
52
  url: z.string().min(1).max(2048).refine(value => {
37
53
  try {
@@ -41,19 +57,33 @@ export function createServer(settings = {}, request = fetch) {
41
57
  catch {
42
58
  return false;
43
59
  }
44
- }, 'Use an absolute HTTPS endpoint URL without credentials.').describe('Exact endpoint URL, including its fixed query parameters. The API rejects private URLs before payment.'),
45
- view: z.enum(['legacy', 'compact', 'evidence', 'debug']).optional(),
60
+ }, 'Use an absolute HTTPS endpoint URL without credentials.').describe('Exact public HTTPS endpoint URL, including any fixed query parameters, e.g. a pick\'s url from recommend. Private, malformed and credential-bearing URLs are rejected before payment.'),
61
+ view: z.enum(['legacy', 'compact', 'evidence', 'debug']).optional().describe('Response detail: compact (smallest), evidence (full evidence blocks), legacy (default, original field layout) or debug (adds diagnostic fields).'),
46
62
  },
47
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
63
+ annotations: { title: 'Inspect evidence for one endpoint', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
48
64
  }, args => run(() => api.inspect(args)));
49
65
  server.registerTool('receipt', {
50
- description: 'Look up payment settlement by payment attempt ID. Free.',
51
- inputSchema: { payment_attempt_id: z.uuid() },
52
- annotations: { readOnlyHint: true, openWorldHint: true },
66
+ title: 'Check payment settlement',
67
+ description: [
68
+ 'Check whether a paid recommend or inspect answer has settled on-chain. Free, read-only, and never repeats the paid request.',
69
+ 'Use it after a paid call, with the payment_attempt_id that call returned; answers arrive before settlement completes.',
70
+ 'Returns data.state (pending, settled, settle_failed_after_answer or settle_unknown_after_answer) and data.transaction (transaction hash once settled, else null).',
71
+ 'An unknown id returns a not-found error. Pending or unavailable does not prove that no money moved: check the wallet before paying again.',
72
+ ].join(' '),
73
+ inputSchema: {
74
+ payment_attempt_id: z.uuid({ version: 'v7' }).describe('The payment_attempt_id returned by a paid recommend or inspect call: a lowercase UUIDv7. Copy it unchanged.'),
75
+ },
76
+ annotations: { title: 'Check payment settlement', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
53
77
  }, args => run(() => api.receipt(args.payment_attempt_id)));
54
78
  server.registerTool('health', {
55
- description: 'Read the Agents Trust service version. Free.', inputSchema: {},
56
- annotations: { readOnlyHint: true, openWorldHint: true },
79
+ title: 'Check service version',
80
+ description: [
81
+ 'Check that the Agents Trust API is reachable and read its deployed version. Free, read-only, no parameters.',
82
+ 'Use it to diagnose connection problems before retrying recommend or inspect; it does not measure data freshness.',
83
+ 'Returns data.status ("ok") and data.version (deployment identifier).',
84
+ ].join(' '),
85
+ inputSchema: {},
86
+ annotations: { title: 'Check service version', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
57
87
  }, () => run(() => api.health()));
58
88
  return server;
59
89
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-trust/mcp",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Find APIs, inspect endpoint evidence and look up payment receipts with Agents Trust.",
5
5
  "scripts": {
6
6
  "build": "node scripts/build.mjs",
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "com.agents-trust/recommend",
4
4
  "title": "Agents Trust",
5
5
  "description": "Find APIs and inspect endpoint evidence. Pay with your own Base USDC wallet.",
6
- "version": "0.1.1",
6
+ "version": "0.1.2",
7
7
  "websiteUrl": "https://agents-trust.com",
8
8
  "repository": {
9
9
  "url": "https://github.com/agents-trust/agents-trust-mcp",
@@ -13,7 +13,7 @@
13
13
  {
14
14
  "registryType": "npm",
15
15
  "identifier": "@agents-trust/mcp",
16
- "version": "0.1.1",
16
+ "version": "0.1.2",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  },