@zeph-to/mcp-server 1.11.2 → 1.12.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 +11 -2
- package/dist/api-client.d.ts +3 -17
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +7 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -13
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +5 -14
- package/dist/index.js +1 -1
- package/dist/poll.d.ts +2 -1
- package/dist/poll.d.ts.map +1 -1
- package/dist/poll.js +5 -0
- package/dist/sanitize.d.ts.map +1 -1
- package/dist/sanitize.js +9 -1
- package/dist/tools/ask.d.ts.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# @zeph-to/mcp-server
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@zeph-to/mcp-server)
|
|
4
|
+
[](https://www.npmjs.com/package/@zeph-to/mcp-server)
|
|
5
|
+
[](https://nodejs.org)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
|
|
3
8
|
Zeph MCP server for AI agents. Send notifications, copy to clipboard, request confirmations, and collect text input from users across their devices — all via the [Model Context Protocol](https://modelcontextprotocol.io).
|
|
4
9
|
|
|
5
10
|
## Setup
|
|
@@ -7,7 +12,7 @@ Zeph MCP server for AI agents. Send notifications, copy to clipboard, request co
|
|
|
7
12
|
The easiest way to set up for all agents at once:
|
|
8
13
|
|
|
9
14
|
```bash
|
|
10
|
-
npx @zeph-to/
|
|
15
|
+
npx @zeph-to/cli install
|
|
11
16
|
```
|
|
12
17
|
|
|
13
18
|
This saves credentials to `~/.zeph/config.json` and configures your agents automatically. The MCP server reads from this file — no env vars needed.
|
|
@@ -54,7 +59,7 @@ Add to `~/.claude/settings.json`:
|
|
|
54
59
|
| `ZEPH_BASE_URL` | No | API base URL (default: `https://api.zeph.to/v1`) |
|
|
55
60
|
| `ZEPH_DISABLE_SESSION_CACHE` | No | Set to `1`/`true` to skip writing the session-id handoff file under `~/.cache/zeph/`. Useful for read-only filesystems, ephemeral CI runners, or sandboxed envs that audit filesystem writes. The plugin's stop hook still works without it (transcript-path UUID extraction is the primary path; the cache is a fallback for older Claude Code versions). |
|
|
56
61
|
|
|
57
|
-
\* If env vars are not set, the server reads from `~/.zeph/config.json` (created by `npx @zeph-to/
|
|
62
|
+
\* If env vars are not set, the server reads from `~/.zeph/config.json` (created by `npx @zeph-to/cli install`). Unresolved `${...}` interpolations are also treated as unset.
|
|
58
63
|
|
|
59
64
|
## Tools
|
|
60
65
|
|
|
@@ -181,6 +186,10 @@ timeout: 120 (seconds, default: 120, max: 600)
|
|
|
181
186
|
|
|
182
187
|
Returns: `{ value: "feat: add clipboard sync", timedOut: false }`
|
|
183
188
|
|
|
189
|
+
### Client timeouts
|
|
190
|
+
|
|
191
|
+
`zeph_ask`, `zeph_prompt`, and `zeph_input` block until the user responds, up to their `timeout` (max 600s). That whole time the MCP request stays open. To keep the client from giving up early, the server emits a `notifications/progress` every 5s while waiting. Clients must either set a per-request timeout above the tool's `timeout`, or reset their timeout on progress notifications. Claude Code does the latter by default.
|
|
192
|
+
|
|
184
193
|
## Resources
|
|
185
194
|
|
|
186
195
|
### zeph://devices
|
package/dist/api-client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { McpServerConfig } from './config.js';
|
|
2
|
-
import type { PushResponse, HookTriggerResponse, HookEventResponse, DevicesResponse, PushListResponse, DismissResponse, ChannelsResponse, UploadRequestResponse } from './types.js';
|
|
2
|
+
import type { PushResponse, HookTriggerResponse, HookEventResponse, DevicesResponse, PushListResponse, DismissResponse, ChannelsResponse, UploadRequestResponse, AttachedFile } from './types.js';
|
|
3
3
|
export declare class ApiError extends Error {
|
|
4
4
|
readonly code: string;
|
|
5
5
|
readonly status: number;
|
|
@@ -18,14 +18,7 @@ export declare class ZephApiClient {
|
|
|
18
18
|
targetDeviceId?: string;
|
|
19
19
|
channelId?: string;
|
|
20
20
|
sessionId?: string;
|
|
21
|
-
files?:
|
|
22
|
-
fileKey: string;
|
|
23
|
-
fileName: string;
|
|
24
|
-
fileSize: number;
|
|
25
|
-
fileType: string;
|
|
26
|
-
iv?: string;
|
|
27
|
-
encryptedKey?: string;
|
|
28
|
-
}[];
|
|
21
|
+
files?: AttachedFile[];
|
|
29
22
|
isEncrypted?: boolean;
|
|
30
23
|
encryptedKey?: string;
|
|
31
24
|
senderPublicKey?: string;
|
|
@@ -41,14 +34,7 @@ export declare class ZephApiClient {
|
|
|
41
34
|
fallback?: string;
|
|
42
35
|
metadata?: Record<string, unknown>;
|
|
43
36
|
hookType?: 'one-way' | 'interactive' | 'input' | 'combo';
|
|
44
|
-
files?:
|
|
45
|
-
fileKey: string;
|
|
46
|
-
fileName: string;
|
|
47
|
-
fileSize: number;
|
|
48
|
-
fileType: string;
|
|
49
|
-
iv?: string;
|
|
50
|
-
encryptedKey?: string;
|
|
51
|
-
}[];
|
|
37
|
+
files?: AttachedFile[];
|
|
52
38
|
sessionId?: string;
|
|
53
39
|
}): Promise<HookTriggerResponse>;
|
|
54
40
|
getHookEvent(hookId: string, eventId: string): Promise<HookEventResponse>;
|
package/dist/api-client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAEV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAEV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,qBAAa,QAAS,SAAQ,KAAK;aAGf,IAAI,EAAE,MAAM;aACZ,MAAM,EAAE,MAAM;gBAF9B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM;CAKjC;AAKD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,eAAe;IAK7B,QAAQ,CAAC,MAAM,EAAE;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;QACvB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,YAAY,CAAC;IAInB,WAAW,CACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,QAAQ,CAAC,EAAE,SAAS,GAAG,aAAa,GAAG,OAAO,GAAG,OAAO,CAAC;QACzD,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC,mBAAmB,CAAC;IAIzB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIzE,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;IAIvC,UAAU,CAAC,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAQjF,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAIrD,gBAAgB,IAAI,OAAO,CAAC,eAAe,CAAC;IAI5C,YAAY,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIzC,aAAa,CAAC,MAAM,EAAE;QAC1B,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI5B,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAc7E,OAAO;CA0CtB"}
|
package/dist/api-client.js
CHANGED
|
@@ -91,12 +91,17 @@ class ZephApiClient {
|
|
|
91
91
|
throw err;
|
|
92
92
|
}
|
|
93
93
|
if (!response.ok) {
|
|
94
|
+
// Read the body as text once, then try to parse it. A non-JSON
|
|
95
|
+
// error (HTML proxy page, gateway error) would otherwise be swallowed
|
|
96
|
+
// silently — surface a truncated snippet so failures are debuggable.
|
|
97
|
+
const raw = await response.text().catch(() => '');
|
|
94
98
|
let errorBody = null;
|
|
95
99
|
try {
|
|
96
|
-
errorBody =
|
|
100
|
+
errorBody = raw ? JSON.parse(raw) : null;
|
|
97
101
|
}
|
|
98
102
|
catch {
|
|
99
|
-
|
|
103
|
+
if (raw)
|
|
104
|
+
console.error(`[api] ${response.status} non-JSON body: ${raw.slice(0, 200)}`);
|
|
100
105
|
}
|
|
101
106
|
const message = errorBody?.error?.message ?? `Request failed with status ${response.status}`;
|
|
102
107
|
const code = errorBody?.error?.code ?? 'UNKNOWN_ERROR';
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;CACvB;AAiBD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,aAAa,MAAM,EAAE,OAAO,MAAM,KAAG,MAGpE,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;CACvB;AAiBD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,aAAa,MAAM,EAAE,OAAO,MAAM,KAAG,MAGpE,CAAC;AAsGF,eAAO,MAAM,UAAU,QAAO,eAsB7B,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -43,22 +43,27 @@ const loadFileConfig = () => {
|
|
|
43
43
|
return {};
|
|
44
44
|
}
|
|
45
45
|
};
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
const SESSION_UUID_RE = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/;
|
|
47
|
+
/**
|
|
48
|
+
* Detect the Claude Code session ID for `projectDir`. Claude Code writes
|
|
49
|
+
* one transcript per session at `~/.claude/projects/<projectHash>/<uuid>.jsonl`
|
|
50
|
+
* where the hash is the project path with `/` replaced by `-`. We pick the
|
|
51
|
+
* most recently modified transcript — that's the live session.
|
|
52
|
+
*/
|
|
53
|
+
const detectClaudeSessionId = (projectDir) => {
|
|
48
54
|
try {
|
|
49
|
-
const projectDir = process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
|
|
50
55
|
const projectHash = projectDir.replace(/\//g, '-');
|
|
51
56
|
const sessionsDir = (0, path_1.join)((0, os_1.homedir)(), '.claude', 'projects', projectHash);
|
|
52
57
|
let latest;
|
|
53
|
-
for (const
|
|
54
|
-
|
|
58
|
+
for (const entry of (0, fs_1.readdirSync)(sessionsDir)) {
|
|
59
|
+
const match = SESSION_UUID_RE.exec(entry);
|
|
60
|
+
if (!match)
|
|
55
61
|
continue;
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
if (!stat.isDirectory())
|
|
62
|
+
const stat = (0, fs_1.statSync)((0, path_1.join)(sessionsDir, entry));
|
|
63
|
+
if (!stat.isFile())
|
|
59
64
|
continue;
|
|
60
65
|
if (!latest || stat.mtimeMs > latest.mtime) {
|
|
61
|
-
latest = { name, mtime: stat.mtimeMs };
|
|
66
|
+
latest = { name: match[1], mtime: stat.mtimeMs };
|
|
62
67
|
}
|
|
63
68
|
}
|
|
64
69
|
return latest?.name;
|
|
@@ -123,10 +128,10 @@ const loadConfig = () => {
|
|
|
123
128
|
const fileConfig = loadFileConfig();
|
|
124
129
|
const apiKey = resolvedEnv('ZEPH_API_KEY') ?? fileConfig.apiKey;
|
|
125
130
|
if (!apiKey) {
|
|
126
|
-
throw new Error('ZEPH_API_KEY not found. Run "npx @zeph-to/
|
|
131
|
+
throw new Error('ZEPH_API_KEY not found. Run "npx @zeph-to/cli install" or set ZEPH_API_KEY env var.');
|
|
127
132
|
}
|
|
128
|
-
const
|
|
129
|
-
const
|
|
133
|
+
const projectDir = detectProjectDir();
|
|
134
|
+
const sessionId = resolvedEnv('ZEPH_SESSION_ID') ?? detectClaudeSessionId(projectDir) ?? `sess_${(0, crypto_1.randomBytes)(12).toString('base64url')}`;
|
|
130
135
|
writeSessionCache(sessionId, projectDir);
|
|
131
136
|
return {
|
|
132
137
|
apiKey,
|
|
@@ -134,7 +139,7 @@ const loadConfig = () => {
|
|
|
134
139
|
hookId: resolvedEnv('ZEPH_HOOK_ID') ?? fileConfig.hookId,
|
|
135
140
|
deviceId: resolvedEnv('ZEPH_DEVICE_ID') ?? fileConfig.deviceId,
|
|
136
141
|
sessionId,
|
|
137
|
-
projectName: projectNameFromDir(
|
|
142
|
+
projectName: projectNameFromDir(projectDir),
|
|
138
143
|
};
|
|
139
144
|
};
|
|
140
145
|
exports.loadConfig = loadConfig;
|
package/dist/crypto.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAoJH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,EAAE,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAsE5E,CAAC;AA8BF,eAAO,MAAM,UAAU,QAAO,aAAa,GAAG,IAAqB,CAAC;AACpE,eAAO,MAAM,YAAY,QAAO,MAAM,GAAG,IAA+B,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,sBAAsB,GACjC,OAAO;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,KACrD,OAAO,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,IAAI,CAAC;CACnB,CAaA,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,KACd,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAQlE,CAAC"}
|
package/dist/crypto.js
CHANGED
|
@@ -34,21 +34,12 @@ const fs_1 = require("fs");
|
|
|
34
34
|
const os_1 = require("os");
|
|
35
35
|
const path_1 = require("path");
|
|
36
36
|
// ─── Base64 helpers ───
|
|
37
|
-
const toBase64 = (buffer) =>
|
|
38
|
-
const bytes = new Uint8Array(buffer);
|
|
39
|
-
let binary = '';
|
|
40
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
41
|
-
binary += String.fromCharCode(bytes[i]);
|
|
42
|
-
}
|
|
43
|
-
return btoa(binary);
|
|
44
|
-
};
|
|
37
|
+
const toBase64 = (buffer) => Buffer.from(buffer).toString('base64');
|
|
45
38
|
const fromBase64 = (base64) => {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
return bytes.buffer;
|
|
39
|
+
const buf = Buffer.from(base64, 'base64');
|
|
40
|
+
// Slice to the exact byte range — Buffer may share a larger pooled
|
|
41
|
+
// ArrayBuffer, so `.buffer` alone could expose unrelated memory.
|
|
42
|
+
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
52
43
|
};
|
|
53
44
|
// ─── ECDH key management ───
|
|
54
45
|
const ECDH_PARAMS = { name: 'ECDH', namedCurve: 'P-256' };
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ const channels_js_1 = require("./resources/channels.js");
|
|
|
22
22
|
const getVersion = () => {
|
|
23
23
|
try {
|
|
24
24
|
const pkg = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '..', 'package.json'), 'utf-8'));
|
|
25
|
-
return pkg.version;
|
|
25
|
+
return typeof pkg.version === 'string' ? pkg.version : '0.0.0';
|
|
26
26
|
}
|
|
27
27
|
catch {
|
|
28
28
|
return '0.0.0';
|
package/dist/poll.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { ServerNotification } from '@modelcontextprotocol/sdk/types.js';
|
|
1
2
|
import type { ZephApiClient } from './api-client.js';
|
|
2
3
|
import type { HookEventResponse } from './types.js';
|
|
3
4
|
export interface PollContext {
|
|
4
5
|
_meta?: {
|
|
5
6
|
progressToken?: string | number;
|
|
6
7
|
};
|
|
7
|
-
sendNotification: (notification:
|
|
8
|
+
sendNotification: (notification: ServerNotification) => Promise<void>;
|
|
8
9
|
}
|
|
9
10
|
export declare const pollForResponse: (client: ZephApiClient, hookId: string, eventId: string, timeoutSeconds: number, ctx: PollContext) => Promise<HookEventResponse | null>;
|
|
10
11
|
//# sourceMappingURL=poll.d.ts.map
|
package/dist/poll.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../src/poll.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../src/poll.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC5C,gBAAgB,EAAE,CAAC,YAAY,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAOD,eAAO,MAAM,eAAe,GAC1B,QAAQ,aAAa,EACrB,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,gBAAgB,MAAM,EACtB,KAAK,WAAW,KACf,OAAO,CAAC,iBAAiB,GAAG,IAAI,CA6ClC,CAAC"}
|
package/dist/poll.js
CHANGED
|
@@ -17,6 +17,11 @@ const pollForResponse = async (client, hookId, eventId, timeoutSeconds, ctx) =>
|
|
|
17
17
|
throw new Error('User cancelled the request');
|
|
18
18
|
if (event.data.status === 'timed_out')
|
|
19
19
|
return null;
|
|
20
|
+
// Only 'pending' should keep us polling. Anything else is server
|
|
21
|
+
// contract drift — fail fast instead of spinning until the timeout.
|
|
22
|
+
if (event.data.status !== 'pending') {
|
|
23
|
+
throw new Error(`Unexpected hook event status: ${String(event.data.status)}`);
|
|
24
|
+
}
|
|
20
25
|
// Throttled progress notification (every 5s)
|
|
21
26
|
if (progressToken !== undefined) {
|
|
22
27
|
const elapsed = Math.floor((Date.now() - startTime) / 1000);
|
package/dist/sanitize.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;CAC5C;AAeD;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAIhE,CAAC;
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;CAC5C;AAeD;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAIhE,CAAC;AAkBF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,GAAG,SAAS,KAAG,eAAe,EAAE,GAAG,SAgB7E,CAAC"}
|
package/dist/sanitize.js
CHANGED
|
@@ -42,9 +42,17 @@ const sanitizeText = (text) => {
|
|
|
42
42
|
return cut === -1 ? text : text.slice(0, cut).trimEnd();
|
|
43
43
|
};
|
|
44
44
|
exports.sanitizeText = sanitizeText;
|
|
45
|
+
// Bounds mirror the zeph_ask contract (1–4 actions). Length caps on the
|
|
46
|
+
// recovered strings keep a malformed/oversized leak from producing absurd
|
|
47
|
+
// buttons; the real server enforces its own limits too.
|
|
45
48
|
const isActionArray = (value) => Array.isArray(value) &&
|
|
46
49
|
value.length > 0 &&
|
|
47
|
-
value.
|
|
50
|
+
value.length <= 4 &&
|
|
51
|
+
value.every((a) => a &&
|
|
52
|
+
typeof a.id === 'string' &&
|
|
53
|
+
a.id.length <= 50 &&
|
|
54
|
+
typeof a.label === 'string' &&
|
|
55
|
+
a.label.length <= 100);
|
|
48
56
|
/**
|
|
49
57
|
* Recover an `actions` array that leaked into the body of a malformed
|
|
50
58
|
* zeph_ask call. Returns undefined when nothing parseable is found.
|
package/dist/tools/ask.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/tools/ask.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/tools/ask.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAwBrE,eAAO,MAAM,eAAe,GAAI,QAAQ,SAAS,EAAE,QAAQ,aAAa,EAAE,QAAQ,eAAe,SAgIhG,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -86,6 +86,14 @@ export interface UploadRequestResponse {
|
|
|
86
86
|
uploadUrl: string;
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
|
+
export interface AttachedFile {
|
|
90
|
+
fileKey: string;
|
|
91
|
+
fileName: string;
|
|
92
|
+
fileSize: number;
|
|
93
|
+
fileType: string;
|
|
94
|
+
iv?: string;
|
|
95
|
+
encryptedKey?: string;
|
|
96
|
+
}
|
|
89
97
|
export interface ToolError {
|
|
90
98
|
error: string;
|
|
91
99
|
message: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeph-to/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Zeph MCP server — AI agent notifications, prompts, and input via MCP protocol",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -62,5 +62,9 @@
|
|
|
62
62
|
"cursor",
|
|
63
63
|
"gemini"
|
|
64
64
|
],
|
|
65
|
-
"license": "Apache-2.0"
|
|
65
|
+
"license": "Apache-2.0",
|
|
66
|
+
"publishConfig": {
|
|
67
|
+
"access": "public",
|
|
68
|
+
"registry": "https://registry.npmjs.org/"
|
|
69
|
+
}
|
|
66
70
|
}
|