@bsvkey/inference-mcp 1.2.0 → 1.2.1

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/package.json +2 -2
  2. package/server.js +9 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsvkey/inference-mcp",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "MCP server: buy Claude & Grok inference metered per token, settled in BSV, through the hosted inference.bsvkey.com gateway. Channels or per-call x402.",
5
5
  "mcpName": "io.github.BSVKey/inference-mcp",
6
6
  "type": "module",
@@ -9,7 +9,7 @@
9
9
  "engines": { "node": ">=18" },
10
10
  "files": ["server.js", "SKILL.md", "README.md", "LICENSE"],
11
11
  "optionalDependencies": {
12
- "@bsvkey/x402-bsv-client": "^0.4.0",
12
+ "@bsvkey/x402-bsv-client": "^0.4.2",
13
13
  "@bsv/sdk": "^2"
14
14
  },
15
15
  "keywords": ["mcp", "model-context-protocol", "bsv", "inference", "pay-per-token", "http-402", "x402", "claude", "grok", "micropayments", "agents"],
package/server.js CHANGED
@@ -78,7 +78,7 @@ async function verifyUsageReceipt(receipt, bytes = {}) {
78
78
  }
79
79
  // The meter: recompute token counts + byte digests from the exact bytes we hold.
80
80
  let meterVerified = null;
81
- if (typeof V.verifyMeter === 'function' && (bytes.prompt !== undefined || bytes.completion !== undefined)) {
81
+ if (typeof V.verifyMeter === 'function' && (bytes.messages !== undefined || bytes.prompt !== undefined || bytes.completion !== undefined)) {
82
82
  const mv = V.verifyMeter(receipt, bytes);
83
83
  if (!mv.ok) return { verified: false, reason: `meter:${mv.reason}`, meterVerified: false };
84
84
  meterVerified = true;
@@ -174,14 +174,15 @@ async function callTool(name, args = {}) {
174
174
  case 'infer': {
175
175
  const k = keyParts(args.apiKey);
176
176
  if (!k) throw new Error('No channel key. Pass apiKey "channelId:channelSecret" or set BSVKEY_API_KEY. Open one via the open_channel tool.');
177
+ const messages = [
178
+ ...(args.system ? [{ role: 'system', content: args.system }] : []),
179
+ { role: 'user', content: String(args.prompt || '') },
180
+ ];
177
181
  const r = await http('POST', '/chat/completions', {
178
182
  headers: { authorization: `Bearer ${k.raw}` },
179
183
  body: {
180
184
  model: args.model || 'auto',
181
- messages: [
182
- ...(args.system ? [{ role: 'system', content: args.system }] : []),
183
- { role: 'user', content: String(args.prompt || '') },
184
- ],
185
+ messages,
185
186
  max_tokens: args.maxTokens || 512,
186
187
  web_search: args.webSearch === true,
187
188
  },
@@ -192,7 +193,9 @@ async function callTool(name, args = {}) {
192
193
  }
193
194
  const x = r.json.x_bsv || {};
194
195
  const completion = r.json.choices?.[0]?.message?.content ?? '';
195
- const rc = await verifyUsageReceipt(x.usageReceipt, { system: args.system, prompt: String(args.prompt || ''), completion });
196
+ // Meter over the SAME messages we sent: the OpenAI shim meters the flattened
197
+ // messages, so the verifier must reproduce that transform (needs @bsvkey/x402-bsv-client >= 0.4.2).
198
+ const rc = await verifyUsageReceipt(x.usageReceipt, { messages, completion });
196
199
  return {
197
200
  model: r.json.model || args.model,
198
201
  completion,