@manudota/artist-mcp 1.5.2-staging.72 → 1.5.2
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/dist/calendar.js +14 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.js +41 -1
- package/dist/init.js +7 -0
- package/dist/server.js +12 -4
- package/package.json +1 -1
package/dist/calendar.js
CHANGED
|
@@ -374,6 +374,20 @@ const draftFrom = (params) => {
|
|
|
374
374
|
if (new Date(end).getTime() < new Date(start).getTime()) {
|
|
375
375
|
throw failure('The event ends before it starts.');
|
|
376
376
|
}
|
|
377
|
+
// Equal ends are the subtler half, and they differ by kind.
|
|
378
|
+
//
|
|
379
|
+
// Google treats an all-day `end.date` as exclusive: a gig on the 11th ends on
|
|
380
|
+
// the 12th. `end` equal to `start` is an empty range, which Google refuses —
|
|
381
|
+
// and a model that does not know the convention writes it without hesitating.
|
|
382
|
+
// A timed event of zero length is not a gig either. Refused here rather than
|
|
383
|
+
// surfacing as a Google 400 that says nothing about what to do.
|
|
384
|
+
if (end === start) {
|
|
385
|
+
throw failure(allDay
|
|
386
|
+
? `An all-day event ends on the following day: Google reads the end date as ` +
|
|
387
|
+
`exclusive, so a single day on ${start} is start ${start}, end ` +
|
|
388
|
+
`${new Date(new Date(start).getTime() + 86_400_000).toISOString().slice(0, 10)}.`
|
|
389
|
+
: 'The event starts and ends at the same moment. Give it a duration.');
|
|
390
|
+
}
|
|
377
391
|
return {
|
|
378
392
|
calendar_id: calendarId,
|
|
379
393
|
summary: text(params.summary, 'summary', true),
|
package/dist/config.d.ts
CHANGED
|
@@ -6,6 +6,22 @@ export declare const ENTRY_NAME = "artist-notes";
|
|
|
6
6
|
* that read this file except against the developer's own Claude Desktop config,
|
|
7
7
|
* which a test suite has no business touching.
|
|
8
8
|
*/
|
|
9
|
+
/**
|
|
10
|
+
* Where Claude Desktop keeps its config on Windows, which is not one place.
|
|
11
|
+
*
|
|
12
|
+
* A packaged install — the one that appears under `AppData\Local\Packages` —
|
|
13
|
+
* has a **virtualised** `%APPDATA%`. Desktop reads
|
|
14
|
+
* `…\Packages\Claude_<id>\LocalCache\Roaming\Claude\`, while this process
|
|
15
|
+
* is an ordinary Node program whose `%APPDATA%` is the real `Roaming` folder.
|
|
16
|
+
* Writing to the obvious path therefore produced two config files that were
|
|
17
|
+
* each internally consistent and never the same one: `init` and `status` agreed
|
|
18
|
+
* with each other about a grant that Claude Desktop had never seen.
|
|
19
|
+
*
|
|
20
|
+
* Found the hard way, and the symptom is maddening — every check passes and the
|
|
21
|
+
* tools do not appear — so the packaged location wins when it exists rather
|
|
22
|
+
* than being offered as a fallback.
|
|
23
|
+
*/
|
|
24
|
+
export declare const windowsConfigPath: (home: string) => string;
|
|
9
25
|
export declare const configPath: () => string;
|
|
10
26
|
type Config = {
|
|
11
27
|
mcpServers?: Record<string, unknown>;
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Locating and editing the Claude Desktop config, without trampling it. */
|
|
2
2
|
import { homedir, platform } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
4
5
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
5
6
|
import { dirname } from "node:path";
|
|
6
7
|
export const ENTRY_NAME = "artist-notes";
|
|
@@ -10,6 +11,45 @@ export const ENTRY_NAME = "artist-notes";
|
|
|
10
11
|
* that read this file except against the developer's own Claude Desktop config,
|
|
11
12
|
* which a test suite has no business touching.
|
|
12
13
|
*/
|
|
14
|
+
/**
|
|
15
|
+
* Where Claude Desktop keeps its config on Windows, which is not one place.
|
|
16
|
+
*
|
|
17
|
+
* A packaged install — the one that appears under `AppData\Local\Packages` —
|
|
18
|
+
* has a **virtualised** `%APPDATA%`. Desktop reads
|
|
19
|
+
* `…\Packages\Claude_<id>\LocalCache\Roaming\Claude\`, while this process
|
|
20
|
+
* is an ordinary Node program whose `%APPDATA%` is the real `Roaming` folder.
|
|
21
|
+
* Writing to the obvious path therefore produced two config files that were
|
|
22
|
+
* each internally consistent and never the same one: `init` and `status` agreed
|
|
23
|
+
* with each other about a grant that Claude Desktop had never seen.
|
|
24
|
+
*
|
|
25
|
+
* Found the hard way, and the symptom is maddening — every check passes and the
|
|
26
|
+
* tools do not appear — so the packaged location wins when it exists rather
|
|
27
|
+
* than being offered as a fallback.
|
|
28
|
+
*/
|
|
29
|
+
export const windowsConfigPath = (home) => {
|
|
30
|
+
const roaming = process.env.APPDATA ?? join(home, "AppData", "Roaming");
|
|
31
|
+
const plain = join(roaming, "Claude", "claude_desktop_config.json");
|
|
32
|
+
const packagesRoot = process.env.LOCALAPPDATA ?? join(home, "AppData", "Local");
|
|
33
|
+
try {
|
|
34
|
+
const packages = readdirSync(join(packagesRoot, "Packages"))
|
|
35
|
+
.filter((name) => /^Claude_/i.test(name))
|
|
36
|
+
.map((name) => join(packagesRoot, "Packages", name, "LocalCache", "Roaming", "Claude", "claude_desktop_config.json"));
|
|
37
|
+
// An existing packaged config is the one Desktop reads. If more than one
|
|
38
|
+
// package directory exists, prefer one that already holds a config over an
|
|
39
|
+
// empty shell left by an uninstall.
|
|
40
|
+
const written = packages.find((candidate) => existsSync(candidate));
|
|
41
|
+
if (written)
|
|
42
|
+
return written;
|
|
43
|
+
// A packaged install with no config yet: still the right place to write,
|
|
44
|
+
// since the plain path would be ignored.
|
|
45
|
+
if (packages.length > 0 && !existsSync(plain))
|
|
46
|
+
return packages[0];
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// No Packages directory at all — an ordinary install. Fall through.
|
|
50
|
+
}
|
|
51
|
+
return plain;
|
|
52
|
+
};
|
|
13
53
|
export const configPath = () => {
|
|
14
54
|
const override = process.env.ARTIST_MCP_CONFIG;
|
|
15
55
|
if (override)
|
|
@@ -19,7 +59,7 @@ export const configPath = () => {
|
|
|
19
59
|
case "darwin":
|
|
20
60
|
return join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
21
61
|
case "win32":
|
|
22
|
-
return
|
|
62
|
+
return windowsConfigPath(home);
|
|
23
63
|
default:
|
|
24
64
|
// Claude Desktop ships on macOS and Windows only; this keeps the error
|
|
25
65
|
// legible rather than writing a config nothing will ever read.
|
package/dist/init.js
CHANGED
|
@@ -2,6 +2,7 @@ import { resolve } from "node:path";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { DEFAULT_EDITABLE_DIRECTORY, describeSeed, seedEditablePack } from "./agents.js";
|
|
4
4
|
import { isStagingVersion, packageVersion } from "./client.js";
|
|
5
|
+
import { sep } from "node:path";
|
|
5
6
|
import { configPath, ENTRY_NAME, readConfig, writeConfig } from "./config.js";
|
|
6
7
|
import { connectedProviders } from "./dispatch.js";
|
|
7
8
|
import { describeGrants, setGrants } from "./grants.js";
|
|
@@ -65,6 +66,12 @@ export const runInit = async ({ local = false, editableDir, grants = [], } = {})
|
|
|
65
66
|
config.mcpServers = servers;
|
|
66
67
|
await writeConfig(path, config);
|
|
67
68
|
console.log(`\nWrote "${ENTRY_NAME}" to ${path}`);
|
|
69
|
+
if (path.includes(`${sep}Packages${sep}`)) {
|
|
70
|
+
// Worth naming. A packaged Windows install virtualises %APPDATA%, so the
|
|
71
|
+
// obvious path is a different file that Claude Desktop never opens — and
|
|
72
|
+
// writing there fails invisibly: every check passes and no tool appears.
|
|
73
|
+
console.log(" (packaged Claude install — this is the config it reads)");
|
|
74
|
+
}
|
|
68
75
|
if (seeded) {
|
|
69
76
|
console.log("");
|
|
70
77
|
describeSeed(seeded);
|
package/dist/server.js
CHANGED
|
@@ -103,7 +103,7 @@ const selectNotebook = async (call, notebook, tool) => {
|
|
|
103
103
|
: null;
|
|
104
104
|
return { pages, scope };
|
|
105
105
|
};
|
|
106
|
-
const serverVersion = '1.5.2
|
|
106
|
+
const serverVersion = '1.5.2'; // x-release-please-version
|
|
107
107
|
const errorResult = (err) => {
|
|
108
108
|
const message = err instanceof GraphError ? err.message : `Unexpected error: ${err}`;
|
|
109
109
|
return { content: [{ type: "text", text: message }], isError: true };
|
|
@@ -809,7 +809,11 @@ const createServer = async (call) => {
|
|
|
809
809
|
start: z
|
|
810
810
|
.string()
|
|
811
811
|
.describe("YYYY-MM-DD for an all-day event, or an RFC3339 date-time such as 2026-10-16T20:00:00"),
|
|
812
|
-
end: z
|
|
812
|
+
end: z
|
|
813
|
+
.string()
|
|
814
|
+
.describe("The same kind as start: both dates, or both date-times. For an all-day " +
|
|
815
|
+
"event Google reads this as EXCLUSIVE, so a gig on 2028-09-11 is " +
|
|
816
|
+
"start 2028-09-11, end 2028-09-12"),
|
|
813
817
|
time_zone: z
|
|
814
818
|
.string()
|
|
815
819
|
.optional()
|
|
@@ -870,7 +874,10 @@ const createServer = async (call) => {
|
|
|
870
874
|
source_page: z
|
|
871
875
|
.string()
|
|
872
876
|
.optional()
|
|
873
|
-
.describe("The
|
|
877
|
+
.describe("The page id from list_notes or read_note, so the write can be traced back " +
|
|
878
|
+
"weeks later. The id, not the title: a notebook can hold two pages with " +
|
|
879
|
+
"the same or nearly the same name, which is exactly when tracing matters. " +
|
|
880
|
+
"Add the title after it if you like"),
|
|
874
881
|
}, async (params) => {
|
|
875
882
|
try {
|
|
876
883
|
const { created, link, calendar_id, written } = await call("create_calendar_event", params);
|
|
@@ -936,7 +943,8 @@ const createServer = async (call) => {
|
|
|
936
943
|
source_page: z
|
|
937
944
|
.string()
|
|
938
945
|
.optional()
|
|
939
|
-
.describe("The
|
|
946
|
+
.describe("The page id from list_notes or read_note, not the title — a title does not " +
|
|
947
|
+
"identify a page in a notebook holding near-duplicates"),
|
|
940
948
|
}, async (params) => {
|
|
941
949
|
try {
|
|
942
950
|
const { deleted, calendar_id } = await call("delete_calendar_event", params);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manudota/artist-mcp",
|
|
3
|
-
"version": "1.5.2
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "MCP server that reads your OneNote notes, with optional Gmail and Calendar as supporting evidence, via a hosted connection.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|