@cyanheads/gbif-biodiversity-mcp-server 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CLAUDE.md +393 -0
  2. package/Dockerfile +99 -0
  3. package/LICENSE +201 -0
  4. package/README.md +367 -0
  5. package/dist/config/server-config.d.ts +14 -0
  6. package/dist/config/server-config.d.ts.map +1 -0
  7. package/dist/config/server-config.js +27 -0
  8. package/dist/config/server-config.js.map +1 -0
  9. package/dist/index.d.ts +7 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +53 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/mcp-server/resources/definitions/gbif-dataset.resource.d.ts +20 -0
  14. package/dist/mcp-server/resources/definitions/gbif-dataset.resource.d.ts.map +1 -0
  15. package/dist/mcp-server/resources/definitions/gbif-dataset.resource.js +50 -0
  16. package/dist/mcp-server/resources/definitions/gbif-dataset.resource.js.map +1 -0
  17. package/dist/mcp-server/resources/definitions/gbif-species.resource.d.ts +27 -0
  18. package/dist/mcp-server/resources/definitions/gbif-species.resource.d.ts.map +1 -0
  19. package/dist/mcp-server/resources/definitions/gbif-species.resource.js +67 -0
  20. package/dist/mcp-server/resources/definitions/gbif-species.resource.js.map +1 -0
  21. package/dist/mcp-server/tools/definitions/gbif-count-occurrences.tool.d.ts +15 -0
  22. package/dist/mcp-server/tools/definitions/gbif-count-occurrences.tool.d.ts.map +1 -0
  23. package/dist/mcp-server/tools/definitions/gbif-count-occurrences.tool.js +42 -0
  24. package/dist/mcp-server/tools/definitions/gbif-count-occurrences.tool.js.map +1 -0
  25. package/dist/mcp-server/tools/definitions/gbif-get-dataset.tool.d.ts +33 -0
  26. package/dist/mcp-server/tools/definitions/gbif-get-dataset.tool.d.ts.map +1 -0
  27. package/dist/mcp-server/tools/definitions/gbif-get-dataset.tool.js +143 -0
  28. package/dist/mcp-server/tools/definitions/gbif-get-dataset.tool.js.map +1 -0
  29. package/dist/mcp-server/tools/definitions/gbif-get-occurrence.tool.d.ts +58 -0
  30. package/dist/mcp-server/tools/definitions/gbif-get-occurrence.tool.d.ts.map +1 -0
  31. package/dist/mcp-server/tools/definitions/gbif-get-occurrence.tool.js +264 -0
  32. package/dist/mcp-server/tools/definitions/gbif-get-occurrence.tool.js.map +1 -0
  33. package/dist/mcp-server/tools/definitions/gbif-get-species-children.tool.d.ts +25 -0
  34. package/dist/mcp-server/tools/definitions/gbif-get-species-children.tool.d.ts.map +1 -0
  35. package/dist/mcp-server/tools/definitions/gbif-get-species-children.tool.js +91 -0
  36. package/dist/mcp-server/tools/definitions/gbif-get-species-children.tool.js.map +1 -0
  37. package/dist/mcp-server/tools/definitions/gbif-get-species-classification.tool.d.ts +22 -0
  38. package/dist/mcp-server/tools/definitions/gbif-get-species-classification.tool.d.ts.map +1 -0
  39. package/dist/mcp-server/tools/definitions/gbif-get-species-classification.tool.js +82 -0
  40. package/dist/mcp-server/tools/definitions/gbif-get-species-classification.tool.js.map +1 -0
  41. package/dist/mcp-server/tools/definitions/gbif-get-species.tool.d.ts +45 -0
  42. package/dist/mcp-server/tools/definitions/gbif-get-species.tool.d.ts.map +1 -0
  43. package/dist/mcp-server/tools/definitions/gbif-get-species.tool.js +182 -0
  44. package/dist/mcp-server/tools/definitions/gbif-get-species.tool.js.map +1 -0
  45. package/dist/mcp-server/tools/definitions/gbif-match-species.tool.d.ts +49 -0
  46. package/dist/mcp-server/tools/definitions/gbif-match-species.tool.d.ts.map +1 -0
  47. package/dist/mcp-server/tools/definitions/gbif-match-species.tool.js +148 -0
  48. package/dist/mcp-server/tools/definitions/gbif-match-species.tool.js.map +1 -0
  49. package/dist/mcp-server/tools/definitions/gbif-occurrence-facets.tool.d.ts +45 -0
  50. package/dist/mcp-server/tools/definitions/gbif-occurrence-facets.tool.d.ts.map +1 -0
  51. package/dist/mcp-server/tools/definitions/gbif-occurrence-facets.tool.js +116 -0
  52. package/dist/mcp-server/tools/definitions/gbif-occurrence-facets.tool.js.map +1 -0
  53. package/dist/mcp-server/tools/definitions/gbif-search-datasets.tool.d.ts +34 -0
  54. package/dist/mcp-server/tools/definitions/gbif-search-datasets.tool.d.ts.map +1 -0
  55. package/dist/mcp-server/tools/definitions/gbif-search-datasets.tool.js +112 -0
  56. package/dist/mcp-server/tools/definitions/gbif-search-datasets.tool.js.map +1 -0
  57. package/dist/mcp-server/tools/definitions/gbif-search-occurrences.tool.d.ts +66 -0
  58. package/dist/mcp-server/tools/definitions/gbif-search-occurrences.tool.d.ts.map +1 -0
  59. package/dist/mcp-server/tools/definitions/gbif-search-occurrences.tool.js +278 -0
  60. package/dist/mcp-server/tools/definitions/gbif-search-occurrences.tool.js.map +1 -0
  61. package/dist/mcp-server/tools/definitions/gbif-search-publishers.tool.d.ts +23 -0
  62. package/dist/mcp-server/tools/definitions/gbif-search-publishers.tool.d.ts.map +1 -0
  63. package/dist/mcp-server/tools/definitions/gbif-search-publishers.tool.js +90 -0
  64. package/dist/mcp-server/tools/definitions/gbif-search-publishers.tool.js.map +1 -0
  65. package/dist/mcp-server/tools/definitions/gbif-search-species.tool.d.ts +48 -0
  66. package/dist/mcp-server/tools/definitions/gbif-search-species.tool.d.ts.map +1 -0
  67. package/dist/mcp-server/tools/definitions/gbif-search-species.tool.js +151 -0
  68. package/dist/mcp-server/tools/definitions/gbif-search-species.tool.js.map +1 -0
  69. package/dist/mcp-server/tools/utils.d.ts +7 -0
  70. package/dist/mcp-server/tools/utils.d.ts.map +1 -0
  71. package/dist/mcp-server/tools/utils.js +20 -0
  72. package/dist/mcp-server/tools/utils.js.map +1 -0
  73. package/dist/services/gbif/gbif-service.d.ts +99 -0
  74. package/dist/services/gbif/gbif-service.d.ts.map +1 -0
  75. package/dist/services/gbif/gbif-service.js +255 -0
  76. package/dist/services/gbif/gbif-service.js.map +1 -0
  77. package/dist/services/gbif/types.d.ts +254 -0
  78. package/dist/services/gbif/types.d.ts.map +1 -0
  79. package/dist/services/gbif/types.js +6 -0
  80. package/dist/services/gbif/types.js.map +1 -0
  81. package/package.json +91 -0
  82. package/server.json +117 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @fileoverview Search or browse the GBIF backbone taxonomy.
3
+ * @module mcp-server/tools/definitions/gbif-search-species
4
+ */
5
+ import { z } from '@cyanheads/mcp-ts-core';
6
+ export declare const gbifSearchSpecies: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
7
+ q: z.ZodOptional<z.ZodString>;
8
+ rank: z.ZodOptional<z.ZodEnum<{
9
+ KINGDOM: "KINGDOM";
10
+ PHYLUM: "PHYLUM";
11
+ CLASS: "CLASS";
12
+ ORDER: "ORDER";
13
+ FAMILY: "FAMILY";
14
+ GENUS: "GENUS";
15
+ SPECIES: "SPECIES";
16
+ SUBSPECIES: "SUBSPECIES";
17
+ }>>;
18
+ kingdom: z.ZodOptional<z.ZodString>;
19
+ family: z.ZodOptional<z.ZodString>;
20
+ genus: z.ZodOptional<z.ZodString>;
21
+ isExtinct: z.ZodOptional<z.ZodBoolean>;
22
+ datasetKey: z.ZodOptional<z.ZodString>;
23
+ limit: z.ZodDefault<z.ZodNumber>;
24
+ offset: z.ZodDefault<z.ZodNumber>;
25
+ }, z.core.$strip>, z.ZodObject<{
26
+ taxa: z.ZodArray<z.ZodObject<{
27
+ key: z.ZodOptional<z.ZodNumber>;
28
+ scientificName: z.ZodOptional<z.ZodString>;
29
+ canonicalName: z.ZodOptional<z.ZodString>;
30
+ rank: z.ZodOptional<z.ZodString>;
31
+ taxonomicStatus: z.ZodOptional<z.ZodString>;
32
+ kingdom: z.ZodOptional<z.ZodString>;
33
+ phylum: z.ZodOptional<z.ZodString>;
34
+ class: z.ZodOptional<z.ZodString>;
35
+ order: z.ZodOptional<z.ZodString>;
36
+ family: z.ZodOptional<z.ZodString>;
37
+ genus: z.ZodOptional<z.ZodString>;
38
+ vernacularName: z.ZodOptional<z.ZodString>;
39
+ numOccurrences: z.ZodOptional<z.ZodNumber>;
40
+ numDescendants: z.ZodOptional<z.ZodNumber>;
41
+ extinct: z.ZodOptional<z.ZodBoolean>;
42
+ }, z.core.$strip>>;
43
+ totalCount: z.ZodNumber;
44
+ offset: z.ZodNumber;
45
+ limit: z.ZodNumber;
46
+ endOfRecords: z.ZodBoolean;
47
+ }, z.core.$strip>, undefined>;
48
+ //# sourceMappingURL=gbif-search-species.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gbif-search-species.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/gbif-search-species.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGjD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA8I5B,CAAC"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * @fileoverview Search or browse the GBIF backbone taxonomy.
3
+ * @module mcp-server/tools/definitions/gbif-search-species
4
+ */
5
+ import { tool, z } from '@cyanheads/mcp-ts-core';
6
+ import { getGbifService } from '../../../services/gbif/gbif-service.js';
7
+ export const gbifSearchSpecies = tool('gbif_search_species', {
8
+ title: 'Search Species Taxonomy',
9
+ description: 'Search or browse the GBIF backbone taxonomy. Accepts scientific name fragments, rank filters, ' +
10
+ 'and higher-taxon constraints. Useful for exploring what species exist under a higher taxon ' +
11
+ '(e.g., "list all families of Coleoptera"), for simple name-fragment searches, or when ' +
12
+ 'gbif_match_species returns too narrow a result. Paginated — use limit and offset to walk through results.',
13
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
14
+ input: z.object({
15
+ q: z
16
+ .string()
17
+ .optional()
18
+ .describe('Name fragment to search for. Matches scientific and vernacular names.'),
19
+ rank: z
20
+ .enum(['KINGDOM', 'PHYLUM', 'CLASS', 'ORDER', 'FAMILY', 'GENUS', 'SPECIES', 'SUBSPECIES'])
21
+ .optional()
22
+ .describe('Filter to a specific taxonomic rank.'),
23
+ kingdom: z
24
+ .string()
25
+ .optional()
26
+ .describe('Scope search to a kingdom (e.g., "Animalia", "Plantae").'),
27
+ family: z.string().optional().describe('Scope search to a family name.'),
28
+ genus: z.string().optional().describe('Scope search to a genus name.'),
29
+ isExtinct: z.boolean().optional().describe('Filter to extinct (true) or extant (false) taxa.'),
30
+ datasetKey: z
31
+ .string()
32
+ .optional()
33
+ .describe('Scope to a specific checklist dataset UUID. Omit to search the GBIF backbone.'),
34
+ limit: z
35
+ .number()
36
+ .min(1)
37
+ .max(1000)
38
+ .default(20)
39
+ .describe('Number of records to return (default 20, max 1000).'),
40
+ offset: z.number().min(0).default(0).describe('Pagination offset.'),
41
+ }),
42
+ output: z.object({
43
+ taxa: z
44
+ .array(z
45
+ .object({
46
+ key: z.number().optional().describe('GBIF backbone taxon key.'),
47
+ scientificName: z.string().optional().describe('Full scientific name with authorship.'),
48
+ canonicalName: z.string().optional().describe('Scientific name without authorship.'),
49
+ rank: z.string().optional().describe('Taxonomic rank.'),
50
+ taxonomicStatus: z.string().optional().describe('ACCEPTED, SYNONYM, DOUBTFUL, etc.'),
51
+ kingdom: z.string().optional().describe('Kingdom classification.'),
52
+ phylum: z.string().optional().describe('Phylum classification.'),
53
+ class: z.string().optional().describe('Class classification.'),
54
+ order: z.string().optional().describe('Order classification.'),
55
+ family: z.string().optional().describe('Family classification.'),
56
+ genus: z.string().optional().describe('Genus classification.'),
57
+ vernacularName: z.string().optional().describe('Common name when available.'),
58
+ numOccurrences: z.number().optional().describe('Occurrence record count in GBIF.'),
59
+ numDescendants: z.number().optional().describe('Count of child taxa in the backbone.'),
60
+ extinct: z.boolean().optional().describe('True when explicitly flagged as extinct.'),
61
+ })
62
+ .describe('A backbone taxon with classification, status, and occurrence counts.'))
63
+ .describe('Matching taxa.'),
64
+ totalCount: z.number().describe('Total matches before pagination.'),
65
+ offset: z.number().describe('Current pagination offset.'),
66
+ limit: z.number().describe('Records returned in this page.'),
67
+ endOfRecords: z.boolean().describe('True when there are no more results after this page.'),
68
+ }),
69
+ async handler(input, ctx) {
70
+ ctx.log.info('Searching species taxonomy', { q: input.q, rank: input.rank });
71
+ const raw = await getGbifService().searchSpecies({
72
+ ...(input.q?.trim() && { q: input.q }),
73
+ ...(input.rank && { rank: input.rank }),
74
+ ...(input.kingdom?.trim() && { kingdom: input.kingdom }),
75
+ ...(input.family?.trim() && { family: input.family }),
76
+ ...(input.genus?.trim() && { genus: input.genus }),
77
+ ...(input.isExtinct !== undefined && { isExtinct: input.isExtinct }),
78
+ ...(input.datasetKey?.trim() && { datasetKey: input.datasetKey }),
79
+ limit: input.limit,
80
+ offset: input.offset,
81
+ }, ctx);
82
+ const taxa = (raw.results ?? []).map((r) => ({
83
+ key: r.key,
84
+ scientificName: r.scientificName,
85
+ canonicalName: r.canonicalName,
86
+ rank: r.rank,
87
+ taxonomicStatus: r.taxonomicStatus,
88
+ kingdom: r.kingdom,
89
+ phylum: r.phylum,
90
+ class: r.clazz,
91
+ order: r.order,
92
+ family: r.family,
93
+ genus: r.genus,
94
+ vernacularName: r.vernacularName,
95
+ numOccurrences: r.numOccurrences,
96
+ numDescendants: r.numDescendants,
97
+ ...(typeof r.extinct === 'boolean' && { extinct: r.extinct }),
98
+ }));
99
+ return {
100
+ taxa,
101
+ totalCount: raw.count ?? 0,
102
+ offset: raw.offset ?? input.offset,
103
+ limit: raw.limit ?? input.limit,
104
+ endOfRecords: raw.endOfRecords ?? true,
105
+ };
106
+ },
107
+ format: (result) => {
108
+ const lines = [
109
+ `**Total matches:** ${result.totalCount} | **Showing:** ${result.taxa.length} | **Limit:** ${result.limit} | **End of records:** ${result.endOfRecords} (offset ${result.offset})`,
110
+ ];
111
+ for (const t of result.taxa) {
112
+ const name = t.canonicalName ?? 'Unknown';
113
+ const sci = t.scientificName && t.scientificName !== name ? ` [${t.scientificName}]` : '';
114
+ lines.push(`\n## ${name}${sci}`);
115
+ if (t.key != null)
116
+ lines.push(`**Taxon key:** ${t.key}`);
117
+ if (t.rank)
118
+ lines.push(`**Rank:** ${t.rank}`);
119
+ if (t.taxonomicStatus)
120
+ lines.push(`**Status:** ${t.taxonomicStatus}`);
121
+ if (t.vernacularName)
122
+ lines.push(`**Common name:** ${t.vernacularName}`);
123
+ const classificationParts = [];
124
+ if (t.kingdom)
125
+ classificationParts.push(`Kingdom: ${t.kingdom}`);
126
+ if (t.phylum)
127
+ classificationParts.push(`Phylum: ${t.phylum}`);
128
+ if (t.class)
129
+ classificationParts.push(`Class: ${t.class}`);
130
+ if (t.order)
131
+ classificationParts.push(`Order: ${t.order}`);
132
+ if (t.family)
133
+ classificationParts.push(`Family: ${t.family}`);
134
+ if (t.genus)
135
+ classificationParts.push(`Genus: ${t.genus}`);
136
+ if (classificationParts.length > 0)
137
+ lines.push(`**Classification:** ${classificationParts.join(' › ')}`);
138
+ if (t.numOccurrences != null)
139
+ lines.push(`**Occurrences:** ${t.numOccurrences}`);
140
+ if (t.numDescendants != null)
141
+ lines.push(`**Descendants:** ${t.numDescendants}`);
142
+ if (typeof t.extinct === 'boolean')
143
+ lines.push(`**Extinct:** ${t.extinct ? 'Yes' : 'No'}`);
144
+ }
145
+ if (!result.endOfRecords) {
146
+ lines.push(`\n*More results available — use offset ${result.offset + result.limit} to continue.*`);
147
+ }
148
+ return [{ type: 'text', text: lines.join('\n') }];
149
+ },
150
+ });
151
+ //# sourceMappingURL=gbif-search-species.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gbif-search-species.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/gbif-search-species.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview Shared utilities for tool definitions.
3
+ * @module mcp-server/tools/utils
4
+ */
5
+ /** Strip HTML tags and decode common entities. */
6
+ export declare function stripHtml(html: string): string;
7
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/tools/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,kDAAkD;AAClD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAa9C"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @fileoverview Shared utilities for tool definitions.
3
+ * @module mcp-server/tools/utils
4
+ */
5
+ /** Strip HTML tags and decode common entities. */
6
+ export function stripHtml(html) {
7
+ return html
8
+ .replace(/<[^>]+>/g, ' ')
9
+ .replace(/&amp;/g, '&')
10
+ .replace(/&lt;/g, '<')
11
+ .replace(/&gt;/g, '>')
12
+ .replace(/&quot;/g, '"')
13
+ .replace(/&#34;/g, '"')
14
+ .replace(/&#39;/g, "'")
15
+ .replace(/&#61;/g, '=')
16
+ .replace(/&#43;/g, '+')
17
+ .replace(/\s+/g, ' ')
18
+ .trim();
19
+ }
20
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,kDAAkD;AAClD,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,IAAI;SACR,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @fileoverview GBIF API v1 service — wraps api.gbif.org/v1 with retry, auth, and response parsing.
3
+ * @module services/gbif/gbif-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 { BasisOfRecord, RawChildrenResponse, RawDatasetRecord, RawDatasetSearchResponse, RawOccurrenceRecord, RawOccurrenceSearchResponse, RawOrganizationSearchResponse, RawParentNode, RawSpeciesMatch, RawSpeciesRecord, RawSpeciesSearchResponse } from './types.js';
9
+ export declare class GbifService {
10
+ private readonly baseUrl;
11
+ private readonly timeoutMs;
12
+ private readonly authHeader;
13
+ constructor(_config: AppConfig, _storage: StorageService, opts: {
14
+ baseUrl: string;
15
+ timeoutMs: number;
16
+ apiKey?: string;
17
+ });
18
+ private buildHeaders;
19
+ private buildUrl;
20
+ private getJson;
21
+ matchSpecies(params: {
22
+ name: string;
23
+ strict?: boolean;
24
+ kingdom?: string;
25
+ rank?: string;
26
+ }, ctx: Context): Promise<RawSpeciesMatch>;
27
+ getSpecies(taxonKey: number, ctx: Context): Promise<RawSpeciesRecord>;
28
+ searchSpecies(params: {
29
+ q?: string;
30
+ rank?: string;
31
+ kingdom?: string;
32
+ family?: string;
33
+ genus?: string;
34
+ isExtinct?: boolean;
35
+ datasetKey?: string;
36
+ limit?: number;
37
+ offset?: number;
38
+ }, ctx: Context): Promise<RawSpeciesSearchResponse>;
39
+ getSpeciesParents(taxonKey: number, ctx: Context): Promise<RawParentNode[]>;
40
+ getSpeciesChildren(taxonKey: number, params: {
41
+ limit?: number;
42
+ offset?: number;
43
+ }, ctx: Context): Promise<RawChildrenResponse>;
44
+ searchOccurrences(params: {
45
+ taxonKey?: number;
46
+ scientificName?: string;
47
+ country?: string;
48
+ decimalLatitude?: string;
49
+ decimalLongitude?: string;
50
+ geometry?: string;
51
+ year?: string;
52
+ month?: number;
53
+ basisOfRecord?: BasisOfRecord;
54
+ hasCoordinate?: boolean;
55
+ isInCluster?: boolean;
56
+ datasetKey?: string;
57
+ limit?: number;
58
+ offset?: number;
59
+ }, ctx: Context): Promise<RawOccurrenceSearchResponse>;
60
+ countOccurrences(params: {
61
+ taxonKey?: number;
62
+ country?: string;
63
+ isGeoreferenced?: boolean;
64
+ datasetKey?: string;
65
+ year?: string;
66
+ }, ctx: Context): Promise<number>;
67
+ getOccurrence(occurrenceKey: number, ctx: Context): Promise<RawOccurrenceRecord>;
68
+ getOccurrenceFacets(params: {
69
+ taxonKey?: number;
70
+ country?: string;
71
+ year?: string;
72
+ basisOfRecord?: BasisOfRecord;
73
+ geometry?: string;
74
+ facet: string;
75
+ facetLimit?: number;
76
+ }, ctx: Context): Promise<RawOccurrenceSearchResponse>;
77
+ searchDatasets(params: {
78
+ q?: string;
79
+ type?: string;
80
+ publishingCountry?: string;
81
+ hostingOrg?: string;
82
+ limit?: number;
83
+ offset?: number;
84
+ }, ctx: Context): Promise<RawDatasetSearchResponse>;
85
+ getDataset(datasetKey: string, ctx: Context): Promise<RawDatasetRecord>;
86
+ searchPublishers(params: {
87
+ q?: string;
88
+ country?: string;
89
+ limit?: number;
90
+ offset?: number;
91
+ }, ctx: Context): Promise<RawOrganizationSearchResponse>;
92
+ }
93
+ export declare function initGbifService(config: AppConfig, storage: StorageService, opts: {
94
+ baseUrl: string;
95
+ timeoutMs: number;
96
+ apiKey?: string;
97
+ }): void;
98
+ export declare function getGbifService(): GbifService;
99
+ //# sourceMappingURL=gbif-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gbif-service.d.ts","sourceRoot":"","sources":["../../../src/services/gbif/gbif-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,255 @@
1
+ /**
2
+ * @fileoverview GBIF API v1 service — wraps api.gbif.org/v1 with retry, auth, and response parsing.
3
+ * @module services/gbif/gbif-service
4
+ */
5
+ import { serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
6
+ import { httpErrorFromResponse, withRetry } from '@cyanheads/mcp-ts-core/utils';
7
+ // ─── Service class ─────────────────────────────────────────────────────────────
8
+ export class GbifService {
9
+ baseUrl;
10
+ timeoutMs;
11
+ authHeader;
12
+ constructor(_config, _storage, opts) {
13
+ this.baseUrl = opts.baseUrl.replace(/\/$/, '');
14
+ this.timeoutMs = opts.timeoutMs;
15
+ if (opts.apiKey) {
16
+ // GBIF auth: Basic base64(apiKey + ':')
17
+ this.authHeader = `Basic ${btoa(`${opts.apiKey}:`)}`;
18
+ }
19
+ }
20
+ // ─── Private helpers ─────────────────────────────────────────────────────────
21
+ buildHeaders() {
22
+ const headers = { Accept: 'application/json' };
23
+ if (this.authHeader)
24
+ headers.Authorization = this.authHeader;
25
+ return headers;
26
+ }
27
+ buildUrl(path, params = {}) {
28
+ const url = new URL(`${this.baseUrl}${path}`);
29
+ for (const [key, value] of Object.entries(params)) {
30
+ if (value === undefined || value === null)
31
+ continue;
32
+ if (Array.isArray(value)) {
33
+ for (const v of value)
34
+ url.searchParams.append(key, String(v));
35
+ }
36
+ else {
37
+ url.searchParams.set(key, String(value));
38
+ }
39
+ }
40
+ return url.toString();
41
+ }
42
+ getJson(url, ctx) {
43
+ return withRetry(async () => {
44
+ const controller = new AbortController();
45
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
46
+ // Propagate ctx.signal cancellation; once:true cleans up after each attempt
47
+ const onAbort = () => controller.abort();
48
+ ctx.signal.addEventListener('abort', onAbort, { once: true });
49
+ try {
50
+ const response = await fetch(url, {
51
+ headers: this.buildHeaders(),
52
+ signal: controller.signal,
53
+ });
54
+ if (!response.ok) {
55
+ throw await httpErrorFromResponse(response, { service: 'GBIF API', data: { url } });
56
+ }
57
+ const text = await response.text();
58
+ if (/^\s*<(!DOCTYPE\s+html|html[\s>])/i.test(text)) {
59
+ throw serviceUnavailable('GBIF API returned HTML — likely rate-limited or unavailable.');
60
+ }
61
+ return JSON.parse(text);
62
+ }
63
+ finally {
64
+ clearTimeout(timeoutId);
65
+ ctx.signal.removeEventListener('abort', onAbort);
66
+ }
67
+ }, {
68
+ operation: 'GbifService.getJson',
69
+ baseDelayMs: 1000,
70
+ signal: ctx.signal,
71
+ });
72
+ }
73
+ // ─── Species/Taxonomy ─────────────────────────────────────────────────────────
74
+ matchSpecies(params, ctx) {
75
+ const queryParams = { name: params.name };
76
+ if (params.strict !== undefined)
77
+ queryParams.strict = params.strict;
78
+ if (params.kingdom)
79
+ queryParams.kingdom = params.kingdom;
80
+ if (params.rank)
81
+ queryParams.rank = params.rank;
82
+ const url = this.buildUrl('/species/match', queryParams);
83
+ ctx.log.debug('Matching species', { name: params.name });
84
+ return this.getJson(url, ctx);
85
+ }
86
+ getSpecies(taxonKey, ctx) {
87
+ const url = this.buildUrl(`/species/${taxonKey}`);
88
+ ctx.log.debug('Fetching species record', { taxonKey });
89
+ return this.getJson(url, ctx);
90
+ }
91
+ searchSpecies(params, ctx) {
92
+ const queryParams = {};
93
+ if (params.q)
94
+ queryParams.q = params.q;
95
+ if (params.rank)
96
+ queryParams.rank = params.rank;
97
+ if (params.kingdom)
98
+ queryParams.kingdom = params.kingdom;
99
+ if (params.family)
100
+ queryParams.family = params.family;
101
+ if (params.genus)
102
+ queryParams.genus = params.genus;
103
+ if (params.isExtinct !== undefined)
104
+ queryParams.isExtinct = params.isExtinct;
105
+ if (params.datasetKey)
106
+ queryParams.datasetKey = params.datasetKey;
107
+ if (params.limit !== undefined)
108
+ queryParams.limit = params.limit;
109
+ if (params.offset !== undefined)
110
+ queryParams.offset = params.offset;
111
+ const url = this.buildUrl('/species/search', queryParams);
112
+ ctx.log.debug('Searching species', { q: params.q, rank: params.rank });
113
+ return this.getJson(url, ctx);
114
+ }
115
+ getSpeciesParents(taxonKey, ctx) {
116
+ const url = this.buildUrl(`/species/${taxonKey}/parents`);
117
+ ctx.log.debug('Fetching species parents', { taxonKey });
118
+ return this.getJson(url, ctx);
119
+ }
120
+ getSpeciesChildren(taxonKey, params, ctx) {
121
+ const queryParams = {};
122
+ if (params.limit !== undefined)
123
+ queryParams.limit = params.limit;
124
+ if (params.offset !== undefined)
125
+ queryParams.offset = params.offset;
126
+ const url = this.buildUrl(`/species/${taxonKey}/children`, queryParams);
127
+ ctx.log.debug('Fetching species children', { taxonKey });
128
+ return this.getJson(url, ctx);
129
+ }
130
+ // ─── Occurrences ─────────────────────────────────────────────────────────────
131
+ searchOccurrences(params, ctx) {
132
+ const queryParams = {};
133
+ if (params.taxonKey !== undefined)
134
+ queryParams.taxonKey = params.taxonKey;
135
+ if (params.scientificName)
136
+ queryParams.scientificName = params.scientificName;
137
+ if (params.country)
138
+ queryParams.country = params.country;
139
+ if (params.decimalLatitude)
140
+ queryParams.decimalLatitude = params.decimalLatitude;
141
+ if (params.decimalLongitude)
142
+ queryParams.decimalLongitude = params.decimalLongitude;
143
+ if (params.geometry)
144
+ queryParams.geometry = params.geometry;
145
+ if (params.year)
146
+ queryParams.year = params.year;
147
+ if (params.month !== undefined)
148
+ queryParams.month = params.month;
149
+ if (params.basisOfRecord)
150
+ queryParams.basisOfRecord = params.basisOfRecord;
151
+ if (params.hasCoordinate !== undefined)
152
+ queryParams.hasCoordinate = params.hasCoordinate;
153
+ if (params.isInCluster !== undefined)
154
+ queryParams.isInCluster = params.isInCluster;
155
+ if (params.datasetKey)
156
+ queryParams.datasetKey = params.datasetKey;
157
+ if (params.limit !== undefined)
158
+ queryParams.limit = params.limit;
159
+ if (params.offset !== undefined)
160
+ queryParams.offset = params.offset;
161
+ const url = this.buildUrl('/occurrence/search', queryParams);
162
+ ctx.log.debug('Searching occurrences', { taxonKey: params.taxonKey, country: params.country });
163
+ return this.getJson(url, ctx);
164
+ }
165
+ countOccurrences(params, ctx) {
166
+ const queryParams = {};
167
+ if (params.taxonKey !== undefined)
168
+ queryParams.taxonKey = params.taxonKey;
169
+ if (params.country)
170
+ queryParams.country = params.country;
171
+ if (params.isGeoreferenced !== undefined)
172
+ queryParams.isGeoreferenced = params.isGeoreferenced;
173
+ if (params.datasetKey)
174
+ queryParams.datasetKey = params.datasetKey;
175
+ if (params.year)
176
+ queryParams.year = params.year;
177
+ const url = this.buildUrl('/occurrence/count', queryParams);
178
+ ctx.log.debug('Counting occurrences', { taxonKey: params.taxonKey });
179
+ return this.getJson(url, ctx);
180
+ }
181
+ getOccurrence(occurrenceKey, ctx) {
182
+ const url = this.buildUrl(`/occurrence/${occurrenceKey}`);
183
+ ctx.log.debug('Fetching occurrence record', { occurrenceKey });
184
+ return this.getJson(url, ctx);
185
+ }
186
+ getOccurrenceFacets(params, ctx) {
187
+ const queryParams = { limit: 0, facet: params.facet };
188
+ if (params.taxonKey !== undefined)
189
+ queryParams.taxonKey = params.taxonKey;
190
+ if (params.country)
191
+ queryParams.country = params.country;
192
+ if (params.year)
193
+ queryParams.year = params.year;
194
+ if (params.basisOfRecord)
195
+ queryParams.basisOfRecord = params.basisOfRecord;
196
+ if (params.geometry)
197
+ queryParams.geometry = params.geometry;
198
+ if (params.facetLimit !== undefined)
199
+ queryParams.facetLimit = params.facetLimit;
200
+ const url = this.buildUrl('/occurrence/search', queryParams);
201
+ ctx.log.debug('Fetching occurrence facets', { facet: params.facet });
202
+ return this.getJson(url, ctx);
203
+ }
204
+ // ─── Datasets ─────────────────────────────────────────────────────────────────
205
+ searchDatasets(params, ctx) {
206
+ const queryParams = {};
207
+ if (params.q)
208
+ queryParams.q = params.q;
209
+ if (params.type)
210
+ queryParams.type = params.type;
211
+ if (params.publishingCountry)
212
+ queryParams.publishingCountry = params.publishingCountry;
213
+ if (params.hostingOrg)
214
+ queryParams.hostingOrg = params.hostingOrg;
215
+ if (params.limit !== undefined)
216
+ queryParams.limit = params.limit;
217
+ if (params.offset !== undefined)
218
+ queryParams.offset = params.offset;
219
+ const url = this.buildUrl('/dataset/search', queryParams);
220
+ ctx.log.debug('Searching datasets', { q: params.q, type: params.type });
221
+ return this.getJson(url, ctx);
222
+ }
223
+ getDataset(datasetKey, ctx) {
224
+ const url = this.buildUrl(`/dataset/${datasetKey}`);
225
+ ctx.log.debug('Fetching dataset record', { datasetKey });
226
+ return this.getJson(url, ctx);
227
+ }
228
+ // ─── Publishers/Organizations ─────────────────────────────────────────────────
229
+ searchPublishers(params, ctx) {
230
+ const queryParams = {};
231
+ if (params.q)
232
+ queryParams.q = params.q;
233
+ if (params.country)
234
+ queryParams.country = params.country;
235
+ if (params.limit !== undefined)
236
+ queryParams.limit = params.limit;
237
+ if (params.offset !== undefined)
238
+ queryParams.offset = params.offset;
239
+ const url = this.buildUrl('/organization', queryParams);
240
+ ctx.log.debug('Searching publishers', { q: params.q, country: params.country });
241
+ return this.getJson(url, ctx);
242
+ }
243
+ }
244
+ // ─── Init/accessor pattern ────────────────────────────────────────────────────
245
+ let _service;
246
+ export function initGbifService(config, storage, opts) {
247
+ _service = new GbifService(config, storage, opts);
248
+ }
249
+ export function getGbifService() {
250
+ if (!_service) {
251
+ throw new Error('GbifService not initialized — call initGbifService() in setup()');
252
+ }
253
+ return _service;
254
+ }
255
+ //# sourceMappingURL=gbif-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gbif-service.js","sourceRoot":"","sources":["../../../src/services/gbif/gbif-service.ts"],"names":[],"mappings":"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"}