@oneshot-agent/mcp-server 0.30.1 → 0.33.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 73 tools over
105
+ server and must not hold a wallet key. For them, OneShot hosts the same 78 tools 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
 
@@ -125,6 +125,18 @@ instead of the wallet variables for a credits-only session on your own machine.
125
125
 
126
126
  ## Available Tools
127
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
+
128
140
  ### Communication
129
141
 
130
142
  | Tool | Description |
package/dist/index.js CHANGED
@@ -46,23 +46,19 @@ async function initAgent() {
46
46
  " ONESHOT_WALLET_PRIVATE_KEY, or ONESHOT_ACCESS_TOKEN (credits-only session)");
47
47
  process.exit(1);
48
48
  }
49
- // Start server
50
49
  async function main() {
51
50
  const agent = await initAgent();
52
- // Create MCP server
53
51
  const server = new Server({
54
52
  name: "oneshot-mcp",
55
- version: "0.30.1", // keep in sync with package.json; guarded by version.test.ts
53
+ version: "0.33.0", // keep in sync with package.json; guarded by version.test.ts
56
54
  }, {
57
55
  capabilities: {
58
56
  tools: {},
59
57
  },
60
58
  });
61
- // List available tools
62
59
  server.setRequestHandler(ListToolsRequestSchema, async () => {
63
60
  return { tools };
64
61
  });
65
- // Handle tool calls
66
62
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
67
63
  const { name, arguments: args } = request.params;
68
64
  return handleToolCall(agent, name, args || {});
@@ -25,7 +25,7 @@ export const receiptsListTool = {
25
25
  type: "object",
26
26
  properties: {
27
27
  period: { type: "number", description: "Lookback window in days" },
28
- category: { type: "string", description: "Filter by tool category" },
28
+ category: { type: "string", enum: ["data", "verification", "communication", "commerce", "infrastructure", "agent_to_agent"], description: "Filter by receipt category" },
29
29
  limit: { type: "number", description: "Max receipts to return (1-100, default 50)" },
30
30
  offset: { type: "number", description: "Pagination offset" },
31
31
  since: { type: "string", description: "Lower bound on created_at (ISO 8601). Page back to older receipts." },
@@ -72,6 +72,10 @@ export async function handleRocs(agent, args) {
72
72
  return agent.rocs({ period: args.period });
73
73
  }
74
74
  export async function handleReceiptsList(agent, args) {
75
+ // Pass `category` through as received — an unrecognized value must still
76
+ // reach the API and get its 400 invalid_category response (#1078), not be
77
+ // silently dropped here into an unfiltered list. The cast only satisfies
78
+ // the SDK's compile-time enum narrowing; the API validates at runtime.
75
79
  return agent.receiptsList({
76
80
  period: args.period,
77
81
  category: args.category,
@@ -6,22 +6,23 @@ const OPEN = true;
6
6
  const OWN = false;
7
7
  const DESTRUCTIVE = true;
8
8
  export const TOOL_ANNOTATIONS = {
9
- // Communication
9
+ oneshot_hunt_list: read("List Soul Hunts", OPEN),
10
+ oneshot_hunt_status: read("Get Soul Hunt Status", OPEN),
11
+ oneshot_hunt_predict: write("Predict Soul Hunt", OPEN),
12
+ oneshot_hunt_collection: read("List Collected Souls", OWN),
13
+ oneshot_hunt_leaderboard: read("Soul Hunt Leaderboard", OPEN),
10
14
  oneshot_email: write("Send email", OPEN),
11
15
  oneshot_voice: write("Place a phone call", OPEN),
12
16
  oneshot_sms: write("Send a text message", OPEN),
13
- // Inbox
14
17
  oneshot_inbox_list: read("List received emails", OWN),
15
18
  oneshot_inbox_get: read("Read a received email", OWN),
16
19
  oneshot_sms_inbox_list: read("List received texts", OWN),
17
20
  oneshot_sms_inbox_get: read("Read a received text", OWN),
18
- // Inbound voice
19
21
  oneshot_voice_number_provision: write("Get a phone number", OPEN),
20
22
  oneshot_voice_numbers: read("List phone numbers", OWN),
21
23
  oneshot_voice_inbound_set: write("Set up call answering", OPEN, DESTRUCTIVE), // replaces the number's answering settings; outside callers reach it via the carrier
22
24
  oneshot_voice_inbound_disable: write("Stop answering calls", OPEN),
23
25
  oneshot_voice_inbound_calls: read("List answered calls", OWN),
24
- // Research & enrichment
25
26
  oneshot_research: read("Deep research", OPEN),
26
27
  oneshot_people_search: read("Find people", OPEN),
27
28
  oneshot_enrich_profile: read("Look up a person's profile", OPEN),
@@ -39,10 +40,8 @@ export const TOOL_ANNOTATIONS = {
39
40
  oneshot_local_search: read("Find local businesses", OPEN),
40
41
  oneshot_local_resolve: read("Look up a local business", OPEN),
41
42
  oneshot_gov_solicitations: read("Find government contracts", OPEN),
42
- // Commerce
43
43
  oneshot_commerce_search: read("Search products", OPEN),
44
44
  oneshot_commerce_buy: write("Buy a product", OPEN),
45
- // Compute orchestration
46
45
  oneshot_compute: write("Start a goal", OPEN),
47
46
  oneshot_compute_status: read("Check a goal", OWN),
48
47
  oneshot_compute_tasks: read("List a goal's tasks", OWN),
@@ -51,17 +50,13 @@ export const TOOL_ANNOTATIONS = {
51
50
  oneshot_compute_pause: write("Pause a goal", OWN),
52
51
  oneshot_compute_resume: write("Resume a goal", OWN),
53
52
  oneshot_compute_fund: write("Add budget to a goal", OWN),
54
- // Build
55
53
  oneshot_build: write("Build a website", OPEN),
56
54
  oneshot_update_build: write("Update a website", OPEN, DESTRUCTIVE), // overwrites the live site
57
- // Browser
58
55
  oneshot_browser: write("Browse and act on a website", OPEN),
59
56
  oneshot_browser_create_profile: write("Create a browser profile", OWN),
60
57
  oneshot_browser_list_profiles: read("List browser profiles", OWN),
61
58
  oneshot_browser_delete_profile: write("Delete a browser profile", OWN, DESTRUCTIVE),
62
- // Web read
63
59
  oneshot_web_read: read("Read a web page", OPEN),
64
- // LinkedIn
65
60
  oneshot_linkedin_connect: write("Connect LinkedIn", OPEN),
66
61
  oneshot_linkedin_accounts: read("List LinkedIn accounts", OWN),
67
62
  oneshot_linkedin_sync: write("Sync LinkedIn messages", OPEN), // paid; imports history into the account
@@ -72,22 +67,18 @@ export const TOOL_ANNOTATIONS = {
72
67
  oneshot_linkedin_withdraw_invitation: write("Withdraw a LinkedIn invitation", OPEN, DESTRUCTIVE),
73
68
  oneshot_linkedin_view_profile: write("View a LinkedIn profile", OPEN), // notify=true is visible to the person
74
69
  oneshot_linkedin_react: write("React to a LinkedIn post", OPEN),
75
- // Domains
76
70
  oneshot_list_domains: read("List sending domains", OWN),
77
71
  oneshot_pause_domain: write("Pause a sending domain", OWN),
78
72
  oneshot_resume_domain: write("Resume a sending domain", OWN),
79
- // Analytics
80
73
  oneshot_spend_breakdown: read("Show spending", OWN),
81
74
  oneshot_return_on_spend: read("Show return on spend", OWN),
82
75
  oneshot_return_on_spend_by_goal: read("Show return on spend by goal", OWN),
83
76
  oneshot_receipts_list: read("List receipts", OWN),
84
77
  oneshot_tag_receipt_value: write("Tag a receipt's value", OWN),
85
- // Account
86
78
  oneshot_notifications: read("List notifications", OWN),
87
79
  oneshot_mark_notification_read: write("Mark a notification read", OWN),
88
80
  oneshot_get_balance: read("Check balance", OWN),
89
81
  oneshot_budget_status: read("Check budget", OWN),
90
- // Approvals
91
82
  oneshot_approval_create: write("Ask a person to approve", OPEN),
92
83
  oneshot_approval_get: read("Check an approval", OWN),
93
84
  oneshot_approval_list: read("List approvals", OWN),
@@ -1,6 +1,5 @@
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.
1
+ // Setting the action policy is deliberately not exposed here — an agent that
2
+ // could loosen its own policy would make the policy meaningless.
4
3
  export const approvalCreateTool = {
5
4
  name: "oneshot_approval_create",
6
5
  description: "Ask a named human to approve or deny something before you do it. They get a one-tap link by email or SMS. " +
@@ -1,12 +1,12 @@
1
1
  export const buildTool = {
2
2
  name: "oneshot_build",
3
- description: "Build and deploy production websites - SaaS landing pages, portfolios, agency sites, restaurant pages, event sites, and more. Creates fully-functional sites with real hosting. Paid tool — quote provided before payment.",
3
+ description: "Build and deploy production websites - SaaS landing pages, portfolios, agency sites, restaurant pages, event sites, and more, single-page or multi-page (pages). Creates fully-functional sites with real hosting. Paid tool — quote provided before payment.",
4
4
  inputSchema: {
5
5
  type: "object",
6
6
  properties: {
7
7
  type: {
8
8
  type: "string",
9
- enum: ["saas", "portfolio", "agency", "personal", "product", "funnel", "restaurant", "event", "app", "social"],
9
+ enum: ["saas", "portfolio", "agency", "personal", "product", "funnel", "restaurant", "event"],
10
10
  description: "Build type (default: saas)",
11
11
  },
12
12
  product: {
@@ -40,6 +40,21 @@ export const buildTool = {
40
40
  items: { type: "string" },
41
41
  description: "Specific sections to include (e.g., ['hero', 'features', 'pricing', 'testimonials'])",
42
42
  },
43
+ pages: {
44
+ type: "array",
45
+ maxItems: 8,
46
+ description: "Extra pages beyond the home page, each priced separately (e.g., [{ path: '/pricing', name: 'Pricing' }, { path: '/about', name: 'About', purpose: 'Team and story' }])",
47
+ items: {
48
+ type: "object",
49
+ properties: {
50
+ path: { type: "string", description: "Route: lowercase words and hyphens, e.g. /pricing or /blog/launch" },
51
+ name: { type: "string", description: "Nav label" },
52
+ purpose: { type: "string", description: "What the page is for" },
53
+ sections: { type: "array", items: { type: "string" }, description: "Sections for this page" },
54
+ },
55
+ required: ["path", "name"],
56
+ },
57
+ },
43
58
  lead_capture: {
44
59
  type: "object",
45
60
  properties: {
@@ -98,7 +113,7 @@ export const buildTool = {
98
113
  };
99
114
  export const updateBuildTool = {
100
115
  name: "oneshot_update_build",
101
- description: "Update an existing website with new content or configuration. Requires the build_id from a previous build. Updates reuse existing hosting infrastructure at a discounted rate.",
116
+ description: "Change an existing website. With `changes` (plain-language edits, e.g. 'make the hero darker and add an FAQ page'), the site's existing code is edited and redeployed to the same URL at a flat price. With `product` and no `changes`, the site is regenerated from scratch at a discounted rate. Requires the build_id from a previous build.",
102
117
  inputSchema: {
103
118
  type: "object",
104
119
  properties: {
@@ -106,6 +121,10 @@ export const updateBuildTool = {
106
121
  type: "string",
107
122
  description: "Existing build ID to update (from previous build result)",
108
123
  },
124
+ changes: {
125
+ type: "string",
126
+ description: "Plain-language edits to apply to the existing site (keeps everything else). Max 5000 chars.",
127
+ },
109
128
  product: {
110
129
  type: "object",
111
130
  properties: {
@@ -130,7 +149,7 @@ export const updateBuildTool = {
130
149
  },
131
150
  type: {
132
151
  type: "string",
133
- enum: ["saas", "portfolio", "agency", "personal", "product", "funnel", "restaurant", "event", "app", "social"],
152
+ enum: ["saas", "portfolio", "agency", "personal", "product", "funnel", "restaurant", "event"],
134
153
  description: "Build type (optional, keeps existing if not specified)",
135
154
  },
136
155
  source_url: {
@@ -142,6 +161,21 @@ export const updateBuildTool = {
142
161
  items: { type: "string" },
143
162
  description: "Specific sections to include",
144
163
  },
164
+ pages: {
165
+ type: "array",
166
+ maxItems: 8,
167
+ description: "Extra pages beyond the home page, each priced separately (e.g., [{ path: '/pricing', name: 'Pricing' }, { path: '/about', name: 'About', purpose: 'Team and story' }])",
168
+ items: {
169
+ type: "object",
170
+ properties: {
171
+ path: { type: "string", description: "Route: lowercase words and hyphens, e.g. /pricing or /blog/launch" },
172
+ name: { type: "string", description: "Nav label" },
173
+ purpose: { type: "string", description: "What the page is for" },
174
+ sections: { type: "array", items: { type: "string" }, description: "Sections for this page" },
175
+ },
176
+ required: ["path", "name"],
177
+ },
178
+ },
145
179
  lead_capture: {
146
180
  type: "object",
147
181
  properties: {
@@ -169,7 +203,7 @@ export const updateBuildTool = {
169
203
  description: "Custom domain",
170
204
  },
171
205
  },
172
- required: ["build_id", "product"],
206
+ required: ["build_id"],
173
207
  },
174
208
  };
175
209
  export async function handleBuild(agent, args) {
@@ -184,6 +218,7 @@ export async function handleBuild(agent, args) {
184
218
  },
185
219
  source_url: args.source_url,
186
220
  sections: args.sections,
221
+ pages: args.pages,
187
222
  lead_capture: args.lead_capture,
188
223
  brand: args.brand,
189
224
  images: args.images,
@@ -192,7 +227,13 @@ export async function handleBuild(agent, args) {
192
227
  });
193
228
  }
194
229
  export async function handleUpdateBuild(agent, args) {
230
+ if (typeof args.changes === "string" && args.changes.trim()) {
231
+ return agent.refineBuild({ build_id: args.build_id, changes: args.changes });
232
+ }
195
233
  const product = args.product;
234
+ if (!product) {
235
+ throw new Error("oneshot_update_build needs either changes (to edit the site) or product (to regenerate it)");
236
+ }
196
237
  return agent.updateBuild({
197
238
  build_id: args.build_id,
198
239
  product: {
@@ -204,6 +245,7 @@ export async function handleUpdateBuild(agent, args) {
204
245
  type: args.type,
205
246
  source_url: args.source_url,
206
247
  sections: args.sections,
248
+ pages: args.pages,
207
249
  lead_capture: args.lead_capture,
208
250
  brand: args.brand,
209
251
  images: args.images,
@@ -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 huntListTool: Tool;
4
+ export declare const huntStatusTool: Tool;
5
+ export declare const huntPredictTool: Tool;
6
+ export declare const huntCollectionTool: Tool;
7
+ export declare const huntLeaderboardTool: Tool;
8
+ export declare function handleHuntList(agent: OneShot, args: Record<string, unknown>): Promise<any>;
9
+ export declare function handleHuntStatus(agent: OneShot, args: Record<string, unknown>): Promise<any>;
10
+ export declare function handleHuntPredict(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").HuntQuote>;
11
+ export declare function handleHuntCollection(agent: OneShot, args: Record<string, unknown>): Promise<any[]>;
12
+ export declare function handleHuntLeaderboard(agent: OneShot, args: Record<string, unknown>): Promise<any>;
@@ -0,0 +1,76 @@
1
+ export const huntListTool = {
2
+ name: "oneshot_hunt_list",
3
+ description: "List active or collected Soul Hunts. Free.",
4
+ inputSchema: {
5
+ type: "object",
6
+ properties: {
7
+ status: { type: "string", description: "Hunt status ('active', 'captured', 'expired', etc.)", default: "active" },
8
+ limit: { type: "number", default: 20 },
9
+ offset: { type: "number", default: 0 },
10
+ },
11
+ },
12
+ };
13
+ export const huntStatusTool = {
14
+ name: "oneshot_hunt_status",
15
+ description: "Get detailed status, rounds, and timeline for a specific Soul Hunt. Free.",
16
+ inputSchema: {
17
+ type: "object",
18
+ properties: {
19
+ hunt_id: { type: "string", description: "Hunt ID or Soul Slug" },
20
+ },
21
+ required: ["hunt_id"],
22
+ },
23
+ };
24
+ export const huntPredictTool = {
25
+ name: "oneshot_hunt_predict",
26
+ description: "Submit a prediction for a Soul Hunt. Debits a stake (USDC) from your balance based on the round tier. Paid.",
27
+ inputSchema: {
28
+ type: "object",
29
+ properties: {
30
+ hunt_id: { type: "string", description: "Hunt ID or Soul Slug" },
31
+ predicted_tool: { type: "string", description: "The exact tool the soul will use next (e.g., 'research', 'email_send')" },
32
+ predicted_action: { type: "string", description: "What the soul will do with the tool (max 500 chars)" },
33
+ predicted_motivation: { type: "string", description: "Why the soul will do this, based on its objective (max 500 chars)" },
34
+ },
35
+ required: ["hunt_id", "predicted_tool", "predicted_action", "predicted_motivation"],
36
+ },
37
+ };
38
+ export const huntCollectionTool = {
39
+ name: "oneshot_hunt_collection",
40
+ description: "View the souls you have successfully captured. Free.",
41
+ inputSchema: {
42
+ type: "object",
43
+ properties: {},
44
+ },
45
+ };
46
+ export const huntLeaderboardTool = {
47
+ name: "oneshot_hunt_leaderboard",
48
+ description: "Get the public predictor leaderboard. Free.",
49
+ inputSchema: {
50
+ type: "object",
51
+ properties: {
52
+ period: { type: "string", description: "Time period ('all', 'month', 'week')", default: "all" },
53
+ sort: { type: "string", description: "Sort column ('captures', 'score', 'earned')", default: "captures" },
54
+ limit: { type: "number", default: 25 },
55
+ offset: { type: "number", default: 0 },
56
+ },
57
+ },
58
+ };
59
+ // MCP clients may send explicit nulls for optional fields; map null to
60
+ // undefined so the SDK's defaults apply instead of serializing "null".
61
+ const opt = (v) => (v === null ? undefined : v);
62
+ export async function handleHuntList(agent, args) {
63
+ return agent.hunts.list(opt(args.status), opt(args.limit), opt(args.offset));
64
+ }
65
+ export async function handleHuntStatus(agent, args) {
66
+ return agent.hunts.status(args.hunt_id);
67
+ }
68
+ export async function handleHuntPredict(agent, args) {
69
+ return agent.hunts.predict(args.hunt_id, args.predicted_tool, args.predicted_action, args.predicted_motivation);
70
+ }
71
+ export async function handleHuntCollection(agent, args) {
72
+ return agent.hunts.collection();
73
+ }
74
+ export async function handleHuntLeaderboard(agent, args) {
75
+ return agent.hunts.leaderboard(opt(args.period), opt(args.sort), opt(args.limit), opt(args.offset));
76
+ }
@@ -22,26 +22,22 @@ import { govSolicitationsTool, handleGovSolicitations } from "./gov.js";
22
22
  import { linkedinConnectTool, linkedinAccountsTool, linkedinSyncTool, linkedinConversationsTool, linkedinMessagesTool, linkedinReplyTool, linkedinViewProfileTool, linkedinReactTool, linkedinInviteTool, linkedinWithdrawInvitationTool, handleLinkedinConnect, handleLinkedinAccounts, handleLinkedinSync, handleLinkedinConversations, handleLinkedinMessages, handleLinkedinReply, handleLinkedinViewProfile, handleLinkedinReact, handleLinkedinInvite, handleLinkedinWithdrawInvitation, } from "./linkedin.js";
23
23
  import { computeTool, computeStatusTool, computeTasksTool, computeCancelTool, computeRespondTool, computePauseTool, computeResumeTool, computeFundTool, handleCompute, handleComputeStatus, handleComputeTasks, handleComputeCancel, handleComputeRespond, handleComputePause, handleComputeResume, handleComputeFund } from "./compute.js";
24
24
  import { listDomainsTool, pauseDomainTool, resumeDomainTool, handleListDomains, handlePauseDomain, handleResumeDomain } from "./domains.js";
25
+ import { huntListTool, huntStatusTool, huntPredictTool, huntCollectionTool, huntLeaderboardTool, handleHuntList, handleHuntStatus, handleHuntPredict, handleHuntCollection, handleHuntLeaderboard } from "./hunt.js";
25
26
  import { TOOL_ANNOTATIONS } from "./annotations.js";
26
27
  import { spendBreakdownTool, rocsTool, rocsByGoalTool, receiptsListTool, tagReceiptValueTool, handleSpendBreakdown, handleRocs, handleRocsByGoal, handleReceiptsList, handleTagReceiptValue } from "./analytics.js";
27
- // All available tools, before annotations
28
28
  const toolDefinitions = [
29
- // Communication
30
29
  emailTool,
31
30
  voiceTool,
32
31
  smsTool,
33
- // Inbox
34
32
  inboxListTool,
35
33
  inboxGetTool,
36
34
  smsInboxListTool,
37
35
  smsInboxGetTool,
38
- // Inbound voice
39
36
  voiceNumberProvisionTool,
40
37
  voiceNumbersTool,
41
38
  voiceInboundSetTool,
42
39
  voiceInboundDisableTool,
43
40
  voiceInboundCallsTool,
44
- // Research & Enrichment
45
41
  researchTool,
46
42
  peopleSearchTool,
47
43
  enrichProfileTool,
@@ -59,10 +55,8 @@ const toolDefinitions = [
59
55
  localSearchTool,
60
56
  localResolveTool,
61
57
  govSolicitationsTool,
62
- // Commerce
63
58
  commerceSearchTool,
64
59
  commerceBuyTool,
65
- // Compute orchestration
66
60
  computeTool,
67
61
  computeStatusTool,
68
62
  computeTasksTool,
@@ -71,17 +65,13 @@ const toolDefinitions = [
71
65
  computePauseTool,
72
66
  computeResumeTool,
73
67
  computeFundTool,
74
- // Build
75
68
  buildTool,
76
69
  updateBuildTool,
77
- // Browser
78
70
  browserTool,
79
71
  browserCreateProfileTool,
80
72
  browserListProfilesTool,
81
73
  browserDeleteProfileTool,
82
- // Web Read
83
74
  webReadTool,
84
- // LinkedIn (human-connected account)
85
75
  linkedinConnectTool,
86
76
  linkedinAccountsTool,
87
77
  linkedinSyncTool,
@@ -91,22 +81,23 @@ const toolDefinitions = [
91
81
  linkedinInviteTool, linkedinWithdrawInvitationTool,
92
82
  linkedinViewProfileTool,
93
83
  linkedinReactTool,
94
- // Domains
95
84
  listDomainsTool,
96
85
  pauseDomainTool,
97
86
  resumeDomainTool,
98
- // Analytics
87
+ huntListTool,
88
+ huntStatusTool,
89
+ huntPredictTool,
90
+ huntCollectionTool,
91
+ huntLeaderboardTool,
99
92
  spendBreakdownTool,
100
93
  rocsTool,
101
94
  rocsByGoalTool,
102
95
  receiptsListTool,
103
96
  tagReceiptValueTool,
104
- // Account
105
97
  notificationsTool,
106
98
  markReadTool,
107
99
  getBalanceTool,
108
100
  budgetStatusTool,
109
- // Approvals
110
101
  approvalCreateTool,
111
102
  approvalGetTool,
112
103
  approvalListTool,
@@ -121,24 +112,19 @@ export const tools = toolDefinitions.map((tool) => {
121
112
  throw new Error(`Tool ${tool.name} has no annotations — add it to tools/annotations.ts`);
122
113
  return { ...tool, title: hints.title, annotations: { ...hints } };
123
114
  });
124
- // Tool handlers map
125
115
  const handlers = {
126
- // Communication
127
116
  "oneshot_email": handleEmail,
128
117
  "oneshot_voice": handleVoice,
129
118
  "oneshot_sms": handleSms,
130
- // Inbox
131
119
  "oneshot_inbox_list": handleInboxList,
132
120
  "oneshot_inbox_get": handleInboxGet,
133
121
  "oneshot_sms_inbox_list": handleSmsInboxList,
134
122
  "oneshot_sms_inbox_get": handleSmsInboxGet,
135
- // Inbound voice
136
123
  "oneshot_voice_number_provision": handleVoiceNumberProvision,
137
124
  "oneshot_voice_numbers": handleVoiceNumbers,
138
125
  "oneshot_voice_inbound_set": handleVoiceInboundSet,
139
126
  "oneshot_voice_inbound_disable": handleVoiceInboundDisable,
140
127
  "oneshot_voice_inbound_calls": handleVoiceInboundCalls,
141
- // Research & Enrichment
142
128
  "oneshot_research": handleResearch,
143
129
  "oneshot_people_search": handlePeopleSearch,
144
130
  "oneshot_enrich_profile": handleEnrichProfile,
@@ -156,10 +142,8 @@ const handlers = {
156
142
  "oneshot_local_search": handleLocalSearch,
157
143
  "oneshot_local_resolve": handleLocalResolve,
158
144
  "oneshot_gov_solicitations": handleGovSolicitations,
159
- // Commerce
160
145
  "oneshot_commerce_search": handleCommerceSearch,
161
146
  "oneshot_commerce_buy": handleCommerceBuy,
162
- // Compute orchestration
163
147
  "oneshot_compute": handleCompute,
164
148
  "oneshot_compute_status": handleComputeStatus,
165
149
  "oneshot_compute_tasks": handleComputeTasks,
@@ -168,17 +152,13 @@ const handlers = {
168
152
  "oneshot_compute_pause": handleComputePause,
169
153
  "oneshot_compute_resume": handleComputeResume,
170
154
  "oneshot_compute_fund": handleComputeFund,
171
- // Build
172
155
  "oneshot_build": handleBuild,
173
156
  "oneshot_update_build": handleUpdateBuild,
174
- // Browser
175
157
  "oneshot_browser": handleBrowser,
176
158
  "oneshot_browser_create_profile": handleBrowserCreateProfile,
177
159
  "oneshot_browser_list_profiles": handleBrowserListProfiles,
178
160
  "oneshot_browser_delete_profile": handleBrowserDeleteProfile,
179
- // Web Read
180
161
  "oneshot_web_read": handleWebRead,
181
- // LinkedIn (human-connected account)
182
162
  "oneshot_linkedin_connect": handleLinkedinConnect,
183
163
  "oneshot_linkedin_accounts": handleLinkedinAccounts,
184
164
  "oneshot_linkedin_sync": handleLinkedinSync,
@@ -189,22 +169,23 @@ const handlers = {
189
169
  "oneshot_linkedin_withdraw_invitation": handleLinkedinWithdrawInvitation,
190
170
  "oneshot_linkedin_view_profile": handleLinkedinViewProfile,
191
171
  "oneshot_linkedin_react": handleLinkedinReact,
192
- // Domains
193
172
  "oneshot_list_domains": handleListDomains,
194
173
  "oneshot_pause_domain": handlePauseDomain,
195
174
  "oneshot_resume_domain": handleResumeDomain,
196
- // Analytics
175
+ "oneshot_hunt_list": handleHuntList,
176
+ "oneshot_hunt_status": handleHuntStatus,
177
+ "oneshot_hunt_predict": handleHuntPredict,
178
+ "oneshot_hunt_collection": handleHuntCollection,
179
+ "oneshot_hunt_leaderboard": handleHuntLeaderboard,
197
180
  "oneshot_spend_breakdown": handleSpendBreakdown,
198
181
  "oneshot_return_on_spend": handleRocs,
199
182
  "oneshot_return_on_spend_by_goal": handleRocsByGoal,
200
183
  "oneshot_receipts_list": handleReceiptsList,
201
184
  "oneshot_tag_receipt_value": handleTagReceiptValue,
202
- // Account
203
185
  "oneshot_notifications": handleNotifications,
204
186
  "oneshot_mark_notification_read": handleMarkRead,
205
187
  "oneshot_get_balance": handleGetBalance,
206
188
  "oneshot_budget_status": handleBudgetStatus,
207
- // Approvals
208
189
  "oneshot_approval_create": handleApprovalCreate,
209
190
  "oneshot_approval_get": handleApprovalGet,
210
191
  "oneshot_approval_list": handleApprovalList,
@@ -1,10 +1,8 @@
1
1
  /**
2
2
  * LinkedIn messaging through a human-connected account (issue #756).
3
- *
4
- * The human connects their own LinkedIn account via a hosted login link and
5
- * grants specific actions (read, reply, view_profile, react, invite). Reconnect and
6
- * revoke are deliberately NOT exposed as MCP tools — a human decides those
7
- * from the application that owns the account.
3
+ * The human grants specific actions (read, reply, view_profile, react, invite)
4
+ * via a hosted login link; reconnect/revoke are deliberately NOT exposed here —
5
+ * a human decides those from the application that owns the account.
8
6
  */
9
7
  const GRANT_ACTIONS = ["read", "reply", "view_profile", "react", "invite", "comment"];
10
8
  export const linkedinConnectTool = {
@@ -72,7 +72,6 @@ export const personInteractionsTool = {
72
72
  required: ["social_media_url"],
73
73
  },
74
74
  };
75
- // Handlers
76
75
  /** Deep person research fans out across several providers; the SDK's 120s default was too short. */
77
76
  export const DEEP_RESEARCH_PERSON_TIMEOUT_SEC = 300;
78
77
  export async function handleDeepResearchPerson(agent, args) {
@@ -2,10 +2,9 @@ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
2
  import type { OneShot } from "@oneshot-agent/sdk";
3
3
  export declare const researchTool: Tool;
4
4
  /**
5
- * Wait budget per depth. The SDK's default is 120s, but deep research runs
6
- * 2–5 minutes (as the tool description says), so every deep call used to end
7
- * in JobTimeoutError while the job kept running. Results are pushed the
8
- * moment they exist, so a generous ceiling costs nothing on fast jobs.
5
+ * The SDK's 120s default is too short for deep research (runs 2-5min);
6
+ * results are pushed the moment they exist, so a generous ceiling costs
7
+ * nothing on fast jobs.
9
8
  */
10
9
  export declare const RESEARCH_TIMEOUT_SEC: Record<"quick" | "deep", number>;
11
10
  export declare function handleResearch(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").ResearchResult>;
@@ -27,10 +27,9 @@ export const researchTool = {
27
27
  },
28
28
  };
29
29
  /**
30
- * Wait budget per depth. The SDK's default is 120s, but deep research runs
31
- * 2–5 minutes (as the tool description says), so every deep call used to end
32
- * in JobTimeoutError while the job kept running. Results are pushed the
33
- * moment they exist, so a generous ceiling costs nothing on fast jobs.
30
+ * The SDK's 120s default is too short for deep research (runs 2-5min);
31
+ * results are pushed the moment they exist, so a generous ceiling costs
32
+ * nothing on fast jobs.
34
33
  */
35
34
  export const RESEARCH_TIMEOUT_SEC = { quick: 180, deep: 600 };
36
35
  export async function handleResearch(agent, args) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oneshot-agent/mcp-server",
3
- "version": "0.30.1",
4
- "description": "MCP server for OneShot - 73 tools for AI agents",
3
+ "version": "0.33.0",
4
+ "description": "MCP server for OneShot - 78 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.44.0",
28
+ "@oneshot-agent/sdk": "^0.47.0",
29
29
  "zod": "3.25.76"
30
30
  },
31
31
  "devDependencies": {