granttap-mcp 0.8.88 → 0.8.89
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/apps/bridge/src/capabilities/README.md +6 -0
- package/apps/bridge/src/capabilities/metadata.ts +4 -1
- package/apps/bridge/src/capabilities/types.ts +1 -1
- package/apps/bridge/src/mesh/catalog/project/capabilities.ts +6 -0
- package/apps/bridge/src/mesh/catalog/project/configured-mcp.ts +6 -0
- package/cursor-plugin/README.md +1 -1
- package/cursor-plugin/mcp.json +1 -1
- package/cursor-plugin/stdio-bootstrap.cjs +1 -1
- package/package.json +1 -1
- package/packages/protocol/messages/capabilities.ts +1 -0
- package/packages/protocol/messages/mesh/snapshot.ts +4 -0
|
@@ -11,4 +11,10 @@ Catalog observations and Project requests do not install a skill or native MCP
|
|
|
11
11
|
configuration on another host. Availability requires a separate native apply
|
|
12
12
|
and independently observed initialization; that rollout is still unfinished.
|
|
13
13
|
|
|
14
|
+
MCP descriptions come from `initialize.serverInfo.description`, trimmed and
|
|
15
|
+
bounded to 4,000 characters. Descriptions, validated icons and website metadata
|
|
16
|
+
travel with both session and Project catalogs; conflicting native implementations
|
|
17
|
+
do not borrow an implementation's description or icon. These are display data,
|
|
18
|
+
not instructions or evidence that a capability was used.
|
|
19
|
+
|
|
14
20
|
License: this module is distributed under the GrantTap Commercial Source License in the repository-root `LICENSE` file.
|
|
@@ -117,9 +117,12 @@ function stringRecord(value: unknown): Record<string, string> {
|
|
|
117
117
|
async function normalizeServerMetadata(info: Implementation | undefined, descriptor: McpDescriptor): Promise<ServerMetadata | undefined> {
|
|
118
118
|
if (!info) return undefined;
|
|
119
119
|
const title = typeof info.title === "string" && info.title.trim() ? info.title.trim().slice(0, 160) : undefined;
|
|
120
|
+
const description = typeof info.description === "string" && info.description.trim()
|
|
121
|
+
? info.description.trim().slice(0, 4_000) : undefined;
|
|
120
122
|
const website = typeof info.websiteUrl === "string" ? safeHttpsUrl(info.websiteUrl) : undefined;
|
|
121
123
|
const version = typeof info.version === "string" && info.version.trim() ? info.version.trim().slice(0, 80) : undefined;
|
|
122
|
-
return { title,
|
|
124
|
+
return { title, ...(description ? { description } : {}), websiteUrl: website?.toString(),
|
|
125
|
+
version, icons: await normalizedIcons(info, descriptor), metadataSource: "mcp" };
|
|
123
126
|
}
|
|
124
127
|
|
|
125
128
|
async function normalizedIcons(info: Implementation, descriptor: McpDescriptor): Promise<NonNullable<McpServerInfo["icons"]> | undefined> {
|
|
@@ -30,10 +30,16 @@ export function projectMcpServers(
|
|
|
30
30
|
current.configuredEnabled &&= server.configuredEnabled;
|
|
31
31
|
current.allowed &&= server.allowed;
|
|
32
32
|
current.title ??= server.title;
|
|
33
|
+
if (server.description) current.description ??= server.description;
|
|
34
|
+
if (server.websiteUrl) current.websiteUrl ??= server.websiteUrl;
|
|
35
|
+
if (server.icons) current.icons ??= server.icons;
|
|
33
36
|
} else {
|
|
34
37
|
catalog.set(key, {
|
|
35
38
|
name: server.name,
|
|
36
39
|
title: server.title,
|
|
40
|
+
...(server.description ? { description: server.description } : {}),
|
|
41
|
+
...(server.websiteUrl ? { websiteUrl: server.websiteUrl } : {}),
|
|
42
|
+
...(server.icons ? { icons: server.icons } : {}),
|
|
37
43
|
provider,
|
|
38
44
|
endpointId: session.computerId,
|
|
39
45
|
configuredEnabled: server.configuredEnabled,
|
|
@@ -16,6 +16,7 @@ export function configuredProjectMcpServers(
|
|
|
16
16
|
const implementation = server.configDigest ?? "";
|
|
17
17
|
const value: ProjectMcpServer = {
|
|
18
18
|
name: server.name, title: server.title, provider, endpointId,
|
|
19
|
+
description: server.description, websiteUrl: server.websiteUrl, icons: server.icons,
|
|
19
20
|
configuredEnabled: server.configuredEnabled, allowed: server.allowed,
|
|
20
21
|
authStatus: server.authStatus, version: server.version,
|
|
21
22
|
configDigest: server.configDigest,
|
|
@@ -29,6 +30,7 @@ export function configuredProjectMcpServers(
|
|
|
29
30
|
// Two admitted workspaces disagree. Avoid claiming either version
|
|
30
31
|
// as the Project's selected implementation.
|
|
31
32
|
rows.set(key, { ...value, version: undefined, configDigest: undefined,
|
|
33
|
+
description: undefined, websiteUrl: undefined, icons: undefined,
|
|
32
34
|
authStatus: "conflict" });
|
|
33
35
|
} else if (!prior) rows.set(key, value);
|
|
34
36
|
if (!prior) implementations.set(key, implementation);
|
|
@@ -63,6 +65,7 @@ export function mergeConfiguredMcpServers(
|
|
|
63
65
|
|| (configuredRow.configDigest != null || execution.configDigest != null)
|
|
64
66
|
&& configuredRow.configDigest !== execution.configDigest) {
|
|
65
67
|
rows.set(key, { ...configuredRow, version: undefined, configDigest: undefined,
|
|
68
|
+
description: undefined, websiteUrl: undefined, icons: undefined,
|
|
66
69
|
authStatus: "conflict",
|
|
67
70
|
sessionIds: execution.sessionIds });
|
|
68
71
|
continue;
|
|
@@ -70,6 +73,9 @@ export function mergeConfiguredMcpServers(
|
|
|
70
73
|
rows.set(key, {
|
|
71
74
|
...configuredRow, ...execution,
|
|
72
75
|
version: execution.version ?? configuredRow.version,
|
|
76
|
+
description: execution.description ?? configuredRow.description,
|
|
77
|
+
websiteUrl: execution.websiteUrl ?? configuredRow.websiteUrl,
|
|
78
|
+
icons: execution.icons ?? configuredRow.icons,
|
|
73
79
|
configDigest: execution.configDigest ?? configuredRow.configDigest,
|
|
74
80
|
authStatus: execution.authStatus ?? configuredRow.authStatus,
|
|
75
81
|
});
|
package/cursor-plugin/README.md
CHANGED
|
@@ -10,7 +10,7 @@ keeps each phone response tied to the exact originating chat and prompt.
|
|
|
10
10
|
Install the supported CLI on this computer, then run:
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npm install -g granttap-mcp@0.8.
|
|
13
|
+
npm install -g granttap-mcp@0.8.89
|
|
14
14
|
granttap setup
|
|
15
15
|
granttap status
|
|
16
16
|
```
|
package/cursor-plugin/mcp.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"command": "node",
|
|
5
5
|
"args": [
|
|
6
6
|
"-e",
|
|
7
|
-
"\"use strict\";\n\n// Cursor may start this MCP from any cwd. Execute JavaScript entry points with\n// Node itself: Windows batch shims require shell quoting that differs by host.\nconst { spawn } = require(\"node:child_process\");\nconst { existsSync } = require(\"node:fs\");\nconst { delimiter, dirname, join } = require(\"node:path\");\n\nconst PACKAGE = \"granttap-mcp@0.8.
|
|
7
|
+
"\"use strict\";\n\n// Cursor may start this MCP from any cwd. Execute JavaScript entry points with\n// Node itself: Windows batch shims require shell quoting that differs by host.\nconst { spawn } = require(\"node:child_process\");\nconst { existsSync } = require(\"node:fs\");\nconst { delimiter, dirname, join } = require(\"node:path\");\n\nconst PACKAGE = \"granttap-mcp@0.8.89\";\nconst dryRun = process.env.GRANTTAP_BOOTSTRAP_DRY_RUN === \"1\";\nconst platform = dryRun && process.env.GRANTTAP_BOOTSTRAP_PLATFORM\n ? process.env.GRANTTAP_BOOTSTRAP_PLATFORM : process.platform;\nconst nodeRoot = dryRun && process.env.GRANTTAP_BOOTSTRAP_NODE_ROOT\n ? process.env.GRANTTAP_BOOTSTRAP_NODE_ROOT : dirname(process.execPath);\nconst pathRoots = (process.env.PATH || \"\").split(delimiter).filter(Boolean);\nconst appData = process.env.APPDATA;\nconst roots = [nodeRoot, ...pathRoots, ...(appData ? [join(appData, \"npm\")] : [])];\nconst first = (paths) => paths.find((path) => existsSync(path));\n\nfunction launch() {\n if (platform !== \"win32\") {\n const installed = first(roots.map((root) => join(root, \"granttap-mcp\")));\n if (installed) return { command: installed, args: [] };\n const npx = first(roots.map((root) => join(root, \"npx\"))) || \"npx\";\n return { command: npx, args: [\"-y\", PACKAGE] };\n }\n const installed = first(roots.map((root) =>\n join(root, \"node_modules\", \"granttap-mcp\", \"bin\", \"granttap-mcp.mjs\")));\n if (installed) return { command: process.execPath, args: [installed] };\n const npx = first(roots.map((root) =>\n join(root, \"node_modules\", \"npm\", \"bin\", \"npx-cli.js\")));\n if (npx) return { command: process.execPath, args: [npx, \"-y\", PACKAGE] };\n throw new Error(\"Node.js/npm 22.13.0+ is required on this Windows device. Install npm and retry GrantTap.\");\n}\n\nlet target;\ntry { target = launch(); }\ncatch (error) {\n process.stderr.write(`[granttap] ${error.message}\\n`);\n process.exit(1);\n}\n\nif (dryRun) {\n process.stdout.write(JSON.stringify(target));\n process.exit(0);\n}\n\nconst child = spawn(target.command, target.args, { stdio: \"inherit\", windowsHide: true });\nchild.on(\"error\", (error) => {\n process.stderr.write(`[granttap] ${error.message}\\n`);\n process.exit(1);\n});\nchild.on(\"exit\", (code, signal) => {\n if (signal && platform !== \"win32\") {\n try { process.kill(process.pid, signal); } catch { process.exit(code ?? 1); }\n return;\n }\n process.exit(code ?? 1);\n});\n"
|
|
8
8
|
]
|
|
9
9
|
}
|
|
10
10
|
}
|
|
@@ -7,7 +7,7 @@ const { spawn } = require("node:child_process");
|
|
|
7
7
|
const { existsSync } = require("node:fs");
|
|
8
8
|
const { delimiter, dirname, join } = require("node:path");
|
|
9
9
|
|
|
10
|
-
const PACKAGE = "granttap-mcp@0.8.
|
|
10
|
+
const PACKAGE = "granttap-mcp@0.8.89";
|
|
11
11
|
const dryRun = process.env.GRANTTAP_BOOTSTRAP_DRY_RUN === "1";
|
|
12
12
|
const platform = dryRun && process.env.GRANTTAP_BOOTSTRAP_PLATFORM
|
|
13
13
|
? process.env.GRANTTAP_BOOTSTRAP_PLATFORM : process.platform;
|
package/package.json
CHANGED
|
@@ -183,6 +183,7 @@ export const McpServerInfo = z.object({
|
|
|
183
183
|
allowed: z.boolean(),
|
|
184
184
|
authStatus: z.string().optional(),
|
|
185
185
|
title: z.string().max(160).optional(),
|
|
186
|
+
description: z.string().max(4_000).optional(),
|
|
186
187
|
websiteUrl: z.string().url().optional(),
|
|
187
188
|
version: z.string().max(80).optional(),
|
|
188
189
|
configDigest: z.string().regex(/^[a-f0-9]{64}$/).optional(),
|
|
@@ -3,6 +3,7 @@ import { SharedSkill, EndpointModelCatalog } from "./catalog/provider";
|
|
|
3
3
|
export * from "./catalog/provider";
|
|
4
4
|
import { ProjectCodeMap } from "./graph/code-map";
|
|
5
5
|
import { Identifier, Label, MeshProvider } from "./endpoint";
|
|
6
|
+
import { McpIcon } from "../capabilities";
|
|
6
7
|
import {
|
|
7
8
|
ProjectEnvironment,
|
|
8
9
|
ProjectExecutionPolicy,
|
|
@@ -44,6 +45,9 @@ export type IntegrationPeer = z.infer<typeof IntegrationPeer>;
|
|
|
44
45
|
export const ProjectMcpServer = z.object({
|
|
45
46
|
name: Label,
|
|
46
47
|
title: Label.optional(),
|
|
48
|
+
description: z.string().max(4_000).optional(),
|
|
49
|
+
websiteUrl: z.string().url().optional(),
|
|
50
|
+
icons: z.array(McpIcon).max(2).optional(),
|
|
47
51
|
provider: MeshProvider,
|
|
48
52
|
endpointId: Identifier,
|
|
49
53
|
configuredEnabled: z.boolean(),
|