@oneshot-agent/mcp-server 0.49.0 → 0.51.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.
@@ -219,7 +219,7 @@ export async function handleLinkedinWithdrawInvitation(agent, args) {
219
219
  }
220
220
  export const linkedinMessageTool = {
221
221
  name: "oneshot_linkedin_message",
222
- description: "Message a first-degree LinkedIn connection through a connected account that granted 'reply': into the 1:1 conversation the account already has with them, or a new one. Use it once an invitation is accepted, or for a connection the account has never messaged. Returns conversation_id. The human's account sends it; a message LinkedIn accepted cannot be recalled. Shares the reply daily cap (default 50); sends are paced. A failed send with not_connected (invite them first) or rate_limited means defer, not give up. An Idempotency-Key is generated automatically so a retry never double-sends. Paid tool.",
222
+ description: "Message a first-degree LinkedIn connection through a connected account that granted 'reply': into the 1:1 conversation the account already has with them, or a new one. Use it once an invitation is accepted, or for a connection the account has never messaged. Returns conversation_id. The human's account sends it; a message LinkedIn accepted cannot be recalled. Shares the reply daily cap (default 50); sends are paced. A failed send with recipient_not_connected means invite them first, not give up. An Idempotency-Key is generated automatically so a retry never double-sends. Paid tool.",
223
223
  inputSchema: {
224
224
  type: "object",
225
225
  properties: {
@@ -6,7 +6,7 @@ export const businessFindTool = {
6
6
  type: "object",
7
7
  properties: {
8
8
  category: { type: "array", items: { type: "string" }, description: "Business categories, e.g. ['hvac contractor', 'dental practice']. category or keywords required." },
9
- keywords: { type: "array", items: { type: "string" }, description: "Free-text keywords (alternative to category)" },
9
+ keywords: { type: "array", items: { type: "string" }, description: "Free-text keywords (alternative to category). category or keywords required." },
10
10
  location: { type: "array", items: { type: "string" }, description: "Cities, neighborhoods, or 'City, ST' strings (required)" },
11
11
  min_rating: { type: "number", description: "Minimum star rating (0-5)" },
12
12
  min_review_count: { type: "number", description: "Minimum review count" },
@@ -17,7 +17,6 @@ export const businessFindTool = {
17
17
  ...FRESH_PROPERTY,
18
18
  },
19
19
  required: ["location"],
20
- anyOf: [{ required: ["category"] }, { required: ["keywords"] }],
21
20
  },
22
21
  };
23
22
  export const businessResolveTool = {
@@ -35,7 +34,6 @@ export const businessResolveTool = {
35
34
  ...FRESH_PROPERTY,
36
35
  },
37
36
  required: ["name"],
38
- anyOf: [{ required: ["address"] }, { required: ["city"] }, { required: ["postal_code"] }, { required: ["phone"] }],
39
37
  },
40
38
  };
41
39
  export async function handleBusinessFind(agent, args) {
@@ -0,0 +1,13 @@
1
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
+ import type { OneShot } from "@oneshot-agent/sdk";
3
+ /**
4
+ * One tool that runs any lookup by name. A client with a short tool list (a
5
+ * platform's cap, or `?tools=compact` on hosted /mcp) lists this instead of
6
+ * every lookup; oneshot_discover_tools finds the names. Lookups only: a route
7
+ * or hand-written tool keeps its own annotations and confirmation, which a
8
+ * read-only meta-tool must not stand in for.
9
+ */
10
+ export declare const lookupCallTool: Tool;
11
+ /** The lookup a oneshot_lookup call targets, as `oneshot_<name>`; null when it names no lookup. */
12
+ export declare function lookupTarget(args: Record<string, unknown>): string | null;
13
+ export declare function handleLookupCall(agent: OneShot, args: Record<string, unknown>): Promise<unknown>;
@@ -0,0 +1,45 @@
1
+ import { LOOKUP_MANIFEST } from "./lookup-manifest.generated.js";
2
+ import { lookupHandlers } from "./lookup.js";
3
+ /**
4
+ * One tool that runs any lookup by name. A client with a short tool list (a
5
+ * platform's cap, or `?tools=compact` on hosted /mcp) lists this instead of
6
+ * every lookup; oneshot_discover_tools finds the names. Lookups only: a route
7
+ * or hand-written tool keeps its own annotations and confirmation, which a
8
+ * read-only meta-tool must not stand in for.
9
+ */
10
+ export const lookupCallTool = {
11
+ name: "oneshot_lookup",
12
+ description: "Run a OneShot lookup by name, including one that is not in your tool list. Find names with oneshot_discover_tools. " +
13
+ "Without input, returns the lookup's description, input schema and an example, free. With input, runs the lookup, " +
14
+ "exactly as calling that tool directly. Paid like the lookup it runs.",
15
+ inputSchema: {
16
+ type: "object",
17
+ properties: {
18
+ tool: { type: "string", description: "Lookup name, e.g. oneshot_company_filings (the oneshot_ prefix is optional)." },
19
+ input: { type: "object", description: "The lookup's input. Omit to get its input schema first." },
20
+ },
21
+ required: ["tool"],
22
+ additionalProperties: false,
23
+ },
24
+ };
25
+ const BY_NAME = new Map(LOOKUP_MANIFEST.map((entry) => [`oneshot_${entry.name}`, entry]));
26
+ /** The lookup a oneshot_lookup call targets, as `oneshot_<name>`; null when it names no lookup. */
27
+ export function lookupTarget(args) {
28
+ if (typeof args.tool !== "string")
29
+ return null;
30
+ const name = args.tool.startsWith("oneshot_") ? args.tool : `oneshot_${args.tool}`;
31
+ return BY_NAME.has(name) ? name : null;
32
+ }
33
+ export async function handleLookupCall(agent, args) {
34
+ const target = lookupTarget(args);
35
+ if (!target)
36
+ throw new Error(`${String(args.tool)} is not a lookup. Find lookup names with oneshot_discover_tools.`);
37
+ const entry = BY_NAME.get(target);
38
+ if (args.input === undefined) {
39
+ return { tool: target, description: entry.description, inputSchema: entry.inputSchema, example: entry.example };
40
+ }
41
+ if (!args.input || typeof args.input !== "object" || Array.isArray(args.input)) {
42
+ throw new Error("input must be an object of the lookup's arguments.");
43
+ }
44
+ return lookupHandlers[target](agent, args.input);
45
+ }
@@ -32,5 +32,7 @@ export interface RouteManifestEntry {
32
32
  example: Record<string, unknown>;
33
33
  /** `false` for a route whose 202 envelope is the answer (a verification_url to hand on): the handler returns it and never waits for the job. */
34
34
  wait?: false;
35
+ /** Seconds to wait for the job, for a long one (a tool backed by a goal runs up to its deadline); else the SDK default. */
36
+ timeout?: number;
35
37
  }
36
38
  export declare const ROUTE_MANIFEST: readonly RouteManifestEntry[];