@chrischall/tripadvisor-mcp 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bundle.js +199 -16
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/server.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "MCP server for the TripAdvisor Terra API — location search, details, photos, and reviews",
|
|
10
|
-
"version": "0.3.
|
|
10
|
+
"version": "0.3.2"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "TripAdvisor",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "TripAdvisor travel data via the Terra API — search hotels, restaurants, and attractions, with details, photos, and reviews",
|
|
18
|
-
"version": "0.3.
|
|
18
|
+
"version": "0.3.2",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
package/dist/bundle.js
CHANGED
|
@@ -34936,7 +34936,7 @@ var pageSchema = {
|
|
|
34936
34936
|
};
|
|
34937
34937
|
|
|
34938
34938
|
// src/version.ts
|
|
34939
|
-
var VERSION = "0.3.
|
|
34939
|
+
var VERSION = "0.3.2";
|
|
34940
34940
|
|
|
34941
34941
|
// src/client.ts
|
|
34942
34942
|
import { dirname, join } from "node:path";
|
|
@@ -35271,7 +35271,8 @@ var KNOWN_CAPABILITIES = /* @__PURE__ */ new Set([
|
|
|
35271
35271
|
"capture_redirect",
|
|
35272
35272
|
"read_indexed_db",
|
|
35273
35273
|
"read_dom",
|
|
35274
|
-
"download"
|
|
35274
|
+
"download",
|
|
35275
|
+
"graphql"
|
|
35275
35276
|
]);
|
|
35276
35277
|
|
|
35277
35278
|
// node_modules/@fetchproxy/protocol/dist/mcp-id.js
|
|
@@ -35574,6 +35575,7 @@ function assertIndexedDbScopesArray(value, label) {
|
|
|
35574
35575
|
}
|
|
35575
35576
|
var DOM_SELECTOR_RE = /^[^-]{1,512}$/;
|
|
35576
35577
|
var DOM_ATTRIBUTE_RE = /^[A-Za-z_:][A-Za-z0-9_:.\-]{0,127}$/;
|
|
35578
|
+
var GRAPHQL_OP_NAME_RE = /^[_A-Za-z][_0-9A-Za-z]{0,127}$/;
|
|
35577
35579
|
function assertDomSelectorsArray(value, label) {
|
|
35578
35580
|
if (!Array.isArray(value)) {
|
|
35579
35581
|
throw new ProtocolError(`${label}: expected array, got ${typeof value}`);
|
|
@@ -35610,6 +35612,37 @@ function assertDomSelectorsArray(value, label) {
|
|
|
35610
35612
|
}
|
|
35611
35613
|
}
|
|
35612
35614
|
}
|
|
35615
|
+
function assertGraphqlOpsArray(value, label) {
|
|
35616
|
+
if (!Array.isArray(value)) {
|
|
35617
|
+
throw new ProtocolError(`${label}: expected array, got ${typeof value}`);
|
|
35618
|
+
}
|
|
35619
|
+
const seen = /* @__PURE__ */ new Set();
|
|
35620
|
+
for (let i = 0; i < value.length; i++) {
|
|
35621
|
+
const entry = value[i];
|
|
35622
|
+
assertObject(entry, `${label}[${i}]`);
|
|
35623
|
+
if (entry.name === void 0) {
|
|
35624
|
+
throw new ProtocolError(`${label}[${i}].name: missing`);
|
|
35625
|
+
}
|
|
35626
|
+
if (entry.operationName === void 0) {
|
|
35627
|
+
throw new ProtocolError(`${label}[${i}].operationName: missing`);
|
|
35628
|
+
}
|
|
35629
|
+
if (typeof entry.name !== "string" || !SCOPE_KEY_RE.test(entry.name)) {
|
|
35630
|
+
throw new ProtocolError(`${label}[${i}].name: invalid ${JSON.stringify(entry.name)}`);
|
|
35631
|
+
}
|
|
35632
|
+
if (typeof entry.operationName !== "string" || !GRAPHQL_OP_NAME_RE.test(entry.operationName)) {
|
|
35633
|
+
throw new ProtocolError(`${label}[${i}].operationName: invalid ${JSON.stringify(entry.operationName)}`);
|
|
35634
|
+
}
|
|
35635
|
+
if (seen.has(entry.name)) {
|
|
35636
|
+
throw new ProtocolError(`${label}: duplicate name ${JSON.stringify(entry.name)}`);
|
|
35637
|
+
}
|
|
35638
|
+
seen.add(entry.name);
|
|
35639
|
+
for (const k of Object.keys(entry)) {
|
|
35640
|
+
if (k !== "name" && k !== "operationName") {
|
|
35641
|
+
throw new ProtocolError(`${label}[${i}]: unexpected field ${JSON.stringify(k)}`);
|
|
35642
|
+
}
|
|
35643
|
+
}
|
|
35644
|
+
}
|
|
35645
|
+
}
|
|
35613
35646
|
function validateFrame(raw) {
|
|
35614
35647
|
assertObject(raw, "frame");
|
|
35615
35648
|
const t = raw.type;
|
|
@@ -35688,6 +35721,9 @@ function validateHello(raw) {
|
|
|
35688
35721
|
if (raw.domSelectors !== void 0) {
|
|
35689
35722
|
assertDomSelectorsArray(raw.domSelectors, "hello.domSelectors");
|
|
35690
35723
|
}
|
|
35724
|
+
if (raw.graphqlOps !== void 0) {
|
|
35725
|
+
assertGraphqlOpsArray(raw.graphqlOps, "hello.graphqlOps");
|
|
35726
|
+
}
|
|
35691
35727
|
assertBase64(raw.identityX25519Pub, "hello.identityX25519Pub");
|
|
35692
35728
|
assertBase64(raw.identityEd25519Pub, "hello.identityEd25519Pub");
|
|
35693
35729
|
assertBase64(raw.sessionNonce, "hello.sessionNonce");
|
|
@@ -35937,6 +35973,28 @@ function validateInnerRequest(raw) {
|
|
|
35937
35973
|
}
|
|
35938
35974
|
return raw;
|
|
35939
35975
|
}
|
|
35976
|
+
if (raw.op === "graphql_query") {
|
|
35977
|
+
assertObject(raw.init, "inner.init");
|
|
35978
|
+
if (raw.init.name === void 0)
|
|
35979
|
+
throw new ProtocolError("inner.init.name: missing");
|
|
35980
|
+
if (raw.init.variables === void 0) {
|
|
35981
|
+
throw new ProtocolError("inner.init.variables: missing");
|
|
35982
|
+
}
|
|
35983
|
+
assertString(raw.init.name, "inner.init.name");
|
|
35984
|
+
if (raw.init.name.length === 0) {
|
|
35985
|
+
throw new ProtocolError("inner.init.name: must be non-empty");
|
|
35986
|
+
}
|
|
35987
|
+
assertObject(raw.init.variables, "inner.init.variables");
|
|
35988
|
+
if (raw.init.tabUrl !== void 0) {
|
|
35989
|
+
assertString(raw.init.tabUrl, "inner.init.tabUrl");
|
|
35990
|
+
}
|
|
35991
|
+
for (const k of Object.keys(raw.init)) {
|
|
35992
|
+
if (k !== "name" && k !== "variables" && k !== "tabUrl") {
|
|
35993
|
+
throw new ProtocolError(`inner.init: unexpected field ${JSON.stringify(k)} on graphql_query`);
|
|
35994
|
+
}
|
|
35995
|
+
}
|
|
35996
|
+
return raw;
|
|
35997
|
+
}
|
|
35940
35998
|
if (raw.op === "download") {
|
|
35941
35999
|
assertObject(raw.init, "inner.init");
|
|
35942
36000
|
if (raw.init.url === void 0) {
|
|
@@ -35962,7 +36020,7 @@ function validateInnerRequest(raw) {
|
|
|
35962
36020
|
}
|
|
35963
36021
|
return raw;
|
|
35964
36022
|
}
|
|
35965
|
-
throw new ProtocolError(`inner.op: must be one of "fetch", "read_cookies", "read_local_storage", "read_session_storage", "capture_request_header", "capture_redirect", "read_indexed_db", "read_dom", "download"; got ${JSON.stringify(raw.op)}`);
|
|
36023
|
+
throw new ProtocolError(`inner.op: must be one of "fetch", "read_cookies", "read_local_storage", "read_session_storage", "capture_request_header", "capture_redirect", "read_indexed_db", "read_dom", "download", "graphql_query"; got ${JSON.stringify(raw.op)}`);
|
|
35966
36024
|
}
|
|
35967
36025
|
function assertNonEmptyKeyArray(value, label) {
|
|
35968
36026
|
if (!Array.isArray(value)) {
|
|
@@ -35993,6 +36051,10 @@ function assertStringMap(value, label) {
|
|
|
35993
36051
|
}
|
|
35994
36052
|
}
|
|
35995
36053
|
}
|
|
36054
|
+
var KNOWN_RESPONSE_OPS = /* @__PURE__ */ new Set([
|
|
36055
|
+
...KNOWN_CAPABILITIES,
|
|
36056
|
+
"graphql_query"
|
|
36057
|
+
]);
|
|
35996
36058
|
function validateInnerResponse(raw) {
|
|
35997
36059
|
assertPositiveInt(raw.id, "inner.id");
|
|
35998
36060
|
if (raw.ok === true) {
|
|
@@ -36054,6 +36116,13 @@ function validateInnerResponse(raw) {
|
|
|
36054
36116
|
assertStringMap(raw.values, "inner.values");
|
|
36055
36117
|
return raw;
|
|
36056
36118
|
}
|
|
36119
|
+
if (op === "graphql_query") {
|
|
36120
|
+
if (raw.data === void 0) {
|
|
36121
|
+
throw new ProtocolError("inner.data: missing on graphql_query response");
|
|
36122
|
+
}
|
|
36123
|
+
assertObject(raw.data, "inner.data");
|
|
36124
|
+
return raw;
|
|
36125
|
+
}
|
|
36057
36126
|
if (op === "download") {
|
|
36058
36127
|
assertObject(raw.value, "inner.value");
|
|
36059
36128
|
assertString(raw.value.path, "inner.value.path");
|
|
@@ -36078,7 +36147,7 @@ function validateInnerResponse(raw) {
|
|
|
36078
36147
|
if (raw.ok === false) {
|
|
36079
36148
|
assertString(raw.error, "inner.error");
|
|
36080
36149
|
if (raw.op !== void 0) {
|
|
36081
|
-
if (typeof raw.op !== "string" || !
|
|
36150
|
+
if (typeof raw.op !== "string" || !KNOWN_RESPONSE_OPS.has(raw.op)) {
|
|
36082
36151
|
throw new ProtocolError(`inner.op: unknown response op ${JSON.stringify(raw.op)}`);
|
|
36083
36152
|
}
|
|
36084
36153
|
}
|
|
@@ -36270,11 +36339,33 @@ async function sealInnerFrame(sessionKey, mcpId, seq, inner) {
|
|
|
36270
36339
|
};
|
|
36271
36340
|
}
|
|
36272
36341
|
async function openEncryptedFrame(sessionKey, frame) {
|
|
36273
|
-
const
|
|
36274
|
-
|
|
36275
|
-
|
|
36276
|
-
|
|
36277
|
-
|
|
36342
|
+
const result = await openEncryptedFrameDetailed(sessionKey, frame);
|
|
36343
|
+
if (result.stage === "ok")
|
|
36344
|
+
return result.inner;
|
|
36345
|
+
throw result.error instanceof Error ? result.error : new Error(String(result.error));
|
|
36346
|
+
}
|
|
36347
|
+
async function openEncryptedFrameDetailed(sessionKey, frame) {
|
|
36348
|
+
let pt;
|
|
36349
|
+
try {
|
|
36350
|
+
const iv = fromB64(frame.iv);
|
|
36351
|
+
const ct = fromB64(frame.ciphertext);
|
|
36352
|
+
pt = await aesGcmOpen(sessionKey, iv, ct);
|
|
36353
|
+
} catch (error51) {
|
|
36354
|
+
return { stage: "decrypt-failed", error: error51 };
|
|
36355
|
+
}
|
|
36356
|
+
let parsed;
|
|
36357
|
+
try {
|
|
36358
|
+
parsed = JSON.parse(dec.decode(pt));
|
|
36359
|
+
} catch (error51) {
|
|
36360
|
+
return { stage: "validation-failed", error: error51, recoveredId: void 0 };
|
|
36361
|
+
}
|
|
36362
|
+
try {
|
|
36363
|
+
const inner = validateInnerFrame(parsed);
|
|
36364
|
+
return { stage: "ok", inner };
|
|
36365
|
+
} catch (error51) {
|
|
36366
|
+
const recoveredId = parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) && typeof parsed.id === "number" && Number.isInteger(parsed.id) && parsed.id > 0 ? parsed.id : void 0;
|
|
36367
|
+
return { stage: "validation-failed", error: error51, recoveredId };
|
|
36368
|
+
}
|
|
36278
36369
|
}
|
|
36279
36370
|
|
|
36280
36371
|
// node_modules/@fetchproxy/server/dist/election.js
|
|
@@ -36400,6 +36491,12 @@ async function buildServerHello(opts) {
|
|
|
36400
36491
|
...d.attribute !== void 0 ? { attribute: d.attribute } : {}
|
|
36401
36492
|
}));
|
|
36402
36493
|
}
|
|
36494
|
+
if (opts.graphqlOps && opts.graphqlOps.length > 0) {
|
|
36495
|
+
hello.graphqlOps = opts.graphqlOps.map((d) => ({
|
|
36496
|
+
name: d.name,
|
|
36497
|
+
operationName: d.operationName
|
|
36498
|
+
}));
|
|
36499
|
+
}
|
|
36403
36500
|
return hello;
|
|
36404
36501
|
}
|
|
36405
36502
|
|
|
@@ -36490,7 +36587,8 @@ async function startHost(opts) {
|
|
|
36490
36587
|
indexedDbScopes: opts.ownIndexedDbScopes,
|
|
36491
36588
|
localStoragePointers: opts.ownLocalStoragePointers,
|
|
36492
36589
|
sessionStoragePointers: opts.ownSessionStoragePointers,
|
|
36493
|
-
domSelectors: opts.ownDomSelectors
|
|
36590
|
+
domSelectors: opts.ownDomSelectors,
|
|
36591
|
+
graphqlOps: opts.ownGraphqlOps
|
|
36494
36592
|
});
|
|
36495
36593
|
const ownSessionNonce = fromB64(ownHello.sessionNonce);
|
|
36496
36594
|
let extensionWs = null;
|
|
@@ -36727,7 +36825,8 @@ async function startPeer(opts) {
|
|
|
36727
36825
|
indexedDbScopes: opts.indexedDbScopes,
|
|
36728
36826
|
domSelectors: opts.domSelectors,
|
|
36729
36827
|
localStoragePointers: opts.localStoragePointers,
|
|
36730
|
-
sessionStoragePointers: opts.sessionStoragePointers
|
|
36828
|
+
sessionStoragePointers: opts.sessionStoragePointers,
|
|
36829
|
+
graphqlOps: opts.graphqlOps
|
|
36731
36830
|
});
|
|
36732
36831
|
const sessionNonce = fromB64(hello.sessionNonce);
|
|
36733
36832
|
ws.send(JSON.stringify(hello));
|
|
@@ -36771,10 +36870,20 @@ async function startPeer(opts) {
|
|
|
36771
36870
|
return;
|
|
36772
36871
|
if (!session.acceptInboundSeq(frame.seq))
|
|
36773
36872
|
return;
|
|
36774
|
-
|
|
36775
|
-
|
|
36776
|
-
innerListeners.forEach((cb) => cb(inner));
|
|
36777
|
-
}
|
|
36873
|
+
const result = await openEncryptedFrameDetailed(session.sessionKey, frame);
|
|
36874
|
+
if (result.stage === "ok") {
|
|
36875
|
+
innerListeners.forEach((cb) => cb(result.inner));
|
|
36876
|
+
} else if (result.stage === "decrypt-failed") {
|
|
36877
|
+
} else {
|
|
36878
|
+
console.error("[fetchproxy] peer: received a frame that decrypted OK but failed validation:", result.error);
|
|
36879
|
+
if (result.recoveredId !== void 0) {
|
|
36880
|
+
innerListeners.forEach((cb) => cb({
|
|
36881
|
+
type: "response",
|
|
36882
|
+
id: result.recoveredId,
|
|
36883
|
+
ok: false,
|
|
36884
|
+
error: `malformed response failed protocol validation: ${String(result.error)}`
|
|
36885
|
+
}));
|
|
36886
|
+
}
|
|
36778
36887
|
}
|
|
36779
36888
|
}
|
|
36780
36889
|
} catch (e) {
|
|
@@ -37051,6 +37160,10 @@ var FetchproxyServer = class {
|
|
|
37051
37160
|
pendingIdb = /* @__PURE__ */ new Map();
|
|
37052
37161
|
// download awaiters resolve the saved-file metadata (path + size + mime).
|
|
37053
37162
|
pendingDownload = /* @__PURE__ */ new Map();
|
|
37163
|
+
// 1.x+: graphql_query awaiters resolve the GraphQL `data` object. Its
|
|
37164
|
+
// shape is operation-specific, so the awaiter resolves `unknown` and the
|
|
37165
|
+
// caller narrows.
|
|
37166
|
+
pendingGraphql = /* @__PURE__ */ new Map();
|
|
37054
37167
|
mcpId = null;
|
|
37055
37168
|
identity = null;
|
|
37056
37169
|
// 0.5.3+: in-flight role-election / handle-start promise. Set the
|
|
@@ -37138,6 +37251,10 @@ var FetchproxyServer = class {
|
|
|
37138
37251
|
selector: d.selector,
|
|
37139
37252
|
...d.attribute !== void 0 ? { attribute: d.attribute } : {}
|
|
37140
37253
|
})),
|
|
37254
|
+
graphqlOps: (opts.graphqlOps ?? []).map((d) => ({
|
|
37255
|
+
name: d.name,
|
|
37256
|
+
operationName: d.operationName
|
|
37257
|
+
})),
|
|
37141
37258
|
// 0.8.0+: timer + lazy-revive default to ON. Every realty MCP
|
|
37142
37259
|
// adapter was about to set these to the same numbers anyway; the
|
|
37143
37260
|
// back-door is `0` (explicit opt-out) if a caller genuinely wants
|
|
@@ -37259,6 +37376,7 @@ var FetchproxyServer = class {
|
|
|
37259
37376
|
ownLocalStoragePointers: this.opts.localStoragePointers,
|
|
37260
37377
|
ownSessionStoragePointers: this.opts.sessionStoragePointers,
|
|
37261
37378
|
ownDomSelectors: this.opts.domSelectors,
|
|
37379
|
+
ownGraphqlOps: this.opts.graphqlOps,
|
|
37262
37380
|
onPairCode: this.opts.onPairCode
|
|
37263
37381
|
});
|
|
37264
37382
|
this.hostHandle.onOwnInner((inner) => this.onInner(inner));
|
|
@@ -37287,7 +37405,8 @@ var FetchproxyServer = class {
|
|
|
37287
37405
|
indexedDbScopes: this.opts.indexedDbScopes,
|
|
37288
37406
|
localStoragePointers: this.opts.localStoragePointers,
|
|
37289
37407
|
sessionStoragePointers: this.opts.sessionStoragePointers,
|
|
37290
|
-
domSelectors: this.opts.domSelectors
|
|
37408
|
+
domSelectors: this.opts.domSelectors,
|
|
37409
|
+
graphqlOps: this.opts.graphqlOps
|
|
37291
37410
|
});
|
|
37292
37411
|
this.peerHandle.onInner((inner) => this.onInner(inner));
|
|
37293
37412
|
this.peerHandle.onRenegotiate(() => {
|
|
@@ -37493,6 +37612,7 @@ var FetchproxyServer = class {
|
|
|
37493
37612
|
this.pendingRedirect.delete(id);
|
|
37494
37613
|
this.pendingDownload.delete(id);
|
|
37495
37614
|
this.pendingIdb.delete(id);
|
|
37615
|
+
this.pendingGraphql.delete(id);
|
|
37496
37616
|
}
|
|
37497
37617
|
throw err;
|
|
37498
37618
|
}
|
|
@@ -38302,6 +38422,52 @@ var FetchproxyServer = class {
|
|
|
38302
38422
|
await this.sendInnerFrame(inner);
|
|
38303
38423
|
return this._withVerbTimeout(pending, this.pendingStorage, id, origin);
|
|
38304
38424
|
}
|
|
38425
|
+
/**
|
|
38426
|
+
* 1.x+: run a declared GraphQL operation through the page's own Apollo
|
|
38427
|
+
* client (`window.__APOLLO_CLIENT__`) in the signed-in tab's MAIN world.
|
|
38428
|
+
* Requires `'graphql'` in capabilities AND `name` to match a declared
|
|
38429
|
+
* `graphqlOps` entry. The extension resolves `name` → `operationName` →
|
|
38430
|
+
* the live DocumentNode the page already observed, then invokes
|
|
38431
|
+
* `client.query({ query, variables })` — the site's own request path, so
|
|
38432
|
+
* per-request bot telemetry (Akamai etc.) runs automatically.
|
|
38433
|
+
*
|
|
38434
|
+
* Returns the GraphQL `data` object on success (shape is
|
|
38435
|
+
* operation-specific; the caller narrows). Throws a plain `Error` on
|
|
38436
|
+
* developer mistakes (undeclared capability, undeclared name) and a
|
|
38437
|
+
* descriptive `Error` on the `ok:false` bridge path — which includes the
|
|
38438
|
+
* typed "operation not yet observed on this tab" case (open the site's
|
|
38439
|
+
* page and retry).
|
|
38440
|
+
*/
|
|
38441
|
+
async graphqlQuery(opts) {
|
|
38442
|
+
if (!this.opts.capabilities.includes("graphql")) {
|
|
38443
|
+
throw new Error('FetchproxyServer.graphqlQuery(): MCP did not declare "graphql" in capabilities');
|
|
38444
|
+
}
|
|
38445
|
+
if (typeof opts.name !== "string" || opts.name.length === 0) {
|
|
38446
|
+
throw new Error("FetchproxyServer.graphqlQuery: opts.name must be a non-empty string");
|
|
38447
|
+
}
|
|
38448
|
+
const declaredNames = this.opts.graphqlOps.map((d) => d.name);
|
|
38449
|
+
if (!declaredNames.includes(opts.name)) {
|
|
38450
|
+
throw new Error(`FetchproxyServer.graphqlQuery: operation ${JSON.stringify(opts.name)} not in declared graphqlOps [${declaredNames.map((n) => JSON.stringify(n)).join(", ")}]`);
|
|
38451
|
+
}
|
|
38452
|
+
await this.ensureConnected();
|
|
38453
|
+
this.throwIfPendingPair();
|
|
38454
|
+
const id = this.nextRequestId++;
|
|
38455
|
+
const inner = {
|
|
38456
|
+
type: "request",
|
|
38457
|
+
id,
|
|
38458
|
+
op: "graphql_query",
|
|
38459
|
+
init: {
|
|
38460
|
+
name: opts.name,
|
|
38461
|
+
variables: opts.variables,
|
|
38462
|
+
...opts.tabUrl !== void 0 ? { tabUrl: opts.tabUrl } : {}
|
|
38463
|
+
}
|
|
38464
|
+
};
|
|
38465
|
+
const pending = new Promise((resolve, reject) => {
|
|
38466
|
+
this.pendingGraphql.set(id, { resolve, reject });
|
|
38467
|
+
});
|
|
38468
|
+
await this.sendInnerFrame(inner);
|
|
38469
|
+
return this._withVerbTimeout(pending, this.pendingGraphql, id, opts.name);
|
|
38470
|
+
}
|
|
38305
38471
|
assertScopeSubset(requested, declared, label) {
|
|
38306
38472
|
const undeclared = undeclaredKeys(requested, declared);
|
|
38307
38473
|
if (undeclared.length > 0) {
|
|
@@ -38439,6 +38605,20 @@ var FetchproxyServer = class {
|
|
|
38439
38605
|
}
|
|
38440
38606
|
return;
|
|
38441
38607
|
}
|
|
38608
|
+
const graphqlCb = this.pendingGraphql.get(inner.id);
|
|
38609
|
+
if (graphqlCb) {
|
|
38610
|
+
this.pendingGraphql.delete(inner.id);
|
|
38611
|
+
if (inner.ok) {
|
|
38612
|
+
if (inner.op === "graphql_query") {
|
|
38613
|
+
graphqlCb.resolve(inner.data);
|
|
38614
|
+
} else {
|
|
38615
|
+
graphqlCb.reject(new FetchproxyProtocolError(`unexpected ${String(inner.op)} response on graphql_query awaiter`));
|
|
38616
|
+
}
|
|
38617
|
+
} else {
|
|
38618
|
+
graphqlCb.reject(new FetchproxyProtocolError(inner.error));
|
|
38619
|
+
}
|
|
38620
|
+
return;
|
|
38621
|
+
}
|
|
38442
38622
|
const cookiesCb = this.pendingReadCookies.get(inner.id);
|
|
38443
38623
|
if (cookiesCb) {
|
|
38444
38624
|
this.pendingReadCookies.delete(inner.id);
|
|
@@ -38490,6 +38670,9 @@ var FetchproxyServer = class {
|
|
|
38490
38670
|
for (const { reject } of this.pendingDownload.values())
|
|
38491
38671
|
reject(err);
|
|
38492
38672
|
this.pendingDownload.clear();
|
|
38673
|
+
for (const { reject } of this.pendingGraphql.values())
|
|
38674
|
+
reject(err);
|
|
38675
|
+
this.pendingGraphql.clear();
|
|
38493
38676
|
}
|
|
38494
38677
|
/**
|
|
38495
38678
|
* 0.5.2+: read the current pair-pending pair code from whichever handle
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Single source of the server version. release-please bumps the literal below. */
|
|
2
|
-
export const VERSION = '0.3.
|
|
2
|
+
export const VERSION = '0.3.2'; // x-release-please-version
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chrischall/tripadvisor-mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"mcpName": "io.github.chrischall/tripadvisor-mcp",
|
|
5
5
|
"description": "TripAdvisor Terra API MCP server for Claude — search locations, details, photos, and reviews. Developed and maintained by AI (Claude Code).",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"test:coverage": "vitest run --coverage"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@chrischall/mcp-utils": "^0.
|
|
48
|
-
"@fetchproxy/server": "^1.
|
|
47
|
+
"@chrischall/mcp-utils": "^0.14.0",
|
|
48
|
+
"@fetchproxy/server": "^1.7.0",
|
|
49
49
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
50
50
|
"dotenv": "^17.4.0",
|
|
51
51
|
"zod": "^4.4.2"
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/tripadvisor-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.2",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@chrischall/tripadvisor-mcp",
|
|
14
|
-
"version": "0.3.
|
|
14
|
+
"version": "0.3.2",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|