palmier 1.1.7 → 1.1.8
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 +1 -2
- package/dist/mcp-tools.d.ts +1 -0
- package/dist/mcp-tools.js +8 -7
- package/dist/transports/http-transport.js +4 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,8 +56,7 @@ Palmier exposes an [MCP](https://modelcontextprotocol.io) server at `http://loca
|
|
|
56
56
|
|------|-------------|
|
|
57
57
|
| `notify` | Send a push notification to the user's device |
|
|
58
58
|
| `request-input` | Request input from the user (blocks until response; aborting the prompt aborts the task) |
|
|
59
|
-
| `request-
|
|
60
|
-
| `request-choice` | Ask the user a question with a fixed set of options, e.g. Yes/No, and return the one picked (blocks until response; aborting aborts the task) |
|
|
59
|
+
| `request-choice` | Ask the user a question with a fixed set of options and return the one picked; a single option serves as a confirmation (blocks until response; aborting aborts the task) |
|
|
61
60
|
| `fill-password` | Fill a saved password or PIN into the active browser session and submit the form, prompting the user if unknown (the secret is never revealed to the agent) |
|
|
62
61
|
| `device-geolocation` | Get GPS location of the user's mobile device |
|
|
63
62
|
| `read-contacts` | Read the contact list from the user's device |
|
package/dist/mcp-tools.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export interface ToolDefinition {
|
|
|
19
19
|
inputSchema: object;
|
|
20
20
|
handler: (args: Record<string, unknown>, ctx: ToolContext) => Promise<unknown>;
|
|
21
21
|
}
|
|
22
|
+
export declare const requestConfirmationTool: ToolDefinition;
|
|
22
23
|
export declare const agentTools: ToolDefinition[];
|
|
23
24
|
export declare const agentToolMap: Map<string, ToolDefinition>;
|
|
24
25
|
export interface ResourceDefinition {
|
package/dist/mcp-tools.js
CHANGED
|
@@ -145,7 +145,7 @@ async function abortSessionTask(ctx) {
|
|
|
145
145
|
return;
|
|
146
146
|
await ctx.abortTask(taskId);
|
|
147
147
|
}
|
|
148
|
-
const requestConfirmationTool = {
|
|
148
|
+
export const requestConfirmationTool = {
|
|
149
149
|
name: "request-confirmation",
|
|
150
150
|
description: [
|
|
151
151
|
"Request confirmation from the user.",
|
|
@@ -191,10 +191,11 @@ const requestConfirmationTool = {
|
|
|
191
191
|
const requestChoiceTool = {
|
|
192
192
|
name: "request-choice",
|
|
193
193
|
description: [
|
|
194
|
-
"Ask the user a question with a fixed set of answers and let them pick one
|
|
194
|
+
"Ask the user a question with a fixed set of answers and let them pick one.",
|
|
195
195
|
"The request blocks until the user picks an option or aborts the task.",
|
|
196
196
|
'Response: `{"choice": "<option>"}` with the selected option, or `{"aborted": true}` if the user aborts.',
|
|
197
197
|
"Use this instead of request-input whenever the possible answers are known in advance.",
|
|
198
|
+
"An abort option that ends the task is always shown, so to ask for confirmation before continuing, pass a single option naming the action (e.g. [\"Send email\"]). Add a decline option only if declining should let the task continue differently.",
|
|
198
199
|
],
|
|
199
200
|
inputSchema: {
|
|
200
201
|
type: "object",
|
|
@@ -203,8 +204,8 @@ const requestChoiceTool = {
|
|
|
203
204
|
options: {
|
|
204
205
|
type: "array",
|
|
205
206
|
items: { type: "string" },
|
|
206
|
-
description: 'Unique option labels, in display order (e.g. ["
|
|
207
|
-
minItems:
|
|
207
|
+
description: 'Unique option labels, in display order (e.g. ["Reply now", "Reply later"])',
|
|
208
|
+
minItems: 1,
|
|
208
209
|
},
|
|
209
210
|
},
|
|
210
211
|
required: ["question", "options"],
|
|
@@ -213,8 +214,8 @@ const requestChoiceTool = {
|
|
|
213
214
|
const { question, options } = args;
|
|
214
215
|
if (!question)
|
|
215
216
|
throw new ToolError("question is required", 400);
|
|
216
|
-
if (!Array.isArray(options) || options.length <
|
|
217
|
-
throw new ToolError("options must contain at least
|
|
217
|
+
if (!Array.isArray(options) || options.length < 1 || options.some((o) => typeof o !== "string" || !o.trim())) {
|
|
218
|
+
throw new ToolError("options must contain at least 1 non-empty string", 400);
|
|
218
219
|
}
|
|
219
220
|
if (new Set(options).size !== options.length)
|
|
220
221
|
throw new ToolError("options must be unique", 400);
|
|
@@ -820,7 +821,7 @@ const sendEmailTool = {
|
|
|
820
821
|
return result;
|
|
821
822
|
},
|
|
822
823
|
};
|
|
823
|
-
export const agentTools = [notifyTool, requestInputTool,
|
|
824
|
+
export const agentTools = [notifyTool, requestInputTool, requestChoiceTool, fillPasswordTool, deviceGeolocationTool, readContactsTool, createContactTool, readCalendarTool, createCalendarEventTool, sendSmsTool, sendEmailTool, sendAlarmTool, readBatteryTool, setRingerModeTool];
|
|
824
825
|
export const agentToolMap = new Map(agentTools.map((t) => [t.name, t]));
|
|
825
826
|
const deviceNotificationsResource = {
|
|
826
827
|
uri: "notifications://device",
|
|
@@ -7,7 +7,7 @@ import { registerPending } from "../pending-requests.js";
|
|
|
7
7
|
import * as fs from "node:fs";
|
|
8
8
|
import { saveConfig } from "../config.js";
|
|
9
9
|
import { detectDefaultInterface } from "../network.js";
|
|
10
|
-
import { agentToolMap, agentResources, ToolError } from "../mcp-tools.js";
|
|
10
|
+
import { agentToolMap, agentResources, requestConfirmationTool, ToolError } from "../mcp-tools.js";
|
|
11
11
|
import { handleMcpRequest, getAgentName, getResourceSubscriptions } from "../mcp-handler.js";
|
|
12
12
|
import { getTaskDir } from "../task.js";
|
|
13
13
|
import { popEvent } from "../event-queues.js";
|
|
@@ -189,12 +189,13 @@ export async function startHttpTransport(config, handleRpc, port, nc, pairingCod
|
|
|
189
189
|
}
|
|
190
190
|
return;
|
|
191
191
|
}
|
|
192
|
-
|
|
192
|
+
const tool = agentToolMap.get(pathname.slice(1))
|
|
193
|
+
?? (pathname === `/${requestConfirmationTool.name}` ? requestConfirmationTool : undefined);
|
|
194
|
+
if (req.method === "POST" && tool) {
|
|
193
195
|
if (!isLocalhost(req)) {
|
|
194
196
|
sendJson(res, 403, { error: "localhost only" });
|
|
195
197
|
return;
|
|
196
198
|
}
|
|
197
|
-
const tool = agentToolMap.get(pathname.slice(1));
|
|
198
199
|
try {
|
|
199
200
|
const taskId = url.searchParams.get("taskId");
|
|
200
201
|
if (!taskId) {
|