open-museum-mcp 0.1.0 → 0.2.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 +40 -12
- package/dist/db.d.ts +46 -1
- package/dist/db.js +111 -4
- package/dist/db.js.map +1 -1
- package/dist/fetchers/aic.d.ts +2 -0
- package/dist/fetchers/aic.js +168 -0
- package/dist/fetchers/aic.js.map +1 -0
- package/dist/fetchers/cleveland.d.ts +2 -0
- package/dist/fetchers/cleveland.js +150 -0
- package/dist/fetchers/cleveland.js.map +1 -0
- package/dist/fetchers/helpers.d.ts +14 -0
- package/dist/fetchers/helpers.js +21 -0
- package/dist/fetchers/helpers.js.map +1 -0
- package/dist/fetchers/met.js +1 -6
- package/dist/fetchers/met.js.map +1 -1
- package/dist/server.js +69 -1
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +4 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# open-museum-mcp
|
|
2
2
|
|
|
3
|
+
[](https://github.com/cfpramod/open-museum-mcp/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/open-museum-mcp)
|
|
5
|
+
|
|
3
6
|
> Open-access museum search for MCP clients, with rights verification per museum.
|
|
4
7
|
|
|
5
8
|
## Why I built this
|
|
@@ -10,7 +13,7 @@ If anyone else is exploring open-access art, I hope this helps. The plan is to k
|
|
|
10
13
|
|
|
11
14
|
## What you get
|
|
12
15
|
|
|
13
|
-
- **One interface, registered museums.** The Met
|
|
16
|
+
- **One interface, registered museums.** The Met, Cleveland Museum of Art, and the Art Institute of Chicago are live. Smithsonian and Rijksmuseum are next.
|
|
14
17
|
- **Strict deny on ambiguity.** Records are validated against per-museum rights rules in code. Missing or unclear indicators drop the record; nothing is defaulted to "open".
|
|
15
18
|
- **Catalog-grade metadata.** A dynasty-aware date parser handles Tang, Edo, Safavid, Mughal and the rest. Regions normalize across museums. Attribution separates named artists from anonymous, workshop, "after", and attributed works.
|
|
16
19
|
- **Listable resources and deterministic citations.** `museum://{code}/{id}` resources, three citation styles, structured JSON search results.
|
|
@@ -65,14 +68,31 @@ A search call returns license-verified results in one normalized shape:
|
|
|
65
68
|
|
|
66
69
|
## Install
|
|
67
70
|
|
|
71
|
+
The package is on npm. The simplest setup is to add it directly to your MCP client config; `npx` will fetch and run it on first launch:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"mcpServers": {
|
|
76
|
+
"open-museum": {
|
|
77
|
+
"command": "npx",
|
|
78
|
+
"args": ["-y", "open-museum-mcp"]
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
That's it. Restart your MCP client and the tools below become available.
|
|
85
|
+
|
|
86
|
+
### From source (for contributors)
|
|
87
|
+
|
|
68
88
|
```bash
|
|
89
|
+
git clone https://github.com/cfpramod/open-museum-mcp
|
|
90
|
+
cd open-museum-mcp
|
|
69
91
|
npm install
|
|
70
92
|
npm run build
|
|
71
93
|
```
|
|
72
94
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
Add to your MCP config (`.mcp.json` in a project, or your user-level config):
|
|
95
|
+
Then point the MCP config at the built binary:
|
|
76
96
|
|
|
77
97
|
```json
|
|
78
98
|
{
|
|
@@ -85,8 +105,6 @@ Add to your MCP config (`.mcp.json` in a project, or your user-level config):
|
|
|
85
105
|
}
|
|
86
106
|
```
|
|
87
107
|
|
|
88
|
-
After restarting your MCP client, the tools below become available.
|
|
89
|
-
|
|
90
108
|
## Tools
|
|
91
109
|
|
|
92
110
|
| Tool | Description |
|
|
@@ -94,6 +112,8 @@ After restarting your MCP client, the tools below become available.
|
|
|
94
112
|
| `search_artworks(query, museum?, has_image?, limit?)` | Search across registered museums. Returns only records that pass the rights gate. |
|
|
95
113
|
| `get_artwork(id)` | Fetch a single artwork by its normalized ID (e.g. `met:436535`). |
|
|
96
114
|
| `cite(id, style?)` | Render a citation. `style`: `full` (artist, title, date, museum, license, URL), `caption` (image attribution), `short` (inline). |
|
|
115
|
+
| `discover_random(region?, period?, not_artist?, museum?)` | Pick one random artwork from the local cache that matches the constraints. Operates over what has already been searched and cached. Useful for breaking out of repetitive search territory. |
|
|
116
|
+
| `list_traditions()` | List the regions and periods present in the local cache, with per-museum record counts. Lets you see where holdings are well-represented and where they're sparse. |
|
|
97
117
|
|
|
98
118
|
### `cite` example outputs
|
|
99
119
|
|
|
@@ -140,10 +160,10 @@ Each accepted record carries:
|
|
|
140
160
|
|
|
141
161
|
- `imageOpenAccess`: the artwork's image may be reused under the recorded license.
|
|
142
162
|
- `metadataOpenAccess`: the artwork's catalog metadata may be reused (often broader than image rights).
|
|
143
|
-
- `license.type`: normalized license tier (`CC0`, `PD`, `CC-BY`, …;
|
|
163
|
+
- `license.type`: normalized license tier (`CC0`, `PD`, `CC-BY`, …; currently only emits `CC0`).
|
|
144
164
|
- `license.rawValue`: the museum's own field value, preserved.
|
|
145
165
|
- `license.verificationSource`: the exact museum field that was checked (e.g. `met.isPublicDomain`).
|
|
146
|
-
- `license.confidence`: `high` for unambiguous accepts (the only level
|
|
166
|
+
- `license.confidence`: `high` for unambiguous accepts (the only level emitted today).
|
|
147
167
|
- `license.verifiedAt`: ISO timestamp of when this verification ran.
|
|
148
168
|
|
|
149
169
|
This is what "rights-verified" means here: validated against published museum metadata using source-specific rules implemented in this repo, with strict deny on ambiguity. It is **not** a guarantee of third-party rights beyond what each museum's API publicly represents. See [Disclaimer](#disclaimer).
|
|
@@ -153,11 +173,19 @@ This is what "rights-verified" means here: validated against published museum me
|
|
|
153
173
|
| Museum | Code | Auth | Status |
|
|
154
174
|
|---|---|---|---|
|
|
155
175
|
| The Metropolitan Museum of Art | `met` | none | ✅ v0.1 |
|
|
156
|
-
| Cleveland Museum of Art | `cleveland` | none |
|
|
157
|
-
| Art Institute of Chicago | `aic` | none |
|
|
176
|
+
| Cleveland Museum of Art | `cleveland` | none | ✅ v0.2 |
|
|
177
|
+
| Art Institute of Chicago | `aic` | none | ✅ v0.2 |
|
|
158
178
|
| Smithsonian Open Access | `si` | API key (free) | 📋 v2 |
|
|
159
179
|
| Rijksmuseum | `rijks` | API key (free) | 📋 v2 |
|
|
160
180
|
|
|
181
|
+
## Suggest a museum
|
|
182
|
+
|
|
183
|
+
If you know an open-access collection that should be on this list and you can't write the adapter yourself, [open a museum-source issue](https://github.com/cfpramod/open-museum-mcp/issues/new?template=museum-source.yml). The form asks for the API URL, the rights field, and a sample record. Anyone — me, or a future contributor — can pick it up from there and build the adapter.
|
|
184
|
+
|
|
185
|
+
The contribution that matters is the source knowledge. Knowing what's in a collection and how that museum represents rights is the part the code can't do for itself.
|
|
186
|
+
|
|
187
|
+
If you can write the adapter, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
188
|
+
|
|
161
189
|
## Schema
|
|
162
190
|
|
|
163
191
|
Full TypeScript definitions in [`src/types.ts`](src/types.ts). The `Artwork` shape is stable; additional fields may be added but existing fields will not be repurposed.
|
|
@@ -178,8 +206,8 @@ Highlights:
|
|
|
178
206
|
|
|
179
207
|
## Roadmap
|
|
180
208
|
|
|
181
|
-
- v0.1: Met adapter, dynasty-aware date parser, license gate, `cite` tool, MCP resources.
|
|
182
|
-
- v0.2: Cleveland and AIC adapters
|
|
209
|
+
- v0.1: Met adapter, dynasty-aware date parser, license gate, `cite` tool, MCP resources.
|
|
210
|
+
- v0.2: Cleveland and AIC adapters (shipped); `discover_random` with constraints (`region`, `period`, `not_artist`), `list_traditions` next. **(here)**
|
|
183
211
|
- v0.5: Dominant-color extraction across museums (`color: "#3a5f7d"` discovery via `sharp`).
|
|
184
212
|
- v1.0: Artist-obscurity scoring (`object_count_total`, `museum_count`) for deliberate exploration of less-canonical work.
|
|
185
213
|
- v2.0: Smithsonian, Rijksmuseum, Wikimedia Commons (long-tail).
|
package/dist/db.d.ts
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
import type { Artwork } from './types.js';
|
|
1
|
+
import type { Artwork, Tradition } from './types.js';
|
|
2
2
|
export interface CacheConfig {
|
|
3
3
|
path: string;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* Constraints for {@link Cache.getRandomObject}. All fields are AND-combined.
|
|
7
|
+
* Region and period are exact matches against the normalized values stored
|
|
8
|
+
* by each fetcher; museum is the registered code (`met`, `cleveland`, …);
|
|
9
|
+
* notArtist is an exact-match exclusion list against the canonical
|
|
10
|
+
* `artist_name` column.
|
|
11
|
+
*/
|
|
12
|
+
export interface DiscoverFilter {
|
|
13
|
+
region?: string;
|
|
14
|
+
period?: string;
|
|
15
|
+
notArtist?: string[];
|
|
16
|
+
museumCode?: string;
|
|
17
|
+
}
|
|
5
18
|
/**
|
|
6
19
|
* SQLite-backed cache for normalized artworks and search-result IDs.
|
|
7
20
|
*
|
|
@@ -23,9 +36,41 @@ export declare class Cache {
|
|
|
23
36
|
constructor(config: CacheConfig);
|
|
24
37
|
private init;
|
|
25
38
|
upsertObject(art: Artwork): void;
|
|
39
|
+
/**
|
|
40
|
+
* Pick one random non-expired artwork that matches the constraints, or
|
|
41
|
+
* null if nothing matches.
|
|
42
|
+
*
|
|
43
|
+
* The query operates over the local cache only — meaning what the user
|
|
44
|
+
* has already searched and pulled. This is intentional: discover_random
|
|
45
|
+
* is a forcing-function over your search history, not a federated
|
|
46
|
+
* sample of every museum's catalog. Callers should seed the cache via
|
|
47
|
+
* search_artworks first.
|
|
48
|
+
*
|
|
49
|
+
* Note on `ORDER BY RANDOM()`: SQLite scans the matching set, which is
|
|
50
|
+
* fine for caches under ~100k rows. The cache here is bounded by what
|
|
51
|
+
* the user actually fetches and the 90-day object TTL.
|
|
52
|
+
*/
|
|
53
|
+
getRandomObject(filter: DiscoverFilter): Artwork | null;
|
|
26
54
|
getObject(id: string): Artwork | null;
|
|
27
55
|
putQuery(cacheKey: string, ids: string[]): void;
|
|
28
56
|
getQuery(cacheKey: string): string[] | null;
|
|
57
|
+
/**
|
|
58
|
+
* List the regions and periods present in non-expired cached records,
|
|
59
|
+
* with per-museum coverage counts. Useful for the `list_traditions`
|
|
60
|
+
* tool — callers see which traditions are well-represented before
|
|
61
|
+
* searching, and where holdings are sparse.
|
|
62
|
+
*
|
|
63
|
+
* `label` is currently the title-cased tag; v1.0+ may swap in a curated
|
|
64
|
+
* lookup (e.g. "tang" → "Tang Dynasty (618–907)") if the tag set
|
|
65
|
+
* grows enough to warrant one.
|
|
66
|
+
*/
|
|
67
|
+
listTraditions(): {
|
|
68
|
+
regions: Tradition[];
|
|
69
|
+
periods: Tradition[];
|
|
70
|
+
};
|
|
71
|
+
private objectsCutoff;
|
|
72
|
+
private queriesCutoff;
|
|
73
|
+
private aggregateByTag;
|
|
29
74
|
pruneExpired(): {
|
|
30
75
|
objects: number;
|
|
31
76
|
queries: number;
|
package/dist/db.js
CHANGED
|
@@ -4,6 +4,13 @@ import { dirname } from 'node:path';
|
|
|
4
4
|
const OBJECT_TTL_DAYS = 90;
|
|
5
5
|
const QUERY_TTL_DAYS = 14;
|
|
6
6
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
7
|
+
// Title-cases the first letter of each whitespace/hyphen-bounded word in
|
|
8
|
+
// an ASCII tag. The tag set in regions.json and dynasties.json is currently
|
|
9
|
+
// ASCII-only; if a future tag introduces non-ASCII letters, switch to a
|
|
10
|
+
// Unicode-aware regex (`/u` flag + `\p{L}` property class).
|
|
11
|
+
function titleCase(s) {
|
|
12
|
+
return s.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
13
|
+
}
|
|
7
14
|
/**
|
|
8
15
|
* SQLite-backed cache for normalized artworks and search-result IDs.
|
|
9
16
|
*
|
|
@@ -127,6 +134,55 @@ export class Cache {
|
|
|
127
134
|
cached_at: new Date().toISOString(),
|
|
128
135
|
});
|
|
129
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Pick one random non-expired artwork that matches the constraints, or
|
|
139
|
+
* null if nothing matches.
|
|
140
|
+
*
|
|
141
|
+
* The query operates over the local cache only — meaning what the user
|
|
142
|
+
* has already searched and pulled. This is intentional: discover_random
|
|
143
|
+
* is a forcing-function over your search history, not a federated
|
|
144
|
+
* sample of every museum's catalog. Callers should seed the cache via
|
|
145
|
+
* search_artworks first.
|
|
146
|
+
*
|
|
147
|
+
* Note on `ORDER BY RANDOM()`: SQLite scans the matching set, which is
|
|
148
|
+
* fine for caches under ~100k rows. The cache here is bounded by what
|
|
149
|
+
* the user actually fetches and the 90-day object TTL.
|
|
150
|
+
*/
|
|
151
|
+
getRandomObject(filter) {
|
|
152
|
+
const conditions = [];
|
|
153
|
+
const params = [];
|
|
154
|
+
if (filter.region) {
|
|
155
|
+
conditions.push('region = ?');
|
|
156
|
+
params.push(filter.region);
|
|
157
|
+
}
|
|
158
|
+
if (filter.period) {
|
|
159
|
+
conditions.push('period = ?');
|
|
160
|
+
params.push(filter.period);
|
|
161
|
+
}
|
|
162
|
+
if (filter.museumCode) {
|
|
163
|
+
conditions.push('museum_code = ?');
|
|
164
|
+
params.push(filter.museumCode);
|
|
165
|
+
}
|
|
166
|
+
if (filter.notArtist && filter.notArtist.length > 0) {
|
|
167
|
+
const placeholders = filter.notArtist.map(() => '?').join(',');
|
|
168
|
+
conditions.push(`artist_name NOT IN (${placeholders})`);
|
|
169
|
+
params.push(...filter.notArtist);
|
|
170
|
+
}
|
|
171
|
+
// TTL gate: defense in depth on top of pruneExpired() at construction.
|
|
172
|
+
conditions.push('cached_at > ?');
|
|
173
|
+
params.push(new Date(Date.now() - OBJECT_TTL_DAYS * MS_PER_DAY).toISOString());
|
|
174
|
+
const where = `WHERE ${conditions.join(' AND ')}`;
|
|
175
|
+
const sql = `SELECT full_record FROM objects ${where} ORDER BY RANDOM() LIMIT 1`;
|
|
176
|
+
const row = this.db.prepare(sql).get(...params);
|
|
177
|
+
if (!row)
|
|
178
|
+
return null;
|
|
179
|
+
try {
|
|
180
|
+
return JSON.parse(row.full_record);
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
130
186
|
getObject(id) {
|
|
131
187
|
const row = this.db.prepare(`SELECT full_record, cached_at FROM objects WHERE id = ?`).get(id);
|
|
132
188
|
if (!row)
|
|
@@ -163,11 +219,62 @@ export class Cache {
|
|
|
163
219
|
return null;
|
|
164
220
|
}
|
|
165
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* List the regions and periods present in non-expired cached records,
|
|
224
|
+
* with per-museum coverage counts. Useful for the `list_traditions`
|
|
225
|
+
* tool — callers see which traditions are well-represented before
|
|
226
|
+
* searching, and where holdings are sparse.
|
|
227
|
+
*
|
|
228
|
+
* `label` is currently the title-cased tag; v1.0+ may swap in a curated
|
|
229
|
+
* lookup (e.g. "tang" → "Tang Dynasty (618–907)") if the tag set
|
|
230
|
+
* grows enough to warrant one.
|
|
231
|
+
*/
|
|
232
|
+
listTraditions() {
|
|
233
|
+
const cutoff = this.objectsCutoff();
|
|
234
|
+
return {
|
|
235
|
+
regions: this.aggregateByTag('region', cutoff),
|
|
236
|
+
periods: this.aggregateByTag('period', cutoff),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
objectsCutoff() {
|
|
240
|
+
return new Date(Date.now() - OBJECT_TTL_DAYS * MS_PER_DAY).toISOString();
|
|
241
|
+
}
|
|
242
|
+
queriesCutoff() {
|
|
243
|
+
return new Date(Date.now() - QUERY_TTL_DAYS * MS_PER_DAY).toISOString();
|
|
244
|
+
}
|
|
245
|
+
// Two literal SQL strings instead of `${column}` interpolation, so the
|
|
246
|
+
// README §Security claim "zero string-concatenated SQL paths" stays
|
|
247
|
+
// verbatim true. The `LOWER()` case-fold is defense-in-depth: if a future
|
|
248
|
+
// fetcher forgets to lowercase a tag, the variants still aggregate under
|
|
249
|
+
// one entry. The `tag != ''` filter drops empty-string ghosts so they
|
|
250
|
+
// can't surface as "" entries in the output.
|
|
251
|
+
aggregateByTag(column, cutoff) {
|
|
252
|
+
const sql = column === 'region'
|
|
253
|
+
? `SELECT LOWER(region) AS tag, museum_code, COUNT(*) AS cnt
|
|
254
|
+
FROM objects
|
|
255
|
+
WHERE region IS NOT NULL AND region != '' AND cached_at > ?
|
|
256
|
+
GROUP BY LOWER(region), museum_code`
|
|
257
|
+
: `SELECT LOWER(period) AS tag, museum_code, COUNT(*) AS cnt
|
|
258
|
+
FROM objects
|
|
259
|
+
WHERE period IS NOT NULL AND period != '' AND cached_at > ?
|
|
260
|
+
GROUP BY LOWER(period), museum_code`;
|
|
261
|
+
const rows = this.db.prepare(sql).all(cutoff);
|
|
262
|
+
const byTag = new Map();
|
|
263
|
+
for (const row of rows) {
|
|
264
|
+
// Object.create(null) prevents prototype pollution if a future
|
|
265
|
+
// museum_code value ever collides with a built-in property name
|
|
266
|
+
// (`__proto__`, `constructor`, `toString`).
|
|
267
|
+
const existing = byTag.get(row.tag) ?? Object.create(null);
|
|
268
|
+
existing[row.museum_code] = row.cnt;
|
|
269
|
+
byTag.set(row.tag, existing);
|
|
270
|
+
}
|
|
271
|
+
return Array.from(byTag.entries())
|
|
272
|
+
.map(([tag, coverage]) => ({ tag, label: titleCase(tag), coverage }))
|
|
273
|
+
.sort((a, b) => a.tag.localeCompare(b.tag));
|
|
274
|
+
}
|
|
166
275
|
pruneExpired() {
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
const objects = this.db.prepare(`DELETE FROM objects WHERE cached_at < ?`).run(objectsCutoff);
|
|
170
|
-
const queries = this.db.prepare(`DELETE FROM query_cache WHERE cached_at < ?`).run(queriesCutoff);
|
|
276
|
+
const objects = this.db.prepare(`DELETE FROM objects WHERE cached_at < ?`).run(this.objectsCutoff());
|
|
277
|
+
const queries = this.db.prepare(`DELETE FROM query_cache WHERE cached_at < ?`).run(this.queriesCutoff());
|
|
171
278
|
return { objects: objects.changes, queries: queries.changes };
|
|
172
279
|
}
|
|
173
280
|
isExpired(isoTimestamp, ttlDays) {
|
package/dist/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { parseDisplayDate } from '../dateParser.js';
|
|
2
|
+
import { validateAicLicense } from '../licenseGate.js';
|
|
3
|
+
import { cleanArtistName, detectAttributionType, normalizeRegion } from '../mappings.js';
|
|
4
|
+
import { asFiniteNumber, asOptionalString, asString } from './helpers.js';
|
|
5
|
+
const AIC_API = 'https://api.artic.edu/api/v1';
|
|
6
|
+
const AIC_IIIF = 'https://www.artic.edu/iiif/2';
|
|
7
|
+
const AIC_PAGE = 'https://www.artic.edu/artworks';
|
|
8
|
+
// Fields requested from /artworks/{id}. Limiting via ?fields= shrinks the
|
|
9
|
+
// payload roughly 10x compared with the default response (which carries
|
|
10
|
+
// every relationship and provenance entry AIC has).
|
|
11
|
+
const AIC_FIELDS = [
|
|
12
|
+
'id',
|
|
13
|
+
'title',
|
|
14
|
+
'is_public_domain',
|
|
15
|
+
'artist_display',
|
|
16
|
+
'artist_title',
|
|
17
|
+
'date_display',
|
|
18
|
+
'date_start',
|
|
19
|
+
'date_end',
|
|
20
|
+
'place_of_origin',
|
|
21
|
+
'medium_display',
|
|
22
|
+
'classification_title',
|
|
23
|
+
'image_id',
|
|
24
|
+
].join(',');
|
|
25
|
+
function reject(id, reason, rawSnapshot) {
|
|
26
|
+
return {
|
|
27
|
+
status: 'rejected',
|
|
28
|
+
rejection: { id, museumCode: 'aic', reason, rawSnapshot },
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// AIC's `artist_display` format mirrors Cleveland's: "Name (Nationality,
|
|
32
|
+
// birthYear–deathYear)". The structured `artist_title` field gives us the
|
|
33
|
+
// canonical name without the parenthetical, so we use that and only mine
|
|
34
|
+
// the display string for nationality and lifespan.
|
|
35
|
+
function looksLikeNationality(token) {
|
|
36
|
+
// Nationality words are short, alphabetic, no digits, and don't start with
|
|
37
|
+
// "born" (which AIC sometimes uses for living artists, e.g.
|
|
38
|
+
// "X (born 1950)"). The strict shape check here keeps year tokens and
|
|
39
|
+
// birth-line tokens out of the nationality field.
|
|
40
|
+
return token.length > 0 && !/\d/.test(token) && !/^born\b/i.test(token);
|
|
41
|
+
}
|
|
42
|
+
function parseArtistDisplay(display) {
|
|
43
|
+
const parenStart = display.indexOf('(');
|
|
44
|
+
if (parenStart < 0)
|
|
45
|
+
return {};
|
|
46
|
+
const parenEnd = display.lastIndexOf(')');
|
|
47
|
+
const inside = parenEnd > parenStart ? display.slice(parenStart + 1, parenEnd) : '';
|
|
48
|
+
const tokens = inside.split(',').map((t) => t.trim()).filter(Boolean);
|
|
49
|
+
const nationality = tokens[0] && looksLikeNationality(tokens[0]) ? tokens[0] : undefined;
|
|
50
|
+
const yearLine = tokens.find((t) => /^\d{1,4}/.test(t) || /^born\b/i.test(t));
|
|
51
|
+
return { nationality, lifespan: yearLine || undefined };
|
|
52
|
+
}
|
|
53
|
+
export const aicFetcher = {
|
|
54
|
+
code: 'aic',
|
|
55
|
+
name: 'Art Institute of Chicago',
|
|
56
|
+
async search(query, limit, options = {}) {
|
|
57
|
+
const url = new URL(`${AIC_API}/artworks/search`);
|
|
58
|
+
url.searchParams.set('q', query);
|
|
59
|
+
// Push the rights filter to AIC server-side via Elasticsearch term
|
|
60
|
+
// query, so the gate has fewer rejections to handle. Defense in depth:
|
|
61
|
+
// validateAicLicense still re-checks each fetched record.
|
|
62
|
+
url.searchParams.set('query[term][is_public_domain]', 'true');
|
|
63
|
+
if (options.hasImage !== false) {
|
|
64
|
+
// exists query against image_id keeps records without IIIF imagery
|
|
65
|
+
// out of the candidate list.
|
|
66
|
+
url.searchParams.set('query[exists][field]', 'image_id');
|
|
67
|
+
}
|
|
68
|
+
url.searchParams.set('limit', String(limit));
|
|
69
|
+
url.searchParams.set('fields', 'id');
|
|
70
|
+
const res = await fetch(url);
|
|
71
|
+
if (!res.ok)
|
|
72
|
+
throw new Error(`AIC search failed: ${res.status}`);
|
|
73
|
+
const json = (await res.json());
|
|
74
|
+
const data = json.data ?? [];
|
|
75
|
+
return data
|
|
76
|
+
.map((d) => (typeof d.id === 'number' ? `aic:${d.id}` : null))
|
|
77
|
+
.filter((s) => s !== null)
|
|
78
|
+
.slice(0, limit);
|
|
79
|
+
},
|
|
80
|
+
async getRaw(id) {
|
|
81
|
+
const numeric = id.replace(/^aic:/, '');
|
|
82
|
+
const url = new URL(`${AIC_API}/artworks/${numeric}`);
|
|
83
|
+
url.searchParams.set('fields', AIC_FIELDS);
|
|
84
|
+
const res = await fetch(url);
|
|
85
|
+
if (!res.ok)
|
|
86
|
+
throw new Error(`AIC get failed for ${id}: ${res.status}`);
|
|
87
|
+
return res.json();
|
|
88
|
+
},
|
|
89
|
+
normalize(raw) {
|
|
90
|
+
if (!raw || typeof raw !== 'object') {
|
|
91
|
+
return reject('aic:unknown', 'aic: response not an object', raw);
|
|
92
|
+
}
|
|
93
|
+
// AIC wraps single-record responses in `{"data": {...}}`. Tolerate
|
|
94
|
+
// either shape (mirrors the Cleveland adapter pattern).
|
|
95
|
+
const wrapped = raw.data;
|
|
96
|
+
const inner = wrapped && typeof wrapped === 'object' ? wrapped : raw;
|
|
97
|
+
const r = inner;
|
|
98
|
+
const objectId = r.id;
|
|
99
|
+
const validId = typeof objectId === 'number' && Number.isInteger(objectId) && objectId > 0;
|
|
100
|
+
const id = validId ? `aic:${objectId}` : 'aic:unknown';
|
|
101
|
+
const decision = validateAicLicense(inner);
|
|
102
|
+
if (!decision.accepted || !decision.license) {
|
|
103
|
+
return reject(id, decision.reason, raw);
|
|
104
|
+
}
|
|
105
|
+
if (!validId) {
|
|
106
|
+
return reject(id, 'aic: missing or non-integer id', raw);
|
|
107
|
+
}
|
|
108
|
+
const displayDate = asString(r.date_display);
|
|
109
|
+
const dateStart = asFiniteNumber(r.date_start);
|
|
110
|
+
const dateEnd = asFiniteNumber(r.date_end);
|
|
111
|
+
// AIC ships date_start/date_end as integers. Trust them when both are
|
|
112
|
+
// present; fall back to parseDisplayDate otherwise so dynasty-aware
|
|
113
|
+
// parsing still helps for sparser records.
|
|
114
|
+
const dateRange = dateStart !== null && dateEnd !== null
|
|
115
|
+
? { yearStart: dateStart, yearEnd: dateEnd }
|
|
116
|
+
: parseDisplayDate(displayDate);
|
|
117
|
+
const artistDisplay = asString(r.artist_display);
|
|
118
|
+
const artistTitle = asString(r.artist_title);
|
|
119
|
+
const attributionType = artistDisplay
|
|
120
|
+
? detectAttributionType(artistDisplay)
|
|
121
|
+
: 'anonymous';
|
|
122
|
+
// Prefer `artist_title` (canonical name without the parenthetical).
|
|
123
|
+
// Fall back to mining `artist_display` if artist_title is missing.
|
|
124
|
+
const cleanName = cleanArtistName(artistTitle || artistDisplay.split('(')[0].trim());
|
|
125
|
+
const { nationality, lifespan } = parseArtistDisplay(artistDisplay);
|
|
126
|
+
const region = normalizeRegion(asString(r.place_of_origin));
|
|
127
|
+
const imageId = asString(r.image_id);
|
|
128
|
+
// AIC publishes through IIIF Image API 2.0. 843px-wide is AIC's
|
|
129
|
+
// standard public-display size; 200px-wide is the thumbnail tier.
|
|
130
|
+
const fullImage = imageId ? `${AIC_IIIF}/${imageId}/full/843,/0/default.jpg` : '';
|
|
131
|
+
const thumbnail = imageId ? `${AIC_IIIF}/${imageId}/full/200,/0/default.jpg` : undefined;
|
|
132
|
+
const artwork = {
|
|
133
|
+
id,
|
|
134
|
+
museum: {
|
|
135
|
+
code: 'aic',
|
|
136
|
+
name: 'Art Institute of Chicago',
|
|
137
|
+
url: 'https://www.artic.edu',
|
|
138
|
+
},
|
|
139
|
+
title: (asString(r.title) || '(Untitled)').trim(),
|
|
140
|
+
artist: {
|
|
141
|
+
name: cleanName || 'Unknown',
|
|
142
|
+
nationality,
|
|
143
|
+
lifespan,
|
|
144
|
+
attributionType,
|
|
145
|
+
},
|
|
146
|
+
displayDate,
|
|
147
|
+
yearStart: dateRange.yearStart,
|
|
148
|
+
yearEnd: dateRange.yearEnd,
|
|
149
|
+
medium: asString(r.medium_display),
|
|
150
|
+
region,
|
|
151
|
+
period: null,
|
|
152
|
+
imageUrls: {
|
|
153
|
+
full: fullImage,
|
|
154
|
+
thumbnail,
|
|
155
|
+
},
|
|
156
|
+
imageOpenAccess: decision.imageOpenAccess,
|
|
157
|
+
metadataOpenAccess: decision.metadataOpenAccess,
|
|
158
|
+
license: decision.license,
|
|
159
|
+
source: {
|
|
160
|
+
apiUrl: `${AIC_API}/artworks/${objectId}`,
|
|
161
|
+
pageUrl: `${AIC_PAGE}/${objectId}`,
|
|
162
|
+
},
|
|
163
|
+
description: asOptionalString(r.classification_title),
|
|
164
|
+
};
|
|
165
|
+
return { status: 'accepted', artwork };
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=aic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aic.js","sourceRoot":"","sources":["../../src/fetchers/aic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { parseDisplayDate } from '../dateParser.js';
|
|
2
|
+
import { validateClevelandLicense } from '../licenseGate.js';
|
|
3
|
+
import { cleanArtistName, detectAttributionType, normalizeRegion } from '../mappings.js';
|
|
4
|
+
import { asFiniteNumber, asOptionalString, asString } from './helpers.js';
|
|
5
|
+
const CLEVELAND_API = 'https://openaccess-api.clevelandart.org/api';
|
|
6
|
+
function reject(id, reason, rawSnapshot) {
|
|
7
|
+
return {
|
|
8
|
+
status: 'rejected',
|
|
9
|
+
rejection: { id, museumCode: 'cleveland', reason, rawSnapshot },
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
// Cleveland's creator description format is "Name (Nationality, birthYear–deathYear)"
|
|
13
|
+
// e.g. "Vincent van Gogh (Dutch, 1853–1890)". The structured fields
|
|
14
|
+
// (birth_year, death_year) supply the lifespan, so we only mine the
|
|
15
|
+
// description for name + nationality.
|
|
16
|
+
function parseCreatorDescription(description) {
|
|
17
|
+
const parenStart = description.indexOf('(');
|
|
18
|
+
if (parenStart < 0)
|
|
19
|
+
return { name: description.trim() };
|
|
20
|
+
const name = description.slice(0, parenStart).trim();
|
|
21
|
+
const parenEnd = description.lastIndexOf(')');
|
|
22
|
+
const inside = parenEnd > parenStart ? description.slice(parenStart + 1, parenEnd) : '';
|
|
23
|
+
const firstToken = inside.split(',')[0].trim();
|
|
24
|
+
// If the first token looks like a year, the description omitted nationality
|
|
25
|
+
// ("Anonymous (1850)") and we should not surface it.
|
|
26
|
+
const looksLikeYear = /^\d{2,4}$/.test(firstToken);
|
|
27
|
+
return looksLikeYear || !firstToken ? { name } : { name, nationality: firstToken };
|
|
28
|
+
}
|
|
29
|
+
export const clevelandFetcher = {
|
|
30
|
+
code: 'cleveland',
|
|
31
|
+
name: 'Cleveland Museum of Art',
|
|
32
|
+
async search(query, limit, options = {}) {
|
|
33
|
+
const url = new URL(`${CLEVELAND_API}/artworks/`);
|
|
34
|
+
url.searchParams.set('q', query);
|
|
35
|
+
// Push the rights filter to the museum so the gate has fewer rejections to
|
|
36
|
+
// handle. Cleveland's `cc0=1` is server-side defense in depth alongside
|
|
37
|
+
// the per-record validateClevelandLicense check on every fetched object.
|
|
38
|
+
url.searchParams.set('cc0', '1');
|
|
39
|
+
if (options.hasImage !== false) {
|
|
40
|
+
url.searchParams.set('has_image', '1');
|
|
41
|
+
}
|
|
42
|
+
url.searchParams.set('limit', String(limit));
|
|
43
|
+
url.searchParams.set('fields', 'id');
|
|
44
|
+
const res = await fetch(url);
|
|
45
|
+
if (!res.ok)
|
|
46
|
+
throw new Error(`Cleveland search failed: ${res.status}`);
|
|
47
|
+
const json = (await res.json());
|
|
48
|
+
const data = json.data ?? [];
|
|
49
|
+
return data
|
|
50
|
+
.map((d) => (typeof d.id === 'number' ? `cleveland:${d.id}` : null))
|
|
51
|
+
.filter((s) => s !== null)
|
|
52
|
+
.slice(0, limit);
|
|
53
|
+
},
|
|
54
|
+
async getRaw(id) {
|
|
55
|
+
const numeric = id.replace(/^cleveland:/, '');
|
|
56
|
+
const res = await fetch(`${CLEVELAND_API}/artworks/${numeric}`);
|
|
57
|
+
if (!res.ok)
|
|
58
|
+
throw new Error(`Cleveland get failed for ${id}: ${res.status}`);
|
|
59
|
+
return res.json();
|
|
60
|
+
},
|
|
61
|
+
normalize(raw) {
|
|
62
|
+
if (!raw || typeof raw !== 'object') {
|
|
63
|
+
return reject('cleveland:unknown', 'cleveland: response not an object', raw);
|
|
64
|
+
}
|
|
65
|
+
// Cleveland wraps single-record responses in `{"data": {...}}`. Tolerate
|
|
66
|
+
// either shape so fixtures and direct-record callers both work.
|
|
67
|
+
const wrapped = raw.data;
|
|
68
|
+
const inner = wrapped && typeof wrapped === 'object' ? wrapped : raw;
|
|
69
|
+
const r = inner;
|
|
70
|
+
const objectId = r.id;
|
|
71
|
+
const validId = typeof objectId === 'number' && Number.isInteger(objectId) && objectId > 0;
|
|
72
|
+
const id = validId ? `cleveland:${objectId}` : 'cleveland:unknown';
|
|
73
|
+
const decision = validateClevelandLicense(inner);
|
|
74
|
+
if (!decision.accepted || !decision.license) {
|
|
75
|
+
return reject(id, decision.reason, raw);
|
|
76
|
+
}
|
|
77
|
+
if (!validId) {
|
|
78
|
+
return reject(id, 'cleveland: missing or non-integer id', raw);
|
|
79
|
+
}
|
|
80
|
+
const displayDate = asString(r.creation_date);
|
|
81
|
+
const earliest = asFiniteNumber(r.creation_date_earliest);
|
|
82
|
+
const latest = asFiniteNumber(r.creation_date_latest);
|
|
83
|
+
// Cleveland publishes earliest/latest year fields directly. Trust those
|
|
84
|
+
// when both are present; otherwise fall through to parseDisplayDate. We
|
|
85
|
+
// prefer the display-date parser over a single available bound because
|
|
86
|
+
// the displayDate string usually carries a richer signal — "1850s"
|
|
87
|
+
// parses to {1850, 1859}, more informative than an isolated
|
|
88
|
+
// creation_date_earliest=1850 with creation_date_latest missing.
|
|
89
|
+
const dateRange = earliest !== null && latest !== null
|
|
90
|
+
? { yearStart: earliest, yearEnd: latest }
|
|
91
|
+
: parseDisplayDate(displayDate);
|
|
92
|
+
const creators = Array.isArray(r.creators)
|
|
93
|
+
? r.creators
|
|
94
|
+
: [];
|
|
95
|
+
const primary = creators[0];
|
|
96
|
+
const description = asString(primary?.description);
|
|
97
|
+
const attributionType = detectAttributionType(description);
|
|
98
|
+
const parsed = parseCreatorDescription(description);
|
|
99
|
+
const cleanName = cleanArtistName(parsed.name);
|
|
100
|
+
const birth = asString(primary?.birth_year);
|
|
101
|
+
const death = asString(primary?.death_year);
|
|
102
|
+
const lifespan = birth || death ? `${birth}–${death}`.replace(/^–|–$/g, '') : undefined;
|
|
103
|
+
const cultureArr = Array.isArray(r.culture) ? r.culture : [];
|
|
104
|
+
const cultureStr = asString(cultureArr[0]);
|
|
105
|
+
const region = normalizeRegion(cultureStr);
|
|
106
|
+
const images = (r.images && typeof r.images === 'object' ? r.images : {});
|
|
107
|
+
const printVariant = images.print;
|
|
108
|
+
const webVariant = images.web;
|
|
109
|
+
// Prefer the higher-resolution `print` URL when both are available; fall
|
|
110
|
+
// back to `web` (smaller display image). The full TIFF is too large for
|
|
111
|
+
// most consumer use cases, so we don't surface it.
|
|
112
|
+
const fullImage = asString(printVariant?.url) || asString(webVariant?.url);
|
|
113
|
+
const thumbnail = asOptionalString(webVariant?.url);
|
|
114
|
+
const artwork = {
|
|
115
|
+
id,
|
|
116
|
+
museum: {
|
|
117
|
+
code: 'cleveland',
|
|
118
|
+
name: 'Cleveland Museum of Art',
|
|
119
|
+
url: 'https://www.clevelandart.org',
|
|
120
|
+
},
|
|
121
|
+
title: (asString(r.title) || '(Untitled)').trim(),
|
|
122
|
+
artist: {
|
|
123
|
+
name: cleanName || 'Unknown',
|
|
124
|
+
nationality: parsed.nationality,
|
|
125
|
+
lifespan,
|
|
126
|
+
attributionType,
|
|
127
|
+
},
|
|
128
|
+
displayDate,
|
|
129
|
+
yearStart: dateRange.yearStart,
|
|
130
|
+
yearEnd: dateRange.yearEnd,
|
|
131
|
+
medium: asString(r.technique),
|
|
132
|
+
region,
|
|
133
|
+
period: null,
|
|
134
|
+
imageUrls: {
|
|
135
|
+
full: fullImage,
|
|
136
|
+
thumbnail,
|
|
137
|
+
},
|
|
138
|
+
imageOpenAccess: decision.imageOpenAccess,
|
|
139
|
+
metadataOpenAccess: decision.metadataOpenAccess,
|
|
140
|
+
license: decision.license,
|
|
141
|
+
source: {
|
|
142
|
+
apiUrl: `${CLEVELAND_API}/artworks/${objectId}`,
|
|
143
|
+
pageUrl: asString(r.url),
|
|
144
|
+
},
|
|
145
|
+
description: asOptionalString(r.accession_number),
|
|
146
|
+
};
|
|
147
|
+
return { status: 'accepted', artwork };
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
//# sourceMappingURL=cleveland.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleveland.js","sourceRoot":"","sources":["../../src/fetchers/cleveland.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared coercion helpers for fetcher.normalize implementations.
|
|
3
|
+
*
|
|
4
|
+
* Each museum API ships fields that may be missing, null, or the wrong type.
|
|
5
|
+
* House style (per CONTRIBUTING.md) is to type uncertain shapes as `unknown`
|
|
6
|
+
* and narrow with explicit checks rather than casting with `as`. These
|
|
7
|
+
* helpers express the most-common narrowings once.
|
|
8
|
+
*/
|
|
9
|
+
/** Returns the string value, or "" for any non-string input. */
|
|
10
|
+
export declare function asString(v: unknown): string;
|
|
11
|
+
/** Returns the trimmed-truthy string, or undefined for missing/empty/non-string. */
|
|
12
|
+
export declare function asOptionalString(v: unknown): string | undefined;
|
|
13
|
+
/** Returns finite number, or null for NaN/Infinity/non-number. */
|
|
14
|
+
export declare function asFiniteNumber(v: unknown): number | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared coercion helpers for fetcher.normalize implementations.
|
|
3
|
+
*
|
|
4
|
+
* Each museum API ships fields that may be missing, null, or the wrong type.
|
|
5
|
+
* House style (per CONTRIBUTING.md) is to type uncertain shapes as `unknown`
|
|
6
|
+
* and narrow with explicit checks rather than casting with `as`. These
|
|
7
|
+
* helpers express the most-common narrowings once.
|
|
8
|
+
*/
|
|
9
|
+
/** Returns the string value, or "" for any non-string input. */
|
|
10
|
+
export function asString(v) {
|
|
11
|
+
return typeof v === 'string' ? v : '';
|
|
12
|
+
}
|
|
13
|
+
/** Returns the trimmed-truthy string, or undefined for missing/empty/non-string. */
|
|
14
|
+
export function asOptionalString(v) {
|
|
15
|
+
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
16
|
+
}
|
|
17
|
+
/** Returns finite number, or null for NaN/Infinity/non-number. */
|
|
18
|
+
export function asFiniteNumber(v) {
|
|
19
|
+
return typeof v === 'number' && Number.isFinite(v) ? v : null;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/fetchers/helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,gEAAgE;AAChE,MAAM,UAAU,QAAQ,CAAC,CAAU;IACjC,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACxC,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,gBAAgB,CAAC,CAAU;IACzC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/D,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,cAAc,CAAC,CAAU;IACvC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChE,CAAC"}
|
package/dist/fetchers/met.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { parseDisplayDate } from '../dateParser.js';
|
|
2
2
|
import { validateMetLicense } from '../licenseGate.js';
|
|
3
3
|
import { cleanArtistName, detectAttributionType, normalizeRegion } from '../mappings.js';
|
|
4
|
+
import { asOptionalString, asString } from './helpers.js';
|
|
4
5
|
const MET_API = 'https://collectionapi.metmuseum.org/public/collection/v1';
|
|
5
|
-
function asString(v) {
|
|
6
|
-
return typeof v === 'string' ? v : '';
|
|
7
|
-
}
|
|
8
|
-
function asOptionalString(v) {
|
|
9
|
-
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
10
|
-
}
|
|
11
6
|
export const metFetcher = {
|
|
12
7
|
code: 'met',
|
|
13
8
|
name: 'The Metropolitan Museum of Art',
|
package/dist/fetchers/met.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"met.js","sourceRoot":"","sources":["../../src/fetchers/met.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"met.js","sourceRoot":"","sources":["../../src/fetchers/met.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEzF,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG1D,MAAM,OAAO,GAAG,0DAA0D,CAAC;AAE3E,MAAM,CAAC,MAAM,UAAU,GAAY;IACjC,IAAI,EAAE,KAAK;IACX,IAAI,EAAE,gCAAgC;IAEtC,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,KAAa,EAAE,UAAyB,EAAE;QACpE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,OAAO,SAAS,CAAC,CAAC;QACzC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACjC,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;YAC/B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;QACD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;QAE/C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAoD,CAAC;QACnF,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QACjC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,YAAY,OAAO,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACxE,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,SAAS,CAAC,GAAY;QACpB,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACpC,OAAO;gBACL,MAAM,EAAE,UAAU;gBAClB,SAAS,EAAE;oBACT,EAAE,EAAE,aAAa;oBACjB,UAAU,EAAE,KAAK;oBACjB,MAAM,EAAE,wBAAwB;oBAChC,WAAW,EAAE,GAAG;iBACjB;aACF,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,GAAG,GAA8B,CAAC;QACzC,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;QAC5B,sEAAsE;QACtE,yEAAyE;QACzE,qCAAqC;QACrC,MAAM,OAAO,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC;QAC3F,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAEvD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC5C,OAAO;gBACL,MAAM,EAAE,UAAU;gBAClB,SAAS,EAAE;oBACT,EAAE;oBACF,UAAU,EAAE,KAAK;oBACjB,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,WAAW,EAAE,GAAG;iBACjB;aACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,MAAM,EAAE,UAAU;gBAClB,SAAS,EAAE;oBACT,EAAE;oBACF,UAAU,EAAE,KAAK;oBACjB,MAAM,EAAE,sCAAsC;oBAC9C,WAAW,EAAE,GAAG;iBACjB;aACF,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAEhD,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAChD,MAAM,eAAe,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QAE7C,MAAM,gBAAgB,GACpB,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;QAEjD,MAAM,SAAS,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QACnF,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;QAExE,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAC5E,MAAM,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAExD,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,OAAO,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEpG,MAAM,OAAO,GAAY;YACvB,EAAE;YACF,MAAM,EAAE;gBACN,IAAI,EAAE,KAAK;gBACX,IAAI,EAAE,gCAAgC;gBACtC,GAAG,EAAE,2BAA2B;aACjC;YACD,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,CAAC,IAAI,EAAE;YACjD,MAAM,EAAE;gBACN,IAAI,EAAE,SAAS,IAAI,SAAS;gBAC5B,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAC;gBAClD,QAAQ;gBACR,eAAe;aAChB;YACD,WAAW;YACX,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1B,MAAM;YACN,MAAM;YACN,SAAS,EAAE;gBACT,IAAI,EAAE,SAAS;gBACf,SAAS;aACV;YACD,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB;YAC/C,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,MAAM,EAAE;gBACN,MAAM,EAAE,GAAG,OAAO,YAAY,QAAQ,EAAE;gBACxC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,mDAAmD,QAAQ,EAAE;aAChG;YACD,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC;YAC3C,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC5B,CAAC,CAAE,CAAC,CAAC,IAAuB;qBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,CAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;qBACrF,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;gBACtD,CAAC,CAAC,SAAS;SACd,CAAC;QAEF,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;IACzC,CAAC;CACF,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -7,9 +7,13 @@ import { join } from 'node:path';
|
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { cite } from './cite.js';
|
|
9
9
|
import { Cache } from './db.js';
|
|
10
|
+
import { aicFetcher } from './fetchers/aic.js';
|
|
11
|
+
import { clevelandFetcher } from './fetchers/cleveland.js';
|
|
10
12
|
import { metFetcher } from './fetchers/met.js';
|
|
11
13
|
const FETCHERS = {
|
|
12
14
|
[metFetcher.code]: metFetcher,
|
|
15
|
+
[clevelandFetcher.code]: clevelandFetcher,
|
|
16
|
+
[aicFetcher.code]: aicFetcher,
|
|
13
17
|
};
|
|
14
18
|
const CACHE_PATH = process.env.OMM_CACHE_PATH ?? join(homedir(), '.open-museum-mcp', 'cache.db');
|
|
15
19
|
const cache = new Cache({ path: CACHE_PATH });
|
|
@@ -49,6 +53,12 @@ const CiteInput = z.object({
|
|
|
49
53
|
id: z.string().regex(ID_REGEX),
|
|
50
54
|
style: z.enum(['short', 'full', 'caption']).default('full'),
|
|
51
55
|
});
|
|
56
|
+
const DiscoverInput = z.object({
|
|
57
|
+
region: z.string().min(1).optional(),
|
|
58
|
+
period: z.string().min(1).optional(),
|
|
59
|
+
not_artist: z.array(z.string().min(1)).optional(),
|
|
60
|
+
museum: z.string().min(1).optional(),
|
|
61
|
+
});
|
|
52
62
|
async function fetchAndCache(id) {
|
|
53
63
|
if (!ID_REGEX.test(id)) {
|
|
54
64
|
return { ok: false, reason: `invalid artwork id: ${id}` };
|
|
@@ -90,7 +100,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
90
100
|
query: { type: 'string', description: 'Free-text query.' },
|
|
91
101
|
museum: {
|
|
92
102
|
type: 'string',
|
|
93
|
-
description: 'Optional museum code. Currently registered: met
|
|
103
|
+
description: 'Optional museum code. Currently registered: met, cleveland, aic.',
|
|
94
104
|
},
|
|
95
105
|
has_image: {
|
|
96
106
|
type: 'boolean',
|
|
@@ -129,6 +139,40 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
129
139
|
required: ['id'],
|
|
130
140
|
},
|
|
131
141
|
},
|
|
142
|
+
{
|
|
143
|
+
name: 'discover_random',
|
|
144
|
+
description: 'Pick one random artwork from the local cache that matches the given constraints. Useful for breaking out of repetitive search territory (e.g. surface a random Edo-period work to satisfy a no-back-to-back-European-pre-1900 pairing rule). Operates over what has already been searched and cached; returns an error if nothing matches, suggesting the caller seed the cache via search_artworks first.',
|
|
145
|
+
inputSchema: {
|
|
146
|
+
type: 'object',
|
|
147
|
+
properties: {
|
|
148
|
+
region: {
|
|
149
|
+
type: 'string',
|
|
150
|
+
description: 'Normalized region tag (e.g. "china", "japan", "netherlands"). Exact match.',
|
|
151
|
+
},
|
|
152
|
+
period: {
|
|
153
|
+
type: 'string',
|
|
154
|
+
description: 'Normalized period tag (e.g. "tang dynasty", "edo", "safavid"). Exact match.',
|
|
155
|
+
},
|
|
156
|
+
not_artist: {
|
|
157
|
+
type: 'array',
|
|
158
|
+
items: { type: 'string' },
|
|
159
|
+
description: 'Artist names to exclude (exact match against the canonical artist name field).',
|
|
160
|
+
},
|
|
161
|
+
museum: {
|
|
162
|
+
type: 'string',
|
|
163
|
+
description: 'Optional museum code to restrict to (met, cleveland, aic).',
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: 'list_traditions',
|
|
170
|
+
description: 'List the regions and periods present in non-expired cached records, with per-museum record counts. Helps you see which traditions are well-represented before searching, and where holdings are sparse. Returns { regions, periods } where each entry has { tag, label, coverage: { museumCode: count } }.',
|
|
171
|
+
inputSchema: {
|
|
172
|
+
type: 'object',
|
|
173
|
+
properties: {},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
132
176
|
],
|
|
133
177
|
}));
|
|
134
178
|
function errorResult(message) {
|
|
@@ -190,6 +234,26 @@ async function handleCite(args) {
|
|
|
190
234
|
return errorResult(out.reason);
|
|
191
235
|
return { content: [{ type: 'text', text: cite(out.artwork, input.style) }] };
|
|
192
236
|
}
|
|
237
|
+
async function handleDiscoverRandom(args) {
|
|
238
|
+
const input = DiscoverInput.parse(args);
|
|
239
|
+
if (input.museum && !FETCHERS[input.museum]) {
|
|
240
|
+
return errorResult(`unknown museum: ${input.museum}`);
|
|
241
|
+
}
|
|
242
|
+
const artwork = cache.getRandomObject({
|
|
243
|
+
region: input.region,
|
|
244
|
+
period: input.period,
|
|
245
|
+
notArtist: input.not_artist,
|
|
246
|
+
museumCode: input.museum,
|
|
247
|
+
});
|
|
248
|
+
if (!artwork) {
|
|
249
|
+
return errorResult('No cached artwork matches these constraints. Seed the cache with search_artworks first; discover_random samples from records you have already pulled.');
|
|
250
|
+
}
|
|
251
|
+
return { content: [{ type: 'text', text: JSON.stringify(artwork, null, 2) }] };
|
|
252
|
+
}
|
|
253
|
+
function handleListTraditions() {
|
|
254
|
+
const traditions = cache.listTraditions();
|
|
255
|
+
return { content: [{ type: 'text', text: JSON.stringify(traditions, null, 2) }] };
|
|
256
|
+
}
|
|
193
257
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
194
258
|
const { name, arguments: args } = request.params;
|
|
195
259
|
try {
|
|
@@ -199,6 +263,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
199
263
|
return await handleGet(args);
|
|
200
264
|
if (name === 'cite')
|
|
201
265
|
return await handleCite(args);
|
|
266
|
+
if (name === 'discover_random')
|
|
267
|
+
return await handleDiscoverRandom(args);
|
|
268
|
+
if (name === 'list_traditions')
|
|
269
|
+
return handleListTraditions();
|
|
202
270
|
return errorResult(`unknown tool: ${name}`);
|
|
203
271
|
}
|
|
204
272
|
catch (err) {
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -77,9 +77,10 @@ export interface DateRange {
|
|
|
77
77
|
yearEnd: number | null;
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
80
|
+
* One tradition tag (a normalized region or period) plus per-museum
|
|
81
|
+
* coverage counts in the local cache. Emitted by the `list_traditions`
|
|
82
|
+
* tool so callers can see where holdings are well-represented and where
|
|
83
|
+
* they're sparse before searching.
|
|
83
84
|
*/
|
|
84
85
|
export interface Tradition {
|
|
85
86
|
tag: string;
|
package/package.json
CHANGED