@oneshot-agent/mcp-server 0.24.1 → 0.28.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/README.md +36 -20
- package/dist/index.js +1 -1
- package/dist/tools/approvals.d.ts +12 -0
- package/dist/tools/approvals.js +81 -0
- package/dist/tools/commerce.js +5 -0
- package/dist/tools/email.js +5 -0
- package/dist/tools/index.js +26 -0
- package/dist/tools/sms.js +5 -0
- package/dist/tools/voice-inbound.d.ts +16 -0
- package/dist/tools/voice-inbound.js +102 -0
- package/dist/tools/voice.js +5 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# @oneshot-agent/mcp-server
|
|
2
2
|
|
|
3
|
-
MCP (Model Context Protocol) server for [OneShot](https://oneshotagent.com)
|
|
3
|
+
MCP (Model Context Protocol) server for [OneShot](https://oneshotagent.com). It gives any MCP client (Claude Desktop, Cursor, Claude Code) OneShot's tools: email, calls, SMS, research, enrichment, commerce, website builds. Paid calls are charged one at a time and show up in your receipts. An optional daily budget caps the spend.
|
|
4
|
+
|
|
5
|
+
Quick start:
|
|
6
|
+
|
|
7
|
+
1. Install the server (below).
|
|
8
|
+
2. Add it to your client's MCP config with CDP credentials ([Configuration](#configuration)).
|
|
9
|
+
3. Send USDC on Base to the agent's wallet ([Funding Your Agent](#funding-your-agent)).
|
|
4
10
|
|
|
5
11
|
## Installation
|
|
6
12
|
|
|
@@ -10,7 +16,7 @@ npm install -g @oneshot-agent/mcp-server
|
|
|
10
16
|
|
|
11
17
|
## Configuration
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
Pick one of three auth methods: **CDP Wallet** (recommended, no private keys in config), a raw private key, or an **access token** (credits-only session with no key; see Remote below).
|
|
14
20
|
|
|
15
21
|
### Environment Variables
|
|
16
22
|
|
|
@@ -87,16 +93,16 @@ Add to `~/.claude/settings.json`:
|
|
|
87
93
|
}
|
|
88
94
|
```
|
|
89
95
|
|
|
90
|
-
Get CDP credentials at [Coinbase Agentic Wallet](https://docs.cdp.coinbase.com/agentic-wallet/welcome)
|
|
96
|
+
Get CDP credentials at [Coinbase Agentic Wallet](https://docs.cdp.coinbase.com/agentic-wallet/welcome), or use `ONESHOT_WALLET_PRIVATE_KEY` instead of the CDP env vars for raw key auth.
|
|
91
97
|
|
|
92
98
|
### Read authentication
|
|
93
99
|
|
|
94
|
-
Read tools (inbox, SMS inbox, notifications, balance, browser profiles) return private, per-agent data. The server wraps the OneShot TypeScript SDK, which
|
|
100
|
+
Read tools (inbox, SMS inbox, notifications, balance, browser profiles) return private, per-agent data. The server wraps the OneShot TypeScript SDK, which signs a short-lived **EIP-712 read proof** (`x-agent-proof`) on each read so the API can verify you control the `X-Agent-ID` wallet. This needs no configuration; it ships in `@oneshot-agent/sdk >= 0.25.0` (the bundled dependency). The server is rolling out read-proof verification in log-only mode, so older callers keep working until enforcement is enabled.
|
|
95
101
|
|
|
96
102
|
## Remote (hosted)
|
|
97
103
|
|
|
98
|
-
Clients that run in someone else's cloud
|
|
99
|
-
server and must not hold a wallet key. For them OneShot hosts the same
|
|
104
|
+
Clients that run in someone else's cloud (Grok Bot, hosted runners) cannot spawn this
|
|
105
|
+
server and must not hold a wallet key. For them, OneShot hosts the same 73 tools over
|
|
100
106
|
Streamable HTTP at **`https://win.oneshotagent.com/mcp`**, authenticated with an
|
|
101
107
|
**agent access token** and billed to the agent's credit balance:
|
|
102
108
|
|
|
@@ -136,6 +142,16 @@ instead of the wallet variables for a credits-only session on your own machine.
|
|
|
136
142
|
| `oneshot_sms_inbox_list` | List received SMS messages |
|
|
137
143
|
| `oneshot_sms_inbox_get` | Get a specific SMS message |
|
|
138
144
|
|
|
145
|
+
### Inbound voice
|
|
146
|
+
|
|
147
|
+
| Tool | Description |
|
|
148
|
+
|------|-------------|
|
|
149
|
+
| `oneshot_voice_number_provision` | Get the agent a phone number (existing one free; new one charges the registration fee from credits) |
|
|
150
|
+
| `oneshot_voice_numbers` | List the agent's phone numbers |
|
|
151
|
+
| `oneshot_voice_inbound_set` | Make a number answer its own calls (wallet session only) |
|
|
152
|
+
| `oneshot_voice_inbound_disable` | Stop answering calls to a number (wallet session only) |
|
|
153
|
+
| `oneshot_voice_inbound_calls` | List inbound calls, or one call with transcript |
|
|
154
|
+
|
|
139
155
|
### Research & Enrichment
|
|
140
156
|
|
|
141
157
|
| Tool | Description |
|
|
@@ -168,7 +184,7 @@ instead of the wallet variables for a credits-only session on your own machine.
|
|
|
168
184
|
|------|-------------|
|
|
169
185
|
| `oneshot_web_search` | Search the web |
|
|
170
186
|
| `oneshot_web_read` | Read any URL as markdown + screenshot |
|
|
171
|
-
| `oneshot_browser` | Autonomous browser
|
|
187
|
+
| `oneshot_browser` | Autonomous browser: navigate, click, extract |
|
|
172
188
|
|
|
173
189
|
### Commerce
|
|
174
190
|
|
|
@@ -188,12 +204,12 @@ instead of the wallet variables for a credits-only session on your own machine.
|
|
|
188
204
|
|
|
189
205
|
| Tool | Description |
|
|
190
206
|
|------|-------------|
|
|
191
|
-
| `oneshot_compute` | Create an autonomous goal
|
|
207
|
+
| `oneshot_compute` | Create an autonomous goal (objective + budget); the orchestrator plans and executes |
|
|
192
208
|
| `oneshot_compute_status` | Get a compute goal's status and budget |
|
|
193
209
|
| `oneshot_compute_tasks` | List tasks planned/executed under a goal |
|
|
194
210
|
| `oneshot_compute_cancel` | Cancel a goal and refund remaining budget |
|
|
195
211
|
| `oneshot_compute_respond` | Respond to a human-in-the-loop task |
|
|
196
|
-
| `oneshot_compute_pause` | Pause a recurring goal
|
|
212
|
+
| `oneshot_compute_pause` | Pause a recurring goal; plan and progress are kept |
|
|
197
213
|
| `oneshot_compute_resume` | Resume a paused recurring goal |
|
|
198
214
|
| `oneshot_compute_fund` | Top up a recurring goal's USDC budget |
|
|
199
215
|
|
|
@@ -223,7 +239,7 @@ instead of the wallet variables for a credits-only session on your own machine.
|
|
|
223
239
|
| `oneshot_get_balance` | Get USDC wallet balance |
|
|
224
240
|
| `oneshot_budget_status` | Today's spend vs the configured budget (read-only) |
|
|
225
241
|
|
|
226
|
-
|
|
242
|
+
Paid tools are priced in USDC via the x402 protocol. Current rates are on the [Pricing](https://docs.oneshotagent.com/pricing) page.
|
|
227
243
|
|
|
228
244
|
## Tool Examples
|
|
229
245
|
|
|
@@ -318,7 +334,16 @@ Use oneshot_inbox_list:
|
|
|
318
334
|
|
|
319
335
|
## Funding Your Agent
|
|
320
336
|
|
|
321
|
-
Send USDC to your agent's wallet address on Base. The server
|
|
337
|
+
Send USDC to your agent's wallet address on Base. The server runs on Base Mainnet (chain 8453).
|
|
338
|
+
|
|
339
|
+
## LinkedIn connection recovery
|
|
340
|
+
|
|
341
|
+
If the active account list is empty or an account is `deleted_upstream` or
|
|
342
|
+
`revoked`, ask the human to use `oneshot_linkedin_connect` and authorize fresh
|
|
343
|
+
grants. An existing account with `reconnect_required` must be reconnected through
|
|
344
|
+
the owning application. Reconnect and revoke are deliberately not agent tools.
|
|
345
|
+
Do not create a new connection automatically after authentication failures or
|
|
346
|
+
timeouts.
|
|
322
347
|
|
|
323
348
|
## Links
|
|
324
349
|
|
|
@@ -328,12 +353,3 @@ Send USDC to your agent's wallet address on Base. The server operates on Base Ma
|
|
|
328
353
|
- [Python SDK (LangChain)](https://pypi.org/project/langchain-oneshot/)
|
|
329
354
|
- [Python SDK (Core)](https://pypi.org/project/oneshot-python/)
|
|
330
355
|
- [GitHub](https://github.com/oneshot-agent/sdk)
|
|
331
|
-
|
|
332
|
-
### LinkedIn connection recovery
|
|
333
|
-
|
|
334
|
-
If the active account list is empty or an account is `deleted_upstream` or
|
|
335
|
-
`revoked`, ask the human to use `oneshot_linkedin_connect` and authorize fresh
|
|
336
|
-
grants. An existing account with `reconnect_required` needs reconnect through
|
|
337
|
-
the owning application. Reconnect and revoke are intentionally not agent tools.
|
|
338
|
-
Do not automatically create a new connection in response to authentication
|
|
339
|
-
failures or timeouts.
|
package/dist/index.js
CHANGED
|
@@ -52,7 +52,7 @@ async function main() {
|
|
|
52
52
|
// Create MCP server
|
|
53
53
|
const server = new Server({
|
|
54
54
|
name: "oneshot-mcp",
|
|
55
|
-
version: "0.
|
|
55
|
+
version: "0.28.0", // keep in sync with package.json; guarded by version.test.ts
|
|
56
56
|
}, {
|
|
57
57
|
capabilities: {
|
|
58
58
|
tools: {},
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import type { OneShot } from "@oneshot-agent/sdk";
|
|
3
|
+
export declare const approvalCreateTool: Tool;
|
|
4
|
+
export declare function handleApprovalCreate(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").Approval>;
|
|
5
|
+
export declare const approvalGetTool: Tool;
|
|
6
|
+
export declare function handleApprovalGet(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").Approval>;
|
|
7
|
+
export declare const approvalListTool: Tool;
|
|
8
|
+
export declare function handleApprovalList(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").Approval[]>;
|
|
9
|
+
export declare const approvalCancelTool: Tool;
|
|
10
|
+
export declare function handleApprovalCancel(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").Approval>;
|
|
11
|
+
export declare const actionPolicyGetTool: Tool;
|
|
12
|
+
export declare function handleActionPolicyGet(agent: OneShot, _args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").ActionPolicy | null>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// Approvals: ask a named human, read decisions, and read (never loosen) the
|
|
2
|
+
// action policy. Setting the policy is deliberately not exposed here — an
|
|
3
|
+
// agent that could edit its own policy would make the policy meaningless.
|
|
4
|
+
export const approvalCreateTool = {
|
|
5
|
+
name: "oneshot_approval_create",
|
|
6
|
+
description: "Ask a named human to approve or deny something before you do it. They get a one-tap link by email or SMS. " +
|
|
7
|
+
"Returns an approval with status 'pending'; poll oneshot_approval_get for the decision. Unanswered = denied at expiry. Free.",
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {
|
|
11
|
+
action_summary: { type: "string", description: "What the human is deciding, in one line (max 2000 chars)" },
|
|
12
|
+
approver_email: { type: "string", description: "Approver's email address" },
|
|
13
|
+
approver_phone: { type: "string", description: "Approver's phone number, E.164 (e.g. +14155551234)" },
|
|
14
|
+
preview: { type: "object", description: "Details shown to the approver (optional, up to 4000 characters as JSON)" },
|
|
15
|
+
expires_in_seconds: { type: "number", description: "Seconds until it expires unanswered (default 3600, max 604800)" },
|
|
16
|
+
},
|
|
17
|
+
required: ["action_summary"],
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
export async function handleApprovalCreate(agent, args) {
|
|
21
|
+
return agent.approvals.create({
|
|
22
|
+
action_summary: args.action_summary,
|
|
23
|
+
approver: {
|
|
24
|
+
...(args.approver_email ? { email: args.approver_email } : {}),
|
|
25
|
+
...(args.approver_phone ? { phone: args.approver_phone } : {}),
|
|
26
|
+
},
|
|
27
|
+
...(args.preview ? { preview: args.preview } : {}),
|
|
28
|
+
...(args.expires_in_seconds ? { expires_in_seconds: args.expires_in_seconds } : {}),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export const approvalGetTool = {
|
|
32
|
+
name: "oneshot_approval_get",
|
|
33
|
+
description: "Read one approval: status is pending, approved, denied, expired, cancelled, or consumed (an approved held call already ran). " +
|
|
34
|
+
"When a paid call failed with approval_required, poll this with its approval_id; once approved, retry the same call with approval_id. Free.",
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: { approval_id: { type: "string", description: "The approval id (appr_...)" } },
|
|
38
|
+
required: ["approval_id"],
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
export async function handleApprovalGet(agent, args) {
|
|
42
|
+
return agent.approvals.get(args.approval_id);
|
|
43
|
+
}
|
|
44
|
+
export const approvalListTool = {
|
|
45
|
+
name: "oneshot_approval_list",
|
|
46
|
+
description: "List this agent's approvals, newest first, optionally filtered by status. Free.",
|
|
47
|
+
inputSchema: {
|
|
48
|
+
type: "object",
|
|
49
|
+
properties: {
|
|
50
|
+
status: { type: "string", enum: ["pending", "approved", "denied", "expired", "cancelled", "consumed"] },
|
|
51
|
+
limit: { type: "number", description: "Max results (default 50, max 200)" },
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
export async function handleApprovalList(agent, args) {
|
|
56
|
+
return agent.approvals.list({
|
|
57
|
+
status: args.status,
|
|
58
|
+
limit: args.limit,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
export const approvalCancelTool = {
|
|
62
|
+
name: "oneshot_approval_cancel",
|
|
63
|
+
description: "Withdraw a pending approval you no longer need. Free.",
|
|
64
|
+
inputSchema: {
|
|
65
|
+
type: "object",
|
|
66
|
+
properties: { approval_id: { type: "string", description: "The approval id (appr_...)" } },
|
|
67
|
+
required: ["approval_id"],
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
export async function handleApprovalCancel(agent, args) {
|
|
71
|
+
return agent.approvals.cancel(args.approval_id);
|
|
72
|
+
}
|
|
73
|
+
export const actionPolicyGetTool = {
|
|
74
|
+
name: "oneshot_action_policy",
|
|
75
|
+
description: "Read-only: this agent's action policy — which email/SMS/voice/commerce calls run, are denied, or need a human approval " +
|
|
76
|
+
"(rules, approver channel, timeout). The policy is set by the operator from a wallet session and cannot be changed from here. Free.",
|
|
77
|
+
inputSchema: { type: "object", properties: {} },
|
|
78
|
+
};
|
|
79
|
+
export async function handleActionPolicyGet(agent, _args) {
|
|
80
|
+
return agent.policy.get();
|
|
81
|
+
}
|
package/dist/tools/commerce.js
CHANGED
|
@@ -50,6 +50,10 @@ export const commerceBuyTool = {
|
|
|
50
50
|
type: "string",
|
|
51
51
|
description: "Product variant ID (optional)",
|
|
52
52
|
},
|
|
53
|
+
approval_id: {
|
|
54
|
+
type: "string",
|
|
55
|
+
description: "Only when retrying a call the action policy held: the approval_id from the approval_required error, once a human approved it. The call then runs once.",
|
|
56
|
+
},
|
|
53
57
|
},
|
|
54
58
|
required: ["product_url", "shipping_address"],
|
|
55
59
|
},
|
|
@@ -77,6 +81,7 @@ export async function handleCommerceBuy(agent, args) {
|
|
|
77
81
|
phone: shippingAddress.phone,
|
|
78
82
|
},
|
|
79
83
|
quantity: args.quantity,
|
|
84
|
+
approvalId: args.approval_id,
|
|
80
85
|
variant_id: args.variant_id,
|
|
81
86
|
});
|
|
82
87
|
}
|
package/dist/tools/email.js
CHANGED
|
@@ -50,6 +50,10 @@ export const emailTool = {
|
|
|
50
50
|
},
|
|
51
51
|
description: "File attachments (optional)",
|
|
52
52
|
},
|
|
53
|
+
approval_id: {
|
|
54
|
+
type: "string",
|
|
55
|
+
description: "Only when retrying a call the action policy held: the approval_id from the approval_required error, once a human approved it. The call then runs once.",
|
|
56
|
+
},
|
|
53
57
|
},
|
|
54
58
|
required: ["body"],
|
|
55
59
|
},
|
|
@@ -65,5 +69,6 @@ export async function handleEmail(agent, args) {
|
|
|
65
69
|
from_name: args.from_name,
|
|
66
70
|
mailbox_mode: args.mailbox_mode,
|
|
67
71
|
attachments: args.attachments,
|
|
72
|
+
approvalId: args.approval_id,
|
|
68
73
|
});
|
|
69
74
|
}
|
package/dist/tools/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { emailTool, handleEmail } from "./email.js";
|
|
2
2
|
import { voiceTool, handleVoice } from "./voice.js";
|
|
3
|
+
import { voiceNumberProvisionTool, voiceNumbersTool, voiceInboundSetTool, voiceInboundDisableTool, voiceInboundCallsTool, handleVoiceNumberProvision, handleVoiceNumbers, handleVoiceInboundSet, handleVoiceInboundDisable, handleVoiceInboundCalls, } from "./voice-inbound.js";
|
|
3
4
|
import { smsTool, handleSms } from "./sms.js";
|
|
4
5
|
import { researchTool, handleResearch } from "./research.js";
|
|
5
6
|
import { peopleSearchTool, handlePeopleSearch } from "./people.js";
|
|
@@ -9,6 +10,7 @@ import { inboxListTool, inboxGetTool, handleInboxList, handleInboxGet } from "./
|
|
|
9
10
|
import { smsInboxListTool, smsInboxGetTool, handleSmsInboxList, handleSmsInboxGet } from "./sms-inbox.js";
|
|
10
11
|
import { notificationsTool, markReadTool, handleNotifications, handleMarkRead } from "./notifications.js";
|
|
11
12
|
import { getBalanceTool, budgetStatusTool, handleGetBalance, handleBudgetStatus } from "./wallet.js";
|
|
13
|
+
import { approvalCreateTool, approvalGetTool, approvalListTool, approvalCancelTool, actionPolicyGetTool, handleApprovalCreate, handleApprovalGet, handleApprovalList, handleApprovalCancel, handleActionPolicyGet, } from "./approvals.js";
|
|
12
14
|
import { buildTool, updateBuildTool, handleBuild, handleUpdateBuild } from "./build.js";
|
|
13
15
|
import { browserTool, browserCreateProfileTool, browserListProfilesTool, browserDeleteProfileTool, handleBrowser, handleBrowserCreateProfile, handleBrowserListProfiles, handleBrowserDeleteProfile } from "./browser.js";
|
|
14
16
|
import { webSearchTool, handleWebSearch } from "./search.js";
|
|
@@ -32,6 +34,12 @@ export const tools = [
|
|
|
32
34
|
inboxGetTool,
|
|
33
35
|
smsInboxListTool,
|
|
34
36
|
smsInboxGetTool,
|
|
37
|
+
// Inbound voice
|
|
38
|
+
voiceNumberProvisionTool,
|
|
39
|
+
voiceNumbersTool,
|
|
40
|
+
voiceInboundSetTool,
|
|
41
|
+
voiceInboundDisableTool,
|
|
42
|
+
voiceInboundCallsTool,
|
|
35
43
|
// Research & Enrichment
|
|
36
44
|
researchTool,
|
|
37
45
|
peopleSearchTool,
|
|
@@ -97,6 +105,12 @@ export const tools = [
|
|
|
97
105
|
markReadTool,
|
|
98
106
|
getBalanceTool,
|
|
99
107
|
budgetStatusTool,
|
|
108
|
+
// Approvals
|
|
109
|
+
approvalCreateTool,
|
|
110
|
+
approvalGetTool,
|
|
111
|
+
approvalListTool,
|
|
112
|
+
approvalCancelTool,
|
|
113
|
+
actionPolicyGetTool,
|
|
100
114
|
];
|
|
101
115
|
// Tool handlers map
|
|
102
116
|
const handlers = {
|
|
@@ -109,6 +123,12 @@ const handlers = {
|
|
|
109
123
|
"oneshot_inbox_get": handleInboxGet,
|
|
110
124
|
"oneshot_sms_inbox_list": handleSmsInboxList,
|
|
111
125
|
"oneshot_sms_inbox_get": handleSmsInboxGet,
|
|
126
|
+
// Inbound voice
|
|
127
|
+
"oneshot_voice_number_provision": handleVoiceNumberProvision,
|
|
128
|
+
"oneshot_voice_numbers": handleVoiceNumbers,
|
|
129
|
+
"oneshot_voice_inbound_set": handleVoiceInboundSet,
|
|
130
|
+
"oneshot_voice_inbound_disable": handleVoiceInboundDisable,
|
|
131
|
+
"oneshot_voice_inbound_calls": handleVoiceInboundCalls,
|
|
112
132
|
// Research & Enrichment
|
|
113
133
|
"oneshot_research": handleResearch,
|
|
114
134
|
"oneshot_people_search": handlePeopleSearch,
|
|
@@ -175,6 +195,12 @@ const handlers = {
|
|
|
175
195
|
"oneshot_mark_notification_read": handleMarkRead,
|
|
176
196
|
"oneshot_get_balance": handleGetBalance,
|
|
177
197
|
"oneshot_budget_status": handleBudgetStatus,
|
|
198
|
+
// Approvals
|
|
199
|
+
"oneshot_approval_create": handleApprovalCreate,
|
|
200
|
+
"oneshot_approval_get": handleApprovalGet,
|
|
201
|
+
"oneshot_approval_list": handleApprovalList,
|
|
202
|
+
"oneshot_approval_cancel": handleApprovalCancel,
|
|
203
|
+
"oneshot_action_policy": handleActionPolicyGet,
|
|
178
204
|
};
|
|
179
205
|
export async function handleToolCall(agent, toolName, args) {
|
|
180
206
|
const handler = handlers[toolName];
|
package/dist/tools/sms.js
CHANGED
|
@@ -12,6 +12,10 @@ export const smsTool = {
|
|
|
12
12
|
type: "string",
|
|
13
13
|
description: "SMS message content (max 1600 chars, 160 chars per segment)",
|
|
14
14
|
},
|
|
15
|
+
approval_id: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: "Only when retrying a call the action policy held: the approval_id from the approval_required error, once a human approved it. The call then runs once.",
|
|
18
|
+
},
|
|
15
19
|
},
|
|
16
20
|
required: ["to_number", "message"],
|
|
17
21
|
},
|
|
@@ -20,5 +24,6 @@ export async function handleSms(agent, args) {
|
|
|
20
24
|
return agent.sms({
|
|
21
25
|
to_number: args.to_number,
|
|
22
26
|
message: args.message,
|
|
27
|
+
approvalId: args.approval_id,
|
|
23
28
|
});
|
|
24
29
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import type { OneShot } from "@oneshot-agent/sdk";
|
|
3
|
+
export declare const voiceNumberProvisionTool: Tool;
|
|
4
|
+
export declare const voiceNumbersTool: Tool;
|
|
5
|
+
export declare const voiceInboundSetTool: Tool;
|
|
6
|
+
export declare const voiceInboundDisableTool: Tool;
|
|
7
|
+
export declare const voiceInboundCallsTool: Tool;
|
|
8
|
+
export declare function handleVoiceNumberProvision(agent: OneShot): Promise<import("@oneshot-agent/sdk").ProvisionedVoiceNumber>;
|
|
9
|
+
export declare function handleVoiceNumbers(agent: OneShot): Promise<{
|
|
10
|
+
numbers: import("@oneshot-agent/sdk").VoiceNumber[];
|
|
11
|
+
}>;
|
|
12
|
+
export declare function handleVoiceInboundSet(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").InboundVoiceConfigResult>;
|
|
13
|
+
export declare function handleVoiceInboundDisable(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").InboundVoiceConfigResult>;
|
|
14
|
+
export declare function handleVoiceInboundCalls(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").InboundCall | {
|
|
15
|
+
calls: import("@oneshot-agent/sdk").InboundCall[];
|
|
16
|
+
}>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export const voiceNumberProvisionTool = {
|
|
2
|
+
name: "oneshot_voice_number_provision",
|
|
3
|
+
description: "Get this agent a phone number without placing a call, so it can answer calls (then use oneshot_voice_inbound_set). " +
|
|
4
|
+
"Returns the existing number for free; otherwise buys one and charges the one-time phone registration fee from prepaid credits. " +
|
|
5
|
+
"Fails with 402 and buys nothing when credits are too low. Requires a wallet session (not available with an agent access token).",
|
|
6
|
+
inputSchema: { type: "object", properties: {} },
|
|
7
|
+
};
|
|
8
|
+
export const voiceNumbersTool = {
|
|
9
|
+
name: "oneshot_voice_numbers",
|
|
10
|
+
description: "List this agent's phone numbers and whether each answers inbound calls. Free. A number comes from oneshot_voice_number_provision or the agent's first outbound voice call.",
|
|
11
|
+
inputSchema: { type: "object", properties: {} },
|
|
12
|
+
};
|
|
13
|
+
export const voiceInboundSetTool = {
|
|
14
|
+
name: "oneshot_voice_inbound_set",
|
|
15
|
+
description: "Make one of the agent's numbers answer its own calls. Replaces the whole inbound config. " +
|
|
16
|
+
"During business hours the assistant follows `prompt`; after hours it takes a message, transfers, or declines. " +
|
|
17
|
+
"Calls are paid from prepaid credits per started minute and are declined when credits cannot cover the minimum fee. " +
|
|
18
|
+
"Requires a wallet session (not available with an agent access token).",
|
|
19
|
+
inputSchema: {
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {
|
|
22
|
+
phone_number_id: { type: "string", description: "Number id from oneshot_voice_numbers" },
|
|
23
|
+
prompt: { type: "string", description: "How the assistant answers this number (max 8000 chars)" },
|
|
24
|
+
first_message: { type: "string", description: "Greeting spoken when the call connects (optional)" },
|
|
25
|
+
voice_id: { type: "string", description: "Voice id (optional)" },
|
|
26
|
+
language: { type: "string", enum: ["en", "es", "fr", "de", "pt", "it", "nl", "multi"] },
|
|
27
|
+
allowed_tools: { type: "array", items: { type: "string", enum: ["transfer_call", "end_call"] }, description: "Default: [\"end_call\"]" },
|
|
28
|
+
transfer_number: { type: "string", description: "E.164. Required with transfer_call or after_hours=transfer" },
|
|
29
|
+
business_hours: {
|
|
30
|
+
type: "object",
|
|
31
|
+
description: "Omit for always open. { timezone: 'America/New_York', windows: [{ days: ['mon',...], start: '09:00', end: '17:00' }] }",
|
|
32
|
+
properties: {
|
|
33
|
+
timezone: { type: "string" },
|
|
34
|
+
windows: {
|
|
35
|
+
type: "array",
|
|
36
|
+
items: {
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: {
|
|
39
|
+
days: { type: "array", items: { type: "string", enum: ["mon", "tue", "wed", "thu", "fri", "sat", "sun"] } },
|
|
40
|
+
start: { type: "string" },
|
|
41
|
+
end: { type: "string" },
|
|
42
|
+
},
|
|
43
|
+
required: ["days", "start", "end"],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
required: ["timezone", "windows"],
|
|
48
|
+
},
|
|
49
|
+
after_hours: { type: "string", enum: ["take_message", "transfer", "decline"], description: "Default: take_message" },
|
|
50
|
+
after_hours_message: { type: "string", description: "What callers hear after hours (optional)" },
|
|
51
|
+
max_minutes: { type: "number", description: "1-60, default 10" },
|
|
52
|
+
webhook_url: { type: "string", description: "HTTPS URL for a signed voice.inbound.completed event after each call (optional)" },
|
|
53
|
+
},
|
|
54
|
+
required: ["phone_number_id", "prompt"],
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
export const voiceInboundDisableTool = {
|
|
58
|
+
name: "oneshot_voice_inbound_disable",
|
|
59
|
+
description: "Stop answering calls to one of the agent's numbers. The settings are kept, disabled. Free. Requires a wallet session.",
|
|
60
|
+
inputSchema: {
|
|
61
|
+
type: "object",
|
|
62
|
+
properties: { phone_number_id: { type: "string", description: "Number id from oneshot_voice_numbers" } },
|
|
63
|
+
required: ["phone_number_id"],
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
export const voiceInboundCallsTool = {
|
|
67
|
+
name: "oneshot_voice_inbound_calls",
|
|
68
|
+
description: "List inbound calls to the agent's numbers, newest first, with caller, summary and charge. Free. Pass call_id for one call with its transcript.",
|
|
69
|
+
inputSchema: {
|
|
70
|
+
type: "object",
|
|
71
|
+
properties: {
|
|
72
|
+
call_id: { type: "string", description: "Return this one call, with transcript" },
|
|
73
|
+
limit: { type: "number", description: "Max calls (default 50, max 100)" },
|
|
74
|
+
before: { type: "string", description: "ISO timestamp; calls created before it" },
|
|
75
|
+
phone_number_id: { type: "string", description: "Only calls to this number" },
|
|
76
|
+
include_transcript: { type: "boolean", description: "Include transcripts in the list" },
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
export async function handleVoiceNumberProvision(agent) {
|
|
81
|
+
return agent.provisionVoiceNumber();
|
|
82
|
+
}
|
|
83
|
+
export async function handleVoiceNumbers(agent) {
|
|
84
|
+
return agent.voiceNumbers();
|
|
85
|
+
}
|
|
86
|
+
export async function handleVoiceInboundSet(agent, args) {
|
|
87
|
+
const { phone_number_id, ...config } = args;
|
|
88
|
+
return agent.setInboundVoice(phone_number_id, config);
|
|
89
|
+
}
|
|
90
|
+
export async function handleVoiceInboundDisable(agent, args) {
|
|
91
|
+
return agent.disableInboundVoice(args.phone_number_id);
|
|
92
|
+
}
|
|
93
|
+
export async function handleVoiceInboundCalls(agent, args) {
|
|
94
|
+
if (typeof args.call_id === "string" && args.call_id)
|
|
95
|
+
return agent.inboundCall(args.call_id);
|
|
96
|
+
return agent.inboundCalls({
|
|
97
|
+
limit: args.limit,
|
|
98
|
+
before: args.before,
|
|
99
|
+
phone_number_id: args.phone_number_id,
|
|
100
|
+
include_transcript: args.include_transcript === true,
|
|
101
|
+
});
|
|
102
|
+
}
|
package/dist/tools/voice.js
CHANGED
|
@@ -24,6 +24,10 @@ export const voiceTool = {
|
|
|
24
24
|
type: "number",
|
|
25
25
|
description: "Maximum call duration in minutes (1-30, optional)",
|
|
26
26
|
},
|
|
27
|
+
approval_id: {
|
|
28
|
+
type: "string",
|
|
29
|
+
description: "Only when retrying a call the action policy held: the approval_id from the approval_required error, once a human approved it. The call then runs once.",
|
|
30
|
+
},
|
|
27
31
|
},
|
|
28
32
|
required: ["target_number", "objective"],
|
|
29
33
|
},
|
|
@@ -35,5 +39,6 @@ export async function handleVoice(agent, args) {
|
|
|
35
39
|
context: args.context,
|
|
36
40
|
caller_persona: args.caller_persona,
|
|
37
41
|
max_duration_minutes: args.max_duration_minutes,
|
|
42
|
+
approvalId: args.approval_id,
|
|
38
43
|
});
|
|
39
44
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneshot-agent/mcp-server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MCP server for OneShot -
|
|
3
|
+
"version": "0.28.0",
|
|
4
|
+
"description": "MCP server for OneShot - 73 tools for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@coinbase/cdp-sdk": "1.45.0",
|
|
27
27
|
"@modelcontextprotocol/sdk": "1.27.1",
|
|
28
|
-
"@oneshot-agent/sdk": "^0.
|
|
28
|
+
"@oneshot-agent/sdk": "^0.42.0",
|
|
29
29
|
"zod": "3.25.76"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|