@oneshot-agent/mcp-server 0.39.1 → 0.41.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
@@ -102,7 +102,7 @@ Read tools (inbox, SMS inbox, notifications, balance, browser profiles) return p
102
102
  ## Remote (hosted)
103
103
 
104
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 117 tools over
105
+ server and must not hold a wallet key. For them, OneShot hosts the same tool registry over
106
106
  Streamable HTTP at **`https://win.oneshotagent.com/mcp`**, authenticated with an
107
107
  **agent access token** and billed to the agent's credit balance:
108
108
 
@@ -169,8 +169,9 @@ Soul Hunt is a separate service (`api.soulhunt.ai`) from the main OneShot API; t
169
169
  | Tool | Description |
170
170
  |------|-------------|
171
171
  | `oneshot_research` | Deep web research with sources |
172
+ | `oneshot_solve` | Plan vehicle routes with constraint checks and conflicts |
172
173
  | `oneshot_person_find` | Search for people by title, company, etc. |
173
- | `oneshot_person_profile` | Enrich person profile from LinkedIn/email |
174
+ | `oneshot_person_profile` | Enrich person profile from LinkedIn URL, email, or name + company |
174
175
  | `oneshot_person_email` | Find someone's email address |
175
176
  | `oneshot_person_email_status` | Verify email deliverability |
176
177
  | `oneshot_company_find` | Search for companies by industry, size, location, etc. |
@@ -205,6 +206,22 @@ Soul Hunt is a separate service (`api.soulhunt.ai`) from the main OneShot API; t
205
206
  | `oneshot_product_find` | Search for products |
206
207
  | `oneshot_commerce_buy` | Purchase products |
207
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
+
208
225
  ### Build
209
226
 
210
227
  | Tool | Description |
@@ -309,9 +326,8 @@ Use oneshot_person_find:
309
326
 
310
327
  ```
311
328
  Use oneshot_person_email:
312
- - first_name: "John"
313
- - last_name: "Smith"
314
- - company_domain: "example.com"
329
+ - name: "John Smith"
330
+ - company: "Example" (a name or a domain)
315
331
  ```
316
332
 
317
333
  ### Check Wallet Balance
@@ -369,3 +385,9 @@ timeouts.
369
385
  ## Optional phone lookup
370
386
 
371
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.
388
+
389
+ ## Predict
390
+
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.
392
+
393
+ See [Predict](https://docs.oneshotagent.com/api-reference/predict) for inputs, results and limits.
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.39.1", // keep in sync with package.json; guarded by version.test.ts
53
+ version: "0.41.0", // keep in sync with package.json; guarded by version.test.ts
54
54
  }, {
55
55
  capabilities: {
56
56
  tools: {},
@@ -7,6 +7,8 @@ const OPEN = true;
7
7
  const OWN = false;
8
8
  const DESTRUCTIVE = true;
9
9
  export const TOOL_ANNOTATIONS = {
10
+ oneshot_solve: read("Solve", OWN),
11
+ oneshot_predict: read("Predict", OWN),
10
12
  oneshot_hunt_list: read("List Soul Hunts", OPEN),
11
13
  oneshot_hunt_status: read("Get Soul Hunt Status", OPEN),
12
14
  oneshot_hunt_predict: write("Predict Soul Hunt", OPEN),
@@ -24,6 +26,10 @@ export const TOOL_ANNOTATIONS = {
24
26
  oneshot_voice_inbound_set: write("Set up call answering", OPEN, DESTRUCTIVE), // replaces the number's answering settings; outside callers reach it via the carrier
25
27
  oneshot_voice_inbound_disable: write("Stop answering calls", OPEN),
26
28
  oneshot_voice_inbound_calls: read("List answered calls", OWN),
29
+ // Physical Mail (#1883): the upload stores artwork in the agent's own account; the send puts a letter in the post.
30
+ // The generated route tools (validate, preview, quote, approve, recover, order, cancel) get their hints from the manifest below.
31
+ oneshot_physical_mail_upload: write("Upload mail artwork", OWN),
32
+ oneshot_physical_mail_send: write("Send approved physical mail", OPEN),
27
33
  oneshot_research: read("Deep research", OPEN),
28
34
  oneshot_person_find: read("Find people", OPEN),
29
35
  oneshot_person_profile: read("Look up a person's profile", OPEN),
@@ -1,5 +1,38 @@
1
1
  import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
- import type { OneShot } from "@oneshot-agent/sdk";
2
+ import type { OneShot, PersonIdentity } from "@oneshot-agent/sdk";
3
+ export declare const PERSON_IDENTITY_PROPERTIES: {
4
+ readonly name: {
5
+ readonly type: "string";
6
+ readonly description: "Person's full name (works best with company)";
7
+ };
8
+ readonly company: {
9
+ readonly type: "string";
10
+ readonly description: "Employer name or domain, e.g. Coinbase or coinbase.com";
11
+ };
12
+ readonly email: {
13
+ readonly type: "string";
14
+ readonly description: "Person's email address";
15
+ };
16
+ readonly phone: {
17
+ readonly type: "string";
18
+ readonly description: "Person's phone number";
19
+ };
20
+ readonly profile_url: {
21
+ readonly type: "string";
22
+ readonly description: "Profile URL on LinkedIn, X or GitHub";
23
+ };
24
+ readonly linkedin_url: {
25
+ readonly type: "string";
26
+ readonly description: "Same as profile_url (older name)";
27
+ };
28
+ readonly social_media_url: {
29
+ readonly type: "string";
30
+ readonly description: "Same as profile_url (older name)";
31
+ };
32
+ };
33
+ /** The shared person shape (#1899), as the SDK's PersonIdentity. */
34
+ declare function personIdentity(args: Record<string, unknown>): PersonIdentity;
35
+ export { personIdentity };
3
36
  export declare const personProfileTool: Tool;
4
37
  export declare const personEmailTool: Tool;
5
38
  export declare const personEmailStatusTool: Tool;
@@ -1,53 +1,51 @@
1
+ export const PERSON_IDENTITY_PROPERTIES = {
2
+ name: { type: "string", description: "Person's full name (works best with company)" },
3
+ company: { type: "string", description: "Employer name or domain, e.g. Coinbase or coinbase.com" },
4
+ email: { type: "string", description: "Person's email address" },
5
+ phone: { type: "string", description: "Person's phone number" },
6
+ profile_url: { type: "string", description: "Profile URL on LinkedIn, X or GitHub" },
7
+ linkedin_url: { type: "string", description: "Same as profile_url (older name)" },
8
+ social_media_url: { type: "string", description: "Same as profile_url (older name)" },
9
+ };
10
+ /** The shared person shape (#1899), as the SDK's PersonIdentity. */
11
+ function personIdentity(args) {
12
+ return {
13
+ name: args.name,
14
+ company: args.company,
15
+ email: args.email,
16
+ phone: args.phone,
17
+ profile_url: args.profile_url,
18
+ linkedin_url: args.linkedin_url,
19
+ social_media_url: args.social_media_url,
20
+ };
21
+ }
22
+ export { personIdentity };
1
23
  export const personProfileTool = {
2
24
  name: "oneshot_person_profile",
3
- description: "Enrich a person's profile from LinkedIn URL, email, or name. Returns job title, company, social links, etc. Paid tool. Phone lookup is off by default. include_phone=true buys a lookup for up to one person at the add-on listed on the pricing page; no phone hit is guaranteed.",
25
+ description: "Enrich a person's profile from whatever you know: name (+ company), email, phone or a profile URL on LinkedIn, X or GitHub. Returns job title, company, social links, etc. Paid tool. Phone lookup is off by default. include_phone=true buys a lookup for up to one person at the add-on listed on the pricing page; no phone hit is guaranteed.",
4
26
  inputSchema: {
5
27
  type: "object",
6
28
  properties: {
7
29
  include_phone: { type: "boolean", default: false, description: "Phone lookup is off by default. include_phone=true buys a lookup for up to one person at the add-on listed on the pricing page; no phone hit is guaranteed." },
8
- linkedin_url: {
9
- type: "string",
10
- description: "LinkedIn profile URL",
11
- },
12
- email: {
13
- type: "string",
14
- description: "Email address to enrich",
15
- },
16
- name: {
17
- type: "string",
18
- description: "Person's full name",
19
- },
20
- company_domain: {
21
- type: "string",
22
- description: "Company domain for additional context",
23
- },
30
+ ...PERSON_IDENTITY_PROPERTIES,
31
+ company_domain: { type: "string", description: "Employer domain (older name; company takes a name or a domain)" },
32
+ company_name: { type: "string", description: "Employer name (older name; company takes a name or a domain)" },
24
33
  },
25
34
  },
26
35
  };
27
36
  export const personEmailTool = {
28
37
  name: "oneshot_person_email",
29
- description: "Find email address for a person at a company. Paid tool.",
38
+ description: "Find a person's email address from a name and company (name or domain), a phone, or a LinkedIn, X or GitHub profile URL. Paid tool.",
30
39
  inputSchema: {
31
40
  type: "object",
32
41
  properties: {
33
- full_name: {
34
- type: "string",
35
- description: "Person's full name",
36
- },
37
- first_name: {
38
- type: "string",
39
- description: "Person's first name (use with last_name)",
40
- },
41
- last_name: {
42
- type: "string",
43
- description: "Person's last name (use with first_name)",
44
- },
45
- company_domain: {
46
- type: "string",
47
- description: "Company domain (e.g., example.com)",
48
- },
42
+ ...PERSON_IDENTITY_PROPERTIES,
43
+ full_name: { type: "string", description: "Same as name (older name)" },
44
+ first_name: { type: "string", description: "Person's first name (use with last_name)" },
45
+ last_name: { type: "string", description: "Person's last name (use with first_name)" },
46
+ company_domain: { type: "string", description: "Employer domain (older name; company takes a name or a domain)" },
47
+ company_name: { type: "string", description: "Employer name (older name; company takes a name or a domain)" },
49
48
  },
50
- required: ["company_domain"],
51
49
  },
52
50
  };
53
51
  export const personEmailStatusTool = {
@@ -67,18 +65,19 @@ export const personEmailStatusTool = {
67
65
  export async function handlePersonProfile(agent, args) {
68
66
  return agent.personProfile({
69
67
  includePhone: args.include_phone,
70
- linkedin_url: args.linkedin_url,
71
- email: args.email,
72
- name: args.name,
68
+ ...personIdentity(args),
73
69
  company_domain: args.company_domain,
70
+ company_name: args.company_name,
74
71
  });
75
72
  }
76
73
  export async function handlePersonEmail(agent, args) {
77
74
  return agent.personEmail({
75
+ ...personIdentity(args),
78
76
  full_name: args.full_name,
79
77
  first_name: args.first_name,
80
78
  last_name: args.last_name,
81
79
  company_domain: args.company_domain,
80
+ company_name: args.company_name,
82
81
  });
83
82
  }
84
83
  export async function handlePersonEmailStatus(agent, args) {
@@ -2,6 +2,8 @@ import { emailTool, handleEmail } from "./email.js";
2
2
  import { voiceTool, handleVoice } from "./voice.js";
3
3
  import { voiceNumberProvisionTool, voiceNumbersTool, voiceInboundSetTool, voiceInboundDisableTool, voiceInboundCallsTool, handleVoiceNumberProvision, handleVoiceNumbers, handleVoiceInboundSet, handleVoiceInboundDisable, handleVoiceInboundCalls, } from "./voice-inbound.js";
4
4
  import { smsTool, handleSms } from "./sms.js";
5
+ import { predictTool, handlePredict } from "./predict.js";
6
+ import { solveTool, handleSolve } from "./solve.js";
5
7
  import { researchTool, handleResearch } from "./research.js";
6
8
  import { personFindTool, handlePersonFind } from "./people.js";
7
9
  import { productFindTool, commerceBuyTool, handleProductFind, handleCommerceBuy } from "./commerce.js";
@@ -25,6 +27,7 @@ import { listDomainsTool, pauseDomainTool, resumeDomainTool, handleListDomains,
25
27
  import { huntListTool, huntStatusTool, huntPredictTool, huntCollectionTool, huntLeaderboardTool, handleHuntList, handleHuntStatus, handleHuntPredict, handleHuntCollection, handleHuntLeaderboard } from "./hunt.js";
26
28
  import { TOOL_ANNOTATIONS } from "./annotations.js";
27
29
  import { lookupToolDefinitions, lookupHandlers, routeToolDefinitions, routeHandlers } from "./lookup.js";
30
+ import { physicalMailSendTool, physicalMailUploadTool, handlePhysicalMailSend, handlePhysicalMailUpload } from "./physical-mail.js";
28
31
  import { spendBreakdownTool, rocsTool, rocsByGoalTool, receiptsListTool, tagReceiptValueTool, handleSpendBreakdown, handleRocs, handleRocsByGoal, handleReceiptsList, handleTagReceiptValue } from "./analytics.js";
29
32
  const toolDefinitions = [
30
33
  emailTool,
@@ -39,6 +42,10 @@ const toolDefinitions = [
39
42
  voiceInboundSetTool,
40
43
  voiceInboundDisableTool,
41
44
  voiceInboundCallsTool,
45
+ solveTool,
46
+ predictTool,
47
+ physicalMailUploadTool,
48
+ physicalMailSendTool,
42
49
  researchTool,
43
50
  personFindTool,
44
51
  personProfileTool,
@@ -129,6 +136,10 @@ const handlers = {
129
136
  "oneshot_voice_inbound_set": handleVoiceInboundSet,
130
137
  "oneshot_voice_inbound_disable": handleVoiceInboundDisable,
131
138
  "oneshot_voice_inbound_calls": handleVoiceInboundCalls,
139
+ "oneshot_solve": handleSolve,
140
+ "oneshot_predict": handlePredict,
141
+ "oneshot_physical_mail_upload": handlePhysicalMailUpload,
142
+ "oneshot_physical_mail_send": handlePhysicalMailSend,
132
143
  "oneshot_research": handleResearch,
133
144
  "oneshot_person_find": handlePersonFind,
134
145
  "oneshot_person_profile": handlePersonProfile,