@cyanheads/wikidata-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 +401 -0
- package/Dockerfile +98 -0
- package/LICENSE +201 -0
- package/README.md +293 -0
- package/changelog/0.1.x/0.1.0.md +20 -0
- package/changelog/0.1.x/0.1.1.md +20 -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 +31 -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 +34 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/entity.resource.d.ts +11 -0
- package/dist/mcp-server/resources/definitions/entity.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/entity.resource.js +127 -0
- package/dist/mcp-server/resources/definitions/entity.resource.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-entity.tool.d.ts +38 -0
- package/dist/mcp-server/tools/definitions/get-entity.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-entity.tool.js +215 -0
- package/dist/mcp-server/tools/definitions/get-entity.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-labels.tool.d.ts +24 -0
- package/dist/mcp-server/tools/definitions/get-labels.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-labels.tool.js +93 -0
- package/dist/mcp-server/tools/definitions/get-labels.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-sitelinks.tool.d.ts +31 -0
- package/dist/mcp-server/tools/definitions/get-sitelinks.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-sitelinks.tool.js +128 -0
- package/dist/mcp-server/tools/definitions/get-sitelinks.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-statements.tool.d.ts +29 -0
- package/dist/mcp-server/tools/definitions/get-statements.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-statements.tool.js +185 -0
- package/dist/mcp-server/tools/definitions/get-statements.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/resolve-external-id.tool.d.ts +30 -0
- package/dist/mcp-server/tools/definitions/resolve-external-id.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/resolve-external-id.tool.js +193 -0
- package/dist/mcp-server/tools/definitions/resolve-external-id.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-entities.tool.d.ts +36 -0
- package/dist/mcp-server/tools/definitions/search-entities.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-entities.tool.js +129 -0
- package/dist/mcp-server/tools/definitions/search-entities.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/sparql-query.tool.d.ts +34 -0
- package/dist/mcp-server/tools/definitions/sparql-query.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/sparql-query.tool.js +151 -0
- package/dist/mcp-server/tools/definitions/sparql-query.tool.js.map +1 -0
- package/dist/services/wikidata/types.d.ts +164 -0
- package/dist/services/wikidata/types.d.ts.map +1 -0
- package/dist/services/wikidata/types.js +6 -0
- package/dist/services/wikidata/types.js.map +1 -0
- package/dist/services/wikidata/wikidata-rest-service.d.ts +48 -0
- package/dist/services/wikidata/wikidata-rest-service.d.ts.map +1 -0
- package/dist/services/wikidata/wikidata-rest-service.js +293 -0
- package/dist/services/wikidata/wikidata-rest-service.js.map +1 -0
- package/dist/services/wikidata/wikidata-sparql-service.d.ts +23 -0
- package/dist/services/wikidata/wikidata-sparql-service.d.ts.map +1 -0
- package/dist/services/wikidata/wikidata-sparql-service.js +163 -0
- package/dist/services/wikidata/wikidata-sparql-service.js.map +1 -0
- package/package.json +82 -0
- package/server.json +141 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Wikidata REST API and MediaWiki wbgetentities client.
|
|
3
|
+
* @module services/wikidata/wikidata-rest-service
|
|
4
|
+
*/
|
|
5
|
+
import { fetchWithTimeout, httpErrorFromResponse, withRetry, } from '@cyanheads/mcp-ts-core/utils';
|
|
6
|
+
import { getServerConfig } from '../../config/server-config.js';
|
|
7
|
+
const REST_BASE = 'https://www.wikidata.org/w/rest.php/wikibase/v1';
|
|
8
|
+
const MW_API_BASE = 'https://www.wikidata.org/w/api.php';
|
|
9
|
+
/** Checks if an ID is a Q-ID (item). */
|
|
10
|
+
export function isQId(id) {
|
|
11
|
+
return /^[Qq]\d+$/.test(id);
|
|
12
|
+
}
|
|
13
|
+
/** Checks if an ID is a P-ID (property). */
|
|
14
|
+
export function isPId(id) {
|
|
15
|
+
return /^[Pp]\d+$/.test(id);
|
|
16
|
+
}
|
|
17
|
+
/** Normalizes a Q/P-ID to uppercase (e.g. q76 → Q76). */
|
|
18
|
+
export function normalizeId(id) {
|
|
19
|
+
return id.toUpperCase();
|
|
20
|
+
}
|
|
21
|
+
export class WikidataRestService {
|
|
22
|
+
userAgent;
|
|
23
|
+
restTimeoutMs;
|
|
24
|
+
constructor(_config, _storage) {
|
|
25
|
+
const serverCfg = getServerConfig();
|
|
26
|
+
this.userAgent = serverCfg.userAgent;
|
|
27
|
+
this.restTimeoutMs = serverCfg.restTimeoutMs;
|
|
28
|
+
}
|
|
29
|
+
get headers() {
|
|
30
|
+
return {
|
|
31
|
+
'User-Agent': this.userAgent,
|
|
32
|
+
Accept: 'application/json',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
getJson(url, ctx) {
|
|
36
|
+
const rctx = ctx;
|
|
37
|
+
return withRetry(async () => {
|
|
38
|
+
const response = await fetchWithTimeout(url, this.restTimeoutMs, rctx, {
|
|
39
|
+
headers: this.headers,
|
|
40
|
+
signal: ctx.signal,
|
|
41
|
+
});
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
throw await httpErrorFromResponse(response, { service: 'Wikidata REST' });
|
|
44
|
+
}
|
|
45
|
+
const text = await response.text();
|
|
46
|
+
if (/^\s*<(!DOCTYPE\s+html|html[\s>])/i.test(text)) {
|
|
47
|
+
const { serviceUnavailable } = await import('@cyanheads/mcp-ts-core/errors');
|
|
48
|
+
throw serviceUnavailable('Wikidata REST returned HTML — likely rate-limited or under maintenance.');
|
|
49
|
+
}
|
|
50
|
+
return JSON.parse(text);
|
|
51
|
+
}, { operation: 'WikidataRest.getJson', context: rctx, baseDelayMs: 1000, signal: ctx.signal });
|
|
52
|
+
}
|
|
53
|
+
/** Search items or properties by text. */
|
|
54
|
+
async search(query, type, language, limit, offset, ctx) {
|
|
55
|
+
const path = type === 'item' ? 'search/items' : 'search/properties';
|
|
56
|
+
const params = new URLSearchParams({
|
|
57
|
+
q: query,
|
|
58
|
+
language,
|
|
59
|
+
limit: String(limit),
|
|
60
|
+
...(offset > 0 ? { offset: String(offset) } : {}),
|
|
61
|
+
});
|
|
62
|
+
const url = `${REST_BASE}/${path}?${params}`;
|
|
63
|
+
ctx.log.debug('Searching entities', { type, query, language, limit, offset });
|
|
64
|
+
const data = await this.getJson(url, ctx);
|
|
65
|
+
return data.results ?? [];
|
|
66
|
+
}
|
|
67
|
+
/** Fetch a single entity by QID or PID. Routes by ID prefix. */
|
|
68
|
+
fetchEntity(id, ctx) {
|
|
69
|
+
const normalized = normalizeId(id);
|
|
70
|
+
const path = isQId(normalized)
|
|
71
|
+
? `entities/items/${normalized}`
|
|
72
|
+
: `entities/properties/${normalized}`;
|
|
73
|
+
const url = `${REST_BASE}/${path}`;
|
|
74
|
+
ctx.log.debug('Fetching entity', { id: normalized });
|
|
75
|
+
return this.getJson(url, ctx);
|
|
76
|
+
}
|
|
77
|
+
/** Fetch statements for an entity, optionally filtered to specific P-IDs. */
|
|
78
|
+
async fetchStatements(id, properties, ctx) {
|
|
79
|
+
const normalized = normalizeId(id);
|
|
80
|
+
const basePath = isQId(normalized)
|
|
81
|
+
? `entities/items/${normalized}/statements`
|
|
82
|
+
: `entities/properties/${normalized}/statements`;
|
|
83
|
+
// The REST API supports a single `property` filter param per request.
|
|
84
|
+
// For multiple properties we fetch all and client-filter.
|
|
85
|
+
const url = properties?.length === 1
|
|
86
|
+
? `${REST_BASE}/${basePath}?property=${properties[0]?.toUpperCase()}`
|
|
87
|
+
: `${REST_BASE}/${basePath}`;
|
|
88
|
+
ctx.log.debug('Fetching statements', { id: normalized, properties });
|
|
89
|
+
const data = await this.getJson(url, ctx);
|
|
90
|
+
if (properties && properties.length > 1) {
|
|
91
|
+
const upperProps = new Set(properties.map((p) => p.toUpperCase()));
|
|
92
|
+
return Object.fromEntries(Object.entries(data).filter(([key]) => upperProps.has(key.toUpperCase())));
|
|
93
|
+
}
|
|
94
|
+
return data;
|
|
95
|
+
}
|
|
96
|
+
/** Fetch sitelinks for a Q-ID, optionally filtered to specific site codes. */
|
|
97
|
+
async fetchSitelinks(id, sites, ctx) {
|
|
98
|
+
const normalized = normalizeId(id);
|
|
99
|
+
const url = `${REST_BASE}/entities/items/${normalized}/sitelinks`;
|
|
100
|
+
ctx.log.debug('Fetching sitelinks', { id: normalized, sites });
|
|
101
|
+
const data = await this.getJson(url, ctx);
|
|
102
|
+
if (sites?.length) {
|
|
103
|
+
const siteSet = new Set(sites);
|
|
104
|
+
return Object.fromEntries(Object.entries(data).filter(([key]) => siteSet.has(key)));
|
|
105
|
+
}
|
|
106
|
+
return data;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Batch-resolve labels and descriptions for up to 50 IDs using the MediaWiki
|
|
110
|
+
* wbgetentities API (the REST API has no batch label endpoint).
|
|
111
|
+
*/
|
|
112
|
+
async fetchLabels(ids, languages, ctx) {
|
|
113
|
+
// Process in batches of 50
|
|
114
|
+
const batches = [];
|
|
115
|
+
for (let i = 0; i < ids.length; i += 50) {
|
|
116
|
+
batches.push(ids.slice(i, i + 50));
|
|
117
|
+
}
|
|
118
|
+
const results = {};
|
|
119
|
+
await Promise.all(batches.map(async (batch) => {
|
|
120
|
+
const params = new URLSearchParams({
|
|
121
|
+
action: 'wbgetentities',
|
|
122
|
+
ids: batch.map(normalizeId).join('|'),
|
|
123
|
+
props: 'labels|descriptions',
|
|
124
|
+
languages: languages.join('|'),
|
|
125
|
+
format: 'json',
|
|
126
|
+
formatversion: '2',
|
|
127
|
+
});
|
|
128
|
+
const url = `${MW_API_BASE}?${params}`;
|
|
129
|
+
ctx.log.debug('Fetching labels batch', { count: batch.length, languages });
|
|
130
|
+
const rctx = ctx;
|
|
131
|
+
const data = await withRetry(async () => {
|
|
132
|
+
const response = await fetchWithTimeout(url, this.restTimeoutMs, rctx, {
|
|
133
|
+
headers: this.headers,
|
|
134
|
+
signal: ctx.signal,
|
|
135
|
+
});
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
throw await httpErrorFromResponse(response, { service: 'Wikidata MW API' });
|
|
138
|
+
}
|
|
139
|
+
const text = await response.text();
|
|
140
|
+
if (/^\s*<(!DOCTYPE\s+html|html[\s>])/i.test(text)) {
|
|
141
|
+
const { serviceUnavailable } = await import('@cyanheads/mcp-ts-core/errors');
|
|
142
|
+
throw serviceUnavailable('Wikidata MW API returned HTML — likely rate-limited.');
|
|
143
|
+
}
|
|
144
|
+
return JSON.parse(text);
|
|
145
|
+
}, {
|
|
146
|
+
operation: 'WikidataRest.fetchLabels',
|
|
147
|
+
context: rctx,
|
|
148
|
+
baseDelayMs: 1000,
|
|
149
|
+
signal: ctx.signal,
|
|
150
|
+
});
|
|
151
|
+
if (data.entities) {
|
|
152
|
+
for (const [id, entity] of Object.entries(data.entities)) {
|
|
153
|
+
if (entity.missing === '')
|
|
154
|
+
continue;
|
|
155
|
+
const labelMap = {};
|
|
156
|
+
const descMap = {};
|
|
157
|
+
if (entity.labels) {
|
|
158
|
+
for (const [lang, lb] of Object.entries(entity.labels)) {
|
|
159
|
+
labelMap[lang] = lb.value;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (entity.descriptions) {
|
|
163
|
+
for (const [lang, ds] of Object.entries(entity.descriptions)) {
|
|
164
|
+
descMap[lang] = ds.value;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
results[id] = { labels: labelMap, descriptions: descMap };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}));
|
|
171
|
+
return results;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
// Statement value normalization
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
/** Normalize a raw statement value to the domain type. */
|
|
178
|
+
export function normalizeStatementValue(dataType, rawContent) {
|
|
179
|
+
const effective = dataType ?? 'string';
|
|
180
|
+
if (effective === 'wikibase-item') {
|
|
181
|
+
const content = rawContent;
|
|
182
|
+
if (typeof content === 'object' && content !== null && 'id' in content) {
|
|
183
|
+
return { type: 'wikibase-item', qid: content.id ?? '' };
|
|
184
|
+
}
|
|
185
|
+
if (typeof content === 'string') {
|
|
186
|
+
return { type: 'wikibase-item', qid: content };
|
|
187
|
+
}
|
|
188
|
+
return { type: 'wikibase-item', qid: String(rawContent ?? '') };
|
|
189
|
+
}
|
|
190
|
+
if (effective === 'time') {
|
|
191
|
+
const content = rawContent;
|
|
192
|
+
if (typeof content === 'object' && content !== null) {
|
|
193
|
+
return { type: 'time', time: content.time ?? '', precision: content.precision ?? 0 };
|
|
194
|
+
}
|
|
195
|
+
return { type: 'other', raw: rawContent };
|
|
196
|
+
}
|
|
197
|
+
if (effective === 'quantity') {
|
|
198
|
+
const content = rawContent;
|
|
199
|
+
if (typeof content === 'object' && content !== null) {
|
|
200
|
+
const unit = content.unit;
|
|
201
|
+
return unit !== undefined
|
|
202
|
+
? { type: 'quantity', amount: content.amount ?? '', unit }
|
|
203
|
+
: { type: 'quantity', amount: content.amount ?? '' };
|
|
204
|
+
}
|
|
205
|
+
return { type: 'other', raw: rawContent };
|
|
206
|
+
}
|
|
207
|
+
if (effective === 'monolingualtext') {
|
|
208
|
+
const content = rawContent;
|
|
209
|
+
if (typeof content === 'object' && content !== null) {
|
|
210
|
+
return {
|
|
211
|
+
type: 'monolingualtext',
|
|
212
|
+
text: content.text ?? '',
|
|
213
|
+
language: content.language ?? '',
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
return { type: 'other', raw: rawContent };
|
|
217
|
+
}
|
|
218
|
+
if (effective === 'globe-coordinate') {
|
|
219
|
+
const content = rawContent;
|
|
220
|
+
if (typeof content === 'object' && content !== null) {
|
|
221
|
+
return {
|
|
222
|
+
type: 'globe-coordinate',
|
|
223
|
+
latitude: content.latitude ?? 0,
|
|
224
|
+
longitude: content.longitude ?? 0,
|
|
225
|
+
...(content.precision != null ? { precision: content.precision } : {}),
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
return { type: 'other', raw: rawContent };
|
|
229
|
+
}
|
|
230
|
+
if ([
|
|
231
|
+
'external-id',
|
|
232
|
+
'url',
|
|
233
|
+
'string',
|
|
234
|
+
'commonsMedia',
|
|
235
|
+
'geo-shape',
|
|
236
|
+
'tabular-data',
|
|
237
|
+
'math',
|
|
238
|
+
'musical-notation',
|
|
239
|
+
].includes(effective)) {
|
|
240
|
+
return { type: 'string', value: String(rawContent ?? '') };
|
|
241
|
+
}
|
|
242
|
+
// Unknown types — preserve as-is
|
|
243
|
+
return { type: 'other', raw: rawContent };
|
|
244
|
+
}
|
|
245
|
+
/** Normalize a raw statement array to domain statements. */
|
|
246
|
+
export function normalizeStatements(propertyId, rawStatements, labelMap) {
|
|
247
|
+
return rawStatements.map((raw) => {
|
|
248
|
+
const dataType = raw.property?.data_type;
|
|
249
|
+
const rawValue = normalizeStatementValue(dataType, raw.value?.content);
|
|
250
|
+
// Resolve label for wikibase-item values
|
|
251
|
+
let value;
|
|
252
|
+
if (rawValue.type === 'wikibase-item') {
|
|
253
|
+
const label = labelMap?.[rawValue.qid];
|
|
254
|
+
value =
|
|
255
|
+
label !== undefined
|
|
256
|
+
? { type: 'wikibase-item', qid: rawValue.qid, label }
|
|
257
|
+
: { type: 'wikibase-item', qid: rawValue.qid };
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
value = rawValue;
|
|
261
|
+
}
|
|
262
|
+
const qualifiers = raw.qualifiers?.map((q) => ({
|
|
263
|
+
property: q.property?.id ?? '',
|
|
264
|
+
value: normalizeStatementValue(q.property?.data_type, q.value?.content),
|
|
265
|
+
}));
|
|
266
|
+
const references = raw.references?.flatMap((ref) => (ref.parts ?? []).map((part) => ({
|
|
267
|
+
property: part.property?.id ?? '',
|
|
268
|
+
value: normalizeStatementValue(part.property?.data_type, part.value?.content),
|
|
269
|
+
})));
|
|
270
|
+
return {
|
|
271
|
+
id: raw.id,
|
|
272
|
+
rank: raw.rank,
|
|
273
|
+
property: propertyId,
|
|
274
|
+
value,
|
|
275
|
+
...(qualifiers?.length ? { qualifiers } : {}),
|
|
276
|
+
...(references?.length ? { references } : {}),
|
|
277
|
+
};
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
// ---------------------------------------------------------------------------
|
|
281
|
+
// Init / accessor pattern
|
|
282
|
+
// ---------------------------------------------------------------------------
|
|
283
|
+
let _service;
|
|
284
|
+
export function initWikidataRestService(config, storage) {
|
|
285
|
+
_service = new WikidataRestService(config, storage);
|
|
286
|
+
}
|
|
287
|
+
export function getWikidataRestService() {
|
|
288
|
+
if (!_service) {
|
|
289
|
+
throw new Error('WikidataRestService not initialized — call initWikidataRestService() in setup()');
|
|
290
|
+
}
|
|
291
|
+
return _service;
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=wikidata-rest-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wikidata-rest-service.js","sourceRoot":"","sources":["../../../src/services/wikidata/wikidata-rest-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Wikidata SPARQL Query Service client.
|
|
3
|
+
* @module services/wikidata/wikidata-sparql-service
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import type { AppConfig } from '@cyanheads/mcp-ts-core/config';
|
|
7
|
+
import type { StorageService } from '@cyanheads/mcp-ts-core/storage';
|
|
8
|
+
import type { SparqlResponse } from './types.js';
|
|
9
|
+
export declare class WikidataSparqlService {
|
|
10
|
+
private readonly userAgent;
|
|
11
|
+
private readonly defaultTimeoutMs;
|
|
12
|
+
constructor(_config: AppConfig, _storage: StorageService);
|
|
13
|
+
/**
|
|
14
|
+
* Execute a SPARQL SELECT query against the Wikidata Query Service.
|
|
15
|
+
* Injects common prefixes and label SERVICE when appropriate.
|
|
16
|
+
*/
|
|
17
|
+
query(rawQuery: string, language: string, timeoutMs: number | undefined, ctx: Context): Promise<SparqlResponse>;
|
|
18
|
+
/** Prepend standard prefixes and inject label SERVICE if needed. */
|
|
19
|
+
private prepareQuery;
|
|
20
|
+
}
|
|
21
|
+
export declare function initWikidataSparqlService(config: AppConfig, storage: StorageService): void;
|
|
22
|
+
export declare function getWikidataSparqlService(): WikidataSparqlService;
|
|
23
|
+
//# sourceMappingURL=wikidata-sparql-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wikidata-sparql-service.d.ts","sourceRoot":"","sources":["../../../src/services/wikidata/wikidata-sparql-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA2CjD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc;IAMxD;;;OAGG;IACH,KAAK,CACH,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,cAAc,CAAC;IAuF1B,oEAAoE;IACpE,OAAO,CAAC,YAAY;CA0BrB;AAQD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAE1F;AAED,wBAAgB,wBAAwB,IAAI,qBAAqB,CAOhE"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Wikidata SPARQL Query Service client.
|
|
3
|
+
* @module services/wikidata/wikidata-sparql-service
|
|
4
|
+
*/
|
|
5
|
+
import { withRetry } from '@cyanheads/mcp-ts-core/utils';
|
|
6
|
+
import { getServerConfig } from '../../config/server-config.js';
|
|
7
|
+
const SPARQL_ENDPOINT = 'https://query.wikidata.org/sparql';
|
|
8
|
+
/** Common SPARQL prefixes pre-pended to every query. */
|
|
9
|
+
const SPARQL_PREFIXES = `PREFIX wd: <http://www.wikidata.org/entity/>
|
|
10
|
+
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
|
|
11
|
+
PREFIX p: <http://www.wikidata.org/prop/>
|
|
12
|
+
PREFIX ps: <http://www.wikidata.org/prop/statement/>
|
|
13
|
+
PREFIX pq: <http://www.wikidata.org/prop/qualifier/>
|
|
14
|
+
PREFIX wikibase: <http://wikiba.se/ontology#>
|
|
15
|
+
PREFIX bd: <http://www.bigdata.com/rdf#>
|
|
16
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
17
|
+
PREFIX schema: <http://schema.org/>
|
|
18
|
+
`;
|
|
19
|
+
/** Label SERVICE snippet injected when language is specified and not already present. */
|
|
20
|
+
const LABEL_SERVICE_SNIPPET = (lang) => `SERVICE wikibase:label { bd:serviceParam wikibase:language "${lang}" }`;
|
|
21
|
+
/**
|
|
22
|
+
* Extract the human-readable cause from a Blazegraph Java stack trace.
|
|
23
|
+
* Stack traces look like:
|
|
24
|
+
* org.openrdf.query.MalformedQueryException: <reason>
|
|
25
|
+
* ... (stack frames)
|
|
26
|
+
*/
|
|
27
|
+
function extractSparqlError(body) {
|
|
28
|
+
// Try to find the MalformedQueryException message
|
|
29
|
+
const mqMatch = /MalformedQueryException:\s*(.+?)(?:\r?\n|$)/.exec(body);
|
|
30
|
+
if (mqMatch?.[1])
|
|
31
|
+
return mqMatch[1].trim();
|
|
32
|
+
// Try QueryEvaluationException
|
|
33
|
+
const qeMatch = /QueryEvaluationException:\s*(.+?)(?:\r?\n|$)/.exec(body);
|
|
34
|
+
if (qeMatch?.[1])
|
|
35
|
+
return qeMatch[1].trim();
|
|
36
|
+
// Try any Exception line
|
|
37
|
+
const anyMatch = /Exception:\s*(.+?)(?:\r?\n|$)/.exec(body);
|
|
38
|
+
if (anyMatch?.[1])
|
|
39
|
+
return anyMatch[1].trim();
|
|
40
|
+
// Fall back to first 200 chars
|
|
41
|
+
return body.slice(0, 200).trim();
|
|
42
|
+
}
|
|
43
|
+
export class WikidataSparqlService {
|
|
44
|
+
userAgent;
|
|
45
|
+
defaultTimeoutMs;
|
|
46
|
+
constructor(_config, _storage) {
|
|
47
|
+
const serverCfg = getServerConfig();
|
|
48
|
+
this.userAgent = serverCfg.userAgent;
|
|
49
|
+
this.defaultTimeoutMs = serverCfg.sparqlTimeoutMs;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Execute a SPARQL SELECT query against the Wikidata Query Service.
|
|
53
|
+
* Injects common prefixes and label SERVICE when appropriate.
|
|
54
|
+
*/
|
|
55
|
+
query(rawQuery, language, timeoutMs, ctx) {
|
|
56
|
+
const effectiveTimeout = Math.min(timeoutMs ?? this.defaultTimeoutMs, 55_000);
|
|
57
|
+
const query = this.prepareQuery(rawQuery, language);
|
|
58
|
+
ctx.log.debug('Executing SPARQL query', { language, timeoutMs: effectiveTimeout });
|
|
59
|
+
const rctx = ctx;
|
|
60
|
+
return withRetry(async () => {
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
const timeoutId = setTimeout(() => controller.abort(), effectiveTimeout);
|
|
63
|
+
// Forward cancellation from the caller's signal to our timeout controller
|
|
64
|
+
const onCallerAbort = () => controller.abort();
|
|
65
|
+
ctx.signal.addEventListener('abort', onCallerAbort);
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch(SPARQL_ENDPOINT, {
|
|
68
|
+
method: 'POST',
|
|
69
|
+
headers: {
|
|
70
|
+
'User-Agent': this.userAgent,
|
|
71
|
+
Accept: 'application/sparql-results+json',
|
|
72
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
73
|
+
},
|
|
74
|
+
body: new URLSearchParams({ query }),
|
|
75
|
+
signal: controller.signal,
|
|
76
|
+
});
|
|
77
|
+
if (response.status === 429) {
|
|
78
|
+
const retryAfter = response.headers.get('Retry-After');
|
|
79
|
+
const { rateLimited } = await import('@cyanheads/mcp-ts-core/errors');
|
|
80
|
+
throw rateLimited(`Wikidata SPARQL endpoint is rate-limited. ${retryAfter ? `Retry after ${retryAfter}s.` : 'Retry shortly.'}`, { reason: 'throttled', ...(retryAfter ? { retryAfter } : {}) });
|
|
81
|
+
}
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
const body = await response.text().catch(() => '');
|
|
84
|
+
if (response.status === 400 || response.status === 422) {
|
|
85
|
+
const cause = extractSparqlError(body);
|
|
86
|
+
const { invalidParams } = await import('@cyanheads/mcp-ts-core/errors');
|
|
87
|
+
throw invalidParams(`SPARQL parse error: ${cause}`, { reason: 'parse_error', cause });
|
|
88
|
+
}
|
|
89
|
+
const { serviceUnavailable } = await import('@cyanheads/mcp-ts-core/errors');
|
|
90
|
+
throw serviceUnavailable(`Wikidata SPARQL endpoint returned HTTP ${response.status}.`, {
|
|
91
|
+
status: response.status,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const text = await response.text();
|
|
95
|
+
if (/^\s*<(!DOCTYPE\s+html|html[\s>])/i.test(text)) {
|
|
96
|
+
const { serviceUnavailable } = await import('@cyanheads/mcp-ts-core/errors');
|
|
97
|
+
throw serviceUnavailable('SPARQL endpoint returned HTML — likely rate-limited or under maintenance.');
|
|
98
|
+
}
|
|
99
|
+
return JSON.parse(text);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
if (err instanceof Error && err.name === 'AbortError') {
|
|
103
|
+
const { serviceUnavailable } = await import('@cyanheads/mcp-ts-core/errors');
|
|
104
|
+
throw serviceUnavailable(`SPARQL query timed out after ${effectiveTimeout / 1000}s. Add a LIMIT clause or simplify the query.`, { reason: 'timeout' });
|
|
105
|
+
}
|
|
106
|
+
throw err;
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
clearTimeout(timeoutId);
|
|
110
|
+
ctx.signal.removeEventListener('abort', onCallerAbort);
|
|
111
|
+
}
|
|
112
|
+
}, {
|
|
113
|
+
operation: 'WikidataSparql.query',
|
|
114
|
+
context: rctx,
|
|
115
|
+
baseDelayMs: 2000,
|
|
116
|
+
signal: ctx.signal,
|
|
117
|
+
// Only retry throttle errors (429), not parse errors or timeouts
|
|
118
|
+
isTransient: (err) => {
|
|
119
|
+
const e = err;
|
|
120
|
+
return e?.data?.reason === 'throttled';
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/** Prepend standard prefixes and inject label SERVICE if needed. */
|
|
125
|
+
prepareQuery(rawQuery, language) {
|
|
126
|
+
let query = rawQuery.trim();
|
|
127
|
+
// Inject label SERVICE if language is set and the SERVICE block is absent
|
|
128
|
+
const hasLabelService = /SERVICE\s+wikibase:label/i.test(query);
|
|
129
|
+
if (language && !hasLabelService) {
|
|
130
|
+
// Insert before closing brace of the last WHERE clause
|
|
131
|
+
query = query.replace(/\}\s*$/, ` ${LABEL_SERVICE_SNIPPET(language)}\n}`);
|
|
132
|
+
}
|
|
133
|
+
// Prepend standard prefixes (only those not already declared)
|
|
134
|
+
const prefixLines = SPARQL_PREFIXES.split('\n').filter(Boolean);
|
|
135
|
+
const existingPrefixes = new Set();
|
|
136
|
+
for (const line of query.split('\n')) {
|
|
137
|
+
const m = /^PREFIX\s+(\w+:)/i.exec(line.trim());
|
|
138
|
+
if (m?.[1])
|
|
139
|
+
existingPrefixes.add(m[1]);
|
|
140
|
+
}
|
|
141
|
+
const neededPrefixes = prefixLines
|
|
142
|
+
.filter((line) => {
|
|
143
|
+
const m = /^PREFIX\s+(\w+:)/.exec(line);
|
|
144
|
+
return m?.[1] && !existingPrefixes.has(m[1]);
|
|
145
|
+
})
|
|
146
|
+
.join('\n');
|
|
147
|
+
return neededPrefixes ? `${neededPrefixes}\n${query}` : query;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
// Init / accessor pattern
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
let _service;
|
|
154
|
+
export function initWikidataSparqlService(config, storage) {
|
|
155
|
+
_service = new WikidataSparqlService(config, storage);
|
|
156
|
+
}
|
|
157
|
+
export function getWikidataSparqlService() {
|
|
158
|
+
if (!_service) {
|
|
159
|
+
throw new Error('WikidataSparqlService not initialized — call initWikidataSparqlService() in setup()');
|
|
160
|
+
}
|
|
161
|
+
return _service;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=wikidata-sparql-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wikidata-sparql-service.js","sourceRoot":"","sources":["../../../src/services/wikidata/wikidata-sparql-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cyanheads/wikidata-mcp-server",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "MCP server for Wikidata — entity search and fetch, SPARQL queries, and external ID lookup.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"@cyanheads/wikidata-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/wikidata-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
|
+
"ai",
|
|
45
|
+
"llm",
|
|
46
|
+
"bun",
|
|
47
|
+
"stdio",
|
|
48
|
+
"streamable-http",
|
|
49
|
+
"wikidata",
|
|
50
|
+
"sparql",
|
|
51
|
+
"knowledge-graph",
|
|
52
|
+
"wikibase",
|
|
53
|
+
"linked-data"
|
|
54
|
+
],
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "https://github.com/cyanheads/wikidata-mcp-server"
|
|
58
|
+
},
|
|
59
|
+
"license": "Apache-2.0",
|
|
60
|
+
"engines": {
|
|
61
|
+
"bun": ">=1.3.0",
|
|
62
|
+
"node": ">=24.0.0"
|
|
63
|
+
},
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public"
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"@cyanheads/mcp-ts-core": "^0.9.7",
|
|
69
|
+
"pino-pretty": "^13.1.3",
|
|
70
|
+
"zod": "^4.4.3"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@biomejs/biome": "^2.4.15",
|
|
74
|
+
"@types/node": "^25.9.1",
|
|
75
|
+
"depcheck": "^1.4.7",
|
|
76
|
+
"ignore": "^7.0.5",
|
|
77
|
+
"tsc-alias": "^1.8.17",
|
|
78
|
+
"tsx": "^4.22.3",
|
|
79
|
+
"typescript": "^6.0.3",
|
|
80
|
+
"vitest": "^4.1.7"
|
|
81
|
+
}
|
|
82
|
+
}
|