@vapi-network/mcp 0.2.2 → 0.3.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/dist/server.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { type VapiPaymentAccount, type VapiConfig } from "@vapi-network/core";
1
+ import { type SecretStore, type VapiPaymentAccount, type VapiConfig, type WalletStore } from "@vapi-network/core";
2
2
  import { z } from "zod";
3
3
  import { callService, type CallToolInput, type CallToolResult } from "./tools/call.js";
4
4
  export { callService, type CallToolInput, type CallToolResult };
5
5
  export type VapiServerOptions = {
6
+ /** The wallet unlocked before stdio was connected. */
6
7
  account: VapiPaymentAccount;
7
8
  config: VapiConfig;
8
9
  fetchImpl?: typeof fetch;
@@ -10,6 +11,15 @@ export type VapiServerOptions = {
10
11
  receiptsPath?: string;
11
12
  searchesPath?: string;
12
13
  reportsDirectory?: string;
14
+ /** The wallets on this machine. Without it the server has exactly one. */
15
+ store?: WalletStore | undefined;
16
+ /** The wallet the session starts on; `VAPI_WALLET` and the default follow. */
17
+ wallet?: string | undefined;
18
+ env?: NodeJS.ProcessEnv | undefined;
19
+ /** The passphrase a payment unlocks with; see `WalletSession`. */
20
+ passphrase?: (() => string | Promise<string>) | undefined;
21
+ /** The OS secret store `vapi unlock` writes to; see `WalletSession`. */
22
+ secretStore?: SecretStore | undefined;
13
23
  };
14
24
  type ToolResult = {
15
25
  isError?: boolean;
@@ -1,4 +1,4 @@
1
- import { type LookupFn, type MarketplaceHit, type VapiPaymentAccount, type VapiConfig } from "@vapi-network/core";
1
+ import { type LookupFn, type MarketplaceHit, type SpendCaps, type VapiPaymentAccount, type VapiConfig, type WalletName } from "@vapi-network/core";
2
2
  export type CallToolInput = {
3
3
  id?: string;
4
4
  url?: string;
@@ -67,6 +67,10 @@ export type CallServiceArgs = {
67
67
  lookup?: LookupFn;
68
68
  ledgerPath?: string;
69
69
  receiptsPath?: string;
70
+ /** The wallet that pays, so its ledger row and its receipts stay its own. */
71
+ wallet?: WalletName;
72
+ /** The caps of that wallet. Without it, the machine-wide config caps apply. */
73
+ spendCaps?: SpendCaps;
70
74
  now?: Date;
71
75
  nowMs?: () => number;
72
76
  timeoutMs?: number;
@@ -7,7 +7,19 @@ export type WalletBalance = {
7
7
  usdc: string | null;
8
8
  error?: string;
9
9
  };
10
- export declare function getWallet(account: Address | VapiPaymentAccount, config: VapiConfig, options?: {
10
+ /**
11
+ * What a balance read needs to know about a wallet: its addresses, never its
12
+ * keys. A `VapiPaymentAccount` satisfies this, and so does the summary the
13
+ * wallet store reads out of a keystore without its passphrase — which is why
14
+ * `wallet.balance` can name another wallet without unlocking anything.
15
+ */
16
+ export type WalletAddresses = {
17
+ address: Address;
18
+ solana?: {
19
+ address: string;
20
+ } | undefined;
21
+ };
22
+ export declare function getWallet(account: Address | WalletAddresses | VapiPaymentAccount, config: VapiConfig, options?: {
11
23
  fetchImpl?: typeof fetch;
12
24
  lookup?: LookupFn;
13
25
  }): Promise<{
@@ -0,0 +1,91 @@
1
+ import { type SecretStore, type SpendCaps, type VapiPaymentAccount, type WalletName, type WalletStore } from "@vapi-network/core";
2
+ import type { WalletAddresses } from "./tools/wallet.js";
3
+ /** The wallet one tool call acts on. `path` is absent on a single-wallet home. */
4
+ export type SessionWallet = {
5
+ name: WalletName;
6
+ /** The keystore file, when this machine has a wallet store. */
7
+ path?: string;
8
+ };
9
+ /** One row of `wallet.list`, before balances are read. */
10
+ export type SessionWalletInfo = {
11
+ name: WalletName;
12
+ address?: string;
13
+ solanaAddress?: string;
14
+ label?: string;
15
+ isDefault: boolean;
16
+ /** Whether this is the wallet the session currently pays from. */
17
+ isActive: boolean;
18
+ spendCaps?: SpendCaps;
19
+ };
20
+ export type WalletSessionOptions = {
21
+ /** The wallet unlocked before stdio was connected, for a store-less home. */
22
+ account: VapiPaymentAccount;
23
+ /** The wallets on this machine. Without it the session has exactly one. */
24
+ store?: WalletStore | undefined;
25
+ /** The name the session starts on, before `VAPI_WALLET` and the default. */
26
+ wallet?: string | undefined;
27
+ env?: NodeJS.ProcessEnv | undefined;
28
+ /**
29
+ * The passphrase a payment unlocks with when neither
30
+ * `VAPI_KEYSTORE_PASSWORD` nor the OS secret store has one. The CLI hands
31
+ * over what it read at startup — from the person who ran `vapi mcp` in a
32
+ * terminal — so switching wallets never needs a prompt on a stdout that
33
+ * belongs to MCP frames.
34
+ */
35
+ passphrase?: (() => string | Promise<string>) | undefined;
36
+ /** The OS secret store to read `vapi unlock` entries from. */
37
+ secretStore?: SecretStore | undefined;
38
+ now?: (() => Date) | undefined;
39
+ };
40
+ /**
41
+ * Which wallet an MCP session pays from, for the lifetime of the process.
42
+ *
43
+ * The session is the only mutable wallet state the server has, and it is
44
+ * deliberately memory-only: `wallet.use` moves it, and nothing in this package
45
+ * ever writes `wallets.json`, creates, removes, renames, backs up or exports a
46
+ * wallet. Reads — addresses, balances, accounts, funding links — need no
47
+ * passphrase at all, because the wallet store can read a keystore's addresses
48
+ * without opening it. Only a payment unlocks a key, once, for that one call.
49
+ */
50
+ export declare class WalletSession {
51
+ #private;
52
+ private readonly options;
53
+ constructor(options: WalletSessionOptions);
54
+ /** The wallet the next tool call uses when it names none. */
55
+ get activeName(): WalletName | undefined;
56
+ get store(): WalletStore | undefined;
57
+ /** The home the audit log lives in, honouring `VAPI_HOME`. */
58
+ get home(): string;
59
+ /**
60
+ * An explicit name first, then the session's active wallet — which already
61
+ * absorbed `VAPI_WALLET` and the registry default when the session started.
62
+ */
63
+ resolve(name?: string): SessionWallet;
64
+ /** The addresses of a wallet, read straight out of its keystore header. */
65
+ addressesFor(name?: string): Promise<{
66
+ wallet: SessionWallet;
67
+ } & WalletAddresses>;
68
+ /**
69
+ * The unlocked key for one payment, plus the caps of that wallet. Nothing
70
+ * here is cached: the account is created for this call and dropped with it,
71
+ * so switching wallets mid-session pays from the wallet that was asked for.
72
+ */
73
+ payment(name?: string): Promise<{
74
+ wallet: SessionWallet;
75
+ account: VapiPaymentAccount;
76
+ spendCaps?: SpendCaps;
77
+ }>;
78
+ /** Every wallet this machine knows, with the session's own marker on one. */
79
+ list(): Promise<SessionWalletInfo[]>;
80
+ /**
81
+ * Points the session at another wallet. Memory only: the human's default in
82
+ * `wallets.json` is not touched, so the next `vapi` command in their terminal
83
+ * still uses the wallet they chose. The switch is audited, because the wallet
84
+ * an agent pays from changed.
85
+ */
86
+ use(name: string): Promise<{
87
+ active: WalletName;
88
+ address?: string;
89
+ previous: WalletName | null;
90
+ }>;
91
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vapi-network/mcp",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Local, non-custodial MCP server for discovering and paying x402 APIs",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -15,7 +15,8 @@
15
15
  "type": "module",
16
16
  "sideEffects": false,
17
17
  "files": [
18
- "dist"
18
+ "dist",
19
+ "README.md"
19
20
  ],
20
21
  "exports": {
21
22
  ".": {