granttap-mcp 0.8.15 → 0.8.16

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
@@ -223,7 +223,8 @@ grok plugin marketplace add sergii-ziborov/granttap-mcp
223
223
  grok plugin install granttap --trust
224
224
  ```
225
225
 
226
- Install **GrantTap** from the Cursor plugin marketplace, then open
226
+ Import `sergii-ziborov/granttap-mcp` as a private Git plugin in Cursor. A public
227
+ listing requires an open-source plugin license and Cursor review. Reload Cursor, then open
227
228
  **Cursor Customize → MCPs → GrantTap → Authenticate**. Complete authorization
228
229
  and any one-time QR pairing on `https://granttap.com/connect`.
229
230
 
@@ -1,6 +1,6 @@
1
1
  /** Per-user Windows Task Scheduler jobs for the loopback MCP and phone monitor. */
2
2
  import { spawnSync } from "node:child_process";
3
- import { existsSync, mkdirSync, unlinkSync, writeFileSync } from "node:fs";
3
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { dirname, join } from "node:path";
5
5
  import { configDir } from "./config";
6
6
  import type { InstallResult } from "./install";
@@ -18,7 +18,7 @@ function xml(value: string): string {
18
18
  .replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
19
19
  }
20
20
 
21
- export function windowsTaskDefinition(job: WindowsJob, node: string, launcher: string, owner = "TestUser"): string {
21
+ export function windowsTaskDefinition(job: WindowsJob, node: string, launcher: string, owner = "TestUser", version = "0.0.0"): string {
22
22
  const date = new Date(Date.now() - 60_000);
23
23
  const local = new Date(date.getTime() - date.getTimezoneOffset() * 60_000);
24
24
  const start = local.toISOString().slice(0, 19);
@@ -26,6 +26,7 @@ export function windowsTaskDefinition(job: WindowsJob, node: string, launcher: s
26
26
  return [
27
27
  '<?xml version="1.0" encoding="UTF-16"?>',
28
28
  '<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">',
29
+ `<RegistrationInfo><Description>GrantTap ${xml(version)} ${job}</Description></RegistrationInfo>`,
29
30
  "<Triggers><TimeTrigger>", `<StartBoundary>${start}</StartBoundary>`,
30
31
  "<Enabled>true</Enabled><Repetition><Interval>PT1M</Interval></Repetition>",
31
32
  "</TimeTrigger></Triggers>",
@@ -85,14 +86,22 @@ export function installWindowsTask(job: WindowsJob, node: string, launcher: stri
85
86
  }
86
87
  const owner = identity();
87
88
  if (!owner) return { status: "manual", detail: "Could not identify the current Windows user." };
89
+ let version: string;
90
+ try {
91
+ version = (JSON.parse(readFileSync(join(dirname(launcher), "..", "package.json"), "utf8")) as { version: string }).version;
92
+ if (!/^\d+\.\d+\.\d+$/.test(version)) throw new Error("invalid version");
93
+ } catch {
94
+ return { status: "manual", detail: "Installed GrantTap package version could not be read." };
95
+ }
88
96
  const path = taskFile(job);
89
- const definition = windowsTaskDefinition(job, node, launcher, owner);
97
+ const definition = windowsTaskDefinition(job, node, launcher, owner, version);
90
98
  const previousCommand = previous?.match(/<Command>([^<]*)<\/Command>/)?.[1];
91
99
  const previousArgs = previous?.match(/<Arguments>([^<]*)<\/Arguments>/)?.[1];
92
100
  const normalizedArgs = previousArgs?.replaceAll("&quot;", '"').replaceAll("&amp;", "&");
93
101
  const already = previousCommand === xml(node)
94
102
  && normalizedArgs === `"${launcher}" internal ${job === "http" ? "serve" : "monitor"}`
95
- && previous?.includes("<Interval>PT1M</Interval>") === true;
103
+ && previous?.includes("<Interval>PT1M</Interval>") === true
104
+ && previous.includes(`<Description>GrantTap ${version} ${job}</Description>`);
96
105
  if (already && !forceReload && inspectWindowsTask(job).running) return { status: "already", detail: names[job] };
97
106
  mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
98
107
  // Task Scheduler reads an XML file; keep it private to this user's config directory.
@@ -102,7 +111,9 @@ export function installWindowsTask(job: WindowsJob, node: string, launcher: stri
102
111
  });
103
112
  unlinkSync(path);
104
113
  if (created.status !== 0) return { status: "manual", detail: `${names[job]} could not be registered for this Windows user.` };
105
- if (forceReload && previous) spawnSync("schtasks.exe", ["/End", "/TN", names[job]], { windowsHide: true });
114
+ if (previous && (forceReload || !already)) {
115
+ spawnSync("schtasks.exe", ["/End", "/TN", names[job]], { windowsHide: true });
116
+ }
106
117
  const started = spawnSync("schtasks.exe", ["/Run", "/TN", names[job]], { encoding: "utf8", windowsHide: true });
107
118
  return started.status === 0
108
119
  ? { status: already ? "already" : "installed", detail: names[job] }
@@ -6,8 +6,7 @@ each phone response tied to the exact originating chat and prompt.
6
6
 
7
7
  ## Connect Cursor
8
8
 
9
- Install the supported CLI and the GrantTap plugin from Cursor's marketplace,
10
- then run:
9
+ Install the supported CLI on this computer, then run:
11
10
 
12
11
  ```bash
13
12
  npm install -g granttap-mcp
@@ -39,12 +38,17 @@ The OAuth service listens only at `http://127.0.0.1:17342/mcp`. Cursor cannot
39
38
  show **Authenticate** for a stdio (`command`/`args`) MCP entry, so do not replace the
40
39
  plugin's HTTP configuration with stdio.
41
40
 
42
- ## Install from the Cursor marketplace
43
-
44
- Install **GrantTap** from Cursor's plugin marketplace, then reload Cursor.
45
- The plugin adds the `/connect` command, a connect skill, and the
46
- exact-correlation rule; `granttap setup` still configures the MCP endpoint
47
- itself.
41
+ ## Install the Cursor plugin
42
+
43
+ A public Cursor Marketplace listing requires an open-source plugin license and
44
+ manual review. The current commercially licensed plugin is available as a
45
+ private Git import: `sergii-ziborov/granttap-mcp`. Reload Cursor after import.
46
+ The private listing is tied to the version imported on that computer; re-import
47
+ it to pick up the current orange icon and plugin changes. If a public listing
48
+ is later approved, install **GrantTap** from Cursor's marketplace to receive
49
+ its reviewed updates. The plugin adds the `/connect` command, a connect
50
+ skill, and the exact-correlation rule; `granttap setup` configures the local
51
+ MCP endpoint separately.
48
52
 
49
53
  ## Exact dual-channel behavior
50
54
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "granttap-mcp",
3
- "version": "0.8.15",
3
+ "version": "0.8.16",
4
4
  "description": "Personal live control center runtime for local coding agents on iPhone and Apple Watch.",
5
5
  "type": "module",
6
6
  "bin": {