@oneshot-agent/mcp-server 0.43.0 → 0.45.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 CHANGED
@@ -1,61 +1,40 @@
1
1
  # @oneshot-agent/mcp-server
2
2
 
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.
3
+ Your agent can think. This lets it act from Claude Desktop, Cursor or Claude
4
+ Code: send email, make calls, research, buy, build sites. It pays per call,
5
+ gets a signed receipt, and spends nothing you did not allow.
4
6
 
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)).
10
-
11
- ## Installation
7
+ ## Install
12
8
 
13
9
  ```bash
14
10
  npm install -g @oneshot-agent/mcp-server
15
11
  ```
16
12
 
17
- ## Configuration
18
-
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).
20
-
21
- ### Environment Variables
13
+ Or skip the install and let your client run `npx -y @oneshot-agent/mcp-server`.
22
14
 
23
- | Variable | Required | Description |
24
- |----------|----------|-------------|
25
- | `CDP_API_KEY_ID` | Option A | Coinbase CDP API key ID |
26
- | `CDP_API_KEY_SECRET` | Option A | Coinbase CDP API key secret |
27
- | `CDP_WALLET_SECRET` | Option A | Coinbase CDP wallet secret |
28
- | `ONESHOT_WALLET_PRIVATE_KEY` | Option B | Raw private key for signing payments |
29
- | `ONESHOT_ACCESS_TOKEN` | Option C | Agent access token (`oneshot_…`): credits-only session, cannot be combined with `ONESHOT_BUDGET_*` |
30
- | `ONESHOT_BUDGET_DAILY` | No | Max USDC the agent may spend per UTC day (spend budget, enforced server-side) |
31
- | `ONESHOT_BUDGET_PER_TRANSACTION` | No | Max USDC for any single call |
32
- | `ONESHOT_BUDGET_ALERT_AT` | No | Fraction of the daily budget that triggers a warning (default 0.8) |
33
- | `ONESHOT_BUDGET_PAUSE_AT` | No | Fraction at which paid calls stop (default 1.0) |
34
- | `ONESHOT_BUDGET_ALERT_EMAIL` | No | Email for budget alerts |
15
+ ## Start
35
16
 
36
- ### Claude Desktop
17
+ Pick one way to pay. Set its env vars in your client's config, below.
37
18
 
38
- Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
39
-
40
- ```json
41
- {
42
- "mcpServers": {
43
- "oneshot": {
44
- "command": "npx",
45
- "args": ["-y", "@oneshot-agent/mcp-server"],
46
- "env": {
47
- "CDP_API_KEY_ID": "your-api-key-id",
48
- "CDP_API_KEY_SECRET": "your-api-key-secret",
49
- "CDP_WALLET_SECRET": "your-wallet-secret"
50
- }
51
- }
52
- }
53
- }
54
- ```
19
+ | Variable | Use | What it is |
20
+ |----------|-----|------------|
21
+ | `CDP_API_KEY_ID` | A (recommended) | CDP API key ID. No private key in your config. |
22
+ | `CDP_API_KEY_SECRET` | A | CDP API key secret |
23
+ | `CDP_WALLET_SECRET` | A | CDP wallet secret |
24
+ | `ONESHOT_WALLET_PRIVATE_KEY` | B | Raw private key that signs payments |
25
+ | `ONESHOT_ACCESS_TOKEN` | C | Access token (`oneshot_…`). Credits only, no key. |
26
+ | `ONESHOT_BUDGET_DAILY` | optional | Max USDC per UTC day |
27
+ | `ONESHOT_BUDGET_PER_TRANSACTION` | optional | Max USDC for one call |
28
+ | `ONESHOT_BUDGET_ALERT_AT` | optional | Fraction of the daily budget that warns (default 0.8) |
29
+ | `ONESHOT_BUDGET_PAUSE_AT` | optional | Fraction at which paid calls stop (default 1.0) |
30
+ | `ONESHOT_BUDGET_ALERT_EMAIL` | optional | Where budget alerts go |
55
31
 
56
- ### Cursor
32
+ Set more than one and the token wins, then CDP, then the raw key.
33
+ Get CDP credentials [here](https://docs.cdp.coinbase.com/agentic-wallet/welcome).
57
34
 
58
- Add to `.cursor/mcp.json` in your project:
35
+ One block, three places:
36
+ Claude Desktop reads `~/Library/Application Support/Claude/claude_desktop_config.json`,
37
+ Cursor reads `.cursor/mcp.json` in your project, Claude Code reads user-scoped servers from `~/.claude.json`.
59
38
 
60
39
  ```json
61
40
  {
@@ -73,38 +52,9 @@ Add to `.cursor/mcp.json` in your project:
73
52
  }
74
53
  ```
75
54
 
76
- ### Claude Code
77
-
78
- Add to `~/.claude/settings.json`:
79
-
80
- ```json
81
- {
82
- "mcpServers": {
83
- "oneshot": {
84
- "command": "npx",
85
- "args": ["-y", "@oneshot-agent/mcp-server"],
86
- "env": {
87
- "CDP_API_KEY_ID": "your-api-key-id",
88
- "CDP_API_KEY_SECRET": "your-api-key-secret",
89
- "CDP_WALLET_SECRET": "your-wallet-secret"
90
- }
91
- }
92
- }
93
- }
94
- ```
95
-
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.
97
-
98
- ### Read authentication
99
-
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 API enforces this proof by default — a request with no proof (or a mismatched one) and no valid access token is rejected.
101
-
102
- ## Remote (hosted)
103
-
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 tool registry over
106
- Streamable HTTP at **`https://win.oneshotagent.com/mcp`**, authenticated with an
107
- **agent access token** and billed to the agent's credit balance:
55
+ **Hosted.** A client in someone else's cloud cannot run this server and must not
56
+ hold a wallet key. Point it at `https://win.oneshotagent.com/mcp` with an access
57
+ token. Same tools, billed to the agent's credits.
108
58
 
109
59
  ```json
110
60
  {
@@ -117,261 +67,70 @@ Streamable HTTP at **`https://win.oneshotagent.com/mcp`**, authenticated with an
117
67
  }
118
68
  ```
119
69
 
120
- Mint a token from a wallet session with `agent.createAccessToken()` (`@oneshot-agent/sdk`
121
- ≥ 0.33.0). Setup and billing details: https://docs.oneshotagent.com/sdk/remote-mcp
122
-
123
- The same token also works with this local server (≥ 0.20.0): set `ONESHOT_ACCESS_TOKEN`
124
- instead of the wallet variables for a credits-only session on your own machine.
125
-
126
- ## Available Tools
127
-
128
- ### Soul Hunt
129
-
130
- | Tool | Description |
131
- |------|-------------|
132
- | `oneshot_hunt_list` | List active or collected Soul Hunts. Free. |
133
- | `oneshot_hunt_status` | Detailed status, rounds and timeline for a specific hunt. Free. |
134
- | `oneshot_hunt_predict` | Submit a prediction for a hunt. Debits a stake from your balance. Paid, and requires a wallet session — Soul Hunt enforces a wallet-signed write proof that an access-token/OAuth session cannot produce. |
135
- | `oneshot_hunt_collection` | View the souls you have captured. Free. |
136
- | `oneshot_hunt_leaderboard` | Public predictor leaderboard. Free. |
137
-
138
- Soul Hunt is a separate service (`api.soulhunt.ai`) from the main OneShot API; the wallet session's `X-Agent-ID`/`x-agent-proof` carry over, but the OneShot bearer token never does.
139
-
140
- ### Communication
141
-
142
- | Tool | Description |
143
- |------|-------------|
144
- | `oneshot_email` | Send emails with attachments |
145
- | `oneshot_voice` | Make phone calls |
146
- | `oneshot_sms` | Send SMS messages |
147
-
148
- ### Inbox
149
-
150
- | Tool | Description |
151
- |------|-------------|
152
- | `oneshot_inbox_list` | List received emails |
153
- | `oneshot_inbox_get` | Get a specific email |
154
- | `oneshot_sms_inbox_list` | List received SMS messages |
155
- | `oneshot_sms_inbox_get` | Get a specific SMS message |
156
-
157
- ### Inbound voice
158
-
159
- | Tool | Description |
160
- |------|-------------|
161
- | `oneshot_voice_number_provision` | Get the agent a phone number (existing one free; new one charges the registration fee from credits) |
162
- | `oneshot_voice_numbers` | List the agent's phone numbers |
163
- | `oneshot_voice_inbound_set` | Make a number answer its own calls (wallet session only) |
164
- | `oneshot_voice_inbound_disable` | Stop answering calls to a number (wallet session only) |
165
- | `oneshot_voice_inbound_calls` | List inbound calls, or one call with transcript |
166
-
167
- ### Research & Enrichment
168
-
169
- | Tool | Description |
170
- |------|-------------|
171
- | `oneshot_research` | Deep web research with sources |
172
- | `oneshot_solve` | Plan vehicle routes with constraint checks and conflicts |
173
- | `oneshot_person_find` | Search for people by title, company, etc. |
174
- | `oneshot_person_profile` | Enrich person profile from LinkedIn URL, email, or name + company |
175
- | `oneshot_person_email` | Find someone's email address |
176
- | `oneshot_person_email_status` | Verify email deliverability |
177
- | `oneshot_company_find` | Search for companies by industry, size, location, etc. |
178
- | `oneshot_company_profile` | Enrich a company from domain, name, LinkedIn, or ticker |
179
- | `oneshot_business_find` | Discover local businesses (restaurants, contractors, practices) by category × location |
180
- | `oneshot_business_resolve` | Business name + address → website domain, phone, status, confidence |
181
- | `oneshot_record_solicitations_find` | Federal Sources Sought / Presolicitation notices by NAICS with the contracting officer's contact |
182
-
183
- ### Person Intelligence
184
-
185
- | Tool | Description |
186
- |------|-------------|
187
- | `oneshot_person_dossier` | A person’s profile, known social accounts, articles, posts and written summary |
188
- | `oneshot_person_social_accounts` | Find all social accounts for a person |
189
- | `oneshot_person_articles` | Find articles about a person |
190
- | `oneshot_person_posts` | Recent social posts with engagement |
191
- | `oneshot_person_interests` | Analyze interests across categories |
192
- | `oneshot_person_followers` | Map followers, following, replies |
193
-
194
- ### Web
195
-
196
- | Tool | Description |
197
- |------|-------------|
198
- | `oneshot_web_search` | Search the web |
199
- | `oneshot_web_read` | Read any URL as markdown + screenshot |
200
- | `oneshot_browser` | Autonomous browser: navigate, click, extract |
201
-
202
- ### Commerce
203
-
204
- | Tool | Description |
205
- |------|-------------|
206
- | `oneshot_product_find` | Search for products |
207
- | `oneshot_commerce_buy` | Purchase products |
208
-
209
- ### Physical Mail
210
-
211
- Quote-to-pay with an explicit approval in between. Prices are on the [Pricing](https://docs.oneshotagent.com/pricing) page; the quote carries the price of each piece.
212
-
213
- | Tool | Description |
214
- |------|-------------|
215
- | `oneshot_physical_mail_upload` | Upload print-ready artwork (PDF, PNG or JPEG as base64, 20 MB max) and get its asset id |
216
- | `oneshot_physical_mail_validate_address` | Check that a U.S. address is deliverable |
217
- | `oneshot_physical_mail_preview` | Quote a letter or postcard and render an uncharged proof |
218
- | `oneshot_physical_mail_quote` | Read a quote |
219
- | `oneshot_physical_mail_approve` | Approve the exact piece and price of a quote |
220
- | `oneshot_physical_mail_send` | Print and post an approved piece (quote id, approval id and an idempotency key you keep) |
221
- | `oneshot_physical_mail_recover` | Find the order a send created, by its idempotency key |
222
- | `oneshot_physical_mail_order` | Read an order and its status |
223
- | `oneshot_physical_mail_cancel` | Ask to cancel an order (not guaranteed once submitted) |
224
-
225
- ### Build
226
-
227
- | Tool | Description |
228
- |------|-------------|
229
- | `oneshot_build` | Build and deploy production websites |
230
- | `oneshot_update_build` | Update an existing website |
231
-
232
- ### Compute Orchestration
233
-
234
- | Tool | Description |
235
- |------|-------------|
236
- | `oneshot_compute` | Create an autonomous goal (objective + budget); OneShot plans and runs the steps |
237
- | `oneshot_compute_status` | Get a compute goal's status and budget |
238
- | `oneshot_compute_tasks` | List tasks planned/executed under a goal |
239
- | `oneshot_compute_cancel` | Cancel a goal and refund remaining budget |
240
- | `oneshot_compute_respond` | Respond to a human-in-the-loop task |
241
- | `oneshot_compute_pause` | Pause a recurring goal; plan and progress are kept |
242
- | `oneshot_compute_resume` | Resume a paused recurring goal |
243
- | `oneshot_compute_fund` | Top up a recurring goal's USDC budget |
244
-
245
- ### Domains
246
-
247
- | Tool | Description |
248
- |------|-------------|
249
- | `oneshot_list_domains` | List sending domains with warmup/limits |
250
- | `oneshot_pause_domain` | Pause a sending domain |
251
- | `oneshot_resume_domain` | Resume a paused sending domain |
252
-
253
- ### Analytics
254
-
255
- | Tool | Description |
256
- |------|-------------|
257
- | `oneshot_spend_breakdown` | Spend by tool/category over a period |
258
- | `oneshot_return_on_spend` | Return on spend: cost vs. value produced |
259
- | `oneshot_receipts_list` | List spend receipts |
260
- | `oneshot_tag_receipt_value` | Tag a receipt with the value it generated |
261
-
262
- ### Account
263
-
264
- | Tool | Description |
265
- |------|-------------|
266
- | `oneshot_notifications` | List agent notifications |
267
- | `oneshot_mark_notification_read` | Mark notification as read |
268
- | `oneshot_get_balance` | Get USDC wallet balance |
269
- | `oneshot_budget_status` | Today's spend vs the configured budget (read-only) |
270
-
271
- Paid tools are priced in USDC via the x402 protocol. Current rates are on the [Pricing](https://docs.oneshotagent.com/pricing) page.
272
-
273
- ## Tool Examples
274
-
275
- ### Send an Email
276
-
277
- ```
278
- Use oneshot_email:
279
- - to: "user@example.com"
280
- - subject: "Hello from AI"
281
- - body: "<h1>Hello!</h1><p>This email was sent by an AI agent.</p>"
282
- - from_name: "Jane Doe" (optional display name → "Jane Doe <jane@domain>")
283
- - from_mailbox: "jane" (optional local-part, defaults to "agent"; requires from_domain)
284
- - from_domain: "acme.com" (optional, must be a domain you own; omit both from_domain and
285
- from_mailbox to rotate across your warmed domains)
286
- - mailbox_mode: "mailbox" (optional, 'relay' (default) | 'mailbox' — dedicated per-address
287
- mailbox; only when first provisioning a new from_domain)
288
- ```
289
-
290
- ### Make a Phone Call
291
-
292
- ```
293
- Use oneshot_voice:
294
- - target_number: "+14155551234"
295
- - objective: "Call the restaurant and make a reservation for 2 people at 7pm tonight"
296
- - caller_persona: "A polite assistant calling on behalf of John"
297
- ```
298
-
299
- ### Send an SMS
300
-
301
- ```
302
- Use oneshot_sms:
303
- - to_number: "+14155551234"
304
- - message: "Your order has shipped! Track it at: https://example.com/track/123"
305
- ```
306
-
307
- ### Research a Topic
308
-
309
- ```
310
- Use oneshot_research:
311
- - topic: "What are the latest developments in quantum computing?"
312
- - depth: "deep"
313
- ```
314
-
315
- ### Search for People
316
-
317
- ```
318
- Use oneshot_person_find:
319
- - job_titles: ["CTO", "VP Engineering"]
320
- - companies: ["Stripe", "Square"]
321
- - location: ["San Francisco"]
322
- - limit: 10
323
- ```
324
-
325
- ### Find Someone's Email
326
-
327
- ```
328
- Use oneshot_person_email:
329
- - name: "John Smith"
330
- - company: "Example" (a name or a domain)
331
- ```
332
-
333
- ### Check Wallet Balance
334
-
335
- ```
336
- Use oneshot_get_balance (no parameters needed)
337
- ```
338
-
339
- ### Build a Website
340
-
341
- ```
342
- Use oneshot_build:
343
- - type: "saas"
344
- - product:
345
- name: "Acme Analytics"
346
- description: "Real-time analytics dashboard for modern teams. Track metrics, visualize data, and make better decisions."
347
- industry: "Software"
348
- - lead_capture:
349
- enabled: true
350
- - brand:
351
- primary_color: "#4F46E5"
352
- tone: "professional"
353
- ```
354
-
355
- ### Read Inbox
356
-
357
- ```
358
- Use oneshot_inbox_list:
359
- - limit: 10
360
- - include_body: true
361
- ```
362
-
363
- ## Funding Your Agent
364
-
365
- Send USDC to your agent's wallet address on Base. The server runs on Base Mainnet (chain 8453).
366
-
367
- ## LinkedIn connection recovery
368
-
369
- If the active account list is empty or an account is `connection_deleted` or
370
- `revoked`, ask the human to use `oneshot_linkedin_connect` and authorize fresh
371
- grants. An existing account with `reconnect_required` must be reconnected through
372
- the owning application. Reconnect and revoke are deliberately not agent tools.
373
- Do not create a new connection automatically after authentication failures or
374
- timeouts.
70
+ Mint the token from a wallet session with `agent.createAccessToken()` in
71
+ `@oneshot-agent/sdk`. [Setup and billing](https://docs.oneshotagent.com/sdk/remote-mcp).
72
+
73
+ ## What it does
74
+
75
+ Every tool is named `oneshot_<name>`. Below are the names.
76
+
77
+ | Area | Tools |
78
+ |------|-------|
79
+ | [Talk](https://docs.oneshotagent.com/api-reference/email/send) | `email` `voice` `sms` `inbox_list` `inbox_get` `sms_inbox_list` `sms_inbox_get` `notifications` `mark_notification_read` |
80
+ | [Inbound calls](https://docs.oneshotagent.com/api-reference/voice/inbound) | `voice_number_provision` `voice_numbers` `voice_inbound_set` `voice_inbound_disable` `voice_inbound_calls` |
81
+ | [Send from your domains](https://docs.oneshotagent.com/api-reference/email/domains) | `list_domains` `pause_domain` `resume_domain` |
82
+ | [Find people and companies](https://docs.oneshotagent.com/api-reference/research/person-find) | `person_find` `person_profile` `person_email` `person_email_status` `person_dossier` `person_social_accounts` `person_articles` `person_posts` `person_interests` `person_followers` `company_find` `company_profile` `business_find` `business_resolve` `record_solicitations_find` |
83
+ | [Lookups](https://docs.oneshotagent.com/tools-and-goals#lookups) | public records, places, products, vehicles, genes, proteins and more, one tool each |
84
+ | [Think](https://docs.oneshotagent.com/api-reference/research) | `research` `predict` `solve` |
85
+ | [Web and buying](https://docs.oneshotagent.com/api-reference/web-search) | `web_search` `web_read` `browser` `product_find` `commerce_buy` |
86
+ | [Physical mail](https://docs.oneshotagent.com/api-reference/physical-mail/overview) | `physical_mail_upload` `physical_mail_validate_address` `physical_mail_preview` `physical_mail_quote` `physical_mail_approve` `physical_mail_send` `physical_mail_recover` `physical_mail_order` `physical_mail_cancel` |
87
+ | [Connected systems](https://docs.oneshotagent.com/api-reference/connections/overview) | `connections_list` `ledger_invoices` `ledger_bills` `ledger_reports` `crm_accounts` `crm_contacts` `crm_opportunities` `tax_rates` `tax_calculate` `shipping_shipments` `shipping_tracking` `shipping_rates` `procurement_transactions` `procurement_bills` `procurement_suppliers` |
88
+ | [LinkedIn](https://docs.oneshotagent.com/api-reference/linkedin/overview) | `linkedin_connect` `linkedin_accounts` `linkedin_invite` `linkedin_message` `linkedin_reply` and more |
89
+ | [Build](https://docs.oneshotagent.com/api-reference/build/create) | `build` `update_build` |
90
+ | [Goals](https://docs.oneshotagent.com/api-reference/compute/create) | `compute` `compute_status` `compute_tasks` `compute_respond` `compute_pause` `compute_resume` `compute_fund` `compute_cancel` |
91
+ | [Money and receipts](https://docs.oneshotagent.com/api-reference/analytics/overview) | `get_balance` `budget_status` `spend_breakdown` `return_on_spend` `receipts_list` `tag_receipt_value` |
92
+ | Soul Hunt | `hunt_list` `hunt_status` `hunt_predict` `hunt_collection` `hunt_leaderboard` |
93
+
94
+ ## Money
95
+
96
+ - It pays in USDC on Base mainnet (chain 8453). Send USDC to the agent's wallet first.
97
+ - A paid call costs what the quote says, or it does not run. [Prices](https://docs.oneshotagent.com/pricing).
98
+ - Budgets live on the server. You set them in env vars; the model cannot.
99
+ `budget_status` only reads them.
100
+ - A budget value that does not parse stops the server at startup. It never runs unguarded.
101
+ - An access token spends prepaid credits only. It never signs a payment, and it
102
+ cannot be combined with `ONESHOT_BUDGET_*`: the server refuses to start.
103
+
104
+ ## Trust
105
+
106
+ Every paid call returns a signed receipt. Reads of private data (inbox, SMS inbox,
107
+ notifications, balance, browser profiles) carry a signed proof that you hold the
108
+ wallet. The server signs it for you. A read with no proof and no valid token is refused.
109
+
110
+ ## Tool notes
111
+
112
+ - **Email.** Omit `from_domain` and `from_mailbox` and the send rotates across
113
+ your warmed domains. `from_mailbox` needs `from_domain`. A new `from_domain`
114
+ only quotes; nothing is charged until you confirm. `mailbox_mode` applies only
115
+ when a domain is first set up. [Details](https://docs.oneshotagent.com/api-reference/email/send).
116
+ - **Phone lookup** is off by default on `person_find`, `person_profile` and
117
+ `person_dossier`. `include_phone: true` is charged for each person you ask for
118
+ (the search limit, default 100), or once for a profile or dossier, found or not.
119
+ A failed job is refunded. Numbers the source already has come back without it.
120
+ [Price](https://docs.oneshotagent.com/pricing).
121
+ - **Physical mail.** Preview, look at the proof and the price, then approve the
122
+ quote yourself. Keep the idempotency key you pass to `physical_mail_send`;
123
+ `physical_mail_recover` finds the order by it. Cancel is not guaranteed once submitted.
124
+ - **LinkedIn.** No active account, or one that is `connection_deleted` or `revoked`:
125
+ ask the human to run `linkedin_connect` and grant again. `reconnect_required`
126
+ is fixed by the owning application. Reconnect and revoke are not agent tools.
127
+ Never open a new connection on your own after an auth failure or a timeout.
128
+ - **Predict.** Pass `model: "simulation"` with a `simulation` block, or
129
+ `model: "forecast"` with a `forecast` block. You get ranges and consistency
130
+ checks back. [Inputs and limits](https://docs.oneshotagent.com/api-reference/predict).
131
+ - **Wallet session only.** `voice_inbound_set`, `voice_inbound_disable` and
132
+ `hunt_predict`, which stakes from your balance. Soul Hunt is a separate
133
+ service: your wallet proof carries over, your access token never does.
375
134
 
376
135
  ## Links
377
136
 
@@ -382,12 +141,16 @@ timeouts.
382
141
  - [Python SDK (Core)](https://pypi.org/project/oneshot-python/)
383
142
  - [GitHub](https://github.com/oneshot-agent/sdk)
384
143
 
385
- ## Optional phone lookup
386
-
387
- `person_find`, `person_profile`, and `person_dossier` accept `include_phone`, off by default. It adds the per-person add-on listed on the pricing page × the requested search limit (default 100) for a search, or once for profile/dossier, for up to that many people with no promised hit. Existing source numbers and published business or record numbers remain available without opting in. Fallbacks and callbacks cost nothing extra; a completed no-match is charged and a failed job is refunded. Use a boolean `true` / `false`. The full quote is checked before payment.
144
+ ## Tool discovery
388
145
 
389
- ## Predict
146
+ The MCP catalog contains 172 tools. `oneshot_discover_tools` is a free, read-only
147
+ search over the tools your token can call. Call it with no arguments for category
148
+ counts, `{ "query": "send a printed letter" }` to search, or `{ "category": "email" }`
149
+ to browse. Results contain public tool names, purposes and required inputs.
150
+ Category pages contain up to five tools; pass `nextCursor` as `cursor` with the
151
+ same query and category. `nextCursor: null` marks the end. Both stdio and hosted
152
+ `/mcp` expose it as an ordinary tool.
390
153
 
391
- Use `oneshot_predict` with the matching model block. Supports `model: "simulation"` with a `simulation` block of named distributions and arithmetic outputs, or `model: "forecast"` with a `forecast` block containing a time series and horizon. Returns uncertainty ranges and consistency checks.
154
+ ## License
392
155
 
393
- See [Predict](https://docs.oneshotagent.com/api-reference/predict) for inputs, results and limits.
156
+ MIT
package/dist/index.js CHANGED
@@ -50,7 +50,7 @@ async function main() {
50
50
  const agent = await initAgent();
51
51
  const server = new Server({
52
52
  name: "oneshot-mcp",
53
- version: "0.43.0", // keep in sync with package.json; guarded by version.test.ts
53
+ version: "0.45.0", // keep in sync with package.json; guarded by version.test.ts
54
54
  }, {
55
55
  capabilities: {
56
56
  tools: {},
@@ -3,10 +3,13 @@ import { LOOKUP_MANIFEST, ROUTE_MANIFEST } from "./lookup-manifest.generated.js"
3
3
  const read = (title, openWorld) => ({ title, readOnlyHint: true, destructiveHint: false, openWorldHint: openWorld });
4
4
  /** Changes something. `destructive` only for delete / overwrite / revoke. */
5
5
  const write = (title, openWorld, destructive = false) => ({ title, readOnlyHint: false, destructiveHint: destructive, openWorldHint: openWorld });
6
+ /** The connected-system reads (#2403): paid, but each reads the caller's own connected business system, so closed-world. */
7
+ const CONNECTED_SYSTEM_READ = /^\/v1\/tools\/(ledger|crm|shipping|tax|procurement)\//;
6
8
  const OPEN = true;
7
9
  const OWN = false;
8
10
  const DESTRUCTIVE = true;
9
11
  export const TOOL_ANNOTATIONS = {
12
+ oneshot_discover_tools: read("Discover tools", OWN),
10
13
  oneshot_solve: read("Solve", OWN),
11
14
  oneshot_predict: read("Predict", OWN),
12
15
  oneshot_hunt_list: read("List Soul Hunts", OPEN),
@@ -94,12 +97,15 @@ export const TOOL_ANNOTATIONS = {
94
97
  oneshot_approval_list: read("List approvals", OWN),
95
98
  oneshot_approval_cancel: write("Cancel an approval", OWN, DESTRUCTIVE),
96
99
  oneshot_action_policy: read("Show approval rules", OWN),
100
+ // Connected systems (#2403): the list is hand-written; the reads come from the route manifest below.
101
+ oneshot_connections_list: read("List connections", OWN),
97
102
  // The lookup tools come from the generated manifest: paid retrieval over public or third-party data (#1445).
98
103
  ...Object.fromEntries(LOOKUP_MANIFEST.map((entry) => [`oneshot_${entry.name}`, read(entry.title, OPEN)])),
99
104
  // The declared routes come from the same manifest (#1580). A read of the agent's own data is closed-world; a paid
100
- // read (Changes, Benchmark) reaches recorded third-party data; a write changes something, and a DELETE removes it.
105
+ // read (Changes, Benchmark) reaches recorded third-party data, a connected-system read the caller's own system; a
106
+ // write changes something, and a DELETE removes it.
101
107
  ...Object.fromEntries(ROUTE_MANIFEST.map((entry) => {
102
- const own = !entry.paid;
108
+ const own = !entry.paid || CONNECTED_SYSTEM_READ.test(entry.path);
103
109
  return [
104
110
  `oneshot_${entry.name}`,
105
111
  entry.readOnly ? read(entry.title, own ? OWN : OPEN) : write(entry.title, own ? OWN : OPEN, entry.method === "DELETE"),
@@ -0,0 +1,11 @@
1
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
+ import type { OneShot } from "@oneshot-agent/sdk";
3
+ /**
4
+ * The agent's connections (#2403). Hand-written because `GET /v1/connections` is not a declared route: the
5
+ * connected-system read tools (`oneshot_ledger_*`, `oneshot_crm_*`, `oneshot_shipping_*`, `oneshot_tax_*`,
6
+ * `oneshot_procurement_*`) are generated from their routes and each tells the model to call this one first.
7
+ * Connecting and revoking stay in the console.
8
+ */
9
+ export declare const connectionsListTool: Tool;
10
+ /** The route's answer as it is: `{ connections: [...] }`. Through `route()`, which the published SDK range already has. */
11
+ export declare function handleConnectionsList(agent: OneShot, _args: Record<string, unknown>): Promise<unknown>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The agent's connections (#2403). Hand-written because `GET /v1/connections` is not a declared route: the
3
+ * connected-system read tools (`oneshot_ledger_*`, `oneshot_crm_*`, `oneshot_shipping_*`, `oneshot_tax_*`,
4
+ * `oneshot_procurement_*`) are generated from their routes and each tells the model to call this one first.
5
+ * Connecting and revoking stay in the console.
6
+ */
7
+ export const connectionsListTool = {
8
+ name: "oneshot_connections_list",
9
+ description: "List the agent's connections to business systems (accounting, CRM, shipping, tax, spend) and GitHub. " +
10
+ "Returns each connection's id, name, kind, system, account_label and status (only an active one can be read). " +
11
+ "Call it before any connected-system read: pick the connection by system and account_label and pass its id as connection_id. " +
12
+ "Connections are added and revoked in the console. Free.",
13
+ inputSchema: {
14
+ type: "object",
15
+ properties: {},
16
+ },
17
+ };
18
+ /** The route's answer as it is: `{ connections: [...] }`. Through `route()`, which the published SDK range already has. */
19
+ export async function handleConnectionsList(agent, _args) {
20
+ return agent.route("GET", "/v1/connections");
21
+ }
@@ -0,0 +1,4 @@
1
+ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
2
+ import type { OneShot } from '@oneshot-agent/sdk';
3
+ export declare const discoverToolsTool: Tool;
4
+ export declare function handleDiscoverTools(agent: OneShot, args: Record<string, unknown>): Promise<unknown>;
@@ -0,0 +1,20 @@
1
+ export const discoverToolsTool = {
2
+ name: 'oneshot_discover_tools',
3
+ description: 'Find OneShot tools by task or category. Free. Returns public names, purposes and required inputs. With no query or category, lists categories. Category pages contain up to five tools; pass nextCursor with the same query and category.',
4
+ inputSchema: {
5
+ type: 'object',
6
+ properties: {
7
+ query: { type: 'string', description: 'Task or tool name to search for.' },
8
+ category: { type: 'string', description: 'Category ID from the directory.' },
9
+ cursor: { type: 'string', description: 'Opaque nextCursor from a category page.' },
10
+ },
11
+ additionalProperties: false,
12
+ },
13
+ };
14
+ export async function handleDiscoverTools(agent, args) {
15
+ if (Object.entries(args).some(([key, value]) => !['query', 'category', 'cursor'].includes(key) || typeof value !== 'string')) {
16
+ throw new Error('Expected optional query, category and cursor strings.');
17
+ }
18
+ // route() is available in the published SDK too; discoverTools() wraps this same free request.
19
+ return agent.route('GET', '/v1/tools/discover', { query: args, paid: false });
20
+ }
@@ -1,13 +1,13 @@
1
1
  export const emailTool = {
2
2
  name: "oneshot_email",
3
- description: "Send an email. Supports HTML body, attachments, and threaded replies (set reply_to_email_id to an inbound email id from oneshot_inbox_list/oneshot_inbox_get). Paid tool — quote provided before payment.\n\n" +
3
+ description: "Send an email. Supports HTML body, attachments, and threaded replies (set reply_to_email_id to an inbound email id from oneshot_inbox_list/oneshot_inbox_get, or one this agent sent). Paid tool — quote provided before payment.\n\n" +
4
4
  "Sending requires a domain the agent owns. A fresh account has none — call oneshot_list_domains first to see what's already owned. If there is no usable domain, pass from_domain with a new domain to register it. A call with a new from_domain only quotes — nothing is charged — and returns status 'confirmation_required' with the exact cost (domain registration plus fees) and a quote_id. Tell the user that exact computed number, never a guessed or approximate one, and only once they say to proceed, call this again with the same arguments and confirm_new_domain set to that quote_id: that registers the domain, charges exactly the quoted total, and sends the email in one call. The workspace balance must cover it, or the call fails with insufficient_credits.",
5
5
  inputSchema: {
6
6
  type: "object",
7
7
  properties: {
8
8
  to: {
9
9
  type: "string",
10
- description: "Recipient email address (or comma-separated list). Optional when reply_to_email_id is set — defaults to the inbound sender.",
10
+ description: "Recipient email address (or comma-separated list). Optional when reply_to_email_id is set — defaults to the other party.",
11
11
  },
12
12
  subject: {
13
13
  type: "string",
@@ -15,7 +15,7 @@ export const emailTool = {
15
15
  },
16
16
  reply_to_email_id: {
17
17
  type: "string",
18
- description: "Reply within a thread: id of an inbound email (from oneshot_inbox_list/oneshot_inbox_get). Sets In-Reply-To/References headers so mail clients group the conversation.",
18
+ description: "Reply within a thread: id of an inbound email (from oneshot_inbox_list/oneshot_inbox_get), or one this agent sent. Sets In-Reply-To/References headers so mail clients group the conversation.",
19
19
  },
20
20
  body: {
21
21
  type: "string",