@oneshot-agent/mcp-server 0.44.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -84,6 +84,7 @@ Every tool is named `oneshot_<name>`. Below are the names.
84
84
  | [Think](https://docs.oneshotagent.com/api-reference/research) | `research` `predict` `solve` |
85
85
  | [Web and buying](https://docs.oneshotagent.com/api-reference/web-search) | `web_search` `web_read` `browser` `product_find` `commerce_buy` |
86
86
  | [Physical mail](https://docs.oneshotagent.com/api-reference/physical-mail/overview) | `physical_mail_upload` `physical_mail_validate_address` `physical_mail_preview` `physical_mail_quote` `physical_mail_approve` `physical_mail_send` `physical_mail_recover` `physical_mail_order` `physical_mail_cancel` |
87
+ | [Connected systems](https://docs.oneshotagent.com/api-reference/connections/overview) | `connections_list` `ledger_invoices` `ledger_bills` `ledger_reports` `crm_accounts` `crm_contacts` `crm_opportunities` `tax_rates` `tax_calculate` `shipping_shipments` `shipping_tracking` `shipping_rates` `procurement_transactions` `procurement_bills` `procurement_suppliers` |
87
88
  | [LinkedIn](https://docs.oneshotagent.com/api-reference/linkedin/overview) | `linkedin_connect` `linkedin_accounts` `linkedin_invite` `linkedin_message` `linkedin_reply` and more |
88
89
  | [Build](https://docs.oneshotagent.com/api-reference/build/create) | `build` `update_build` |
89
90
  | [Goals](https://docs.oneshotagent.com/api-reference/compute/create) | `compute` `compute_status` `compute_tasks` `compute_respond` `compute_pause` `compute_resume` `compute_fund` `compute_cancel` |
@@ -140,6 +141,16 @@ wallet. The server signs it for you. A read with no proof and no valid token is
140
141
  - [Python SDK (Core)](https://pypi.org/project/oneshot-python/)
141
142
  - [GitHub](https://github.com/oneshot-agent/sdk)
142
143
 
144
+ ## Tool discovery
145
+
146
+ The MCP catalog contains 172 tools. `oneshot_discover_tools` is a free, read-only
147
+ search over the tools your token can call. Call it with no arguments for category
148
+ counts, `{ "query": "send a printed letter" }` to search, or `{ "category": "email" }`
149
+ to browse. Results contain public tool names, purposes and required inputs.
150
+ Category pages contain up to five tools; pass `nextCursor` as `cursor` with the
151
+ same query and category. `nextCursor: null` marks the end. Both stdio and hosted
152
+ `/mcp` expose it as an ordinary tool.
153
+
143
154
  ## License
144
155
 
145
156
  MIT
package/dist/index.js CHANGED
@@ -50,7 +50,7 @@ async function main() {
50
50
  const agent = await initAgent();
51
51
  const server = new Server({
52
52
  name: "oneshot-mcp",
53
- version: "0.44.0", // keep in sync with package.json; guarded by version.test.ts
53
+ version: "0.45.0", // keep in sync with package.json; guarded by version.test.ts
54
54
  }, {
55
55
  capabilities: {
56
56
  tools: {},
@@ -3,10 +3,13 @@ import { LOOKUP_MANIFEST, ROUTE_MANIFEST } from "./lookup-manifest.generated.js"
3
3
  const read = (title, openWorld) => ({ title, readOnlyHint: true, destructiveHint: false, openWorldHint: openWorld });
4
4
  /** Changes something. `destructive` only for delete / overwrite / revoke. */
5
5
  const write = (title, openWorld, destructive = false) => ({ title, readOnlyHint: false, destructiveHint: destructive, openWorldHint: openWorld });
6
+ /** The connected-system reads (#2403): paid, but each reads the caller's own connected business system, so closed-world. */
7
+ const CONNECTED_SYSTEM_READ = /^\/v1\/tools\/(ledger|crm|shipping|tax|procurement)\//;
6
8
  const OPEN = true;
7
9
  const OWN = false;
8
10
  const DESTRUCTIVE = true;
9
11
  export const TOOL_ANNOTATIONS = {
12
+ oneshot_discover_tools: read("Discover tools", OWN),
10
13
  oneshot_solve: read("Solve", OWN),
11
14
  oneshot_predict: read("Predict", OWN),
12
15
  oneshot_hunt_list: read("List Soul Hunts", OPEN),
@@ -94,12 +97,15 @@ export const TOOL_ANNOTATIONS = {
94
97
  oneshot_approval_list: read("List approvals", OWN),
95
98
  oneshot_approval_cancel: write("Cancel an approval", OWN, DESTRUCTIVE),
96
99
  oneshot_action_policy: read("Show approval rules", OWN),
100
+ // Connected systems (#2403): the list is hand-written; the reads come from the route manifest below.
101
+ oneshot_connections_list: read("List connections", OWN),
97
102
  // The lookup tools come from the generated manifest: paid retrieval over public or third-party data (#1445).
98
103
  ...Object.fromEntries(LOOKUP_MANIFEST.map((entry) => [`oneshot_${entry.name}`, read(entry.title, OPEN)])),
99
104
  // The declared routes come from the same manifest (#1580). A read of the agent's own data is closed-world; a paid
100
- // read (Changes, Benchmark) reaches recorded third-party data; a write changes something, and a DELETE removes it.
105
+ // read (Changes, Benchmark) reaches recorded third-party data, a connected-system read the caller's own system; a
106
+ // write changes something, and a DELETE removes it.
101
107
  ...Object.fromEntries(ROUTE_MANIFEST.map((entry) => {
102
- const own = !entry.paid;
108
+ const own = !entry.paid || CONNECTED_SYSTEM_READ.test(entry.path);
103
109
  return [
104
110
  `oneshot_${entry.name}`,
105
111
  entry.readOnly ? read(entry.title, own ? OWN : OPEN) : write(entry.title, own ? OWN : OPEN, entry.method === "DELETE"),
@@ -0,0 +1,11 @@
1
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
+ import type { OneShot } from "@oneshot-agent/sdk";
3
+ /**
4
+ * The agent's connections (#2403). Hand-written because `GET /v1/connections` is not a declared route: the
5
+ * connected-system read tools (`oneshot_ledger_*`, `oneshot_crm_*`, `oneshot_shipping_*`, `oneshot_tax_*`,
6
+ * `oneshot_procurement_*`) are generated from their routes and each tells the model to call this one first.
7
+ * Connecting and revoking stay in the console.
8
+ */
9
+ export declare const connectionsListTool: Tool;
10
+ /** The route's answer as it is: `{ connections: [...] }`. Through `route()`, which the published SDK range already has. */
11
+ export declare function handleConnectionsList(agent: OneShot, _args: Record<string, unknown>): Promise<unknown>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The agent's connections (#2403). Hand-written because `GET /v1/connections` is not a declared route: the
3
+ * connected-system read tools (`oneshot_ledger_*`, `oneshot_crm_*`, `oneshot_shipping_*`, `oneshot_tax_*`,
4
+ * `oneshot_procurement_*`) are generated from their routes and each tells the model to call this one first.
5
+ * Connecting and revoking stay in the console.
6
+ */
7
+ export const connectionsListTool = {
8
+ name: "oneshot_connections_list",
9
+ description: "List the agent's connections to business systems (accounting, CRM, shipping, tax, spend) and GitHub. " +
10
+ "Returns each connection's id, name, kind, system, account_label and status (only an active one can be read). " +
11
+ "Call it before any connected-system read: pick the connection by system and account_label and pass its id as connection_id. " +
12
+ "Connections are added and revoked in the console. Free.",
13
+ inputSchema: {
14
+ type: "object",
15
+ properties: {},
16
+ },
17
+ };
18
+ /** The route's answer as it is: `{ connections: [...] }`. Through `route()`, which the published SDK range already has. */
19
+ export async function handleConnectionsList(agent, _args) {
20
+ return agent.route("GET", "/v1/connections");
21
+ }
@@ -0,0 +1,4 @@
1
+ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
2
+ import type { OneShot } from '@oneshot-agent/sdk';
3
+ export declare const discoverToolsTool: Tool;
4
+ export declare function handleDiscoverTools(agent: OneShot, args: Record<string, unknown>): Promise<unknown>;
@@ -0,0 +1,20 @@
1
+ export const discoverToolsTool = {
2
+ name: 'oneshot_discover_tools',
3
+ description: 'Find OneShot tools by task or category. Free. Returns public names, purposes and required inputs. With no query or category, lists categories. Category pages contain up to five tools; pass nextCursor with the same query and category.',
4
+ inputSchema: {
5
+ type: 'object',
6
+ properties: {
7
+ query: { type: 'string', description: 'Task or tool name to search for.' },
8
+ category: { type: 'string', description: 'Category ID from the directory.' },
9
+ cursor: { type: 'string', description: 'Opaque nextCursor from a category page.' },
10
+ },
11
+ additionalProperties: false,
12
+ },
13
+ };
14
+ export async function handleDiscoverTools(agent, args) {
15
+ if (Object.entries(args).some(([key, value]) => !['query', 'category', 'cursor'].includes(key) || typeof value !== 'string')) {
16
+ throw new Error('Expected optional query, category and cursor strings.');
17
+ }
18
+ // route() is available in the published SDK too; discoverTools() wraps this same free request.
19
+ return agent.route('GET', '/v1/tools/discover', { query: args, paid: false });
20
+ }
@@ -1,13 +1,13 @@
1
1
  export const emailTool = {
2
2
  name: "oneshot_email",
3
- description: "Send an email. Supports HTML body, attachments, and threaded replies (set reply_to_email_id to an inbound email id from oneshot_inbox_list/oneshot_inbox_get). Paid tool — quote provided before payment.\n\n" +
3
+ description: "Send an email. Supports HTML body, attachments, and threaded replies (set reply_to_email_id to an inbound email id from oneshot_inbox_list/oneshot_inbox_get, or one this agent sent). Paid tool — quote provided before payment.\n\n" +
4
4
  "Sending requires a domain the agent owns. A fresh account has none — call oneshot_list_domains first to see what's already owned. If there is no usable domain, pass from_domain with a new domain to register it. A call with a new from_domain only quotes — nothing is charged — and returns status 'confirmation_required' with the exact cost (domain registration plus fees) and a quote_id. Tell the user that exact computed number, never a guessed or approximate one, and only once they say to proceed, call this again with the same arguments and confirm_new_domain set to that quote_id: that registers the domain, charges exactly the quoted total, and sends the email in one call. The workspace balance must cover it, or the call fails with insufficient_credits.",
5
5
  inputSchema: {
6
6
  type: "object",
7
7
  properties: {
8
8
  to: {
9
9
  type: "string",
10
- description: "Recipient email address (or comma-separated list). Optional when reply_to_email_id is set — defaults to the inbound sender.",
10
+ description: "Recipient email address (or comma-separated list). Optional when reply_to_email_id is set — defaults to the other party.",
11
11
  },
12
12
  subject: {
13
13
  type: "string",
@@ -15,7 +15,7 @@ export const emailTool = {
15
15
  },
16
16
  reply_to_email_id: {
17
17
  type: "string",
18
- description: "Reply within a thread: id of an inbound email (from oneshot_inbox_list/oneshot_inbox_get). Sets In-Reply-To/References headers so mail clients group the conversation.",
18
+ description: "Reply within a thread: id of an inbound email (from oneshot_inbox_list/oneshot_inbox_get), or one this agent sent. Sets In-Reply-To/References headers so mail clients group the conversation.",
19
19
  },
20
20
  body: {
21
21
  type: "string",
@@ -1,3 +1,4 @@
1
+ import { discoverToolsTool, handleDiscoverTools } from './discover.js';
1
2
  import { emailTool, handleEmail } from "./email.js";
2
3
  import { voiceTool, handleVoice } from "./voice.js";
3
4
  import { voiceNumberProvisionTool, voiceNumbersTool, voiceInboundSetTool, voiceInboundDisableTool, voiceInboundCallsTool, handleVoiceNumberProvision, handleVoiceNumbers, handleVoiceInboundSet, handleVoiceInboundDisable, handleVoiceInboundCalls, } from "./voice-inbound.js";
@@ -28,8 +29,10 @@ import { huntListTool, huntStatusTool, huntPredictTool, huntCollectionTool, hunt
28
29
  import { TOOL_ANNOTATIONS } from "./annotations.js";
29
30
  import { lookupToolDefinitions, lookupHandlers, routeToolDefinitions, routeHandlers } from "./lookup.js";
30
31
  import { physicalMailSendTool, physicalMailUploadTool, handlePhysicalMailSend, handlePhysicalMailUpload } from "./physical-mail.js";
32
+ import { connectionsListTool, handleConnectionsList } from "./connections.js";
31
33
  import { spendBreakdownTool, rocsTool, rocsByGoalTool, receiptsListTool, tagReceiptValueTool, handleSpendBreakdown, handleRocs, handleRocsByGoal, handleReceiptsList, handleTagReceiptValue } from "./analytics.js";
32
34
  const toolDefinitions = [
35
+ discoverToolsTool,
33
36
  emailTool,
34
37
  voiceTool,
35
38
  smsTool,
@@ -112,6 +115,7 @@ const toolDefinitions = [
112
115
  approvalListTool,
113
116
  approvalCancelTool,
114
117
  actionPolicyGetTool,
118
+ connectionsListTool,
115
119
  ...lookupToolDefinitions,
116
120
  ...routeToolDefinitions,
117
121
  ];
@@ -124,6 +128,7 @@ export const tools = toolDefinitions.map((tool) => {
124
128
  return { ...tool, title: hints.title, annotations: { ...hints } };
125
129
  });
126
130
  const handlers = {
131
+ oneshot_discover_tools: handleDiscoverTools,
127
132
  "oneshot_email": handleEmail,
128
133
  "oneshot_voice": handleVoice,
129
134
  "oneshot_sms": handleSms,
@@ -209,6 +214,7 @@ const handlers = {
209
214
  "oneshot_approval_list": handleApprovalList,
210
215
  "oneshot_approval_cancel": handleApprovalCancel,
211
216
  "oneshot_action_policy": handleActionPolicyGet,
217
+ "oneshot_connections_list": handleConnectionsList,
212
218
  ...lookupHandlers,
213
219
  ...routeHandlers,
214
220
  };
@@ -111,6 +111,29 @@ export const LOOKUP_MANIFEST = [
111
111
  "limit": 1
112
112
  }
113
113
  },
114
+ {
115
+ "name": "compound_hazards",
116
+ "path": "lookup/compound-hazards",
117
+ "title": "Compound Hazards",
118
+ "description": "Give the GHS hazard classification of a chemical compound by its compound identifier (CID) or by a name: a common, trade or systematic name, or a CAS registry number such as 50-00-0. Returns one classification per classifying source, in the source order: the GHS pictograms with their codes (GHS05), the signal word, the hazard statements with their codes (H314) and the precautionary statement codes. Only two classifying sources are returned: the EU harmonised classification (Regulation (EC) No 1272/2008) and the Hazardous Substances Data Bank of the US National Library of Medicine; every other source is left out, so a compound classified only by others returns an empty list. `classified` is true when a returned classification has a hazard statement. A name matching several compounds uses the first and lists them all in `matched_cids`. `compound` is null when the name or CID matches nothing, or the source has no classification for the compound. Give exactly one of `cid` and `name`. Toxicity values, exposure limits, the full safety data sheet, and any synthesis or preparation data are not returned.",
119
+ "inputSchema": {
120
+ "type": "object",
121
+ "properties": {
122
+ "cid": {
123
+ "type": "integer",
124
+ "description": "The compound identifier (CID), for example 712. From 1 to 999999999."
125
+ },
126
+ "name": {
127
+ "type": "string",
128
+ "description": "A common, trade or systematic name, or a CAS registry number such as 50-00-0. 2 to 200 characters."
129
+ }
130
+ },
131
+ "required": []
132
+ },
133
+ "example": {
134
+ "name": "50-00-0"
135
+ }
136
+ },
114
137
  {
115
138
  "name": "compound_properties",
116
139
  "path": "lookup/compound-properties",
@@ -806,6 +829,44 @@ export const LOOKUP_MANIFEST = [
806
829
  "height_in": 48
807
830
  }
808
831
  },
832
+ {
833
+ "name": "vehicle_fuel_economy",
834
+ "path": "lookup/vehicle-fuel-economy",
835
+ "title": "Fuel Economy",
836
+ "description": "Get federal fuel economy ratings and annual fuel expenditure for US light-duty vehicles from model year 1984 on. The model name must be the source's: Camry, Camry AWD LE/SE and Camry Hybrid LE are three separate models. Make and model matching is case-insensitive. The result lists the engine and transmission options in source order. `variant` picks among the options by case-insensitive text, for example 4 cyl, 2.5 L or S8; without it the first option is used. An unknown model or unmatched variant completes with `matched: false` and the available options. City, highway and combined ratings are miles per gallon, or miles per gallon equivalent for electric vehicles. Unavailable or inapplicable values are null. The source refreshes weekly; updated_on dates the selected record.",
837
+ "inputSchema": {
838
+ "type": "object",
839
+ "properties": {
840
+ "model_year": {
841
+ "type": "integer",
842
+ "description": "The model year, from 1984 through next calendar year. At least 1984. Model year cannot be later than next year."
843
+ },
844
+ "make": {
845
+ "type": "string",
846
+ "description": "The vehicle make, for example Toyota. 2 to 40 characters."
847
+ },
848
+ "model": {
849
+ "type": "string",
850
+ "description": "The model as the source names it, for example Camry or Camry Hybrid LE. 1 to 60 characters."
851
+ },
852
+ "variant": {
853
+ "type": "string",
854
+ "description": "Case-insensitive text in the option description, for example 4 cyl, 2.5 L or S8; omitted selects the first option. 1 to 60 characters."
855
+ }
856
+ },
857
+ "required": [
858
+ "model_year",
859
+ "make",
860
+ "model"
861
+ ]
862
+ },
863
+ "example": {
864
+ "model_year": 2020,
865
+ "make": "Toyota",
866
+ "model": "Camry",
867
+ "variant": "4 cyl"
868
+ }
869
+ },
809
870
  {
810
871
  "name": "gene_pathways",
811
872
  "path": "lookup/gene-pathways",
@@ -1958,6 +2019,147 @@ export const ROUTE_MANIFEST = [
1958
2019
  "start_url": "https://example.com/login"
1959
2020
  }
1960
2021
  },
2022
+ {
2023
+ "name": "crm_accounts",
2024
+ "method": "POST",
2025
+ "path": "/v1/tools/crm/accounts",
2026
+ "paid": true,
2027
+ "readOnly": true,
2028
+ "title": "CRM accounts",
2029
+ "description": "Read accounts from a connected Salesforce or HubSpot account. Read-only. Nothing fetched is stored. Contacts include personal data, returned inline only. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2030
+ "inputSchema": {
2031
+ "type": "object",
2032
+ "properties": {
2033
+ "connection_id": {
2034
+ "type": "string",
2035
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2036
+ },
2037
+ "query": {
2038
+ "type": "string",
2039
+ "description": "Name contains this text, case insensitive. A filtered page can be empty; continue while next_cursor is present."
2040
+ },
2041
+ "updated_since": {
2042
+ "type": "string",
2043
+ "description": "Updated on or after this ISO date (YYYY-MM-DD, UTC)"
2044
+ },
2045
+ "limit": {
2046
+ "type": "number",
2047
+ "description": "Records per page (1 to 100, default 25)"
2048
+ },
2049
+ "cursor": {
2050
+ "type": "string",
2051
+ "description": "The next_cursor of the previous page; keep the same filters"
2052
+ }
2053
+ },
2054
+ "required": [
2055
+ "connection_id"
2056
+ ]
2057
+ },
2058
+ "example": {
2059
+ "connection_id": "5f4a3b2c-1d0e-4f9a-8b7c-6d5e4f3a2b1c",
2060
+ "limit": 25
2061
+ }
2062
+ },
2063
+ {
2064
+ "name": "crm_contacts",
2065
+ "method": "POST",
2066
+ "path": "/v1/tools/crm/contacts",
2067
+ "paid": true,
2068
+ "readOnly": true,
2069
+ "title": "CRM contacts",
2070
+ "description": "Read contacts from a connected Salesforce or HubSpot account. Read-only. Nothing fetched is stored. Contacts include personal data, returned inline only. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2071
+ "inputSchema": {
2072
+ "type": "object",
2073
+ "properties": {
2074
+ "connection_id": {
2075
+ "type": "string",
2076
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2077
+ },
2078
+ "query": {
2079
+ "type": "string",
2080
+ "description": "Name contains this text, case insensitive. A filtered page can be empty; continue while next_cursor is present."
2081
+ },
2082
+ "updated_since": {
2083
+ "type": "string",
2084
+ "description": "Updated on or after this ISO date (YYYY-MM-DD, UTC)"
2085
+ },
2086
+ "limit": {
2087
+ "type": "number",
2088
+ "description": "Records per page (1 to 100, default 25)"
2089
+ },
2090
+ "cursor": {
2091
+ "type": "string",
2092
+ "description": "The next_cursor of the previous page; keep the same filters"
2093
+ },
2094
+ "account_id": {
2095
+ "type": "string",
2096
+ "description": "Only records associated with this account id"
2097
+ }
2098
+ },
2099
+ "required": [
2100
+ "connection_id"
2101
+ ]
2102
+ },
2103
+ "example": {
2104
+ "connection_id": "5f4a3b2c-1d0e-4f9a-8b7c-6d5e4f3a2b1c",
2105
+ "limit": 25
2106
+ }
2107
+ },
2108
+ {
2109
+ "name": "crm_opportunities",
2110
+ "method": "POST",
2111
+ "path": "/v1/tools/crm/opportunities",
2112
+ "paid": true,
2113
+ "readOnly": true,
2114
+ "title": "CRM opportunities",
2115
+ "description": "Read opportunities from a connected Salesforce or HubSpot account. Read-only. Nothing fetched is stored. Contacts include personal data, returned inline only. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2116
+ "inputSchema": {
2117
+ "type": "object",
2118
+ "properties": {
2119
+ "connection_id": {
2120
+ "type": "string",
2121
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2122
+ },
2123
+ "query": {
2124
+ "type": "string",
2125
+ "description": "Name contains this text, case insensitive. A filtered page can be empty; continue while next_cursor is present."
2126
+ },
2127
+ "updated_since": {
2128
+ "type": "string",
2129
+ "description": "Updated on or after this ISO date (YYYY-MM-DD, UTC)"
2130
+ },
2131
+ "limit": {
2132
+ "type": "number",
2133
+ "description": "Records per page (1 to 100, default 25)"
2134
+ },
2135
+ "cursor": {
2136
+ "type": "string",
2137
+ "description": "The next_cursor of the previous page; keep the same filters"
2138
+ },
2139
+ "account_id": {
2140
+ "type": "string",
2141
+ "description": "Only records associated with this account id"
2142
+ },
2143
+ "status": {
2144
+ "type": "string",
2145
+ "enum": [
2146
+ "open",
2147
+ "won",
2148
+ "lost",
2149
+ "all"
2150
+ ],
2151
+ "description": "Opportunity status (default all)"
2152
+ }
2153
+ },
2154
+ "required": [
2155
+ "connection_id"
2156
+ ]
2157
+ },
2158
+ "example": {
2159
+ "connection_id": "5f4a3b2c-1d0e-4f9a-8b7c-6d5e4f3a2b1c",
2160
+ "limit": 25
2161
+ }
2162
+ },
1961
2163
  {
1962
2164
  "name": "watch_delete",
1963
2165
  "method": "DELETE",
@@ -2078,6 +2280,174 @@ export const ROUTE_MANIFEST = [
2078
2280
  "phone_number_id": "pn_01HX"
2079
2281
  }
2080
2282
  },
2283
+ {
2284
+ "name": "ledger_bills",
2285
+ "method": "POST",
2286
+ "path": "/v1/tools/ledger/bills",
2287
+ "paid": true,
2288
+ "readOnly": true,
2289
+ "title": "Ledger bills",
2290
+ "description": "Bills (payables) from a connected accounting system (QuickBooks, Zoho Books, Xero, NetSuite), filtered by date, status and counterparty. Read-only. Nothing fetched is stored. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2291
+ "inputSchema": {
2292
+ "type": "object",
2293
+ "properties": {
2294
+ "connection_id": {
2295
+ "type": "string",
2296
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2297
+ },
2298
+ "limit": {
2299
+ "type": "number",
2300
+ "description": "Records per page (1 to 100, default 25)"
2301
+ },
2302
+ "cursor": {
2303
+ "type": "string",
2304
+ "description": "The next_cursor of the previous page"
2305
+ },
2306
+ "from": {
2307
+ "type": "string",
2308
+ "description": "Records issued on or after this date (YYYY-MM-DD)"
2309
+ },
2310
+ "to": {
2311
+ "type": "string",
2312
+ "description": "Records issued on or before this date (YYYY-MM-DD)"
2313
+ },
2314
+ "status": {
2315
+ "type": "string",
2316
+ "enum": [
2317
+ "open",
2318
+ "paid",
2319
+ "overdue",
2320
+ "all"
2321
+ ],
2322
+ "description": "Payment status filter (default all)"
2323
+ },
2324
+ "counterparty": {
2325
+ "type": "string",
2326
+ "description": "Only records whose counterparty name contains this text"
2327
+ }
2328
+ },
2329
+ "required": [
2330
+ "connection_id"
2331
+ ]
2332
+ },
2333
+ "example": {
2334
+ "connection_id": "5f4a3b2c-1d0e-4f9a-8b7c-6d5e4f3a2b1c",
2335
+ "status": "overdue",
2336
+ "limit": 25
2337
+ }
2338
+ },
2339
+ {
2340
+ "name": "ledger_invoices",
2341
+ "method": "POST",
2342
+ "path": "/v1/tools/ledger/invoices",
2343
+ "paid": true,
2344
+ "readOnly": true,
2345
+ "title": "Ledger invoices",
2346
+ "description": "Invoices from a connected accounting system (QuickBooks, Zoho Books, Xero, NetSuite), filtered by date, status and counterparty. Read-only. Nothing fetched is stored. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2347
+ "inputSchema": {
2348
+ "type": "object",
2349
+ "properties": {
2350
+ "connection_id": {
2351
+ "type": "string",
2352
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2353
+ },
2354
+ "limit": {
2355
+ "type": "number",
2356
+ "description": "Records per page (1 to 100, default 25)"
2357
+ },
2358
+ "cursor": {
2359
+ "type": "string",
2360
+ "description": "The next_cursor of the previous page"
2361
+ },
2362
+ "from": {
2363
+ "type": "string",
2364
+ "description": "Records issued on or after this date (YYYY-MM-DD)"
2365
+ },
2366
+ "to": {
2367
+ "type": "string",
2368
+ "description": "Records issued on or before this date (YYYY-MM-DD)"
2369
+ },
2370
+ "status": {
2371
+ "type": "string",
2372
+ "enum": [
2373
+ "open",
2374
+ "paid",
2375
+ "overdue",
2376
+ "all"
2377
+ ],
2378
+ "description": "Payment status filter (default all)"
2379
+ },
2380
+ "counterparty": {
2381
+ "type": "string",
2382
+ "description": "Only records whose counterparty name contains this text"
2383
+ }
2384
+ },
2385
+ "required": [
2386
+ "connection_id"
2387
+ ]
2388
+ },
2389
+ "example": {
2390
+ "connection_id": "5f4a3b2c-1d0e-4f9a-8b7c-6d5e4f3a2b1c",
2391
+ "status": "open",
2392
+ "limit": 25
2393
+ }
2394
+ },
2395
+ {
2396
+ "name": "ledger_reports",
2397
+ "method": "POST",
2398
+ "path": "/v1/tools/ledger/reports",
2399
+ "paid": true,
2400
+ "readOnly": true,
2401
+ "title": "Ledger reports",
2402
+ "description": "A report from a connected accounting system. QuickBooks: balance_sheet, profit_and_loss and trial_balance, dated with as_of or from/to. Xero: the same three, with a profit_and_loss of at most 365 days. Zoho Books: trial_balance as of today only (no as_of); no balance_sheet or profit_and_loss. NetSuite reports are not supported. A report the system does not serve is refused as unsupported_for_system before payment. Read-only. Nothing fetched is stored. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2403
+ "inputSchema": {
2404
+ "type": "object",
2405
+ "properties": {
2406
+ "connection_id": {
2407
+ "type": "string",
2408
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2409
+ },
2410
+ "limit": {
2411
+ "type": "number",
2412
+ "description": "Records per page (1 to 100, default 25)"
2413
+ },
2414
+ "cursor": {
2415
+ "type": "string",
2416
+ "description": "The next_cursor of the previous page"
2417
+ },
2418
+ "type": {
2419
+ "type": "string",
2420
+ "enum": [
2421
+ "balance_sheet",
2422
+ "profit_and_loss",
2423
+ "trial_balance"
2424
+ ],
2425
+ "description": "The report. QuickBooks and Xero: all three. Zoho Books: trial_balance only. NetSuite: no reports"
2426
+ },
2427
+ "as_of": {
2428
+ "type": "string",
2429
+ "description": "Balance sheet and trial balance: the date the report stands at (YYYY-MM-DD). QuickBooks and Xero; Zoho Books serves the trial balance as of today"
2430
+ },
2431
+ "from": {
2432
+ "type": "string",
2433
+ "description": "Profit and loss: the first day of the period (YYYY-MM-DD)"
2434
+ },
2435
+ "to": {
2436
+ "type": "string",
2437
+ "description": "Profit and loss: the last day of the period (YYYY-MM-DD)"
2438
+ }
2439
+ },
2440
+ "required": [
2441
+ "connection_id",
2442
+ "type"
2443
+ ]
2444
+ },
2445
+ "example": {
2446
+ "connection_id": "5f4a3b2c-1d0e-4f9a-8b7c-6d5e4f3a2b1c",
2447
+ "type": "balance_sheet",
2448
+ "as_of": "2026-09-30"
2449
+ }
2450
+ },
2081
2451
  {
2082
2452
  "name": "linkedin_sync_run",
2083
2453
  "method": "GET",
@@ -2185,6 +2555,132 @@ export const ROUTE_MANIFEST = [
2185
2555
  }
2186
2556
  }
2187
2557
  },
2558
+ {
2559
+ "name": "procurement_bills",
2560
+ "method": "POST",
2561
+ "path": "/v1/tools/procurement/bills",
2562
+ "paid": true,
2563
+ "readOnly": true,
2564
+ "title": "Procurement bills",
2565
+ "description": "Bills awaiting or past approval, read from the customer's connected spend system. Read-only: nothing is approved or paid. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2566
+ "inputSchema": {
2567
+ "type": "object",
2568
+ "properties": {
2569
+ "connection_id": {
2570
+ "type": "string",
2571
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2572
+ },
2573
+ "from": {
2574
+ "type": "string",
2575
+ "description": "Bills issued on or after this day (YYYY-MM-DD, UTC)"
2576
+ },
2577
+ "to": {
2578
+ "type": "string",
2579
+ "description": "Bills issued on or before this day (YYYY-MM-DD, UTC)"
2580
+ },
2581
+ "limit": {
2582
+ "type": "integer",
2583
+ "description": "Bills per page, 1 to 100 (default 25)"
2584
+ },
2585
+ "cursor": {
2586
+ "type": "string",
2587
+ "description": "The next_cursor of the previous page"
2588
+ }
2589
+ },
2590
+ "required": [
2591
+ "connection_id"
2592
+ ]
2593
+ },
2594
+ "example": {
2595
+ "connection_id": "6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
2596
+ "from": "2026-09-01",
2597
+ "limit": 25
2598
+ }
2599
+ },
2600
+ {
2601
+ "name": "procurement_suppliers",
2602
+ "method": "POST",
2603
+ "path": "/v1/tools/procurement/suppliers",
2604
+ "paid": true,
2605
+ "readOnly": true,
2606
+ "title": "Procurement suppliers",
2607
+ "description": "Suppliers with their category and all-time spend, read from the customer's connected spend system. Read-only. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2608
+ "inputSchema": {
2609
+ "type": "object",
2610
+ "properties": {
2611
+ "connection_id": {
2612
+ "type": "string",
2613
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2614
+ },
2615
+ "from": {
2616
+ "type": "string",
2617
+ "description": "Suppliers added on or after this day (YYYY-MM-DD, UTC)"
2618
+ },
2619
+ "to": {
2620
+ "type": "string",
2621
+ "description": "Suppliers added on or before this day (YYYY-MM-DD, UTC)"
2622
+ },
2623
+ "limit": {
2624
+ "type": "integer",
2625
+ "description": "Suppliers per page, 1 to 100 (default 25)"
2626
+ },
2627
+ "cursor": {
2628
+ "type": "string",
2629
+ "description": "The next_cursor of the previous page"
2630
+ }
2631
+ },
2632
+ "required": [
2633
+ "connection_id"
2634
+ ]
2635
+ },
2636
+ "example": {
2637
+ "connection_id": "6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
2638
+ "limit": 25
2639
+ }
2640
+ },
2641
+ {
2642
+ "name": "procurement_transactions",
2643
+ "method": "POST",
2644
+ "path": "/v1/tools/procurement/transactions",
2645
+ "paid": true,
2646
+ "readOnly": true,
2647
+ "title": "Procurement transactions",
2648
+ "description": "Card and spend transactions read from the customer's connected spend system. Read-only. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2649
+ "inputSchema": {
2650
+ "type": "object",
2651
+ "properties": {
2652
+ "connection_id": {
2653
+ "type": "string",
2654
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2655
+ },
2656
+ "from": {
2657
+ "type": "string",
2658
+ "description": "Transactions made on or after this day (YYYY-MM-DD, UTC)"
2659
+ },
2660
+ "to": {
2661
+ "type": "string",
2662
+ "description": "Transactions made on or before this day (YYYY-MM-DD, UTC)"
2663
+ },
2664
+ "limit": {
2665
+ "type": "integer",
2666
+ "description": "Transactions per page, 1 to 100 (default 25)"
2667
+ },
2668
+ "cursor": {
2669
+ "type": "string",
2670
+ "description": "The next_cursor of the previous page"
2671
+ }
2672
+ },
2673
+ "required": [
2674
+ "connection_id"
2675
+ ]
2676
+ },
2677
+ "example": {
2678
+ "connection_id": "6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
2679
+ "from": "2026-10-01",
2680
+ "to": "2026-10-15",
2681
+ "limit": 25
2682
+ }
2683
+ },
2188
2684
  {
2189
2685
  "name": "physical_mail_recover",
2190
2686
  "method": "GET",
@@ -2277,6 +2773,308 @@ export const ROUTE_MANIFEST = [
2277
2773
  "limit": 10
2278
2774
  }
2279
2775
  },
2776
+ {
2777
+ "name": "shipping_rates",
2778
+ "method": "POST",
2779
+ "path": "/v1/tools/shipping/rates",
2780
+ "paid": true,
2781
+ "readOnly": true,
2782
+ "title": "Shipping rates",
2783
+ "description": "Rates already quoted on a shipment, read from the customer's connected shipping system. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2784
+ "inputSchema": {
2785
+ "type": "object",
2786
+ "properties": {
2787
+ "connection_id": {
2788
+ "type": "string",
2789
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2790
+ },
2791
+ "shipment_id": {
2792
+ "type": "string",
2793
+ "description": "The existing shipment whose quoted rates to read"
2794
+ }
2795
+ },
2796
+ "required": [
2797
+ "connection_id",
2798
+ "shipment_id"
2799
+ ]
2800
+ },
2801
+ "example": {
2802
+ "connection_id": "6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
2803
+ "shipment_id": "se-1001"
2804
+ }
2805
+ },
2806
+ {
2807
+ "name": "shipping_shipments",
2808
+ "method": "POST",
2809
+ "path": "/v1/tools/shipping/shipments",
2810
+ "paid": true,
2811
+ "readOnly": true,
2812
+ "title": "Shipping shipments",
2813
+ "description": "Shipments read from the customer's connected shipping system. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2814
+ "inputSchema": {
2815
+ "type": "object",
2816
+ "properties": {
2817
+ "connection_id": {
2818
+ "type": "string",
2819
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2820
+ },
2821
+ "limit": {
2822
+ "type": "integer",
2823
+ "description": "Shipments per page, 1 to 100 (default 25)"
2824
+ },
2825
+ "cursor": {
2826
+ "type": "string",
2827
+ "description": "The next_cursor of the previous page"
2828
+ },
2829
+ "from": {
2830
+ "type": "string",
2831
+ "description": "Shipments created on or after this day (YYYY-MM-DD)"
2832
+ },
2833
+ "to": {
2834
+ "type": "string",
2835
+ "description": "Shipments created on or before this day (YYYY-MM-DD)"
2836
+ },
2837
+ "status": {
2838
+ "type": "string",
2839
+ "description": "Only shipments in this status, as the system names it (for example label_purchased)"
2840
+ }
2841
+ },
2842
+ "required": [
2843
+ "connection_id"
2844
+ ]
2845
+ },
2846
+ "example": {
2847
+ "connection_id": "6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
2848
+ "limit": 25,
2849
+ "from": "2026-10-01",
2850
+ "to": "2026-10-15"
2851
+ }
2852
+ },
2853
+ {
2854
+ "name": "shipping_tracking",
2855
+ "method": "POST",
2856
+ "path": "/v1/tools/shipping/tracking",
2857
+ "paid": true,
2858
+ "readOnly": true,
2859
+ "title": "Shipping tracking",
2860
+ "description": "Tracking of one shipment read from the customer's connected shipping system. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2861
+ "inputSchema": {
2862
+ "type": "object",
2863
+ "properties": {
2864
+ "connection_id": {
2865
+ "type": "string",
2866
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2867
+ },
2868
+ "shipment_id": {
2869
+ "type": "string",
2870
+ "description": "The shipment to track, by the system's shipment id"
2871
+ },
2872
+ "carrier": {
2873
+ "type": "string",
2874
+ "description": "The carrier code, with tracking_number, to track without a shipment id"
2875
+ },
2876
+ "tracking_number": {
2877
+ "type": "string",
2878
+ "description": "The tracking number, with carrier"
2879
+ }
2880
+ },
2881
+ "required": [
2882
+ "connection_id"
2883
+ ]
2884
+ },
2885
+ "example": {
2886
+ "connection_id": "6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
2887
+ "shipment_id": "se-1001"
2888
+ }
2889
+ },
2890
+ {
2891
+ "name": "tax_calculate",
2892
+ "method": "POST",
2893
+ "path": "/v1/tools/tax/calculate",
2894
+ "paid": true,
2895
+ "readOnly": true,
2896
+ "title": "Tax calculation",
2897
+ "description": "Tax calculation for an order, read from the customer's connected tax system. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
2898
+ "inputSchema": {
2899
+ "type": "object",
2900
+ "properties": {
2901
+ "connection_id": {
2902
+ "type": "string",
2903
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
2904
+ },
2905
+ "from": {
2906
+ "type": "object",
2907
+ "properties": {
2908
+ "country": {
2909
+ "type": "string",
2910
+ "description": "Two-letter country code"
2911
+ },
2912
+ "zip": {
2913
+ "type": "string",
2914
+ "description": "Postal code"
2915
+ },
2916
+ "state": {
2917
+ "type": "string",
2918
+ "description": "State or province code (required for US and CA)"
2919
+ },
2920
+ "city": {
2921
+ "type": "string"
2922
+ },
2923
+ "street": {
2924
+ "type": "string"
2925
+ }
2926
+ },
2927
+ "required": [
2928
+ "country",
2929
+ "zip"
2930
+ ],
2931
+ "description": "Where the order ships from"
2932
+ },
2933
+ "to": {
2934
+ "type": "object",
2935
+ "properties": {
2936
+ "country": {
2937
+ "type": "string",
2938
+ "description": "Two-letter country code"
2939
+ },
2940
+ "zip": {
2941
+ "type": "string",
2942
+ "description": "Postal code"
2943
+ },
2944
+ "state": {
2945
+ "type": "string",
2946
+ "description": "State or province code (required for US and CA)"
2947
+ },
2948
+ "city": {
2949
+ "type": "string"
2950
+ },
2951
+ "street": {
2952
+ "type": "string"
2953
+ }
2954
+ },
2955
+ "required": [
2956
+ "country",
2957
+ "zip"
2958
+ ],
2959
+ "description": "Where the order ships to"
2960
+ },
2961
+ "line_items": {
2962
+ "type": "array",
2963
+ "description": "The goods on the order (1 to 100 lines)",
2964
+ "items": {
2965
+ "type": "object",
2966
+ "properties": {
2967
+ "id": {
2968
+ "type": "string",
2969
+ "description": "Your reference for the line; returned in the breakdown"
2970
+ },
2971
+ "quantity": {
2972
+ "type": "integer",
2973
+ "description": "Units on the line (default 1)"
2974
+ },
2975
+ "unit_price": {
2976
+ "type": "number",
2977
+ "description": "Price of one unit, before tax"
2978
+ },
2979
+ "discount": {
2980
+ "type": "number",
2981
+ "description": "Discount on the whole line, before tax"
2982
+ },
2983
+ "product_tax_code": {
2984
+ "type": "string",
2985
+ "description": "The system's product tax category code, when the goods are not taxed at the general rate"
2986
+ }
2987
+ },
2988
+ "required": [
2989
+ "unit_price"
2990
+ ]
2991
+ }
2992
+ },
2993
+ "shipping": {
2994
+ "type": "number",
2995
+ "description": "Shipping charged on the order, before tax (default 0)"
2996
+ }
2997
+ },
2998
+ "required": [
2999
+ "connection_id",
3000
+ "from",
3001
+ "to",
3002
+ "line_items"
3003
+ ]
3004
+ },
3005
+ "example": {
3006
+ "connection_id": "6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
3007
+ "from": {
3008
+ "country": "US",
3009
+ "zip": "92093",
3010
+ "state": "CA"
3011
+ },
3012
+ "to": {
3013
+ "country": "US",
3014
+ "zip": "90002",
3015
+ "state": "CA",
3016
+ "city": "Los Angeles"
3017
+ },
3018
+ "line_items": [
3019
+ {
3020
+ "id": "1",
3021
+ "quantity": 1,
3022
+ "unit_price": 15,
3023
+ "product_tax_code": "20010"
3024
+ }
3025
+ ],
3026
+ "shipping": 1.5
3027
+ }
3028
+ },
3029
+ {
3030
+ "name": "tax_rates",
3031
+ "method": "POST",
3032
+ "path": "/v1/tools/tax/rates",
3033
+ "paid": true,
3034
+ "readOnly": true,
3035
+ "title": "Tax rates",
3036
+ "description": "Tax rate for a location, read from the customer's connected tax system. Paid per read. Call oneshot_connections_list first and pick the connection_id by system and account_label.",
3037
+ "inputSchema": {
3038
+ "type": "object",
3039
+ "properties": {
3040
+ "connection_id": {
3041
+ "type": "string",
3042
+ "description": "The connection to read. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`."
3043
+ },
3044
+ "country": {
3045
+ "type": "string",
3046
+ "description": "Two-letter country code; US when omitted"
3047
+ },
3048
+ "zip": {
3049
+ "type": "string",
3050
+ "description": "Postal code of the location"
3051
+ },
3052
+ "state": {
3053
+ "type": "string",
3054
+ "description": "State or province code, for a more precise rate"
3055
+ },
3056
+ "city": {
3057
+ "type": "string",
3058
+ "description": "City, for a more precise rate"
3059
+ },
3060
+ "street": {
3061
+ "type": "string",
3062
+ "description": "Street address, for a rooftop-precise rate where the system offers one"
3063
+ }
3064
+ },
3065
+ "required": [
3066
+ "connection_id",
3067
+ "zip"
3068
+ ]
3069
+ },
3070
+ "example": {
3071
+ "connection_id": "6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
3072
+ "country": "US",
3073
+ "zip": "90210",
3074
+ "state": "CA",
3075
+ "city": "Beverly Hills"
3076
+ }
3077
+ },
2280
3078
  {
2281
3079
  "name": "physical_mail_validate_address",
2282
3080
  "method": "POST",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oneshot-agent/mcp-server",
3
- "version": "0.44.0",
4
- "description": "MCP server for OneShot - 154 tools for AI agents",
3
+ "version": "0.45.0",
4
+ "description": "MCP server for OneShot - 172 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.57.0",
29
+ "@oneshot-agent/sdk": "^0.58.0",
30
30
  "zod": "3.25.76"
31
31
  },
32
32
  "devDependencies": {