@oneshot-agent/mcp-server 0.28.0 → 0.29.1
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 +2 -2
- package/dist/index.js +1 -1
- package/dist/tools/analytics.d.ts +5 -0
- package/dist/tools/analytics.js +13 -5
- package/dist/tools/annotations.d.ts +16 -0
- package/dist/tools/annotations.js +96 -0
- package/dist/tools/index.js +16 -5
- package/dist/tools/voice-inbound.js +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -97,7 +97,7 @@ Get CDP credentials at [Coinbase Agentic Wallet](https://docs.cdp.coinbase.com/a
|
|
|
97
97
|
|
|
98
98
|
### Read authentication
|
|
99
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
|
|
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
101
|
|
|
102
102
|
## Remote (hosted)
|
|
103
103
|
|
|
@@ -226,7 +226,7 @@ instead of the wallet variables for a credits-only session on your own machine.
|
|
|
226
226
|
| Tool | Description |
|
|
227
227
|
|------|-------------|
|
|
228
228
|
| `oneshot_spend_breakdown` | Spend by tool/category over a period |
|
|
229
|
-
| `
|
|
229
|
+
| `oneshot_return_on_spend` | Return on spend: cost vs. value produced |
|
|
230
230
|
| `oneshot_receipts_list` | List spend receipts |
|
|
231
231
|
| `oneshot_tag_receipt_value` | Tag a receipt with the value it generated |
|
|
232
232
|
|
package/dist/index.js
CHANGED
|
@@ -52,7 +52,7 @@ async function main() {
|
|
|
52
52
|
// Create MCP server
|
|
53
53
|
const server = new Server({
|
|
54
54
|
name: "oneshot-mcp",
|
|
55
|
-
version: "0.
|
|
55
|
+
version: "0.29.1", // keep in sync with package.json; guarded by version.test.ts
|
|
56
56
|
}, {
|
|
57
57
|
capabilities: {
|
|
58
58
|
tools: {},
|
|
@@ -10,3 +10,8 @@ export declare function handleRocs(agent: OneShot, args: Record<string, unknown>
|
|
|
10
10
|
export declare function handleReceiptsList(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").ReceiptsListResult>;
|
|
11
11
|
export declare function handleRocsByGoal(agent: OneShot, args: Record<string, unknown>): Promise<import("@oneshot-agent/sdk").RoCSByGoalResult>;
|
|
12
12
|
export declare function handleTagReceiptValue(agent: OneShot, args: Record<string, unknown>): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Old tool names (renamed in 0.29.1 because "rocs" was unclear to users and
|
|
15
|
+
* to ChatGPT's review scan). Still dispatched, never listed.
|
|
16
|
+
*/
|
|
17
|
+
export declare const LEGACY_TOOL_ALIASES: Record<string, (agent: OneShot, args: Record<string, unknown>) => Promise<unknown>>;
|
package/dist/tools/analytics.js
CHANGED
|
@@ -9,8 +9,8 @@ export const spendBreakdownTool = {
|
|
|
9
9
|
},
|
|
10
10
|
};
|
|
11
11
|
export const rocsTool = {
|
|
12
|
-
name: "
|
|
13
|
-
description: "Get
|
|
12
|
+
name: "oneshot_return_on_spend",
|
|
13
|
+
description: "Get the agent's return on spend over a period: what its tool calls cost compared with the value they produced (return on compute spend). Free.",
|
|
14
14
|
inputSchema: {
|
|
15
15
|
type: "object",
|
|
16
16
|
properties: {
|
|
@@ -54,9 +54,9 @@ export const tagReceiptValueTool = {
|
|
|
54
54
|
},
|
|
55
55
|
};
|
|
56
56
|
export const rocsByGoalTool = {
|
|
57
|
-
name: "
|
|
58
|
-
description: "
|
|
59
|
-
"Answers 'what did this
|
|
57
|
+
name: "oneshot_return_on_spend_by_goal",
|
|
58
|
+
description: "Return on spend per goal: what each goal cost (receipts) compared with the value it produced (tagged outcomes), grouped by goal_id. " +
|
|
59
|
+
"Answers 'what did this goal cost vs. earn' in one query. Free.",
|
|
60
60
|
inputSchema: {
|
|
61
61
|
type: "object",
|
|
62
62
|
properties: {
|
|
@@ -98,3 +98,11 @@ export async function handleTagReceiptValue(agent, args) {
|
|
|
98
98
|
label: args.label,
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Old tool names (renamed in 0.29.1 because "rocs" was unclear to users and
|
|
103
|
+
* to ChatGPT's review scan). Still dispatched, never listed.
|
|
104
|
+
*/
|
|
105
|
+
export const LEGACY_TOOL_ALIASES = {
|
|
106
|
+
oneshot_rocs: handleRocs,
|
|
107
|
+
oneshot_rocs_by_goal: handleRocsByGoal,
|
|
108
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* MCP tool annotations for every tool (#999). ChatGPT requires all three hints
|
|
4
|
+
* on every tool, and uses them: a tool that is not read-only asks the user to
|
|
5
|
+
* confirm before it runs.
|
|
6
|
+
*
|
|
7
|
+
* readOnlyHint true = retrieval only (paid lookups included — the only
|
|
8
|
+
* side effect is our own billing)
|
|
9
|
+
* destructiveHint true = deletes, overwrites or revokes something. Sends are
|
|
10
|
+
* additive writes, so false — like any mail app's send.
|
|
11
|
+
* openWorldHint true = reaches the public web or third parties;
|
|
12
|
+
* false = only the caller's own OneShot account data.
|
|
13
|
+
*/
|
|
14
|
+
type Hints = Required<Pick<ToolAnnotations, "title" | "readOnlyHint" | "destructiveHint" | "openWorldHint">>;
|
|
15
|
+
export declare const TOOL_ANNOTATIONS: Record<string, Hints>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/** Retrieval only. */
|
|
2
|
+
const read = (title, openWorld) => ({ title, readOnlyHint: true, destructiveHint: false, openWorldHint: openWorld });
|
|
3
|
+
/** Changes something. `destructive` only for delete / overwrite / revoke. */
|
|
4
|
+
const write = (title, openWorld, destructive = false) => ({ title, readOnlyHint: false, destructiveHint: destructive, openWorldHint: openWorld });
|
|
5
|
+
const OPEN = true;
|
|
6
|
+
const OWN = false;
|
|
7
|
+
const DESTRUCTIVE = true;
|
|
8
|
+
export const TOOL_ANNOTATIONS = {
|
|
9
|
+
// Communication
|
|
10
|
+
oneshot_email: write("Send email", OPEN),
|
|
11
|
+
oneshot_voice: write("Place a phone call", OPEN),
|
|
12
|
+
oneshot_sms: write("Send a text message", OPEN),
|
|
13
|
+
// Inbox
|
|
14
|
+
oneshot_inbox_list: read("List received emails", OWN),
|
|
15
|
+
oneshot_inbox_get: read("Read a received email", OWN),
|
|
16
|
+
oneshot_sms_inbox_list: read("List received texts", OWN),
|
|
17
|
+
oneshot_sms_inbox_get: read("Read a received text", OWN),
|
|
18
|
+
// Inbound voice
|
|
19
|
+
oneshot_voice_number_provision: write("Get a phone number", OPEN),
|
|
20
|
+
oneshot_voice_numbers: read("List phone numbers", OWN),
|
|
21
|
+
oneshot_voice_inbound_set: write("Set up call answering", OWN, DESTRUCTIVE), // replaces the number's answering settings
|
|
22
|
+
oneshot_voice_inbound_disable: write("Stop answering calls", OWN),
|
|
23
|
+
oneshot_voice_inbound_calls: read("List answered calls", OWN),
|
|
24
|
+
// Research & enrichment
|
|
25
|
+
oneshot_research: read("Deep research", OPEN),
|
|
26
|
+
oneshot_people_search: read("Find people", OPEN),
|
|
27
|
+
oneshot_enrich_profile: read("Look up a person's profile", OPEN),
|
|
28
|
+
oneshot_find_email: read("Find a work email", OPEN),
|
|
29
|
+
oneshot_verify_email: read("Verify an email address", OPEN),
|
|
30
|
+
oneshot_web_search: read("Web search", OPEN),
|
|
31
|
+
oneshot_deep_research_person: read("Research a person", OPEN),
|
|
32
|
+
oneshot_social_profiles: read("Find social profiles", OPEN),
|
|
33
|
+
oneshot_article_search: read("Find articles about a person", OPEN),
|
|
34
|
+
oneshot_person_newsfeed: read("Get a person's recent posts", OPEN),
|
|
35
|
+
oneshot_person_interests: read("Summarize a person's interests", OPEN),
|
|
36
|
+
oneshot_person_interactions: read("Find a person's interactions", OPEN),
|
|
37
|
+
oneshot_company_search: read("Find companies", OPEN),
|
|
38
|
+
oneshot_enrich_company: read("Look up a company", OPEN),
|
|
39
|
+
oneshot_local_search: read("Find local businesses", OPEN),
|
|
40
|
+
oneshot_local_resolve: read("Look up a local business", OPEN),
|
|
41
|
+
oneshot_gov_solicitations: read("Find government contracts", OPEN),
|
|
42
|
+
// Commerce
|
|
43
|
+
oneshot_commerce_search: read("Search products", OPEN),
|
|
44
|
+
oneshot_commerce_buy: write("Buy a product", OPEN),
|
|
45
|
+
// Compute orchestration
|
|
46
|
+
oneshot_compute: write("Start a goal", OPEN),
|
|
47
|
+
oneshot_compute_status: read("Check a goal", OWN),
|
|
48
|
+
oneshot_compute_tasks: read("List a goal's tasks", OWN),
|
|
49
|
+
oneshot_compute_cancel: write("Cancel a goal", OWN, DESTRUCTIVE),
|
|
50
|
+
oneshot_compute_respond: write("Answer a goal's question", OWN),
|
|
51
|
+
oneshot_compute_pause: write("Pause a goal", OWN),
|
|
52
|
+
oneshot_compute_resume: write("Resume a goal", OWN),
|
|
53
|
+
oneshot_compute_fund: write("Add budget to a goal", OWN),
|
|
54
|
+
// Build
|
|
55
|
+
oneshot_build: write("Build a website", OPEN),
|
|
56
|
+
oneshot_update_build: write("Update a website", OPEN, DESTRUCTIVE), // overwrites the live site
|
|
57
|
+
// Browser
|
|
58
|
+
oneshot_browser: write("Browse and act on a website", OPEN),
|
|
59
|
+
oneshot_browser_create_profile: write("Create a browser profile", OWN),
|
|
60
|
+
oneshot_browser_list_profiles: read("List browser profiles", OWN),
|
|
61
|
+
oneshot_browser_delete_profile: write("Delete a browser profile", OWN, DESTRUCTIVE),
|
|
62
|
+
// Web read
|
|
63
|
+
oneshot_web_read: read("Read a web page", OPEN),
|
|
64
|
+
// LinkedIn
|
|
65
|
+
oneshot_linkedin_connect: write("Connect LinkedIn", OPEN),
|
|
66
|
+
oneshot_linkedin_accounts: read("List LinkedIn accounts", OWN),
|
|
67
|
+
oneshot_linkedin_sync: write("Sync LinkedIn messages", OPEN), // paid; imports history into the account
|
|
68
|
+
oneshot_linkedin_conversations: read("List LinkedIn conversations", OWN),
|
|
69
|
+
oneshot_linkedin_messages: read("Read LinkedIn messages", OWN),
|
|
70
|
+
oneshot_linkedin_reply: write("Send a LinkedIn message", OPEN),
|
|
71
|
+
oneshot_linkedin_invite: write("Send a LinkedIn invitation", OPEN),
|
|
72
|
+
oneshot_linkedin_withdraw_invitation: write("Withdraw a LinkedIn invitation", OPEN, DESTRUCTIVE),
|
|
73
|
+
oneshot_linkedin_view_profile: write("View a LinkedIn profile", OPEN), // notify=true is visible to the person
|
|
74
|
+
oneshot_linkedin_react: write("React to a LinkedIn post", OPEN),
|
|
75
|
+
// Domains
|
|
76
|
+
oneshot_list_domains: read("List sending domains", OWN),
|
|
77
|
+
oneshot_pause_domain: write("Pause a sending domain", OWN),
|
|
78
|
+
oneshot_resume_domain: write("Resume a sending domain", OWN),
|
|
79
|
+
// Analytics
|
|
80
|
+
oneshot_spend_breakdown: read("Show spending", OWN),
|
|
81
|
+
oneshot_return_on_spend: read("Show return on spend", OWN),
|
|
82
|
+
oneshot_return_on_spend_by_goal: read("Show return on spend by goal", OWN),
|
|
83
|
+
oneshot_receipts_list: read("List receipts", OWN),
|
|
84
|
+
oneshot_tag_receipt_value: write("Tag a receipt's value", OWN),
|
|
85
|
+
// Account
|
|
86
|
+
oneshot_notifications: read("List notifications", OWN),
|
|
87
|
+
oneshot_mark_notification_read: write("Mark a notification read", OWN),
|
|
88
|
+
oneshot_get_balance: read("Check balance", OWN),
|
|
89
|
+
oneshot_budget_status: read("Check budget", OWN),
|
|
90
|
+
// Approvals
|
|
91
|
+
oneshot_approval_create: write("Ask a person to approve", OPEN),
|
|
92
|
+
oneshot_approval_get: read("Check an approval", OWN),
|
|
93
|
+
oneshot_approval_list: read("List approvals", OWN),
|
|
94
|
+
oneshot_approval_cancel: write("Cancel an approval", OWN, DESTRUCTIVE),
|
|
95
|
+
oneshot_action_policy: read("Show approval rules", OWN),
|
|
96
|
+
};
|
package/dist/tools/index.js
CHANGED
|
@@ -22,9 +22,10 @@ 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 {
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
import { TOOL_ANNOTATIONS } from "./annotations.js";
|
|
26
|
+
import { spendBreakdownTool, rocsTool, rocsByGoalTool, receiptsListTool, tagReceiptValueTool, handleSpendBreakdown, handleRocs, handleRocsByGoal, handleReceiptsList, handleTagReceiptValue, LEGACY_TOOL_ALIASES } from "./analytics.js";
|
|
27
|
+
// All available tools, before annotations
|
|
28
|
+
const toolDefinitions = [
|
|
28
29
|
// Communication
|
|
29
30
|
emailTool,
|
|
30
31
|
voiceTool,
|
|
@@ -112,6 +113,14 @@ export const tools = [
|
|
|
112
113
|
approvalCancelTool,
|
|
113
114
|
actionPolicyGetTool,
|
|
114
115
|
];
|
|
116
|
+
// Every tool carries a human title and the three MCP hints clients rely on
|
|
117
|
+
// (ChatGPT confirms any tool that is not read-only). See annotations.ts.
|
|
118
|
+
export const tools = toolDefinitions.map((tool) => {
|
|
119
|
+
const hints = TOOL_ANNOTATIONS[tool.name];
|
|
120
|
+
if (!hints)
|
|
121
|
+
throw new Error(`Tool ${tool.name} has no annotations — add it to tools/annotations.ts`);
|
|
122
|
+
return { ...tool, title: hints.title, annotations: { ...hints } };
|
|
123
|
+
});
|
|
115
124
|
// Tool handlers map
|
|
116
125
|
const handlers = {
|
|
117
126
|
// Communication
|
|
@@ -186,8 +195,10 @@ const handlers = {
|
|
|
186
195
|
"oneshot_resume_domain": handleResumeDomain,
|
|
187
196
|
// Analytics
|
|
188
197
|
"oneshot_spend_breakdown": handleSpendBreakdown,
|
|
189
|
-
"
|
|
190
|
-
"
|
|
198
|
+
"oneshot_return_on_spend": handleRocs,
|
|
199
|
+
"oneshot_return_on_spend_by_goal": handleRocsByGoal,
|
|
200
|
+
// Pre-0.29.1 names: callable, never listed, so existing clients keep working.
|
|
201
|
+
...LEGACY_TOOL_ALIASES,
|
|
191
202
|
"oneshot_receipts_list": handleReceiptsList,
|
|
192
203
|
"oneshot_tag_receipt_value": handleTagReceiptValue,
|
|
193
204
|
// Account
|
|
@@ -2,7 +2,7 @@ export const voiceNumberProvisionTool = {
|
|
|
2
2
|
name: "oneshot_voice_number_provision",
|
|
3
3
|
description: "Get this agent a phone number without placing a call, so it can answer calls (then use oneshot_voice_inbound_set). " +
|
|
4
4
|
"Returns the existing number for free; otherwise buys one and charges the one-time phone registration fee from prepaid credits. " +
|
|
5
|
-
"Fails with 402 and buys nothing when credits are too low.
|
|
5
|
+
"Fails with 402 and buys nothing when credits are too low. Needs a wallet or OAuth session; a plain agent access token cannot buy numbers.",
|
|
6
6
|
inputSchema: { type: "object", properties: {} },
|
|
7
7
|
};
|
|
8
8
|
export const voiceNumbersTool = {
|
|
@@ -15,7 +15,7 @@ export const voiceInboundSetTool = {
|
|
|
15
15
|
description: "Make one of the agent's numbers answer its own calls. Replaces the whole inbound config. " +
|
|
16
16
|
"During business hours the assistant follows `prompt`; after hours it takes a message, transfers, or declines. " +
|
|
17
17
|
"Calls are paid from prepaid credits per started minute and are declined when credits cannot cover the minimum fee. " +
|
|
18
|
-
"
|
|
18
|
+
"Needs a wallet or OAuth session; a plain agent access token can only read these settings.",
|
|
19
19
|
inputSchema: {
|
|
20
20
|
type: "object",
|
|
21
21
|
properties: {
|
|
@@ -56,7 +56,7 @@ export const voiceInboundSetTool = {
|
|
|
56
56
|
};
|
|
57
57
|
export const voiceInboundDisableTool = {
|
|
58
58
|
name: "oneshot_voice_inbound_disable",
|
|
59
|
-
description: "Stop answering calls to one of the agent's numbers. The settings are kept, disabled. Free.
|
|
59
|
+
description: "Stop answering calls to one of the agent's numbers. The settings are kept, disabled. Free. Needs a wallet or OAuth session.",
|
|
60
60
|
inputSchema: {
|
|
61
61
|
type: "object",
|
|
62
62
|
properties: { phone_number_id: { type: "string", description: "Number id from oneshot_voice_numbers" } },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneshot-agent/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.1",
|
|
4
4
|
"description": "MCP server for OneShot - 73 tools for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@coinbase/cdp-sdk": "1.45.0",
|
|
27
27
|
"@modelcontextprotocol/sdk": "1.27.1",
|
|
28
|
-
"@oneshot-agent/sdk": "^0.
|
|
28
|
+
"@oneshot-agent/sdk": "^0.43.0",
|
|
29
29
|
"zod": "3.25.76"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|