@cyanheads/interpro-mcp-server 0.0.0-stage → 0.1.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.
Files changed (82) hide show
  1. package/AGENTS.md +376 -0
  2. package/CLAUDE.md +376 -0
  3. package/Dockerfile +186 -0
  4. package/LICENSE +201 -0
  5. package/README.md +289 -2
  6. package/changelog/0.1.x/0.1.1.md +20 -0
  7. package/changelog/0.1.x/0.1.2.md +27 -0
  8. package/changelog/template.md +151 -0
  9. package/dist/index.d.ts +7 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +34 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/mcp-server/tools/definitions/interpro-find-proteins-by-domain.tool.d.ts +180 -0
  14. package/dist/mcp-server/tools/definitions/interpro-find-proteins-by-domain.tool.d.ts.map +1 -0
  15. package/dist/mcp-server/tools/definitions/interpro-find-proteins-by-domain.tool.js +212 -0
  16. package/dist/mcp-server/tools/definitions/interpro-find-proteins-by-domain.tool.js.map +1 -0
  17. package/dist/mcp-server/tools/definitions/interpro-get-clan.tool.d.ts +160 -0
  18. package/dist/mcp-server/tools/definitions/interpro-get-clan.tool.d.ts.map +1 -0
  19. package/dist/mcp-server/tools/definitions/interpro-get-clan.tool.js +259 -0
  20. package/dist/mcp-server/tools/definitions/interpro-get-clan.tool.js.map +1 -0
  21. package/dist/mcp-server/tools/definitions/interpro-get-entry.tool.d.ts +131 -0
  22. package/dist/mcp-server/tools/definitions/interpro-get-entry.tool.d.ts.map +1 -0
  23. package/dist/mcp-server/tools/definitions/interpro-get-entry.tool.js +105 -0
  24. package/dist/mcp-server/tools/definitions/interpro-get-entry.tool.js.map +1 -0
  25. package/dist/mcp-server/tools/definitions/interpro-get-protein-domains.tool.d.ts +172 -0
  26. package/dist/mcp-server/tools/definitions/interpro-get-protein-domains.tool.d.ts.map +1 -0
  27. package/dist/mcp-server/tools/definitions/interpro-get-protein-domains.tool.js +374 -0
  28. package/dist/mcp-server/tools/definitions/interpro-get-protein-domains.tool.js.map +1 -0
  29. package/dist/mcp-server/tools/definitions/interpro-list-reference.tool.d.ts +89 -0
  30. package/dist/mcp-server/tools/definitions/interpro-list-reference.tool.d.ts.map +1 -0
  31. package/dist/mcp-server/tools/definitions/interpro-list-reference.tool.js +99 -0
  32. package/dist/mcp-server/tools/definitions/interpro-list-reference.tool.js.map +1 -0
  33. package/dist/mcp-server/tools/definitions/interpro-search-entries.tool.d.ts +190 -0
  34. package/dist/mcp-server/tools/definitions/interpro-search-entries.tool.d.ts.map +1 -0
  35. package/dist/mcp-server/tools/definitions/interpro-search-entries.tool.js +165 -0
  36. package/dist/mcp-server/tools/definitions/interpro-search-entries.tool.js.map +1 -0
  37. package/dist/services/interpro/budget.d.ts +26 -0
  38. package/dist/services/interpro/budget.d.ts.map +1 -0
  39. package/dist/services/interpro/budget.js +41 -0
  40. package/dist/services/interpro/budget.js.map +1 -0
  41. package/dist/services/interpro/cursors.d.ts +25 -0
  42. package/dist/services/interpro/cursors.d.ts.map +1 -0
  43. package/dist/services/interpro/cursors.js +99 -0
  44. package/dist/services/interpro/cursors.js.map +1 -0
  45. package/dist/services/interpro/description-text.d.ts +3 -0
  46. package/dist/services/interpro/description-text.d.ts.map +1 -0
  47. package/dist/services/interpro/description-text.js +179 -0
  48. package/dist/services/interpro/description-text.js.map +1 -0
  49. package/dist/services/interpro/format.d.ts +17 -0
  50. package/dist/services/interpro/format.d.ts.map +1 -0
  51. package/dist/services/interpro/format.js +130 -0
  52. package/dist/services/interpro/format.js.map +1 -0
  53. package/dist/services/interpro/http-adapter.d.ts +11 -0
  54. package/dist/services/interpro/http-adapter.d.ts.map +1 -0
  55. package/dist/services/interpro/http-adapter.js +134 -0
  56. package/dist/services/interpro/http-adapter.js.map +1 -0
  57. package/dist/services/interpro/interpro-service.d.ts +57 -0
  58. package/dist/services/interpro/interpro-service.d.ts.map +1 -0
  59. package/dist/services/interpro/interpro-service.js +284 -0
  60. package/dist/services/interpro/interpro-service.js.map +1 -0
  61. package/dist/services/interpro/reference.d.ts +31 -0
  62. package/dist/services/interpro/reference.d.ts.map +1 -0
  63. package/dist/services/interpro/reference.js +122 -0
  64. package/dist/services/interpro/reference.js.map +1 -0
  65. package/dist/services/interpro/relationships.d.ts +38 -0
  66. package/dist/services/interpro/relationships.d.ts.map +1 -0
  67. package/dist/services/interpro/relationships.js +70 -0
  68. package/dist/services/interpro/relationships.js.map +1 -0
  69. package/dist/services/interpro/routing.d.ts +24 -0
  70. package/dist/services/interpro/routing.d.ts.map +1 -0
  71. package/dist/services/interpro/routing.js +106 -0
  72. package/dist/services/interpro/routing.js.map +1 -0
  73. package/dist/services/interpro/schemas.d.ts +192 -0
  74. package/dist/services/interpro/schemas.d.ts.map +1 -0
  75. package/dist/services/interpro/schemas.js +226 -0
  76. package/dist/services/interpro/schemas.js.map +1 -0
  77. package/dist/services/interpro/upstream-errors.d.ts +43 -0
  78. package/dist/services/interpro/upstream-errors.d.ts.map +1 -0
  79. package/dist/services/interpro/upstream-errors.js +49 -0
  80. package/dist/services/interpro/upstream-errors.js.map +1 -0
  81. package/package.json +104 -4
  82. package/server.json +91 -0
@@ -0,0 +1,134 @@
1
+ /**
2
+ * @fileoverview Bounded HTTP/1.1 adapter for InterPro's malformed bodyless 204 responses.
3
+ * @module services/interpro/http-adapter
4
+ */
5
+ import { request } from 'node:https';
6
+ import { serviceUnavailable, timeout } from '@cyanheads/mcp-ts-core/errors';
7
+ import { API_BASE } from './routing.js';
8
+ /** Maximum decoded response size, shared by native and injected transports. */
9
+ export const MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
10
+ /** Collect one response without following redirects or retaining malformed connections. */
11
+ export const interproHttpFetch = (url, init) => new Promise((resolve, reject) => {
12
+ const target = new URL(url);
13
+ if (target.origin !== new URL(API_BASE).origin ||
14
+ !target.pathname.startsWith('/interpro/api/')) {
15
+ reject(serviceUnavailable('InterPro request left the fixed API origin.', {
16
+ reason: 'upstream_rejected',
17
+ retryable: false,
18
+ }));
19
+ return;
20
+ }
21
+ const signal = init.signal;
22
+ signal?.throwIfAborted();
23
+ let settled = false;
24
+ let response;
25
+ const cleanup = () => {
26
+ clearTimeout(timer);
27
+ signal?.removeEventListener('abort', abort);
28
+ };
29
+ const fail = (error) => {
30
+ if (settled)
31
+ return;
32
+ settled = true;
33
+ cleanup();
34
+ response?.destroy();
35
+ req.destroy();
36
+ reject(error);
37
+ };
38
+ const abort = () => fail(signal?.reason);
39
+ const timer = setTimeout(() => fail(timeout('InterPro response exceeded its attempt deadline.', {
40
+ reason: 'upstream_timeout',
41
+ retryable: true,
42
+ })), 15_000);
43
+ const connectionOptions = { ALPNProtocols: ['http/1.1'] };
44
+ const req = request(target, {
45
+ ...connectionOptions,
46
+ method: 'GET',
47
+ agent: false,
48
+ headers: { Accept: 'application/json', 'Accept-Encoding': 'identity' },
49
+ });
50
+ req.on('error', (cause) => fail(serviceUnavailable('InterPro connection failed.', { reason: 'upstream_unavailable', retryable: true }, { cause })));
51
+ req.on('close', () => {
52
+ if (!response)
53
+ fail(serviceUnavailable('InterPro connection closed before response headers.', {
54
+ reason: 'upstream_unavailable',
55
+ retryable: true,
56
+ }));
57
+ });
58
+ req.on('response', (incoming) => {
59
+ response = incoming;
60
+ incoming.on('error', (cause) => fail(serviceUnavailable('InterPro response stream failed.', { reason: 'upstream_unavailable', retryable: true }, { cause })));
61
+ incoming.on('aborted', () => fail(serviceUnavailable('InterPro response ended prematurely.', {
62
+ reason: 'upstream_unavailable',
63
+ retryable: true,
64
+ })));
65
+ incoming.on('close', () => {
66
+ if (!incoming.complete)
67
+ fail(serviceUnavailable('InterPro response closed before completion.', {
68
+ reason: 'upstream_unavailable',
69
+ retryable: true,
70
+ }));
71
+ });
72
+ const headers = new Headers();
73
+ for (const [name, value] of Object.entries(incoming.headers))
74
+ if (value !== undefined)
75
+ headers.set(name, Array.isArray(value) ? value.join(', ') : value);
76
+ const status = incoming.statusCode;
77
+ if (!status) {
78
+ fail(serviceUnavailable('InterPro response lacks an HTTP status.', {
79
+ reason: 'upstream_shape_invalid',
80
+ retryable: false,
81
+ }));
82
+ return;
83
+ }
84
+ if (status === 204) {
85
+ settled = true;
86
+ cleanup();
87
+ resolve(new Response(null, { status, headers }));
88
+ incoming.destroy();
89
+ req.destroy();
90
+ return;
91
+ }
92
+ const encoding = headers.get('content-encoding');
93
+ if (encoding && encoding.toLowerCase() !== 'identity') {
94
+ fail(serviceUnavailable('InterPro returned an unexpected content encoding.', {
95
+ reason: 'upstream_shape_invalid',
96
+ retryable: false,
97
+ }));
98
+ return;
99
+ }
100
+ const chunks = [];
101
+ let bytes = 0;
102
+ incoming.on('data', (chunk) => {
103
+ if (settled)
104
+ return;
105
+ bytes += chunk.length;
106
+ if (bytes > MAX_RESPONSE_BYTES) {
107
+ fail(serviceUnavailable('InterPro response exceeds 4 MiB.', {
108
+ reason: 'upstream_response_too_large',
109
+ retryable: false,
110
+ }));
111
+ return;
112
+ }
113
+ chunks.push(chunk);
114
+ });
115
+ incoming.on('end', () => {
116
+ if (settled)
117
+ return;
118
+ settled = true;
119
+ cleanup();
120
+ try {
121
+ resolve(new Response(status === 304 ? null : Buffer.concat(chunks), { status, headers }));
122
+ }
123
+ catch (cause) {
124
+ reject(serviceUnavailable('InterPro returned invalid HTTP response metadata.', { reason: 'upstream_shape_invalid', retryable: false }, { cause }));
125
+ }
126
+ });
127
+ });
128
+ signal?.addEventListener('abort', abort, { once: true });
129
+ if (signal?.aborted)
130
+ abort();
131
+ else
132
+ req.end();
133
+ });
134
+ //# sourceMappingURL=http-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-adapter.js","sourceRoot":"","sources":["../../../src/services/interpro/http-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @fileoverview One paced, cancellable InterPro request boundary for every tool workflow.
3
+ * @module services/interpro/interpro-service
4
+ */
5
+ import type { Context } from '@cyanheads/mcp-ts-core';
6
+ import { z } from '@cyanheads/mcp-ts-core';
7
+ import { type InterproFetch } from './http-adapter.js';
8
+ /** One deadline shared by every distinct operation of a tool invocation. */
9
+ export interface InterproCall {
10
+ readonly ctx: Context;
11
+ readonly deadline: number;
12
+ }
13
+ /** The record a request addresses, reported under `reason` when InterPro has no such record. */
14
+ export interface MissingRecord {
15
+ readonly accession: string;
16
+ /** A list scoped to the record: 204 is a valid empty page, so only 404 reports it missing. */
17
+ readonly list?: boolean;
18
+ readonly reason: 'entry_not_found' | 'protein_not_found' | 'clan_not_found';
19
+ readonly sourceDatabase: string;
20
+ }
21
+ /** Domain status handling selected by the tool workflow. */
22
+ export interface RequestOptions {
23
+ readonly continuation?: boolean;
24
+ readonly missing?: MissingRecord;
25
+ }
26
+ /** Validated response plus headers needed for release consistency. */
27
+ export interface InterproResponse<T> {
28
+ readonly data: T | null;
29
+ readonly headers: Headers;
30
+ readonly sourceUrl: string;
31
+ }
32
+ /** InterPro service; inject only the network seam, retaining the real domain behavior. */
33
+ export declare class InterproService {
34
+ private readonly fetch;
35
+ constructor(fetch?: InterproFetch);
36
+ /** Start a 50-second call budget, once per handler invocation. */
37
+ begin(ctx: Context): InterproCall;
38
+ /** Fetch, classify, parse and validate one fixed-origin operation within a shared call. */
39
+ request<T extends z.ZodType>(call: InterproCall, segments: readonly string[], query: Readonly<Record<string, string | number | boolean | undefined>>, schema: T, options?: RequestOptions): Promise<InterproResponse<z.output<T>>>;
40
+ /** Retrieve a coherent current release and its complete database-count object. */
41
+ release(ctx: Context): Promise<{
42
+ version: string;
43
+ date: string;
44
+ databaseCounts: {
45
+ [x: string]: z.JSONType;
46
+ entries: Record<string, z.JSONType>;
47
+ };
48
+ sourceUrls: string[];
49
+ }>;
50
+ }
51
+ /** Initialize the process service in createApp.setup. */
52
+ export declare function initInterproService(fetch?: InterproFetch): void;
53
+ /** Obtain the initialized process service. */
54
+ export declare function getInterproService(): InterproService;
55
+ /** Dispose queued pacing work during application teardown. */
56
+ export declare function disposeInterproService(): void;
57
+ //# sourceMappingURL=interpro-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpro-service.d.ts","sourceRoot":"","sources":["../../../src/services/interpro/interpro-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAe3C,OAAO,EAAE,KAAK,aAAa,EAAyC,MAAM,mBAAmB,CAAC;AAU9F,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AACD,gGAAgG;AAChG,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,mBAAmB,GAAG,gBAAgB,CAAC;IAC5E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAuBD,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;CAClC;AACD,sEAAsE;AACtE,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,0FAA0F;AAC1F,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAlC,YAA6B,KAAK,GAAE,aAAiC,EAAI;IAEzE,kEAAkE;IAClE,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CAEhC;IAED,2FAA2F;IACrF,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAC/B,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC,EACtE,MAAM,EAAE,CAAC,EACT,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAiLxC;IAED,kFAAkF;IAC5E,OAAO,CAAC,GAAG,EAAE,OAAO;;cA0CU,MAAM;;;;;;OAIzC;CACF;AAmCD,yDAAyD;AACzD,wBAAgB,mBAAmB,CAAC,KAAK,GAAE,aAAiC,GAAG,IAAI,CAElF;AACD,8CAA8C;AAC9C,wBAAgB,kBAAkB,IAAI,eAAe,CAGpD;AACD,8DAA8D;AAC9D,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -0,0 +1,284 @@
1
+ import { z } from '@cyanheads/mcp-ts-core';
2
+ import { JsonRpcErrorCode, McpError, notFound, serviceUnavailable, timeout, validationError, } from '@cyanheads/mcp-ts-core/errors';
3
+ import { createPacer, defaultIsTransient, httpErrorFromResponse, withRetry, } from '@cyanheads/mcp-ts-core/utils';
4
+ import { interproHttpFetch, MAX_RESPONSE_BYTES } from './http-adapter.js';
5
+ import { apiUrl } from './routing.js';
6
+ import { isAccession, JsonObjectSchema, JsonValueSchema } from './schemas.js';
7
+ const pacer = createPacer({
8
+ name: 'interpro',
9
+ minStartGapMs: 1000,
10
+ maxConcurrent: 1,
11
+ maxQueueDepth: 20,
12
+ });
13
+ /** Upstream fields of a 410 body that are echoed in the withdrawal error. */
14
+ const WITHDRAWAL_FIELDS = new Set([
15
+ 'accession',
16
+ 'source_database',
17
+ 'deletion_date',
18
+ 'short_name',
19
+ 'history',
20
+ ]);
21
+ /**
22
+ * Single-line forms a withdrawal date or short name must match whole before the message names it;
23
+ * any other upstream value stays in error data only.
24
+ */
25
+ const WITHDRAWAL_DATE = /^\d{4}-\d{2}-\d{2}(?:T[\d:.]+Z?)?$/;
26
+ const SHORT_NAME = /^[A-Za-z0-9_.:+-]{1,100}$/;
27
+ const RECORD_NOUNS = {
28
+ entry_not_found: 'entry',
29
+ clan_not_found: 'set',
30
+ protein_not_found: 'protein',
31
+ };
32
+ /** Name a record in a caller-facing message, e.g. `entry PF00870 in pfam`. */
33
+ const describeRecord = ({ reason, accession, sourceDatabase }) => `${RECORD_NOUNS[reason]} ${accession} in ${sourceDatabase}`;
34
+ /** InterPro service; inject only the network seam, retaining the real domain behavior. */
35
+ export class InterproService {
36
+ fetch;
37
+ constructor(fetch = interproHttpFetch) {
38
+ this.fetch = fetch;
39
+ }
40
+ /** Start a 50-second call budget, once per handler invocation. */
41
+ begin(ctx) {
42
+ return { ctx, deadline: performance.now() + 50_000 };
43
+ }
44
+ /** Fetch, classify, parse and validate one fixed-origin operation within a shared call. */
45
+ async request(call, segments, query, schema, options = {}) {
46
+ call.ctx.signal.throwIfAborted();
47
+ const remaining = call.deadline - performance.now();
48
+ if (remaining <= 0)
49
+ throw timeout('InterPro call exhausted its 50-second budget.', {
50
+ reason: 'retry_deadline_exceeded',
51
+ retryable: true,
52
+ deadlineMs: 50_000,
53
+ });
54
+ const sourceUrl = apiUrl(segments, query);
55
+ return await withRetry(async ({ signal }) => pacer.run(async () => {
56
+ const attemptMs = Math.min(15_000, call.deadline - performance.now());
57
+ const controller = new AbortController();
58
+ const timer = setTimeout(() => controller.abort(timeout('InterPro attempt deadline elapsed.', {
59
+ reason: 'upstream_timeout',
60
+ retryable: true,
61
+ })), Math.max(0, attemptMs));
62
+ const attemptSignal = AbortSignal.any([signal, controller.signal, call.ctx.signal]);
63
+ try {
64
+ const response = await this.fetch(sourceUrl, {
65
+ signal: attemptSignal,
66
+ headers: { Accept: 'application/json', 'Accept-Encoding': 'identity' },
67
+ redirect: 'manual',
68
+ });
69
+ attemptSignal.throwIfAborted();
70
+ if ((response.status === 400 || response.status === 404) && options.continuation)
71
+ throw validationError('InterPro rejected the continuation cursor.', {
72
+ reason: 'invalid_cursor',
73
+ retryable: false,
74
+ status: response.status,
75
+ });
76
+ const { missing } = options;
77
+ if (missing &&
78
+ (response.status === 404 || (response.status === 204 && !missing.list)))
79
+ throw notFound(`InterPro could not find ${describeRecord(missing)}.`, {
80
+ reason: missing.reason,
81
+ retryable: false,
82
+ status: response.status,
83
+ accession: missing.accession,
84
+ sourceDatabase: missing.sourceDatabase,
85
+ });
86
+ if (response.status === 204)
87
+ return { data: null, sourceUrl, headers: response.headers };
88
+ if (response.status === 410) {
89
+ const body = await readBody(response, attemptSignal);
90
+ let withdrawal = {};
91
+ try {
92
+ const parsed = JsonObjectSchema.parse(JSON.parse(body));
93
+ withdrawal = Object.fromEntries(Object.entries(parsed).filter(([key, value]) => WITHDRAWAL_FIELDS.has(key) && JSON.stringify(value).length <= 4096));
94
+ }
95
+ catch {
96
+ /* A withdrawn record need not include valid metadata. */
97
+ }
98
+ const { accession, deletion_date: deleted, short_name: shortName } = withdrawal;
99
+ const subject = missing
100
+ ? describeRecord(missing)
101
+ : isAccession(accession)
102
+ ? `record ${accession}`
103
+ : 'the requested record';
104
+ const on = typeof deleted === 'string' && WITHDRAWAL_DATE.test(deleted)
105
+ ? ` on ${deleted}`
106
+ : '';
107
+ const named = typeof shortName === 'string' && SHORT_NAME.test(shortName)
108
+ ? ` (short name ${shortName})`
109
+ : '';
110
+ throw notFound(`InterPro reports that ${subject} was withdrawn${on}${named}.`, {
111
+ reason: 'entry_withdrawn',
112
+ retryable: false,
113
+ status: 410,
114
+ ...withdrawal,
115
+ // The canonical accession the message names wins over upstream's spelling.
116
+ ...(missing ? { accession: missing.accession } : {}),
117
+ });
118
+ }
119
+ if (!response.ok) {
120
+ const status = response.status;
121
+ const reason = status === 408 || status === 504
122
+ ? 'upstream_timeout'
123
+ : status === 429
124
+ ? 'upstream_rate_limited'
125
+ : status >= 500
126
+ ? 'upstream_unavailable'
127
+ : 'upstream_rejected';
128
+ throw await httpErrorFromResponse(response, {
129
+ service: 'InterPro',
130
+ captureBody: false,
131
+ codeOverride: (value) => value < 500 && value !== 408 && value !== 429
132
+ ? JsonRpcErrorCode.ServiceUnavailable
133
+ : undefined,
134
+ data: {
135
+ reason,
136
+ retryable: (status >= 500 && status !== 501) || status === 408 || status === 429,
137
+ },
138
+ });
139
+ }
140
+ const encoding = response.headers.get('content-encoding');
141
+ if (encoding && encoding.toLowerCase() !== 'identity')
142
+ throw serviceUnavailable('InterPro returned an unexpected content encoding.', {
143
+ reason: 'upstream_shape_invalid',
144
+ retryable: false,
145
+ });
146
+ const body = await readBody(response, attemptSignal);
147
+ if (/^\s*<(?:!doctype\s+html|html[\s>])/i.test(body))
148
+ throw serviceUnavailable('InterPro returned HTML instead of JSON.', {
149
+ reason: 'upstream_unavailable',
150
+ retryable: true,
151
+ });
152
+ let json;
153
+ try {
154
+ json = JSON.parse(body);
155
+ }
156
+ catch (cause) {
157
+ throw serviceUnavailable('InterPro returned malformed JSON.', { reason: 'upstream_shape_invalid', retryable: false }, { cause });
158
+ }
159
+ const parsed = schema.safeParse(json);
160
+ if (!parsed.success)
161
+ throw serviceUnavailable('InterPro JSON does not match the required response structure.', { reason: 'upstream_shape_invalid', retryable: false });
162
+ attemptSignal.throwIfAborted();
163
+ if (performance.now() > call.deadline)
164
+ throw timeout('InterPro call exhausted its total budget.', {
165
+ reason: 'retry_deadline_exceeded',
166
+ retryable: true,
167
+ });
168
+ return { data: parsed.data, sourceUrl, headers: response.headers };
169
+ }
170
+ catch (cause) {
171
+ if (call.ctx.signal.aborted)
172
+ throw call.ctx.signal.reason;
173
+ if (signal.aborted)
174
+ throw signal.reason;
175
+ if (controller.signal.aborted)
176
+ throw controller.signal.reason;
177
+ if (cause instanceof McpError)
178
+ throw cause;
179
+ throw serviceUnavailable('InterPro network request failed.', { reason: 'upstream_unavailable', retryable: true }, { cause });
180
+ }
181
+ finally {
182
+ clearTimeout(timer);
183
+ }
184
+ }, { signal, maxWaitMs: Math.max(0, Math.min(5000, call.deadline - performance.now())) }), {
185
+ signal: call.ctx.signal,
186
+ context: call.ctx,
187
+ operation: 'interpro.request',
188
+ deadlineMs: remaining,
189
+ maxRetries: 1,
190
+ baseDelayMs: 1000,
191
+ maxDelayMs: 3000,
192
+ isTransient: defaultIsTransient,
193
+ });
194
+ }
195
+ /** Retrieve a coherent current release and its complete database-count object. */
196
+ async release(ctx) {
197
+ const call = this.begin(ctx);
198
+ const releases = await this.request(call, ['utils', 'release'], {}, z.record(z.string().regex(/^\d+(?:\.\d+)*$/), z.string()));
199
+ const counts = await this.request(call, ['entry'], {}, z.object({ entries: JsonObjectSchema }).catchall(JsonValueSchema));
200
+ if (!releases.data || !counts.data || !Object.keys(releases.data).length)
201
+ throw serviceUnavailable('InterPro release metadata is missing.', {
202
+ reason: 'upstream_shape_invalid',
203
+ retryable: false,
204
+ });
205
+ const firstVersion = releases.headers.get('interpro-version');
206
+ const secondVersion = counts.headers.get('interpro-version');
207
+ if (firstVersion && secondVersion && firstVersion !== secondVersion)
208
+ throw serviceUnavailable('InterPro release changed between metadata responses.', {
209
+ reason: 'release_changed',
210
+ retryable: true,
211
+ });
212
+ const version = Object.keys(releases.data).sort((a, b) => {
213
+ const left = a.split('.').map(Number);
214
+ const right = b.split('.').map(Number);
215
+ for (let index = 0; index < Math.max(left.length, right.length); index++) {
216
+ const difference = (right[index] ?? 0) - (left[index] ?? 0);
217
+ if (difference)
218
+ return difference;
219
+ }
220
+ return 0;
221
+ })[0];
222
+ if (!version)
223
+ throw serviceUnavailable('InterPro release map has no version.', {
224
+ reason: 'upstream_shape_invalid',
225
+ retryable: false,
226
+ });
227
+ return {
228
+ version,
229
+ date: releases.data[version],
230
+ databaseCounts: counts.data,
231
+ sourceUrls: [releases.sourceUrl, counts.sourceUrl],
232
+ };
233
+ }
234
+ }
235
+ async function readBody(response, signal) {
236
+ if (!response.body)
237
+ return '';
238
+ const reader = response.body.getReader();
239
+ const chunks = [];
240
+ let bytes = 0;
241
+ const abort = () => {
242
+ void reader.cancel(signal.reason).catch(() => { });
243
+ };
244
+ signal.addEventListener('abort', abort, { once: true });
245
+ try {
246
+ while (true) {
247
+ signal.throwIfAborted();
248
+ const { done, value } = await reader.read();
249
+ signal.throwIfAborted();
250
+ if (done)
251
+ break;
252
+ bytes += value.byteLength;
253
+ if (bytes > MAX_RESPONSE_BYTES) {
254
+ await reader.cancel();
255
+ throw serviceUnavailable('InterPro response exceeds 4 MiB.', {
256
+ reason: 'upstream_response_too_large',
257
+ retryable: false,
258
+ });
259
+ }
260
+ chunks.push(value);
261
+ }
262
+ return Buffer.concat(chunks).toString('utf8');
263
+ }
264
+ finally {
265
+ signal.removeEventListener('abort', abort);
266
+ reader.releaseLock();
267
+ }
268
+ }
269
+ let service;
270
+ /** Initialize the process service in createApp.setup. */
271
+ export function initInterproService(fetch = interproHttpFetch) {
272
+ service = new InterproService(fetch);
273
+ }
274
+ /** Obtain the initialized process service. */
275
+ export function getInterproService() {
276
+ if (!service)
277
+ throw new Error('InterPro service is not initialized.');
278
+ return service;
279
+ }
280
+ /** Dispose queued pacing work during application teardown. */
281
+ export function disposeInterproService() {
282
+ pacer.dispose();
283
+ }
284
+ //# sourceMappingURL=interpro-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpro-service.js","sourceRoot":"","sources":["../../../src/services/interpro/interpro-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @fileoverview Static API vocabulary and common taxonomy examples.
3
+ * @module services/interpro/reference
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ /** Available reference topics; only release performs network operations. */
7
+ export declare const ReferenceTopicSchema: z.ZodEnum<{
8
+ accession_patterns: "accession_patterns";
9
+ databases: "databases";
10
+ entry_types: "entry_types";
11
+ release: "release";
12
+ taxa: "taxa";
13
+ }>;
14
+ /** Applicable reference fields, without fabricated empty annotations. */
15
+ export declare const ReferenceItemSchema: z.ZodObject<{
16
+ id: z.ZodString;
17
+ label: z.ZodString;
18
+ description: z.ZodOptional<z.ZodString>;
19
+ sourceDatabase: z.ZodOptional<z.ZodString>;
20
+ accessionPattern: z.ZodOptional<z.ZodString>;
21
+ example: z.ZodOptional<z.ZodString>;
22
+ taxonId: z.ZodOptional<z.ZodString>;
23
+ }, z.core.$strip>;
24
+ /** A reference vocabulary row. */
25
+ export type ReferenceItem = z.infer<typeof ReferenceItemSchema>;
26
+ /** Return bounded local reference data without making upstream requests. */
27
+ export declare function staticReference(topic: Exclude<z.infer<typeof ReferenceTopicSchema>, 'release'>): {
28
+ items: ReferenceItem[];
29
+ sourceUrls: string[];
30
+ };
31
+ //# sourceMappingURL=reference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../../../src/services/interpro/reference.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAI3C,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB;;;;;;EAE2C,CAAC;AAC7E,yEAAyE;AACzE,eAAO,MAAM,mBAAmB;;;;;;;;iBAaa,CAAC;AAC9C,kCAAkC;AAClC,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AA0DhE,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,EAAE,SAAS,CAAC,GAAG;IAChG,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAsCA"}