@oneshot-agent/mcp-server 0.40.0 → 0.42.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
@@ -326,9 +326,8 @@ Use oneshot_person_find:
326
326
 
327
327
  ```
328
328
  Use oneshot_person_email:
329
- - first_name: "John"
330
- - last_name: "Smith"
331
- - company_domain: "example.com"
329
+ - name: "John Smith"
330
+ - company: "Example" (a name or a domain)
332
331
  ```
333
332
 
334
333
  ### Check Wallet Balance
@@ -386,3 +385,9 @@ timeouts.
386
385
  ## Optional phone lookup
387
386
 
388
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.40.0", // keep in sync with package.json; guarded by version.test.ts
53
+ version: "0.42.0", // keep in sync with package.json; guarded by version.test.ts
54
54
  }, {
55
55
  capabilities: {
56
56
  tools: {},
@@ -8,6 +8,7 @@ const OWN = false;
8
8
  const DESTRUCTIVE = true;
9
9
  export const TOOL_ANNOTATIONS = {
10
10
  oneshot_solve: read("Solve", OWN),
11
+ oneshot_predict: read("Predict", OWN),
11
12
  oneshot_hunt_list: read("List Soul Hunts", OPEN),
12
13
  oneshot_hunt_status: read("Get Soul Hunt Status", OPEN),
13
14
  oneshot_hunt_predict: write("Predict Soul Hunt", 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,57 +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
- },
24
- company_name: {
25
- type: "string",
26
- description: "Employer name, for a name lookup when the company domain is not known (e.g. Coinbase)",
27
- },
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)" },
28
33
  },
29
34
  },
30
35
  };
31
36
  export const personEmailTool = {
32
37
  name: "oneshot_person_email",
33
- 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.",
34
39
  inputSchema: {
35
40
  type: "object",
36
41
  properties: {
37
- full_name: {
38
- type: "string",
39
- description: "Person's full name",
40
- },
41
- first_name: {
42
- type: "string",
43
- description: "Person's first name (use with last_name)",
44
- },
45
- last_name: {
46
- type: "string",
47
- description: "Person's last name (use with first_name)",
48
- },
49
- company_domain: {
50
- type: "string",
51
- description: "Company domain (e.g., example.com)",
52
- },
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)" },
53
48
  },
54
- required: ["company_domain"],
55
49
  },
56
50
  };
57
51
  export const personEmailStatusTool = {
@@ -71,19 +65,19 @@ export const personEmailStatusTool = {
71
65
  export async function handlePersonProfile(agent, args) {
72
66
  return agent.personProfile({
73
67
  includePhone: args.include_phone,
74
- linkedin_url: args.linkedin_url,
75
- email: args.email,
76
- name: args.name,
68
+ ...personIdentity(args),
77
69
  company_domain: args.company_domain,
78
70
  company_name: args.company_name,
79
71
  });
80
72
  }
81
73
  export async function handlePersonEmail(agent, args) {
82
74
  return agent.personEmail({
75
+ ...personIdentity(args),
83
76
  full_name: args.full_name,
84
77
  first_name: args.first_name,
85
78
  last_name: args.last_name,
86
79
  company_domain: args.company_domain,
80
+ company_name: args.company_name,
87
81
  });
88
82
  }
89
83
  export async function handlePersonEmailStatus(agent, args) {
@@ -2,6 +2,7 @@ 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";
5
6
  import { solveTool, handleSolve } from "./solve.js";
6
7
  import { researchTool, handleResearch } from "./research.js";
7
8
  import { personFindTool, handlePersonFind } from "./people.js";
@@ -42,6 +43,7 @@ const toolDefinitions = [
42
43
  voiceInboundDisableTool,
43
44
  voiceInboundCallsTool,
44
45
  solveTool,
46
+ predictTool,
45
47
  physicalMailUploadTool,
46
48
  physicalMailSendTool,
47
49
  researchTool,
@@ -135,6 +137,7 @@ const handlers = {
135
137
  "oneshot_voice_inbound_disable": handleVoiceInboundDisable,
136
138
  "oneshot_voice_inbound_calls": handleVoiceInboundCalls,
137
139
  "oneshot_solve": handleSolve,
140
+ "oneshot_predict": handlePredict,
138
141
  "oneshot_physical_mail_upload": handlePhysicalMailUpload,
139
142
  "oneshot_physical_mail_send": handlePhysicalMailSend,
140
143
  "oneshot_research": handleResearch,
@@ -806,6 +806,35 @@ export const LOOKUP_MANIFEST = [
806
806
  "height_in": 48
807
807
  }
808
808
  },
809
+ {
810
+ "name": "gene_resolve",
811
+ "path": "resolve/gene",
812
+ "title": "Gene Resolve",
813
+ "description": "Give `query`: an official gene symbol (TP53), an alias (P53, HER2) or an Ensembl gene ID (ENSG00000141510; a version suffix is dropped). Letters, digits, dots, dashes and `_` only. `taxon_id` picks the organism and is human (9606) unless set. Returns the matching live genes, up to `limit`: genes whose official symbol is the query first, then genes that carry it as an alias, each in the source's order, with the NCBI Gene ID (the input of Gene Summary), the symbol, the full name, the aliases, the nomenclature status, the organism, the chromosome, the cytogenetic band and the gene page link. `matched_on` says how each gene matched. A search hit that carries the query as neither its symbol nor an alias is dropped. `ambiguous` is true when more than one gene matched and none has the query as its official symbol. An unknown query returns an empty matches list. Replaced and discontinued Gene IDs are not returned. A query whose search finds more than 20 live records fails rather than returning a partial answer. Data from NCBI Gene at the US National Center for Biotechnology Information; official human symbols are assigned by the HUGO Gene Nomenclature Committee.",
814
+ "inputSchema": {
815
+ "type": "object",
816
+ "properties": {
817
+ "query": {
818
+ "type": "string",
819
+ "description": "An official gene symbol (TP53), an alias (P53, HER2) or an Ensembl gene ID (ENSG00000141510, a version suffix is dropped). 1 to 40 characters. Letters, digits, dots, dashes and `_` only, starting with a letter or digit."
820
+ },
821
+ "taxon_id": {
822
+ "type": "integer",
823
+ "description": "The organism as an NCBI Taxonomy ID; 9606 (human) unless set, 10090 is mouse. From 1 to 999999999. Defaults to `9606`."
824
+ },
825
+ "limit": {
826
+ "type": "integer",
827
+ "description": "The most matching genes to return. From 1 to 10. Defaults to `5`."
828
+ }
829
+ },
830
+ "required": [
831
+ "query"
832
+ ]
833
+ },
834
+ "example": {
835
+ "query": "HER2"
836
+ }
837
+ },
809
838
  {
810
839
  "name": "gene_summary",
811
840
  "path": "lookup/gene-summary",
@@ -1062,6 +1091,47 @@ export const LOOKUP_MANIFEST = [
1062
1091
  "limit": 10
1063
1092
  }
1064
1093
  },
1094
+ {
1095
+ "name": "protein_domains",
1096
+ "path": "lookup/protein-domains",
1097
+ "title": "Protein Domains",
1098
+ "description": "InterPro entries from InterPro at EMBL-EBI, under CC0 1.0. Returns integrated InterPro entries only, never member-database signatures. Covers canonical UniProtKB sequences; isoform accessions are refused. Filter by entry type or omit types for all entries. An empty types list keeps no entries. Entries are sorted by their first location’s start, then identifier. Locations span the first through last fragment; discontinuous marks multiple fragments or a fragment whose dc-status is not CONTINUOUS. Releases arrive about every eight weeks; no per-entry date is supplied, so changes are recorded as observations. Returns the first page only (up to 200 entries), with truncated true when another page exists. No match completes with an empty entries list and null protein_length.",
1099
+ "inputSchema": {
1100
+ "type": "object",
1101
+ "properties": {
1102
+ "accession": {
1103
+ "type": "string",
1104
+ "description": "The canonical UniProt accession identifying the protein, for example P04637; isoforms are not accepted"
1105
+ },
1106
+ "types": {
1107
+ "type": "array",
1108
+ "items": {
1109
+ "type": "string",
1110
+ "enum": [
1111
+ "family",
1112
+ "domain",
1113
+ "homologous_superfamily",
1114
+ "repeat",
1115
+ "conserved_site",
1116
+ "active_site",
1117
+ "binding_site",
1118
+ "ptm"
1119
+ ]
1120
+ },
1121
+ "description": "Keep only these entry types; omitted means all types"
1122
+ }
1123
+ },
1124
+ "required": [
1125
+ "accession"
1126
+ ]
1127
+ },
1128
+ "example": {
1129
+ "accession": "P04637",
1130
+ "types": [
1131
+ "conserved_site"
1132
+ ]
1133
+ }
1134
+ },
1065
1135
  {
1066
1136
  "name": "protein_function",
1067
1137
  "path": "lookup/protein-function",
@@ -1088,6 +1158,27 @@ export const LOOKUP_MANIFEST = [
1088
1158
  "include_sequence": false
1089
1159
  }
1090
1160
  },
1161
+ {
1162
+ "name": "protein_sequence",
1163
+ "path": "lookup/protein-sequence",
1164
+ "title": "Protein Sequence",
1165
+ "description": "Protein sequences from UniProt under CC BY 4.0, attributed to the UniProt Consortium. Medical or genetic information is for research and education only. The sequence is the reference sequence UniProtKB holds for a protein, never an individual’s sequence. Covers reviewed and unreviewed entries; an accession with an isoform suffix (P04637-2) returns that isoform’s sequence. Returns the one-letter sequence, length, molecular weight in daltons, CRC64 and MD5 checksums, gene, organism and the isoforms the entry lists. sequence_version and last_sequence_update describe the entry, also for an isoform. UniProt releases updates every eight weeks. Absent values are null. A merged, demerged or deleted accession returns no protein and the source’s inactive reason with any replacement accessions. No match, including an isoform the entry does not list, returns null for both.",
1166
+ "inputSchema": {
1167
+ "type": "object",
1168
+ "properties": {
1169
+ "accession": {
1170
+ "type": "string",
1171
+ "description": "The UniProt accession, for example P04637, or an isoform accession, for example P04637-2"
1172
+ }
1173
+ },
1174
+ "required": [
1175
+ "accession"
1176
+ ]
1177
+ },
1178
+ "example": {
1179
+ "accession": "P00001"
1180
+ }
1181
+ },
1091
1182
  {
1092
1183
  "name": "protein_structure",
1093
1184
  "path": "lookup/protein-structure",
@@ -1,25 +1,22 @@
1
+ import { PERSON_IDENTITY_PROPERTIES, personIdentity } from "./enrichment.js";
1
2
  export const personDossierTool = {
2
3
  name: "oneshot_person_dossier",
3
- description: "Get a person’s profile, known social accounts, articles, posts and written summary. Takes 2-5 minutes. 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
+ description: "Get a person’s profile, known social accounts, articles, posts and written summary, from whatever you know: name (+ company), email, phone or a profile URL. Takes 2-5 minutes. 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
5
  inputSchema: {
5
6
  type: "object",
6
7
  properties: {
7
8
  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
- email: { type: "string", description: "Person's email address" },
9
- social_media_url: { type: "string", description: "LinkedIn, Twitter, or other social profile URL" },
10
- name: { type: "string", description: "Person's full name" },
11
- company: { type: "string", description: "Company name (helps disambiguate)" },
9
+ ...PERSON_IDENTITY_PROPERTIES,
12
10
  },
13
11
  },
14
12
  };
15
13
  export const personSocialAccountsTool = {
16
14
  name: "oneshot_person_social_accounts",
17
- description: "Discover all social media profiles for a person across platforms (LinkedIn, Twitter, GitHub, YouTube, etc). Paid tool.",
15
+ description: "Discover all social media profiles for a person across platforms (LinkedIn, Twitter, GitHub, YouTube, etc), from a name (+ company), email, phone or a known profile URL. Paid tool.",
18
16
  inputSchema: {
19
17
  type: "object",
20
18
  properties: {
21
- email: { type: "string", description: "Person's email address" },
22
- social_media_url: { type: "string", description: "Known social profile URL to start from" },
19
+ ...PERSON_IDENTITY_PROPERTIES,
23
20
  },
24
21
  },
25
22
  };
@@ -39,38 +36,34 @@ export const personArticlesTool = {
39
36
  };
40
37
  export const personPostsTool = {
41
38
  name: "oneshot_person_posts",
42
- description: "Get a person's recent social media posts with likes, replies, and shares. Paid tool.",
39
+ description: "Get a person's recent social media posts with likes, replies, and shares. Give a profile URL, or a name (+ company) / email to resolve one. Paid tool.",
43
40
  inputSchema: {
44
41
  type: "object",
45
42
  properties: {
46
- social_media_url: { type: "string", description: "Social profile URL (Twitter, LinkedIn, etc)" },
43
+ ...PERSON_IDENTITY_PROPERTIES,
47
44
  },
48
- required: ["social_media_url"],
49
45
  },
50
46
  };
51
47
  export const personInterestsTool = {
52
48
  name: "oneshot_person_interests",
53
- description: "Figure out what someone cares about — sports, politics, tech, entertainment, etc. Paid tool.",
49
+ description: "Figure out what someone cares about — sports, politics, tech, entertainment, etc. Give a name (+ company), email, phone or profile URL. Paid tool.",
54
50
  inputSchema: {
55
51
  type: "object",
56
52
  properties: {
57
- email: { type: "string", description: "Person's email address" },
58
- phone: { type: "string", description: "Person's phone number" },
59
- social_media_url: { type: "string", description: "Social profile URL" },
53
+ ...PERSON_IDENTITY_PROPERTIES,
60
54
  },
61
55
  },
62
56
  };
63
57
  export const personFollowersTool = {
64
58
  name: "oneshot_person_followers",
65
- description: "See who someone follows, who follows them, and who they reply to. Paid tool.",
59
+ description: "See who someone follows, who follows them, and who they reply to. Give an X profile URL, or a name (+ company) / email to resolve one. Paid tool.",
66
60
  inputSchema: {
67
61
  type: "object",
68
62
  properties: {
69
- social_media_url: { type: "string", description: "Social profile or post URL (Twitter/X or Instagram)" },
63
+ ...PERSON_IDENTITY_PROPERTIES,
70
64
  type: { type: "string", enum: ["replies", "followers", "following", "followers,following"], description: "Interaction type (default: followers,following)" },
71
65
  max_results: { type: "number", description: "Max results 1-1000 (default: 100)" },
72
66
  },
73
- required: ["social_media_url"],
74
67
  },
75
68
  };
76
69
  /** Deep person research fans out across several providers. The SDK now defaults personDossier to the same 300 s (#1913); this keeps the MCP value explicit. */
@@ -78,18 +71,12 @@ export const PERSON_DOSSIER_TIMEOUT_SEC = 300;
78
71
  export async function handlePersonDossier(agent, args) {
79
72
  return agent.personDossier({
80
73
  includePhone: args.include_phone,
81
- email: args.email,
82
- social_media_url: args.social_media_url,
83
- name: args.name,
84
- company: args.company,
74
+ ...personIdentity(args),
85
75
  timeout: PERSON_DOSSIER_TIMEOUT_SEC,
86
76
  });
87
77
  }
88
78
  export async function handlePersonSocialAccounts(agent, args) {
89
- return agent.personSocialAccounts({
90
- email: args.email,
91
- social_media_url: args.social_media_url,
92
- });
79
+ return agent.personSocialAccounts(personIdentity(args));
93
80
  }
94
81
  export async function handlePersonArticles(agent, args) {
95
82
  return agent.personArticles({
@@ -100,20 +87,14 @@ export async function handlePersonArticles(agent, args) {
100
87
  });
101
88
  }
102
89
  export async function handlePersonPosts(agent, args) {
103
- return agent.personPosts({
104
- social_media_url: args.social_media_url,
105
- });
90
+ return agent.personPosts(personIdentity(args));
106
91
  }
107
92
  export async function handlePersonInterests(agent, args) {
108
- return agent.personInterests({
109
- email: args.email,
110
- phone: args.phone,
111
- social_media_url: args.social_media_url,
112
- });
93
+ return agent.personInterests(personIdentity(args));
113
94
  }
114
95
  export async function handlePersonFollowers(agent, args) {
115
96
  return agent.personFollowers({
116
- social_media_url: args.social_media_url,
97
+ ...personIdentity(args),
117
98
  type: args.type,
118
99
  max_results: args.max_results,
119
100
  });
@@ -0,0 +1,275 @@
1
+ export declare const predictInputSchema: {
2
+ readonly type: "object";
3
+ readonly properties: {
4
+ readonly model: {
5
+ readonly type: "string";
6
+ readonly enum: readonly ["simulation", "forecast"];
7
+ };
8
+ readonly time_limit_s: {
9
+ readonly type: "integer";
10
+ readonly minimum: 1;
11
+ readonly maximum: 120;
12
+ readonly default: 20;
13
+ };
14
+ readonly simulation: {
15
+ readonly type: "object";
16
+ readonly properties: {
17
+ readonly runs: {
18
+ readonly type: "integer";
19
+ readonly minimum: 100;
20
+ readonly maximum: 100000;
21
+ readonly default: 10000;
22
+ };
23
+ readonly seed: {
24
+ readonly type: "integer";
25
+ readonly minimum: 0;
26
+ readonly maximum: 4294967295;
27
+ };
28
+ readonly percentiles: {
29
+ readonly type: "array";
30
+ readonly items: {
31
+ readonly type: "number";
32
+ readonly minimum: 0;
33
+ readonly maximum: 100;
34
+ };
35
+ readonly minItems: 1;
36
+ readonly maxItems: 20;
37
+ readonly default: readonly [5, 10, 25, 50, 75, 90, 95];
38
+ };
39
+ readonly variables: {
40
+ readonly type: "array";
41
+ readonly items: {
42
+ readonly type: "object";
43
+ readonly properties: {
44
+ readonly id: {
45
+ readonly type: "string";
46
+ readonly minLength: 1;
47
+ readonly maxLength: 64;
48
+ readonly pattern: "^[A-Za-z_][A-Za-z0-9_]*$";
49
+ };
50
+ readonly distribution: {
51
+ readonly anyOf: readonly [{
52
+ readonly type: "object";
53
+ readonly properties: {
54
+ readonly kind: {
55
+ readonly type: "string";
56
+ readonly const: "fixed";
57
+ };
58
+ readonly value: {
59
+ readonly type: "number";
60
+ };
61
+ };
62
+ readonly required: readonly ["kind", "value"];
63
+ readonly additionalProperties: false;
64
+ }, {
65
+ readonly type: "object";
66
+ readonly properties: {
67
+ readonly kind: {
68
+ readonly type: "string";
69
+ readonly const: "uniform";
70
+ };
71
+ readonly min: {
72
+ readonly type: "number";
73
+ };
74
+ readonly max: {
75
+ readonly type: "number";
76
+ };
77
+ };
78
+ readonly required: readonly ["kind", "min", "max"];
79
+ readonly additionalProperties: false;
80
+ }, {
81
+ readonly type: "object";
82
+ readonly properties: {
83
+ readonly kind: {
84
+ readonly type: "string";
85
+ readonly const: "normal";
86
+ };
87
+ readonly mean: {
88
+ readonly type: "number";
89
+ };
90
+ readonly sd: {
91
+ readonly type: "number";
92
+ readonly exclusiveMinimum: 0;
93
+ };
94
+ };
95
+ readonly required: readonly ["kind", "mean", "sd"];
96
+ readonly additionalProperties: false;
97
+ }, {
98
+ readonly type: "object";
99
+ readonly properties: {
100
+ readonly kind: {
101
+ readonly type: "string";
102
+ readonly const: "lognormal";
103
+ };
104
+ readonly log_mean: {
105
+ readonly type: "number";
106
+ };
107
+ readonly log_sd: {
108
+ readonly type: "number";
109
+ readonly exclusiveMinimum: 0;
110
+ };
111
+ };
112
+ readonly required: readonly ["kind", "log_mean", "log_sd"];
113
+ readonly additionalProperties: false;
114
+ }, {
115
+ readonly type: "object";
116
+ readonly properties: {
117
+ readonly kind: {
118
+ readonly type: "string";
119
+ readonly const: "triangular";
120
+ };
121
+ readonly min: {
122
+ readonly type: "number";
123
+ };
124
+ readonly mode: {
125
+ readonly type: "number";
126
+ };
127
+ readonly max: {
128
+ readonly type: "number";
129
+ };
130
+ };
131
+ readonly required: readonly ["kind", "min", "mode", "max"];
132
+ readonly additionalProperties: false;
133
+ }, {
134
+ readonly type: "object";
135
+ readonly properties: {
136
+ readonly kind: {
137
+ readonly type: "string";
138
+ readonly const: "bernoulli";
139
+ };
140
+ readonly p: {
141
+ readonly type: "number";
142
+ readonly minimum: 0;
143
+ readonly maximum: 1;
144
+ };
145
+ };
146
+ readonly required: readonly ["kind", "p"];
147
+ readonly additionalProperties: false;
148
+ }, {
149
+ readonly type: "object";
150
+ readonly properties: {
151
+ readonly kind: {
152
+ readonly type: "string";
153
+ readonly const: "discrete";
154
+ };
155
+ readonly values: {
156
+ readonly type: "array";
157
+ readonly items: {
158
+ readonly type: "number";
159
+ };
160
+ readonly minItems: 1;
161
+ readonly maxItems: 100;
162
+ };
163
+ readonly weights: {
164
+ readonly type: "array";
165
+ readonly items: {
166
+ readonly type: "number";
167
+ readonly minimum: 0;
168
+ };
169
+ readonly minItems: 1;
170
+ readonly maxItems: 100;
171
+ };
172
+ };
173
+ readonly required: readonly ["kind", "values"];
174
+ readonly additionalProperties: false;
175
+ }];
176
+ };
177
+ };
178
+ readonly required: readonly ["id", "distribution"];
179
+ readonly additionalProperties: false;
180
+ };
181
+ readonly minItems: 1;
182
+ readonly maxItems: 50;
183
+ };
184
+ readonly outputs: {
185
+ readonly type: "array";
186
+ readonly items: {
187
+ readonly type: "object";
188
+ readonly properties: {
189
+ readonly id: {
190
+ readonly type: "string";
191
+ readonly minLength: 1;
192
+ readonly maxLength: 64;
193
+ readonly pattern: "^[A-Za-z_][A-Za-z0-9_]*$";
194
+ };
195
+ readonly expression: {
196
+ readonly type: "string";
197
+ readonly minLength: 1;
198
+ readonly maxLength: 1000;
199
+ };
200
+ };
201
+ readonly required: readonly ["id", "expression"];
202
+ readonly additionalProperties: false;
203
+ };
204
+ readonly minItems: 1;
205
+ readonly maxItems: 10;
206
+ };
207
+ };
208
+ readonly required: readonly ["variables", "outputs"];
209
+ readonly additionalProperties: false;
210
+ };
211
+ readonly forecast: {
212
+ readonly type: "object";
213
+ readonly properties: {
214
+ readonly series: {
215
+ readonly type: "array";
216
+ readonly items: {
217
+ readonly type: "object";
218
+ readonly properties: {
219
+ readonly t: {
220
+ readonly anyOf: readonly [{
221
+ readonly type: "string";
222
+ readonly minLength: 1;
223
+ }, {
224
+ readonly type: "integer";
225
+ readonly minimum: -9007199254740991;
226
+ readonly maximum: 9007199254740991;
227
+ }];
228
+ };
229
+ readonly y: {
230
+ readonly type: "number";
231
+ };
232
+ };
233
+ readonly required: readonly ["t", "y"];
234
+ readonly additionalProperties: false;
235
+ };
236
+ readonly minItems: 8;
237
+ readonly maxItems: 10000;
238
+ };
239
+ readonly horizon: {
240
+ readonly type: "integer";
241
+ readonly minimum: 1;
242
+ readonly maximum: 365;
243
+ };
244
+ readonly frequency: {
245
+ readonly type: "string";
246
+ readonly enum: readonly ["hourly", "daily", "weekly", "monthly", "quarterly", "yearly"];
247
+ };
248
+ readonly seasonal_period: {
249
+ readonly type: "integer";
250
+ readonly minimum: 2;
251
+ readonly maximum: 366;
252
+ };
253
+ readonly interval_levels: {
254
+ readonly type: "array";
255
+ readonly items: {
256
+ readonly type: "integer";
257
+ readonly minimum: 50;
258
+ readonly maximum: 99;
259
+ };
260
+ readonly minItems: 1;
261
+ readonly maxItems: 3;
262
+ readonly default: readonly [80, 95];
263
+ };
264
+ readonly floor: {
265
+ readonly type: "number";
266
+ };
267
+ };
268
+ readonly required: readonly ["series", "horizon"];
269
+ readonly additionalProperties: false;
270
+ };
271
+ };
272
+ readonly required: readonly ["model"];
273
+ readonly additionalProperties: false;
274
+ readonly $schema: "http://json-schema.org/draft-07/schema#";
275
+ };
@@ -0,0 +1,351 @@
1
+ // Generated by bun scripts/generate-predict-client.ts from the shared PredictRequestSchema.
2
+ export const predictInputSchema = {
3
+ "type": "object",
4
+ "properties": {
5
+ "model": {
6
+ "type": "string",
7
+ "enum": [
8
+ "simulation",
9
+ "forecast"
10
+ ]
11
+ },
12
+ "time_limit_s": {
13
+ "type": "integer",
14
+ "minimum": 1,
15
+ "maximum": 120,
16
+ "default": 20
17
+ },
18
+ "simulation": {
19
+ "type": "object",
20
+ "properties": {
21
+ "runs": {
22
+ "type": "integer",
23
+ "minimum": 100,
24
+ "maximum": 100000,
25
+ "default": 10000
26
+ },
27
+ "seed": {
28
+ "type": "integer",
29
+ "minimum": 0,
30
+ "maximum": 4294967295
31
+ },
32
+ "percentiles": {
33
+ "type": "array",
34
+ "items": {
35
+ "type": "number",
36
+ "minimum": 0,
37
+ "maximum": 100
38
+ },
39
+ "minItems": 1,
40
+ "maxItems": 20,
41
+ "default": [
42
+ 5,
43
+ 10,
44
+ 25,
45
+ 50,
46
+ 75,
47
+ 90,
48
+ 95
49
+ ]
50
+ },
51
+ "variables": {
52
+ "type": "array",
53
+ "items": {
54
+ "type": "object",
55
+ "properties": {
56
+ "id": {
57
+ "type": "string",
58
+ "minLength": 1,
59
+ "maxLength": 64,
60
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
61
+ },
62
+ "distribution": {
63
+ "anyOf": [
64
+ {
65
+ "type": "object",
66
+ "properties": {
67
+ "kind": {
68
+ "type": "string",
69
+ "const": "fixed"
70
+ },
71
+ "value": {
72
+ "type": "number"
73
+ }
74
+ },
75
+ "required": [
76
+ "kind",
77
+ "value"
78
+ ],
79
+ "additionalProperties": false
80
+ },
81
+ {
82
+ "type": "object",
83
+ "properties": {
84
+ "kind": {
85
+ "type": "string",
86
+ "const": "uniform"
87
+ },
88
+ "min": {
89
+ "type": "number"
90
+ },
91
+ "max": {
92
+ "type": "number"
93
+ }
94
+ },
95
+ "required": [
96
+ "kind",
97
+ "min",
98
+ "max"
99
+ ],
100
+ "additionalProperties": false
101
+ },
102
+ {
103
+ "type": "object",
104
+ "properties": {
105
+ "kind": {
106
+ "type": "string",
107
+ "const": "normal"
108
+ },
109
+ "mean": {
110
+ "type": "number"
111
+ },
112
+ "sd": {
113
+ "type": "number",
114
+ "exclusiveMinimum": 0
115
+ }
116
+ },
117
+ "required": [
118
+ "kind",
119
+ "mean",
120
+ "sd"
121
+ ],
122
+ "additionalProperties": false
123
+ },
124
+ {
125
+ "type": "object",
126
+ "properties": {
127
+ "kind": {
128
+ "type": "string",
129
+ "const": "lognormal"
130
+ },
131
+ "log_mean": {
132
+ "type": "number"
133
+ },
134
+ "log_sd": {
135
+ "type": "number",
136
+ "exclusiveMinimum": 0
137
+ }
138
+ },
139
+ "required": [
140
+ "kind",
141
+ "log_mean",
142
+ "log_sd"
143
+ ],
144
+ "additionalProperties": false
145
+ },
146
+ {
147
+ "type": "object",
148
+ "properties": {
149
+ "kind": {
150
+ "type": "string",
151
+ "const": "triangular"
152
+ },
153
+ "min": {
154
+ "type": "number"
155
+ },
156
+ "mode": {
157
+ "type": "number"
158
+ },
159
+ "max": {
160
+ "type": "number"
161
+ }
162
+ },
163
+ "required": [
164
+ "kind",
165
+ "min",
166
+ "mode",
167
+ "max"
168
+ ],
169
+ "additionalProperties": false
170
+ },
171
+ {
172
+ "type": "object",
173
+ "properties": {
174
+ "kind": {
175
+ "type": "string",
176
+ "const": "bernoulli"
177
+ },
178
+ "p": {
179
+ "type": "number",
180
+ "minimum": 0,
181
+ "maximum": 1
182
+ }
183
+ },
184
+ "required": [
185
+ "kind",
186
+ "p"
187
+ ],
188
+ "additionalProperties": false
189
+ },
190
+ {
191
+ "type": "object",
192
+ "properties": {
193
+ "kind": {
194
+ "type": "string",
195
+ "const": "discrete"
196
+ },
197
+ "values": {
198
+ "type": "array",
199
+ "items": {
200
+ "type": "number"
201
+ },
202
+ "minItems": 1,
203
+ "maxItems": 100
204
+ },
205
+ "weights": {
206
+ "type": "array",
207
+ "items": {
208
+ "type": "number",
209
+ "minimum": 0
210
+ },
211
+ "minItems": 1,
212
+ "maxItems": 100
213
+ }
214
+ },
215
+ "required": [
216
+ "kind",
217
+ "values"
218
+ ],
219
+ "additionalProperties": false
220
+ }
221
+ ]
222
+ }
223
+ },
224
+ "required": [
225
+ "id",
226
+ "distribution"
227
+ ],
228
+ "additionalProperties": false
229
+ },
230
+ "minItems": 1,
231
+ "maxItems": 50
232
+ },
233
+ "outputs": {
234
+ "type": "array",
235
+ "items": {
236
+ "type": "object",
237
+ "properties": {
238
+ "id": {
239
+ "type": "string",
240
+ "minLength": 1,
241
+ "maxLength": 64,
242
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
243
+ },
244
+ "expression": {
245
+ "type": "string",
246
+ "minLength": 1,
247
+ "maxLength": 1000
248
+ }
249
+ },
250
+ "required": [
251
+ "id",
252
+ "expression"
253
+ ],
254
+ "additionalProperties": false
255
+ },
256
+ "minItems": 1,
257
+ "maxItems": 10
258
+ }
259
+ },
260
+ "required": [
261
+ "variables",
262
+ "outputs"
263
+ ],
264
+ "additionalProperties": false
265
+ },
266
+ "forecast": {
267
+ "type": "object",
268
+ "properties": {
269
+ "series": {
270
+ "type": "array",
271
+ "items": {
272
+ "type": "object",
273
+ "properties": {
274
+ "t": {
275
+ "anyOf": [
276
+ {
277
+ "type": "string",
278
+ "minLength": 1
279
+ },
280
+ {
281
+ "type": "integer",
282
+ "minimum": -9007199254740991,
283
+ "maximum": 9007199254740991
284
+ }
285
+ ]
286
+ },
287
+ "y": {
288
+ "type": "number"
289
+ }
290
+ },
291
+ "required": [
292
+ "t",
293
+ "y"
294
+ ],
295
+ "additionalProperties": false
296
+ },
297
+ "minItems": 8,
298
+ "maxItems": 10000
299
+ },
300
+ "horizon": {
301
+ "type": "integer",
302
+ "minimum": 1,
303
+ "maximum": 365
304
+ },
305
+ "frequency": {
306
+ "type": "string",
307
+ "enum": [
308
+ "hourly",
309
+ "daily",
310
+ "weekly",
311
+ "monthly",
312
+ "quarterly",
313
+ "yearly"
314
+ ]
315
+ },
316
+ "seasonal_period": {
317
+ "type": "integer",
318
+ "minimum": 2,
319
+ "maximum": 366
320
+ },
321
+ "interval_levels": {
322
+ "type": "array",
323
+ "items": {
324
+ "type": "integer",
325
+ "minimum": 50,
326
+ "maximum": 99
327
+ },
328
+ "minItems": 1,
329
+ "maxItems": 3,
330
+ "default": [
331
+ 80,
332
+ 95
333
+ ]
334
+ },
335
+ "floor": {
336
+ "type": "number"
337
+ }
338
+ },
339
+ "required": [
340
+ "series",
341
+ "horizon"
342
+ ],
343
+ "additionalProperties": false
344
+ }
345
+ },
346
+ "required": [
347
+ "model"
348
+ ],
349
+ "additionalProperties": false,
350
+ "$schema": "http://json-schema.org/draft-07/schema#"
351
+ };
@@ -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 predictTool: Tool;
4
+ export declare function handlePredict(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").PredictPendingResult | import("@oneshot-agent/sdk").PredictSimulationResult | import("@oneshot-agent/sdk").PredictForecastResult>;
@@ -0,0 +1,9 @@
1
+ import { predictInputSchema } from './predict-schema.generated.js';
2
+ export const predictTool = {
3
+ name: 'oneshot_predict',
4
+ description: 'Predict outcomes with uncertainty and consistency checks. Supported models: simulation (named distributions and arithmetic outputs, returning means, medians and percentiles) and forecast (time series projected ahead with prediction intervals). Provide the matching model block.',
5
+ inputSchema: JSON.parse(JSON.stringify(predictInputSchema)),
6
+ };
7
+ export async function handlePredict(agent, args) {
8
+ return agent.predict(args);
9
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oneshot-agent/mcp-server",
3
- "version": "0.40.0",
4
- "description": "MCP server for OneShot - 146 tools for AI agents",
3
+ "version": "0.42.0",
4
+ "description": "MCP server for OneShot - 150 tools for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -26,7 +26,7 @@
26
26
  "dependencies": {
27
27
  "@coinbase/cdp-sdk": "1.45.0",
28
28
  "@modelcontextprotocol/sdk": "1.27.1",
29
- "@oneshot-agent/sdk": "^0.55.0",
29
+ "@oneshot-agent/sdk": "^0.56.0",
30
30
  "zod": "3.25.76"
31
31
  },
32
32
  "devDependencies": {