@tiongcreative/assistant-mcp 0.3.0 → 0.4.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/CHANGELOG.md +6 -0
- package/README.md +14 -0
- package/package.json +2 -2
- package/src/chatgpt-install.js +78 -0
- package/src/install.js +40 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.0] - 2026-10-19
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- One-command setup, status and removal for ChatGPT desktop on the same Mac. ChatGPT runs the existing local assistant server; app access still depends on each app's assistant setting.
|
|
8
|
+
|
|
3
9
|
## [0.3.0] - 2026-10-19
|
|
4
10
|
|
|
5
11
|
### Added
|
package/README.md
CHANGED
|
@@ -40,6 +40,20 @@ Desktop starts it, so after installing another app restart Claude Desktop once.
|
|
|
40
40
|
|
|
41
41
|
To remove it: `npx @tiongcreative/assistant-mcp uninstall`. To check: `npx @tiongcreative/assistant-mcp status`.
|
|
42
42
|
|
|
43
|
+
### ChatGPT desktop on the same Mac
|
|
44
|
+
|
|
45
|
+
For ChatGPT desktop, run this one command instead:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
npx @tiongcreative/assistant-mcp install chatgpt
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
It registers the same local server in ChatGPT's MCP settings. Restart ChatGPT, turn on
|
|
52
|
+
**Allow assistant access** in each app, and type `/mcp` in ChatGPT to check the connection.
|
|
53
|
+
The Tiong Creative apps must be open on this Mac. This setup is for ChatGPT desktop, not
|
|
54
|
+
ChatGPT in a web browser. To check or remove it, run `npx @tiongcreative/assistant-mcp status chatgpt`
|
|
55
|
+
or `npx @tiongcreative/assistant-mcp uninstall chatgpt`.
|
|
56
|
+
|
|
43
57
|
For Claude Code: `claude mcp add tiongcreative -- npx -y @tiongcreative/assistant-mcp`.
|
|
44
58
|
|
|
45
59
|
## How it stays on your Mac
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiongcreative/assistant-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "MCP server that lets an AI assistant on your Mac use your Tiong Creative apps while they are open.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"prepare": "husky",
|
|
35
35
|
"validate": "npm run lint && npm run format:check",
|
|
36
36
|
"quality": "npm run validate && npm run sast && npm run security && npm run secrets && npm run licenses && npm run deps:check && npm run review",
|
|
37
|
-
"test:unit": "node --test tests/dates.test.js tests/install.test.js",
|
|
37
|
+
"test:unit": "node --test tests/dates.test.js tests/install.test.js tests/chatgpt-install.test.js",
|
|
38
38
|
"test:integration": "node --test tests/due-again.test.js tests/gift-keeper.test.js tests/client-manager.test.js tests/lists-and-notes.test.js"
|
|
39
39
|
},
|
|
40
40
|
"license": "MIT",
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// ChatGPT desktop and Codex share MCP configuration. Use the CLI shipped with
|
|
2
|
+
// ChatGPT to edit it, so other servers and unrelated settings stay intact.
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { execFileSync } from 'node:child_process';
|
|
7
|
+
import { npxPath, SERVER_KEY } from './install.js';
|
|
8
|
+
|
|
9
|
+
const PACKAGE = '@tiongcreative/assistant-mcp';
|
|
10
|
+
|
|
11
|
+
function cliPath() {
|
|
12
|
+
const relative = path.join('Contents', 'Resources', 'codex-cli', 'bin', 'codex');
|
|
13
|
+
for (const apps of ['/Applications', path.join(os.homedir(), 'Applications')]) {
|
|
14
|
+
const candidate = path.join(apps, 'ChatGPT.app', relative);
|
|
15
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
16
|
+
}
|
|
17
|
+
throw new Error(
|
|
18
|
+
'ChatGPT desktop was not found in Applications. Install it before running this command.',
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function run(cli, args) {
|
|
23
|
+
try {
|
|
24
|
+
return execFileSync(cli, args, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
25
|
+
} catch (err) {
|
|
26
|
+
const detail = err.stderr?.toString().trim() || err.message;
|
|
27
|
+
throw new Error(`ChatGPT could not update its MCP settings: ${detail}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function current(cli) {
|
|
32
|
+
const servers = JSON.parse(run(cli, ['mcp', 'list', '--json']));
|
|
33
|
+
if (!Array.isArray(servers)) throw new Error('ChatGPT returned an unexpected MCP server list.');
|
|
34
|
+
return servers.find((server) => server.name === SERVER_KEY) ?? null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function matches(server, env) {
|
|
38
|
+
const transport = server?.transport;
|
|
39
|
+
return (
|
|
40
|
+
transport?.type === 'stdio' &&
|
|
41
|
+
transport.command === npxPath() &&
|
|
42
|
+
JSON.stringify(transport.args) === JSON.stringify(['-y', PACKAGE]) &&
|
|
43
|
+
JSON.stringify(transport.env ?? {}) === JSON.stringify(env)
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function chatGptStatus(cli = cliPath()) {
|
|
48
|
+
const server = current(cli);
|
|
49
|
+
return { installed: !!server, managed: matches(server, server?.transport?.env ?? {}) };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function installChatGpt({ allowFresh = false, cli = cliPath() } = {}) {
|
|
53
|
+
const env = allowFresh ? { npm_config_min_release_age: '0' } : {};
|
|
54
|
+
const server = current(cli);
|
|
55
|
+
if (matches(server, env)) return { already: true };
|
|
56
|
+
if (server) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
'An MCP server named "tiongcreative" already exists in ChatGPT. Remove it in ChatGPT settings before installing this one.',
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const args = ['mcp', 'add'];
|
|
62
|
+
for (const [key, value] of Object.entries(env)) args.push('--env', `${key}=${value}`);
|
|
63
|
+
args.push(SERVER_KEY, '--', npxPath(), '-y', PACKAGE);
|
|
64
|
+
run(cli, args);
|
|
65
|
+
return { already: false };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function uninstallChatGpt(cli = cliPath()) {
|
|
69
|
+
const server = current(cli);
|
|
70
|
+
if (!server) return { removed: false };
|
|
71
|
+
if (!matches(server, server.transport?.env ?? {})) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
'The "tiongcreative" entry in ChatGPT does not match this package; nothing was removed.',
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
run(cli, ['mcp', 'remove', SERVER_KEY]);
|
|
77
|
+
return { removed: true };
|
|
78
|
+
}
|
package/src/install.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import fs from 'node:fs';
|
|
8
8
|
import os from 'node:os';
|
|
9
9
|
import path from 'node:path';
|
|
10
|
+
import { chatGptStatus, installChatGpt, uninstallChatGpt } from './chatgpt-install.js';
|
|
10
11
|
|
|
11
12
|
export const SERVER_KEY = 'tiongcreative';
|
|
12
13
|
const PACKAGE = '@tiongcreative/assistant-mcp';
|
|
@@ -109,8 +110,45 @@ const NEXT_STEPS = [
|
|
|
109
110
|
|
|
110
111
|
/** Runs the command and returns the process exit code. Prints with the given writer. */
|
|
111
112
|
export function runCli(args, print = console.log) {
|
|
112
|
-
const [command] = args;
|
|
113
|
+
const [command, client] = args;
|
|
113
114
|
try {
|
|
115
|
+
if (client === 'chatgpt' && ['install', 'uninstall', 'status'].includes(command)) {
|
|
116
|
+
if (command === 'install') {
|
|
117
|
+
const result = installChatGpt({ allowFresh: args.includes('--allow-fresh') });
|
|
118
|
+
print(
|
|
119
|
+
result.already
|
|
120
|
+
? 'The Tiong Creative assistant is already set up in ChatGPT.'
|
|
121
|
+
: 'Added the Tiong Creative assistant to ChatGPT.',
|
|
122
|
+
);
|
|
123
|
+
print(
|
|
124
|
+
'\nNext:\n1. Restart the ChatGPT desktop app.\n2. Open each Tiong Creative app and turn on "Allow assistant access" in Settings.\n3. Type /mcp in ChatGPT to check the connection.',
|
|
125
|
+
);
|
|
126
|
+
} else if (command === 'uninstall') {
|
|
127
|
+
const result = uninstallChatGpt();
|
|
128
|
+
print(
|
|
129
|
+
result.removed
|
|
130
|
+
? 'Removed the Tiong Creative assistant from ChatGPT. Restart ChatGPT to finish.'
|
|
131
|
+
: 'The Tiong Creative assistant was not set up in ChatGPT.',
|
|
132
|
+
);
|
|
133
|
+
} else {
|
|
134
|
+
const result = chatGptStatus();
|
|
135
|
+
print(
|
|
136
|
+
result.managed
|
|
137
|
+
? 'Set up in ChatGPT.'
|
|
138
|
+
: result.installed
|
|
139
|
+
? 'ChatGPT has a different MCP server named "tiongcreative".'
|
|
140
|
+
: 'Not set up in ChatGPT.',
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
return 0;
|
|
144
|
+
}
|
|
145
|
+
if (
|
|
146
|
+
client &&
|
|
147
|
+
client !== '--allow-fresh' &&
|
|
148
|
+
['install', 'uninstall', 'status'].includes(command)
|
|
149
|
+
) {
|
|
150
|
+
throw new Error('Choose "chatgpt" as the client, or omit it for Claude Desktop.');
|
|
151
|
+
}
|
|
114
152
|
if (command === 'install') {
|
|
115
153
|
const env = {};
|
|
116
154
|
// Developer convenience: `install --allow-fresh` passes npm's release-age override
|
|
@@ -146,7 +184,7 @@ export function runCli(args, print = console.log) {
|
|
|
146
184
|
return 0;
|
|
147
185
|
}
|
|
148
186
|
print(
|
|
149
|
-
`Usage:\n npx ${PACKAGE} install
|
|
187
|
+
`Usage:\n npx ${PACKAGE} install add the assistant to Claude Desktop\n npx ${PACKAGE} install chatgpt add it to ChatGPT desktop\n npx ${PACKAGE} uninstall [chatgpt] remove it from the chosen client\n npx ${PACKAGE} status [chatgpt] check the chosen client\n\nWith no command, this runs the MCP server itself.`,
|
|
150
188
|
);
|
|
151
189
|
return command === 'help' || command === '--help' ? 0 : 2;
|
|
152
190
|
} catch (err) {
|