@mgcrea/mcp-apple-maps 1.15.0 → 1.16.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 +18 -3
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +114 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{server-CpYiHM_a.js → server-ip7LF8Un.js} +444 -5
- package/dist/server-ip7LF8Un.js.map +1 -0
- package/package.json +2 -2
- package/dist/server-CpYiHM_a.js.map +0 -1
package/README.md
CHANGED
|
@@ -20,20 +20,35 @@ from Maps' Core Data store.
|
|
|
20
20
|
| `apple_maps_list_favorites` | the places saved as favourites |
|
|
21
21
|
| `apple_maps_list_collections` | the Guides |
|
|
22
22
|
| `apple_maps_list_collection_places` | what is filed in one Guide |
|
|
23
|
+
| `apple_maps_list_unfiled_places` | saved places filed in no Guide |
|
|
23
24
|
| `apple_maps_list_recents` | where you have looked recently |
|
|
24
25
|
| `apple_maps_search_places` | all three at once, by name, label or address |
|
|
25
26
|
| `apple_maps_get_place` | one place, by ref |
|
|
26
27
|
| `apple_maps_diagnostics` | what opened, which columns resolved, what it cannot do |
|
|
27
28
|
|
|
29
|
+
## What it writes
|
|
30
|
+
|
|
31
|
+
Only with `APPLE_MAPS_ALLOW_WRITES=1`. Both are unregistered rather than refused when it is off, so a
|
|
32
|
+
client that has not opted in is never told they exist.
|
|
33
|
+
|
|
34
|
+
| Tool | What |
|
|
35
|
+
| ---------------------------- | --------------------------------------------------------- |
|
|
36
|
+
| `apple_maps_add_favorite` | save a place as a favourite, seeding it through `maps://` |
|
|
37
|
+
| `apple_maps_remove_favorite` | drop a favourite row |
|
|
38
|
+
|
|
28
39
|
## What it does not do
|
|
29
40
|
|
|
30
41
|
It reads what is **saved on this Mac**. It does not search Apple's map of the world, geocode an
|
|
31
42
|
address, give directions or compute a travel time. Those are network calls to Apple's services,
|
|
32
43
|
not data on your disk.
|
|
33
44
|
|
|
34
|
-
It
|
|
35
|
-
by `NSPersistentCloudKitContainer`, so
|
|
36
|
-
|
|
45
|
+
It writes only **favourites**, and only with `APPLE_MAPS_ALLOW_WRITES` set. Everything else here is
|
|
46
|
+
read-only. The store is mirrored to iCloud by `NSPersistentCloudKitContainer`, so a write is an edit
|
|
47
|
+
to one replica of a synchronising object graph underneath a running app — a malformed row reaches
|
|
48
|
+
every device on the account. That is why a place record is never fabricated: adding a favourite opens
|
|
49
|
+
`maps://` so that Maps itself mints the record, and only then is it copied. **The place is left in
|
|
50
|
+
your Recents whether or not you keep the favourite**, and resolving it over the network can take tens
|
|
51
|
+
of seconds.
|
|
37
52
|
|
|
38
53
|
## Full Disk Access is mandatory
|
|
39
54
|
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as MAPS_SURFACE, N as BUILD_INFO, a as loadConfig, r as createServer } from "./server-
|
|
2
|
+
import { C as MAPS_SURFACE, N as BUILD_INFO, a as loadConfig, r as createServer } from "./server-ip7LF8Un.js";
|
|
3
3
|
import { runStdioServer } from "@mgcrea/mcp-apple-core";
|
|
4
4
|
//#region src/cli.ts
|
|
5
5
|
const LOG_PREFIX = "apple-maps-mcp";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppleAutomationError, AppleAutomationError as AppleMapsError, BuildInfo, CORE_DATA_EPOCH_OFFSET, FileFacts, IndexUnavailableError, Logger, ReadOnlyMode, SchemaDriftError, StoreFacts, SurfaceContext } from "@mgcrea/mcp-apple-core";
|
|
1
|
+
import { AppleAutomationError, AppleAutomationError as AppleMapsError, BuildInfo, CORE_DATA_EPOCH_OFFSET, FileFacts, IndexUnavailableError, InterferenceWatch, Logger, ReadOnlyMode, SchemaDriftError, StoreFacts, SurfaceContext } from "@mgcrea/mcp-apple-core";
|
|
2
2
|
import { DatabaseSync } from "node:sqlite";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -135,6 +135,110 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
135
135
|
type Config = z.infer<typeof ConfigSchema>;
|
|
136
136
|
declare const loadConfig: (env?: NodeJS.ProcessEnv) => Config;
|
|
137
137
|
//#endregion
|
|
138
|
+
//#region src/client/ax.d.ts
|
|
139
|
+
type Guide = {
|
|
140
|
+
name: string;
|
|
141
|
+
places: number | null;
|
|
142
|
+
};
|
|
143
|
+
/** Injected so tests never shell out, matching `write.ts`'s `OpenUrl` seam. */
|
|
144
|
+
type OpenUrl$1 = (url: string) => void;
|
|
145
|
+
/**
|
|
146
|
+
* How long to wait for a card, a sheet or a picker.
|
|
147
|
+
*
|
|
148
|
+
* Overridable so a test can pin a "this never appeared" path without waiting for
|
|
149
|
+
* it. Ten seconds because a place has to resolve over the network before its
|
|
150
|
+
* card exists; sheets and pickers are local and get less.
|
|
151
|
+
*/
|
|
152
|
+
type Waits = {
|
|
153
|
+
card: number;
|
|
154
|
+
sheet: number;
|
|
155
|
+
};
|
|
156
|
+
declare class MapsAxLane {
|
|
157
|
+
#private;
|
|
158
|
+
private constructor();
|
|
159
|
+
/** Null when this server is not hosted by Cupertino — see `core/src/ax.ts`. */
|
|
160
|
+
static open(env?: NodeJS.ProcessEnv, openUrl?: OpenUrl$1, waits?: Partial<Waits>): MapsAxLane | null;
|
|
161
|
+
close(): void;
|
|
162
|
+
/** Start watching for someone using the Mac during a sequence. */
|
|
163
|
+
watch(): InterferenceWatch;
|
|
164
|
+
/**
|
|
165
|
+
* Open a place and wait for its card.
|
|
166
|
+
*
|
|
167
|
+
* The combined `q=` and `ll=` form, because a coordinate positions the map and
|
|
168
|
+
* a NAME selects a place — `write.ts` records the same thing for the same
|
|
169
|
+
* reason.
|
|
170
|
+
*/
|
|
171
|
+
openCard(place: {
|
|
172
|
+
name: string;
|
|
173
|
+
latitude: number;
|
|
174
|
+
longitude: number;
|
|
175
|
+
}): Promise<boolean>;
|
|
176
|
+
/**
|
|
177
|
+
* Is this place saved?
|
|
178
|
+
*
|
|
179
|
+
* Read off `AddButton`'s NAME, which is the state bit. `docs/desktop.md`
|
|
180
|
+
* corrected itself on this: `FavoriteButton` reports identical attributes
|
|
181
|
+
* either way, and the sibling carries `"Add"` versus `"Added"`.
|
|
182
|
+
*
|
|
183
|
+
* Localised, and that is a real limit rather than an oversight — there is no
|
|
184
|
+
* unlocalised state anywhere on this card.
|
|
185
|
+
*/
|
|
186
|
+
isSaved(): Promise<boolean | null>;
|
|
187
|
+
/**
|
|
188
|
+
* Save the open place into the Places library.
|
|
189
|
+
*
|
|
190
|
+
* Two presses, not one: `AddButton` raises a **"Name This Location"** sheet
|
|
191
|
+
* and nothing is written until its `Save` is pressed. The sheet REPLACES the
|
|
192
|
+
* window list — a full walk during it returns the sheet and nothing else — so
|
|
193
|
+
* the card's elements are unreachable until it closes, and `Save` carries no
|
|
194
|
+
* `AXIdentifier`, which is why it is addressed by name.
|
|
195
|
+
*/
|
|
196
|
+
savePlace(): Promise<boolean>;
|
|
197
|
+
/**
|
|
198
|
+
* Remove the open place from the Places library.
|
|
199
|
+
*
|
|
200
|
+
* The menu item is `delete_from_places`, and it is only present when the place
|
|
201
|
+
* IS saved — the same slot carries `add_to_places` when it is not. So its
|
|
202
|
+
* absence is a state reading rather than a failure, and this reports which.
|
|
203
|
+
*/
|
|
204
|
+
removePlace(): Promise<"removed" | "not-saved" | "no-menu">;
|
|
205
|
+
/**
|
|
206
|
+
* Every guide Maps knows about, read off its own picker.
|
|
207
|
+
*
|
|
208
|
+
* This is the authoritative list, and it is not the same as the store's:
|
|
209
|
+
* `docs/desktop.md` found the picker showing a "Favorites" guide that
|
|
210
|
+
* `apple_maps_list_collections` does not return. Read here as a side effect of
|
|
211
|
+
* being on the way to a write, rather than as a tool of its own — reaching it
|
|
212
|
+
* needs a place card, which needs a `maps://` open, which leaves a Recents
|
|
213
|
+
* entry. That is too much side effect for something calling itself a read.
|
|
214
|
+
*
|
|
215
|
+
* Leaves the picker OPEN, because the caller is normally about to press a row.
|
|
216
|
+
*/
|
|
217
|
+
openGuidePicker(): Promise<Guide[] | null>;
|
|
218
|
+
/** Press one guide row, then Done. Returns false if no row matched. */
|
|
219
|
+
chooseGuide(name: string): Promise<boolean>;
|
|
220
|
+
/**
|
|
221
|
+
* Re-open the card and read the state bit, which is the only way to verify.
|
|
222
|
+
*
|
|
223
|
+
* **A write closes the card.** Saving through the naming sheet dismisses the
|
|
224
|
+
* whole place card and returns Maps to its main view, so reading `AddButton`
|
|
225
|
+
* straight after a press finds nothing and reports "the card does not say it
|
|
226
|
+
* is saved" — which is a sentence about the write having failed, when what
|
|
227
|
+
* actually happened is that the thing being read went away.
|
|
228
|
+
*
|
|
229
|
+
* So verification re-opens the place first. That costs another `maps://`,
|
|
230
|
+
* which is free in the sense that matters: the Recents entry this leaves was
|
|
231
|
+
* already left by opening the card in the first place.
|
|
232
|
+
*/
|
|
233
|
+
verifySaved(place: {
|
|
234
|
+
name: string;
|
|
235
|
+
latitude: number;
|
|
236
|
+
longitude: number;
|
|
237
|
+
}): Promise<boolean | null>;
|
|
238
|
+
/** Abandon the picker without filing anything. */
|
|
239
|
+
cancelGuidePicker(): Promise<void>;
|
|
240
|
+
}
|
|
241
|
+
//#endregion
|
|
138
242
|
//#region src/client/store.d.ts
|
|
139
243
|
type FieldMap = {
|
|
140
244
|
/**
|
|
@@ -497,11 +601,20 @@ type CreateClientOptions = {
|
|
|
497
601
|
logger?: Logger;
|
|
498
602
|
/** Injected by tests so discovery never reaches the developer's real home. */
|
|
499
603
|
home?: string;
|
|
604
|
+
/**
|
|
605
|
+
* The interface lane, for tests.
|
|
606
|
+
*
|
|
607
|
+
* A seam of the same shape as `home`: null pins the store-only surface on a
|
|
608
|
+
* machine that IS hosted, and a stub drives the interface lane on one that is
|
|
609
|
+
* not. Undefined means "ask the environment", which is what the server does.
|
|
610
|
+
*/
|
|
611
|
+
ax?: MapsAxLane | null | undefined;
|
|
500
612
|
};
|
|
501
613
|
declare class AppleMapsClient {
|
|
502
614
|
#private;
|
|
503
615
|
constructor(opts: CreateClientOptions);
|
|
504
616
|
get config(): Config;
|
|
617
|
+
get axLane(): MapsAxLane | null;
|
|
505
618
|
located(): LocateResult;
|
|
506
619
|
/**
|
|
507
620
|
* A writer bound to the located store, or an error explaining why not.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/build-info.ts","../src/client/dates.ts","../src/client/errors.ts","../src/client/locate.ts","../src/config.ts","../src/client/store.ts","../src/client/ref.ts","../src/client/write.ts","../src/client/maps.ts","../src/server.ts","../src/tools/index.ts"],"mappings":";;;;;cAkBa,YAAY;;;;;;;;;;;;KCsBb;EACV;EACA;EACA;;cAMW,eAAY,6BAA+B,iBAA6B;;cAMxE,eAAe;;cAOf,gBAAa,sBAAwB,OAAS,UAAQ;;cAQtD,gBAAa,sBAAwB,OAAS;;;cC9D9C,cAAc;;;;;;;;;;;;cAgBd;;;;;;;;;;;;;;;;cA4BA,kCAAkC;WAC3B;EAElB,YAAY;;;cAUD,2BAA2B;WACpB;EAElB,YAAY;;;;;;;;;;;;cAmBD,4BAA4B;WACrB;EAElB,YAAY;;;;KC5BF,cAAc;EAAc;;KAE5B,eAAe;EACzB;EACA;;EAEA,YAAY;;EAEZ;EACA;;cAGW,mBAAgB;cAEhB,mBAAgB;cAgChB,cAAW;EAEpB;EACA;;EAEA,WAAW;MAEZ;;;;;;;;;;;;;;;cC9FG,cAAY,EAAA;;;;;;;;;;;;;;;GAIP,EAAA,KAAA;KAEC,SAAS,EAAE,aAAa;cAEvB,aAAU,MAAS,OAAO,eAA2B;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/build-info.ts","../src/client/dates.ts","../src/client/errors.ts","../src/client/locate.ts","../src/config.ts","../src/client/ax.ts","../src/client/store.ts","../src/client/ref.ts","../src/client/write.ts","../src/client/maps.ts","../src/server.ts","../src/tools/index.ts"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as fromStoreTime, C as MAPS_SURFACE, D as UndatableStoreError, E as SchemaDriftError, M as resolveEpoch, N as BUILD_INFO, O as APPLE_SECONDS, S as MAPS_BUNDLE_ID, T as PlaceNotFoundError, _ as defaultDirectory, a as loadConfig, b as AppleMapsError, c as introspect, d as InvalidMapsRefError, f as PLACE_REF_VERSION, g as encodePlaceRef, h as encodeCollectionRef, i as registerTools, j as renderInstant, k as CORE_DATA_EPOCH_OFFSET, l as openStore, m as decodePlaceRef, n as SERVER_VERSION, o as AppleMapsClient, p as decodeCollectionRef, r as createServer, s as MapsStore, t as SERVER_NAME, u as COLLECTION_REF_VERSION, v as defaultStorePath, w as MapsStoreUnavailableError, x as IndexUnavailableError, y as locateStore } from "./server-
|
|
1
|
+
import { A as fromStoreTime, C as MAPS_SURFACE, D as UndatableStoreError, E as SchemaDriftError, M as resolveEpoch, N as BUILD_INFO, O as APPLE_SECONDS, S as MAPS_BUNDLE_ID, T as PlaceNotFoundError, _ as defaultDirectory, a as loadConfig, b as AppleMapsError, c as introspect, d as InvalidMapsRefError, f as PLACE_REF_VERSION, g as encodePlaceRef, h as encodeCollectionRef, i as registerTools, j as renderInstant, k as CORE_DATA_EPOCH_OFFSET, l as openStore, m as decodePlaceRef, n as SERVER_VERSION, o as AppleMapsClient, p as decodeCollectionRef, r as createServer, s as MapsStore, t as SERVER_NAME, u as COLLECTION_REF_VERSION, v as defaultStorePath, w as MapsStoreUnavailableError, x as IndexUnavailableError, y as locateStore } from "./server-ip7LF8Un.js";
|
|
2
2
|
export { APPLE_SECONDS, AppleMapsClient, AppleMapsError, BUILD_INFO, COLLECTION_REF_VERSION, CORE_DATA_EPOCH_OFFSET, IndexUnavailableError, InvalidMapsRefError, MAPS_BUNDLE_ID, MAPS_SURFACE, MapsStore, MapsStoreUnavailableError, PLACE_REF_VERSION, PlaceNotFoundError, SERVER_NAME, SERVER_VERSION, SchemaDriftError, UndatableStoreError, createServer, decodeCollectionRef, decodePlaceRef, defaultDirectory, defaultStorePath, encodeCollectionRef, encodePlaceRef, fromStoreTime, introspect, loadConfig, locateStore, openStore, registerTools, renderInstant, resolveEpoch };
|