@cyanheads/openlibrary-mcp-server 0.1.1
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/CLAUDE.md +391 -0
- package/Dockerfile +98 -0
- package/LICENSE +201 -0
- package/README.md +316 -0
- package/changelog/0.1.x/0.1.0.md +22 -0
- package/changelog/0.1.x/0.1.1.md +25 -0
- package/changelog/template.md +119 -0
- package/dist/config/server-config.d.ts +11 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +20 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/openlibrary-author.resource.d.ts +25 -0
- package/dist/mcp-server/resources/definitions/openlibrary-author.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/openlibrary-author.resource.js +48 -0
- package/dist/mcp-server/resources/definitions/openlibrary-author.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/openlibrary-work.resource.d.ts +21 -0
- package/dist/mcp-server/resources/definitions/openlibrary-work.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/openlibrary-work.resource.js +42 -0
- package/dist/mcp-server/resources/definitions/openlibrary-work.resource.js.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-author-works.tool.d.ts +26 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-author-works.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-author-works.tool.js +68 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-author-works.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-author.tool.d.ts +31 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-author.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-author.tool.js +86 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-author.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-cover-url.tool.d.ts +26 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-cover-url.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-cover-url.tool.js +56 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-cover-url.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-edition.tool.d.ts +45 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-edition.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-edition.tool.js +132 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-edition.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-editions.tool.d.ts +32 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-editions.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-editions.tool.js +106 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-editions.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-subject.tool.d.ts +29 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-subject.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-subject.tool.js +82 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-subject.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-work.tool.d.ts +27 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-work.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-work.tool.js +90 -0
- package/dist/mcp-server/tools/definitions/openlibrary-get-work.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-search-authors.tool.d.ts +31 -0
- package/dist/mcp-server/tools/definitions/openlibrary-search-authors.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-search-authors.tool.js +105 -0
- package/dist/mcp-server/tools/definitions/openlibrary-search-authors.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-search-books.tool.d.ts +65 -0
- package/dist/mcp-server/tools/definitions/openlibrary-search-books.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/openlibrary-search-books.tool.js +217 -0
- package/dist/mcp-server/tools/definitions/openlibrary-search-books.tool.js.map +1 -0
- package/dist/services/open-library/open-library-service.d.ts +57 -0
- package/dist/services/open-library/open-library-service.d.ts.map +1 -0
- package/dist/services/open-library/open-library-service.js +347 -0
- package/dist/services/open-library/open-library-service.js.map +1 -0
- package/dist/services/open-library/types.d.ts +129 -0
- package/dist/services/open-library/types.d.ts.map +1 -0
- package/dist/services/open-library/types.js +6 -0
- package/dist/services/open-library/types.js.map +1 -0
- package/package.json +79 -0
- package/server.json +99 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Open Library REST API client. Handles search, works, editions, authors,
|
|
3
|
+
* subjects, and cover URL construction with retry and timeout.
|
|
4
|
+
* @module services/open-library/open-library-service
|
|
5
|
+
*/
|
|
6
|
+
import { notFound } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { fetchWithTimeout, withRetry } from '@cyanheads/mcp-ts-core/utils';
|
|
8
|
+
import { getServerConfig } from '../../config/server-config.js';
|
|
9
|
+
const BASE_URL = 'https://openlibrary.org';
|
|
10
|
+
const COVERS_URL = 'https://covers.openlibrary.org';
|
|
11
|
+
const TIMEOUT_MS = 15_000;
|
|
12
|
+
/** Strips a leading path segment prefix from an OL ID (e.g. "/works/OL45804W" → "OL45804W"). */
|
|
13
|
+
function stripPrefix(id, prefix) {
|
|
14
|
+
return id.startsWith(prefix) ? id.slice(prefix.length) : id;
|
|
15
|
+
}
|
|
16
|
+
/** Extracts the 3-letter language code from a raw language key path ("/languages/eng" → "eng"). */
|
|
17
|
+
function extractLanguageCode(key) {
|
|
18
|
+
const parts = key.split('/');
|
|
19
|
+
return parts[parts.length - 1] ?? key;
|
|
20
|
+
}
|
|
21
|
+
/** Normalizes a description that may be a string or { value: string } object. */
|
|
22
|
+
function extractDescription(raw) {
|
|
23
|
+
if (typeof raw === 'string')
|
|
24
|
+
return raw || undefined;
|
|
25
|
+
if (raw &&
|
|
26
|
+
typeof raw === 'object' &&
|
|
27
|
+
'value' in raw &&
|
|
28
|
+
typeof raw.value === 'string') {
|
|
29
|
+
return raw.value || undefined;
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
export class OpenLibraryService {
|
|
34
|
+
userAgent;
|
|
35
|
+
constructor(userAgent) {
|
|
36
|
+
this.userAgent = userAgent;
|
|
37
|
+
}
|
|
38
|
+
headers() {
|
|
39
|
+
return { 'User-Agent': this.userAgent };
|
|
40
|
+
}
|
|
41
|
+
fetch(url, ctx) {
|
|
42
|
+
// `fetchWithTimeout` and `withRetry` accept `RequestContext` which requires an index signature.
|
|
43
|
+
// `Context` is structurally compatible at runtime — cast is safe per framework docs.
|
|
44
|
+
// biome-ignore lint/suspicious/noExplicitAny: safe per framework docs
|
|
45
|
+
const rCtx = ctx;
|
|
46
|
+
return withRetry(async () => {
|
|
47
|
+
const response = await fetchWithTimeout(url, TIMEOUT_MS, rCtx, {
|
|
48
|
+
headers: this.headers(),
|
|
49
|
+
signal: ctx.signal,
|
|
50
|
+
});
|
|
51
|
+
const text = await response.text();
|
|
52
|
+
if (/^\s*<(!DOCTYPE\s+html|html[\s>])/i.test(text)) {
|
|
53
|
+
throw new Error('Service unavailable — API returned HTML instead of JSON.');
|
|
54
|
+
}
|
|
55
|
+
return JSON.parse(text);
|
|
56
|
+
}, {
|
|
57
|
+
operation: `OpenLibrary.fetch`,
|
|
58
|
+
context: rCtx,
|
|
59
|
+
baseDelayMs: 1000,
|
|
60
|
+
signal: ctx.signal,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// ─── Search ───────────────────────────────────────────────────────────────────
|
|
64
|
+
async searchBooks(params, ctx) {
|
|
65
|
+
const qs = new URLSearchParams();
|
|
66
|
+
if (params.query)
|
|
67
|
+
qs.set('q', params.query);
|
|
68
|
+
if (params.title)
|
|
69
|
+
qs.set('title', params.title);
|
|
70
|
+
if (params.author)
|
|
71
|
+
qs.set('author', params.author);
|
|
72
|
+
if (params.subject)
|
|
73
|
+
qs.set('subject', params.subject);
|
|
74
|
+
if (params.publisher)
|
|
75
|
+
qs.set('publisher', params.publisher);
|
|
76
|
+
if (params.isbn)
|
|
77
|
+
qs.set('isbn', params.isbn.replace(/-/g, ''));
|
|
78
|
+
if (params.language)
|
|
79
|
+
qs.set('lang', params.language);
|
|
80
|
+
if (params.sort && params.sort !== 'relevance') {
|
|
81
|
+
qs.set('sort', params.sort);
|
|
82
|
+
}
|
|
83
|
+
qs.set('limit', String(params.limit));
|
|
84
|
+
qs.set('offset', String(params.offset));
|
|
85
|
+
const baseFields = 'key,title,author_name,author_key,first_publish_year,edition_count,cover_i,subject,ebook_access,has_fulltext,ratings_average,ia';
|
|
86
|
+
const fields = params.include_availability ? `${baseFields},availability` : baseFields;
|
|
87
|
+
qs.set('fields', fields);
|
|
88
|
+
const url = `${BASE_URL}/search.json?${qs.toString()}`;
|
|
89
|
+
ctx.log.debug('Searching books', { url });
|
|
90
|
+
const raw = await this.fetch(url, ctx);
|
|
91
|
+
const works = raw.docs.map((doc) => {
|
|
92
|
+
const workId = doc.key ? stripPrefix(doc.key, '/works/') : '';
|
|
93
|
+
const ebookAccess = doc.ebook_access ?? 'no_ebook';
|
|
94
|
+
return {
|
|
95
|
+
work_id: workId,
|
|
96
|
+
title: doc.title ?? '',
|
|
97
|
+
author_names: doc.author_name ?? [],
|
|
98
|
+
author_ids: (doc.author_key ?? []).map((k) => stripPrefix(k, '/authors/')),
|
|
99
|
+
...(typeof doc.first_publish_year === 'number' && {
|
|
100
|
+
first_publish_year: doc.first_publish_year,
|
|
101
|
+
}),
|
|
102
|
+
edition_count: doc.edition_count ?? 0,
|
|
103
|
+
...(typeof doc.cover_i === 'number' && { cover_id: doc.cover_i }),
|
|
104
|
+
...(doc.subject?.length ? { subjects: doc.subject.slice(0, 5) } : {}),
|
|
105
|
+
ebook_access: ebookAccess,
|
|
106
|
+
has_fulltext: doc.has_fulltext ?? false,
|
|
107
|
+
...(typeof doc.ratings_average === 'number' && { ratings_average: doc.ratings_average }),
|
|
108
|
+
availability: params.include_availability ? (doc.availability ?? null) : undefined,
|
|
109
|
+
ia_identifiers: doc.ia ?? [],
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
total: raw.numFound,
|
|
114
|
+
offset: raw.start,
|
|
115
|
+
works,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
// ─── Works ────────────────────────────────────────────────────────────────────
|
|
119
|
+
async getWork(workId, ctx) {
|
|
120
|
+
const id = stripPrefix(workId, '/works/');
|
|
121
|
+
const url = `${BASE_URL}/works/${id}.json`;
|
|
122
|
+
ctx.log.debug('Fetching work', { workId: id });
|
|
123
|
+
const raw = await this.fetch(url, ctx);
|
|
124
|
+
if (!raw.key)
|
|
125
|
+
throw notFound(`Work ${id} not found on Open Library.`);
|
|
126
|
+
const desc = extractDescription(raw.description);
|
|
127
|
+
return {
|
|
128
|
+
work_id: stripPrefix(raw.key, '/works/'),
|
|
129
|
+
title: raw.title ?? '',
|
|
130
|
+
...(desc !== undefined ? { description: desc } : {}),
|
|
131
|
+
subjects: raw.subjects ?? [],
|
|
132
|
+
subject_places: raw.subject_places ?? [],
|
|
133
|
+
subject_times: raw.subject_times ?? [],
|
|
134
|
+
subject_people: raw.subject_people ?? [],
|
|
135
|
+
cover_ids: raw.covers ?? [],
|
|
136
|
+
author_ids: (raw.authors ?? []).map((a) => stripPrefix(a.author.key, '/authors/')),
|
|
137
|
+
...(raw.created?.value !== undefined ? { created: raw.created.value } : {}),
|
|
138
|
+
...(raw.last_modified?.value !== undefined ? { last_modified: raw.last_modified.value } : {}),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// ─── Editions ─────────────────────────────────────────────────────────────────
|
|
142
|
+
async getEditions(workId, limit, offset, ctx) {
|
|
143
|
+
const id = stripPrefix(workId, '/works/');
|
|
144
|
+
const url = `${BASE_URL}/works/${id}/editions.json?limit=${limit}&offset=${offset}`;
|
|
145
|
+
ctx.log.debug('Fetching editions', { workId: id, limit, offset });
|
|
146
|
+
const raw = await this.fetch(url, ctx);
|
|
147
|
+
if (!raw.entries)
|
|
148
|
+
throw notFound(`Work ${id} not found on Open Library.`);
|
|
149
|
+
const editions = raw.entries.map((e) => ({
|
|
150
|
+
edition_id: stripPrefix(e.key ?? '', '/books/'),
|
|
151
|
+
title: e.title ?? '',
|
|
152
|
+
...(e.publish_date ? { publish_date: e.publish_date } : {}),
|
|
153
|
+
publishers: e.publishers ?? [],
|
|
154
|
+
languages: (e.languages ?? []).map((l) => extractLanguageCode(l.key)),
|
|
155
|
+
isbn_10: e.isbn_10 ?? [],
|
|
156
|
+
isbn_13: e.isbn_13 ?? [],
|
|
157
|
+
...(typeof e.number_of_pages === 'number' && { page_count: e.number_of_pages }),
|
|
158
|
+
cover_ids: e.covers ?? [],
|
|
159
|
+
...(e.works?.[0]?.key ? { work_id: stripPrefix(e.works[0].key, '/works/') } : {}),
|
|
160
|
+
}));
|
|
161
|
+
return { total: raw.size, work_id: id, editions };
|
|
162
|
+
}
|
|
163
|
+
// ─── Edition by identifier ────────────────────────────────────────────────────
|
|
164
|
+
async getEditionByIdentifier(identifier, idType, ctx) {
|
|
165
|
+
ctx.log.debug('Fetching edition', { identifier, idType });
|
|
166
|
+
if (idType === 'isbn' || idType === 'olid') {
|
|
167
|
+
const path = idType === 'isbn' ? `isbn/${identifier.replace(/-/g, '')}` : `books/${identifier}`;
|
|
168
|
+
const url = `${BASE_URL}/${path}.json`;
|
|
169
|
+
const raw = await this.fetch(url, ctx);
|
|
170
|
+
if (raw.error === 'notfound' || !raw.key) {
|
|
171
|
+
throw notFound(`Edition not found for ${idType.toUpperCase()} "${identifier}". Verify the identifier or try searching by title/author.`);
|
|
172
|
+
}
|
|
173
|
+
// Resolve author names via secondary lookup (sequential per design)
|
|
174
|
+
const authors = [];
|
|
175
|
+
for (const authorRef of raw.authors ?? []) {
|
|
176
|
+
const authorId = stripPrefix(authorRef.key, '/authors/');
|
|
177
|
+
try {
|
|
178
|
+
const authorRaw = await this.fetch(`${BASE_URL}/authors/${authorId}.json`, ctx);
|
|
179
|
+
authors.push({ name: authorRaw.name ?? authorId, author_id: authorId });
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
authors.push({ author_id: authorId, name: authorId });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const editionId = stripPrefix(raw.key, '/books/');
|
|
186
|
+
const edDesc = extractDescription(raw.description);
|
|
187
|
+
return {
|
|
188
|
+
edition_id: editionId,
|
|
189
|
+
title: raw.title ?? '',
|
|
190
|
+
authors,
|
|
191
|
+
...(raw.publish_date ? { publish_date: raw.publish_date } : {}),
|
|
192
|
+
publishers: raw.publishers ?? [],
|
|
193
|
+
...(raw.languages?.[0] ? { language: extractLanguageCode(raw.languages[0].key) } : {}),
|
|
194
|
+
isbn_10: raw.isbn_10 ?? [],
|
|
195
|
+
isbn_13: raw.isbn_13 ?? [],
|
|
196
|
+
oclc: raw.oclc_numbers ?? [],
|
|
197
|
+
lccn: raw.lc_classifications ?? [],
|
|
198
|
+
...(typeof raw.number_of_pages === 'number' && { page_count: raw.number_of_pages }),
|
|
199
|
+
...(edDesc !== undefined ? { description: edDesc } : {}),
|
|
200
|
+
cover_ids: raw.covers ?? [],
|
|
201
|
+
...(raw.works?.[0]?.key ? { work_id: stripPrefix(raw.works[0].key, '/works/') } : {}),
|
|
202
|
+
...(raw.ocaid ? { ebook_url: `https://archive.org/details/${raw.ocaid}` } : {}),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
// OCLC / LCCN route — use /api/books with jscmd=details
|
|
206
|
+
const prefix = idType === 'oclc' ? 'OCLC' : 'LCCN';
|
|
207
|
+
const bibkey = `${prefix}:${identifier}`;
|
|
208
|
+
const url = `${BASE_URL}/api/books?bibkeys=${encodeURIComponent(bibkey)}&format=json&jscmd=details`;
|
|
209
|
+
const rawMap = await this.fetch(url, ctx);
|
|
210
|
+
const entry = rawMap[bibkey];
|
|
211
|
+
if (!entry?.details?.key) {
|
|
212
|
+
throw notFound(`Edition not found for ${prefix} "${identifier}". Verify the identifier or try searching by title/author.`);
|
|
213
|
+
}
|
|
214
|
+
const d = entry.details;
|
|
215
|
+
const authors = (d.authors ?? []).map((a) => ({
|
|
216
|
+
name: a.name ?? stripPrefix(a.key, '/authors/'),
|
|
217
|
+
author_id: stripPrefix(a.key, '/authors/'),
|
|
218
|
+
}));
|
|
219
|
+
const oclcDesc = extractDescription(d.description);
|
|
220
|
+
return {
|
|
221
|
+
edition_id: stripPrefix(d.key ?? '', '/books/'),
|
|
222
|
+
title: d.title ?? '',
|
|
223
|
+
authors,
|
|
224
|
+
...(d.publish_date ? { publish_date: d.publish_date } : {}),
|
|
225
|
+
publishers: d.publishers ?? [],
|
|
226
|
+
...(d.languages?.[0] ? { language: extractLanguageCode(d.languages[0].key) } : {}),
|
|
227
|
+
isbn_10: d.isbn_10 ?? [],
|
|
228
|
+
isbn_13: d.isbn_13 ?? [],
|
|
229
|
+
oclc: d.oclc_numbers ?? [],
|
|
230
|
+
lccn: d.lc_classifications ?? [],
|
|
231
|
+
...(typeof d.number_of_pages === 'number' && { page_count: d.number_of_pages }),
|
|
232
|
+
...(oclcDesc !== undefined ? { description: oclcDesc } : {}),
|
|
233
|
+
cover_ids: d.covers ?? [],
|
|
234
|
+
...(d.works?.[0]?.key ? { work_id: stripPrefix(d.works[0].key, '/works/') } : {}),
|
|
235
|
+
...(d.ocaid ? { ebook_url: `https://archive.org/details/${d.ocaid}` } : {}),
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
// ─── Authors ──────────────────────────────────────────────────────────────────
|
|
239
|
+
async searchAuthors(query, limit, offset, ctx) {
|
|
240
|
+
const url = `${BASE_URL}/search/authors.json?q=${encodeURIComponent(query)}&limit=${limit}&offset=${offset}`;
|
|
241
|
+
ctx.log.debug('Searching authors', { query, limit, offset });
|
|
242
|
+
const raw = await this.fetch(url, ctx);
|
|
243
|
+
return {
|
|
244
|
+
total: raw.numFound,
|
|
245
|
+
authors: raw.docs.map((d) => ({
|
|
246
|
+
author_id: stripPrefix(d.key, '/authors/'),
|
|
247
|
+
name: d.name ?? '',
|
|
248
|
+
alternate_names: d.alternate_names ?? [],
|
|
249
|
+
...(d.birth_date ? { birth_date: d.birth_date } : {}),
|
|
250
|
+
...(d.death_date ? { death_date: d.death_date } : {}),
|
|
251
|
+
...(d.top_work ? { top_work: d.top_work } : {}),
|
|
252
|
+
work_count: d.work_count ?? 0,
|
|
253
|
+
top_subjects: d.top_subjects ?? [],
|
|
254
|
+
...(typeof d.ratings_average === 'number' && { ratings_average: d.ratings_average }),
|
|
255
|
+
})),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
async getAuthor(authorId, ctx) {
|
|
259
|
+
const id = stripPrefix(authorId, '/authors/');
|
|
260
|
+
const url = `${BASE_URL}/authors/${id}.json`;
|
|
261
|
+
ctx.log.debug('Fetching author', { authorId: id });
|
|
262
|
+
const raw = await this.fetch(url, ctx);
|
|
263
|
+
if (raw.error === 'notfound' || !raw.key) {
|
|
264
|
+
throw notFound(`Author ${id} not found on Open Library. Verify the OLID or search by name first.`);
|
|
265
|
+
}
|
|
266
|
+
const bio = extractDescription(raw.bio);
|
|
267
|
+
return {
|
|
268
|
+
author_id: stripPrefix(raw.key, '/authors/'),
|
|
269
|
+
name: raw.name ?? '',
|
|
270
|
+
...(raw.personal_name ? { personal_name: raw.personal_name } : {}),
|
|
271
|
+
...(raw.fuller_name ? { fuller_name: raw.fuller_name } : {}),
|
|
272
|
+
...(bio !== undefined ? { bio } : {}),
|
|
273
|
+
...(raw.birth_date ? { birth_date: raw.birth_date } : {}),
|
|
274
|
+
...(raw.death_date ? { death_date: raw.death_date } : {}),
|
|
275
|
+
photo_ids: raw.photos ?? [],
|
|
276
|
+
remote_ids: {
|
|
277
|
+
...(raw.remote_ids?.wikidata ? { wikidata: raw.remote_ids.wikidata } : {}),
|
|
278
|
+
...(raw.remote_ids?.viaf ? { viaf: raw.remote_ids.viaf } : {}),
|
|
279
|
+
...(raw.remote_ids?.isni ? { isni: raw.remote_ids.isni } : {}),
|
|
280
|
+
...(raw.remote_ids?.goodreads ? { goodreads: raw.remote_ids.goodreads } : {}),
|
|
281
|
+
...(raw.remote_ids?.librarything ? { librarything: raw.remote_ids.librarything } : {}),
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
async getAuthorWorks(authorId, limit, offset, ctx) {
|
|
286
|
+
const id = stripPrefix(authorId, '/authors/');
|
|
287
|
+
const url = `${BASE_URL}/authors/${id}/works.json?limit=${limit}&offset=${offset}`;
|
|
288
|
+
ctx.log.debug('Fetching author works', { authorId: id, limit, offset });
|
|
289
|
+
const raw = await this.fetch(url, ctx);
|
|
290
|
+
return {
|
|
291
|
+
total: raw.size,
|
|
292
|
+
author_id: id,
|
|
293
|
+
works: (raw.entries ?? []).map((e) => ({
|
|
294
|
+
work_id: stripPrefix(e.key ?? '', '/works/'),
|
|
295
|
+
title: e.title ?? '',
|
|
296
|
+
...(e.first_publish_date ? { first_publish_date: e.first_publish_date } : {}),
|
|
297
|
+
cover_ids: e.covers ?? [],
|
|
298
|
+
})),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
// ─── Subjects ─────────────────────────────────────────────────────────────────
|
|
302
|
+
async getSubject(subject, limit, offset, ebooksOnly, ctx) {
|
|
303
|
+
const subjectKey = subject.toLowerCase().replace(/\s+/g, '_');
|
|
304
|
+
const qs = new URLSearchParams({
|
|
305
|
+
limit: String(limit),
|
|
306
|
+
offset: String(offset),
|
|
307
|
+
...(ebooksOnly ? { ebooks: '1' } : {}),
|
|
308
|
+
});
|
|
309
|
+
const url = `${BASE_URL}/subjects/${encodeURIComponent(subjectKey)}.json?${qs.toString()}`;
|
|
310
|
+
ctx.log.debug('Fetching subject', { subjectKey, limit, offset });
|
|
311
|
+
const raw = await this.fetch(url, ctx);
|
|
312
|
+
if (raw.error === 'notfound' || (!raw.name && !raw.work_count)) {
|
|
313
|
+
throw notFound(`Subject "${subject}" not found or has no works. Try a broader term (e.g., "fiction" instead of a specific subgenre).`);
|
|
314
|
+
}
|
|
315
|
+
return {
|
|
316
|
+
subject_name: raw.name ?? subject,
|
|
317
|
+
subject_key: subjectKey,
|
|
318
|
+
work_count: raw.work_count ?? 0,
|
|
319
|
+
works: (raw.works ?? []).map((w) => ({
|
|
320
|
+
work_id: stripPrefix(w.key ?? '', '/works/'),
|
|
321
|
+
title: w.title ?? '',
|
|
322
|
+
author_names: (w.authors ?? []).map((a) => a.name),
|
|
323
|
+
edition_count: w.edition_count ?? 0,
|
|
324
|
+
...(typeof w.cover_id === 'number' && { cover_id: w.cover_id }),
|
|
325
|
+
})),
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
// ─── Covers ───────────────────────────────────────────────────────────────────
|
|
329
|
+
getCoverUrl(identifier, idType, target, size) {
|
|
330
|
+
const prefix = target === 'author' ? 'a' : 'b';
|
|
331
|
+
const clean = idType === 'isbn' ? identifier.replace(/-/g, '') : identifier;
|
|
332
|
+
return `${COVERS_URL}/${prefix}/${idType}/${clean}-${size}.jpg`;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// ─── Init / Accessor ──────────────────────────────────────────────────────────
|
|
336
|
+
let _service;
|
|
337
|
+
export function initOpenLibraryService() {
|
|
338
|
+
const { userAgent } = getServerConfig();
|
|
339
|
+
_service = new OpenLibraryService(userAgent);
|
|
340
|
+
}
|
|
341
|
+
export function getOpenLibraryService() {
|
|
342
|
+
if (!_service) {
|
|
343
|
+
throw new Error('OpenLibraryService not initialized — call initOpenLibraryService() in setup()');
|
|
344
|
+
}
|
|
345
|
+
return _service;
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=open-library-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-library-service.js","sourceRoot":"","sources":["../../../src/services/open-library/open-library-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Domain types for the Open Library service.
|
|
3
|
+
* @module services/open-library/types
|
|
4
|
+
*/
|
|
5
|
+
/** Work-level record as returned by the search API. */
|
|
6
|
+
export type SearchWork = {
|
|
7
|
+
work_id: string;
|
|
8
|
+
title: string;
|
|
9
|
+
author_names: string[];
|
|
10
|
+
author_ids: string[];
|
|
11
|
+
first_publish_year?: number;
|
|
12
|
+
edition_count: number;
|
|
13
|
+
cover_id?: number;
|
|
14
|
+
subjects?: string[];
|
|
15
|
+
ebook_access: 'no_ebook' | 'printdisabled' | 'borrowable' | 'public';
|
|
16
|
+
has_fulltext: boolean;
|
|
17
|
+
ratings_average?: number;
|
|
18
|
+
/** Present when include_availability is true; null when work has no IA item. */
|
|
19
|
+
availability?: WorkAvailability | null | undefined;
|
|
20
|
+
ia_identifiers: string[];
|
|
21
|
+
};
|
|
22
|
+
/** Reading availability from Internet Archive. */
|
|
23
|
+
export type WorkAvailability = {
|
|
24
|
+
status: string;
|
|
25
|
+
available_to_browse: boolean;
|
|
26
|
+
available_to_borrow: boolean;
|
|
27
|
+
available_to_waitlist: boolean;
|
|
28
|
+
is_readable: boolean;
|
|
29
|
+
is_lendable: boolean;
|
|
30
|
+
is_previewable: boolean;
|
|
31
|
+
is_restricted: boolean;
|
|
32
|
+
openlibrary_edition?: string;
|
|
33
|
+
};
|
|
34
|
+
/** Full work detail. */
|
|
35
|
+
export type WorkDetail = {
|
|
36
|
+
work_id: string;
|
|
37
|
+
title: string;
|
|
38
|
+
description?: string | undefined;
|
|
39
|
+
subjects: string[];
|
|
40
|
+
subject_places: string[];
|
|
41
|
+
subject_times: string[];
|
|
42
|
+
subject_people: string[];
|
|
43
|
+
cover_ids: number[];
|
|
44
|
+
author_ids: string[];
|
|
45
|
+
created?: string;
|
|
46
|
+
last_modified?: string;
|
|
47
|
+
};
|
|
48
|
+
/** Edition summary within a work's edition list. */
|
|
49
|
+
export type EditionSummary = {
|
|
50
|
+
edition_id: string;
|
|
51
|
+
title: string;
|
|
52
|
+
publish_date?: string;
|
|
53
|
+
publishers: string[];
|
|
54
|
+
languages: string[];
|
|
55
|
+
isbn_10: string[];
|
|
56
|
+
isbn_13: string[];
|
|
57
|
+
page_count?: number;
|
|
58
|
+
cover_ids: number[];
|
|
59
|
+
work_id?: string;
|
|
60
|
+
};
|
|
61
|
+
/** Full edition detail. */
|
|
62
|
+
export type EditionDetail = {
|
|
63
|
+
edition_id: string;
|
|
64
|
+
title: string;
|
|
65
|
+
authors: Array<{
|
|
66
|
+
name: string;
|
|
67
|
+
author_id?: string | undefined;
|
|
68
|
+
}>;
|
|
69
|
+
publish_date?: string | undefined;
|
|
70
|
+
publishers: string[];
|
|
71
|
+
language?: string | undefined;
|
|
72
|
+
isbn_10: string[];
|
|
73
|
+
isbn_13: string[];
|
|
74
|
+
oclc: string[];
|
|
75
|
+
lccn: string[];
|
|
76
|
+
page_count?: number | undefined;
|
|
77
|
+
description?: string | undefined;
|
|
78
|
+
cover_ids: number[];
|
|
79
|
+
work_id?: string | undefined;
|
|
80
|
+
ebook_url?: string | undefined;
|
|
81
|
+
};
|
|
82
|
+
/** Author search result. */
|
|
83
|
+
export type AuthorSearchResult = {
|
|
84
|
+
author_id: string;
|
|
85
|
+
name: string;
|
|
86
|
+
alternate_names: string[];
|
|
87
|
+
birth_date?: string;
|
|
88
|
+
death_date?: string;
|
|
89
|
+
top_work?: string;
|
|
90
|
+
work_count: number;
|
|
91
|
+
top_subjects: string[];
|
|
92
|
+
ratings_average?: number;
|
|
93
|
+
};
|
|
94
|
+
/** Full author detail. */
|
|
95
|
+
export type AuthorDetail = {
|
|
96
|
+
author_id: string;
|
|
97
|
+
name: string;
|
|
98
|
+
personal_name?: string | undefined;
|
|
99
|
+
fuller_name?: string | undefined;
|
|
100
|
+
bio?: string | undefined;
|
|
101
|
+
birth_date?: string | undefined;
|
|
102
|
+
death_date?: string | undefined;
|
|
103
|
+
photo_ids: number[];
|
|
104
|
+
remote_ids: {
|
|
105
|
+
wikidata?: string | undefined;
|
|
106
|
+
viaf?: string | undefined;
|
|
107
|
+
isni?: string | undefined;
|
|
108
|
+
goodreads?: string | undefined;
|
|
109
|
+
librarything?: string | undefined;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
/** Work summary in author works list. */
|
|
113
|
+
export type AuthorWork = {
|
|
114
|
+
work_id: string;
|
|
115
|
+
title: string;
|
|
116
|
+
first_publish_date?: string;
|
|
117
|
+
cover_ids: number[];
|
|
118
|
+
};
|
|
119
|
+
/** Work summary in a subject's work list. */
|
|
120
|
+
export type SubjectWork = {
|
|
121
|
+
work_id: string;
|
|
122
|
+
title: string;
|
|
123
|
+
author_names: string[];
|
|
124
|
+
edition_count: number;
|
|
125
|
+
cover_id?: number;
|
|
126
|
+
};
|
|
127
|
+
/** Identifier type for edition lookup. */
|
|
128
|
+
export type EditionIdType = 'isbn' | 'oclc' | 'lccn' | 'olid';
|
|
129
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/open-library/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,UAAU,GAAG,eAAe,GAAG,YAAY,GAAG,QAAQ,CAAC;IACrE,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gFAAgF;IAChF,YAAY,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,CAAC;IACnD,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,kDAAkD;AAClD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,EAAE,OAAO,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,wBAAwB;AACxB,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,oDAAoD;AACpD,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,2BAA2B;AAC3B,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;IACjE,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,4BAA4B;AAC5B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,0BAA0B;AAC1B,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE;QACV,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACnC,CAAC;CACH,CAAC;AAEF,yCAAyC;AACzC,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAEF,6CAA6C;AAC7C,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,0CAA0C;AAC1C,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/services/open-library/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cyanheads/openlibrary-mcp-server",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "MCP server for Open Library — search 20M+ books, fetch editions, authors, subjects, and cover images.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"openlibrary-mcp-server": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"changelog/",
|
|
13
|
+
"dist/",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE",
|
|
16
|
+
"CLAUDE.md",
|
|
17
|
+
"AGENTS.md",
|
|
18
|
+
"Dockerfile",
|
|
19
|
+
"server.json"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsx scripts/build.ts",
|
|
23
|
+
"rebuild": "tsx scripts/clean.ts && tsx scripts/build.ts",
|
|
24
|
+
"clean": "tsx scripts/clean.ts",
|
|
25
|
+
"devcheck": "tsx scripts/devcheck.ts",
|
|
26
|
+
"audit:refresh": "rm -f bun.lock && bun install && bun audit",
|
|
27
|
+
"tree": "tsx scripts/tree.ts",
|
|
28
|
+
"list-skills": "tsx scripts/list-skills.ts",
|
|
29
|
+
"format": "biome check --write --unsafe .",
|
|
30
|
+
"lint:mcp": "tsx scripts/lint-mcp.ts",
|
|
31
|
+
"lint:packaging": "tsx scripts/lint-packaging.ts",
|
|
32
|
+
"bundle": "npm run build && npx -y @anthropic-ai/mcpb pack . dist/openlibrary-mcp-server.mcpb",
|
|
33
|
+
"changelog:build": "tsx scripts/build-changelog.ts",
|
|
34
|
+
"changelog:check": "tsx scripts/build-changelog.ts --check",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"start": "node dist/index.js",
|
|
37
|
+
"start:stdio": "MCP_TRANSPORT_TYPE=stdio node dist/index.js",
|
|
38
|
+
"start:http": "MCP_TRANSPORT_TYPE=http node dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"mcp",
|
|
42
|
+
"mcp-server",
|
|
43
|
+
"model-context-protocol",
|
|
44
|
+
"open-library",
|
|
45
|
+
"books",
|
|
46
|
+
"library",
|
|
47
|
+
"isbn",
|
|
48
|
+
"authors",
|
|
49
|
+
"editions",
|
|
50
|
+
"internet-archive"
|
|
51
|
+
],
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "https://github.com/cyanheads/openlibrary-mcp-server"
|
|
55
|
+
},
|
|
56
|
+
"license": "Apache-2.0",
|
|
57
|
+
"engines": {
|
|
58
|
+
"bun": ">=1.3.0",
|
|
59
|
+
"node": ">=24.0.0"
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public"
|
|
63
|
+
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@cyanheads/mcp-ts-core": "^0.9.7",
|
|
66
|
+
"pino-pretty": "^13.1.3",
|
|
67
|
+
"zod": "^4.4.3"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@biomejs/biome": "^2.4.15",
|
|
71
|
+
"@types/node": "^25.9.1",
|
|
72
|
+
"depcheck": "^1.4.7",
|
|
73
|
+
"ignore": "^7.0.5",
|
|
74
|
+
"tsc-alias": "^1.8.17",
|
|
75
|
+
"tsx": "^4.22.3",
|
|
76
|
+
"typescript": "^6.0.3",
|
|
77
|
+
"vitest": "^4.1.7"
|
|
78
|
+
}
|
|
79
|
+
}
|