@digital-science-dsl/dimensions-analytics-mcp 1.1.0 → 1.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.
- package/CHANGELOG.md +6 -0
- package/dist/mcp/examples/dsl-examples.d.ts.map +1 -1
- package/dist/mcp/examples/dsl-examples.js +2 -0
- package/dist/mcp/examples/dsl-examples.js.map +1 -1
- package/dist/mcp/examples/usage-scenarios.d.ts.map +1 -1
- package/dist/mcp/examples/usage-scenarios.js +19 -0
- package/dist/mcp/examples/usage-scenarios.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +6 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/similar-documents.d.ts +26 -0
- package/dist/mcp/tools/similar-documents.d.ts.map +1 -0
- package/dist/mcp/tools/similar-documents.js +171 -0
- package/dist/mcp/tools/similar-documents.js.map +1 -0
- package/package.json +1 -1
- package/src/mcp/examples/dsl-examples.ts +2 -0
- package/src/mcp/examples/usage-scenarios.ts +19 -0
- package/src/mcp/server.ts +6 -2
- package/src/mcp/tools/similar-documents.ts +232 -0
- package/test/examples/usage-scenarios.test.ts +5 -3
- package/test/integration/suites/index.ts +2 -0
- package/test/integration/suites/similar-documents.integration.ts +51 -0
- package/test/server.test.ts +2 -0
- package/test/tools/similar-documents.test.ts +173 -0
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add `similar_documents` MCP tool for concept-based similar publication/grant lookup from abstract text (replacing the need to hand-write `similar_documents()` via `execute_dsl`).
|
|
8
|
+
|
|
3
9
|
## 1.1.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dsl-examples.d.ts","sourceRoot":"","sources":["../../../src/mcp/examples/dsl-examples.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qDAAqD;AACrD,eAAO,MAAM,0BAA0B,mCAAmC,CAAC;AAE3E,4CAA4C;AAC5C,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"dsl-examples.d.ts","sourceRoot":"","sources":["../../../src/mcp/examples/dsl-examples.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qDAAqD;AACrD,eAAO,MAAM,0BAA0B,mCAAmC,CAAC;AAE3E,4CAA4C;AAC5C,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CA8CpE,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,oBAAoB,6OAMvB,CAAC;AAEX,0CAA0C;AAC1C,eAAO,MAAM,qBAAqB,oCAAoC,CAAC;AAEvE,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,UAA6C,CAAC;AAEnF;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAErF"}
|
|
@@ -10,11 +10,13 @@ export const DSL_EXAMPLES_BY_ENTITY = {
|
|
|
10
10
|
'search publications for "machine learning" return publications[id+title+doi] limit 10',
|
|
11
11
|
'search publications for "CRISPR" where year >= 2020 return publications[id+title+times_cited+year] sort by times_cited desc limit 25',
|
|
12
12
|
'search publications in title_only for "gene therapy" return publications[basics] limit 10',
|
|
13
|
+
'search publications for similar_documents("After spinal cord injury, macrophages infiltrate the lesion site") where year > 2015 return publications[id+title+year] sort by score desc limit 5',
|
|
13
14
|
"search publications return publications facet journal limit 20",
|
|
14
15
|
],
|
|
15
16
|
grants: [
|
|
16
17
|
'search grants for "cancer immunotherapy" return grants limit 10',
|
|
17
18
|
'search grants where funder_org_name = "National Institutes of Health" return grants[basics] limit 10',
|
|
19
|
+
'search grants for similar_documents("Cancer immunotherapy with checkpoint inhibitors and CAR-T") where start_year >= 2020 return grants[id+title] sort by score desc limit 5',
|
|
18
20
|
"search grants return grants aggregate funding_usd",
|
|
19
21
|
],
|
|
20
22
|
patents: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dsl-examples.js","sourceRoot":"","sources":["../../../src/mcp/examples/dsl-examples.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qDAAqD;AACrD,MAAM,CAAC,MAAM,0BAA0B,GAAG,gCAAgC,CAAC;AAE3E,4CAA4C;AAC5C,MAAM,CAAC,MAAM,sBAAsB,GAAsC;IACvE,YAAY,EAAE;QACZ,uFAAuF;QACvF,sIAAsI;QACtI,2FAA2F;QAC3F,gEAAgE;KACjE;IACD,MAAM,EAAE;QACN,iEAAiE;QACjE,sGAAsG;QACtG,mDAAmD;KACpD;IACD,OAAO,EAAE;QACP,8DAA8D;QAC9D,qEAAqE;KACtE;IACD,eAAe,EAAE;QACf,uEAAuE;QACvE,gFAAgF;KACjF;IACD,QAAQ,EAAE,CAAC,8DAA8D,CAAC;IAC1E,gBAAgB,EAAE;QAChB,iFAAiF;KAClF;IACD,WAAW,EAAE;QACX,0EAA0E;QAC1E,+EAA+E;KAChF;IACD,aAAa,EAAE;QACb,mEAAmE;QACnE,oFAAoF;KACrF;IACD,OAAO,EAAE;QACP,qEAAqE;QACrE,0EAA0E;KAC3E;IACD,aAAa,EAAE;QACb,yEAAyE;QACzE,8FAA8F;KAC/F;IACD,aAAa,EAAE,CAAC,sEAAsE,CAAC;IACvF,mBAAmB,EAAE;QACnB,yFAAyF;KAC1F;CACF,CAAC;AAEF,8DAA8D;AAC9D,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,kBAAkB;IAClB,iBAAiB;IACjB,8BAA8B;IAC9B,gFAAgF;IAChF,iEAAiE;CACzD,CAAC;AAEX,0CAA0C;AAC1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,iCAAiC,CAAC;AAEvE,mEAAmE;AACnE,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,IAAI,EAAE,CAAC;AAEnF;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc;IACpD,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC"}
|
|
1
|
+
{"version":3,"file":"dsl-examples.js","sourceRoot":"","sources":["../../../src/mcp/examples/dsl-examples.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qDAAqD;AACrD,MAAM,CAAC,MAAM,0BAA0B,GAAG,gCAAgC,CAAC;AAE3E,4CAA4C;AAC5C,MAAM,CAAC,MAAM,sBAAsB,GAAsC;IACvE,YAAY,EAAE;QACZ,uFAAuF;QACvF,sIAAsI;QACtI,2FAA2F;QAC3F,+LAA+L;QAC/L,gEAAgE;KACjE;IACD,MAAM,EAAE;QACN,iEAAiE;QACjE,sGAAsG;QACtG,8KAA8K;QAC9K,mDAAmD;KACpD;IACD,OAAO,EAAE;QACP,8DAA8D;QAC9D,qEAAqE;KACtE;IACD,eAAe,EAAE;QACf,uEAAuE;QACvE,gFAAgF;KACjF;IACD,QAAQ,EAAE,CAAC,8DAA8D,CAAC;IAC1E,gBAAgB,EAAE;QAChB,iFAAiF;KAClF;IACD,WAAW,EAAE;QACX,0EAA0E;QAC1E,+EAA+E;KAChF;IACD,aAAa,EAAE;QACb,mEAAmE;QACnE,oFAAoF;KACrF;IACD,OAAO,EAAE;QACP,qEAAqE;QACrE,0EAA0E;KAC3E;IACD,aAAa,EAAE;QACb,yEAAyE;QACzE,8FAA8F;KAC/F;IACD,aAAa,EAAE,CAAC,sEAAsE,CAAC;IACvF,mBAAmB,EAAE;QACnB,yFAAyF;KAC1F;CACF,CAAC;AAEF,8DAA8D;AAC9D,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,kBAAkB;IAClB,iBAAiB;IACjB,8BAA8B;IAC9B,gFAAgF;IAChF,iEAAiE;CACzD,CAAC;AAEX,0CAA0C;AAC1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,iCAAiC,CAAC;AAEvE,mEAAmE;AACnE,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,IAAI,EAAE,CAAC;AAEnF;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc;IACpD,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-scenarios.d.ts","sourceRoot":"","sources":["../../../src/mcp/examples/usage-scenarios.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,
|
|
1
|
+
{"version":3,"file":"usage-scenarios.d.ts","sourceRoot":"","sources":["../../../src/mcp/examples/usage-scenarios.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EAuL1C,CAAC"}
|
|
@@ -148,6 +148,25 @@ export const USAGE_SCENARIOS = [
|
|
|
148
148
|
},
|
|
149
149
|
dslContains: ["large language model", "citations_per_year(2018, 2024)"],
|
|
150
150
|
},
|
|
151
|
+
{
|
|
152
|
+
id: "similar-documents",
|
|
153
|
+
goal: "Similar papers from an abstract",
|
|
154
|
+
prompt: "Find publications similar to this abstract about spinal cord injury macrophages.",
|
|
155
|
+
tool: "similar_documents",
|
|
156
|
+
args: {
|
|
157
|
+
entityType: "publications",
|
|
158
|
+
text: "After spinal cord injury, macrophages infiltrate the lesion site and contribute to both tissue damage and repair processes.",
|
|
159
|
+
yearFrom: 2016,
|
|
160
|
+
limit: 10,
|
|
161
|
+
fields: ["id", "title", "year"],
|
|
162
|
+
},
|
|
163
|
+
dslContains: [
|
|
164
|
+
"search publications for similar_documents(",
|
|
165
|
+
"year >= 2016",
|
|
166
|
+
"sort by score desc",
|
|
167
|
+
"limit 10",
|
|
168
|
+
],
|
|
169
|
+
},
|
|
151
170
|
{
|
|
152
171
|
id: "build-complex-query",
|
|
153
172
|
goal: "Build a complex query",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-scenarios.js","sourceRoot":"","sources":["../../../src/mcp/examples/usage-scenarios.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usage-scenarios.js","sourceRoot":"","sources":["../../../src/mcp/examples/usage-scenarios.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,EAAE,KAAK,eAAe,EAAwB,MAAM,oBAAoB,CAAC;AAEhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EACL,gBAAgB,EAEhB,UAAU,EACV,KAAK,WAAW,EACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,EAAE,KAAK,eAAe,EAAwB,MAAM,oBAAoB,CAAC;AAEhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EACL,gBAAgB,EAEhB,UAAU,EACV,KAAK,WAAW,EACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAYzD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,+BAA+B;IAC/B,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACpC,qEAAqE;IACrE,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4BD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAyCxE;AAoCD;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAIzF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,GAAE,eAAoB,GAAG,OAAO,CAAC;IAChF,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC,CAoDD;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,iBAAiB,CAAC,EAAE,SAAS,EAC7B,MAAM,GAAE,eAAoB,GAC3B,OAAO,CAAC,eAAe,CAAC,CAmB1B;AAED,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -18,6 +18,7 @@ import { registerLookupTools } from "./tools/lookup.js";
|
|
|
18
18
|
import { registerQueryTools } from "./tools/query.js";
|
|
19
19
|
import { registerSchemaTools, validateFieldAliases } from "./tools/schema.js";
|
|
20
20
|
import { registerSearchTools } from "./tools/search.js";
|
|
21
|
+
import { registerSimilarDocumentsTool } from "./tools/similar-documents.js";
|
|
21
22
|
import { initMcpUsageTracking } from "./usage-tracking.js";
|
|
22
23
|
/**
|
|
23
24
|
* Reads a positive integer from an environment variable with a default fallback.
|
|
@@ -54,7 +55,7 @@ export function buildServerInstructions(schemaStore) {
|
|
|
54
55
|
[
|
|
55
56
|
"Workflow:",
|
|
56
57
|
"(1) Discover schema — read dimensions://schema/summary, dimensions://fields/{entity}, dimensions://examples/{source}, or describe_schema;",
|
|
57
|
-
"(2) Search — search_* for keyword discovery with filters; get_by_doi, get_by_pmid, get_by_id for known identifiers;",
|
|
58
|
+
"(2) Search — search_* for keyword discovery with filters; similar_documents for topic-similar pubs/grants from abstract text; get_by_doi, get_by_pmid, get_by_id for known identifiers;",
|
|
58
59
|
"(3) Analyze — facet_query, aggregate_query, citation_trend, funding_trend;",
|
|
59
60
|
"(4) Drill down — get_by_id, search_* with filters (e.g. researchers.id, research_orgs.id), facet_query for top researchers at an org.",
|
|
60
61
|
].join(" "),
|
|
@@ -65,12 +66,14 @@ export function buildServerInstructions(schemaStore) {
|
|
|
65
66
|
"search_organizations for institution lookup — prefer GRID id in filters when the name is ambiguous;",
|
|
66
67
|
"search_source_titles for journals / ISSN lookup (not articles); search_reports for technical reports;",
|
|
67
68
|
"search_funder_groups / search_research_org_groups for curated group name → member GRID ids;",
|
|
69
|
+
"similar_documents finds concept-similar publications/grants from prose (not embeddings); for a known ID, get_by_id then pass abstract/description as text;",
|
|
68
70
|
"facet_query supports yearFrom/yearTo for year-scoped facets.",
|
|
69
71
|
].join(" "),
|
|
70
72
|
[
|
|
71
73
|
"Query construction:",
|
|
72
74
|
"for ranked publication search (e.g. most-cited since 2020), use search_publications with query, yearFrom, sortBy (times_cited or total_citations), limit — do not hand-write execute_dsl;",
|
|
73
|
-
"use
|
|
75
|
+
"for similar-document lookup, use similar_documents — do not hand-write similar_documents() in execute_dsl;",
|
|
76
|
+
"use execute_dsl for boolean concept groups and remaining DSL special functions (classify, extract_concepts);",
|
|
74
77
|
"use execute_dsl only when structured tools are insufficient; DSL order is return ... sort by FIELD order limit N (never limit before sort).",
|
|
75
78
|
].join(" "),
|
|
76
79
|
[
|
|
@@ -91,6 +94,7 @@ function registerAllTools(server, client, schemaStore, schemaContext, deployment
|
|
|
91
94
|
registerLookupTools(server, client);
|
|
92
95
|
registerQueryTools(server, client, schemaStore);
|
|
93
96
|
registerFunctionTools(server, client);
|
|
97
|
+
registerSimilarDocumentsTool(server, client);
|
|
94
98
|
registerAnalyticsTools(server, client, schemaStore);
|
|
95
99
|
registerSchemaTools(server, client, schemaContext);
|
|
96
100
|
}
|
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,GAAG,MAAM,oBAAoB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3D,OAAO,EAAwB,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,+BAA+B,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAElG,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,UAAU,GAEX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AA0B3D;;GAEG;AACH,SAAS,UAAU,CAAC,GAAuB,EAAE,QAAgB,EAAE,GAAW;IACxE,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IACtD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACvC,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;AACnE,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAuB;IAIhD,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,cAAc;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;IACtC,IAAI,MAAM,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAwB;IAC9D,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,WAAW,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,MAAM,cAAc,GAClB,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,QAAQ;QACtC,CAAC,CAAC,iFAAiF;QACnF,CAAC,CAAC,oFAAoF,CAAC;IAE3F,OAAO;QACL,sDAAsD,OAAO,EAAE;QAC/D;YACE,WAAW;YACX,2IAA2I;YAC3I,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* similar_documents MCP tool — find publications/grants with similar topics via DSL.
|
|
3
|
+
* Uses concept extraction + weighted concepts search (not vector embeddings).
|
|
4
|
+
* @module mcp/tools/similar-documents
|
|
5
|
+
*/
|
|
6
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
import type { DimensionsClient } from "../../dsl/index.js";
|
|
8
|
+
/** Entity types that support the DSL similar_documents() search function. */
|
|
9
|
+
export declare const SIMILAR_DOCUMENTS_ENTITY_TYPES: readonly ["publications", "grants"];
|
|
10
|
+
/** Entity type supported by similar_documents. */
|
|
11
|
+
export type SimilarDocumentsEntityType = (typeof SIMILAR_DOCUMENTS_ENTITY_TYPES)[number];
|
|
12
|
+
/**
|
|
13
|
+
* Builds DSL for a similar_documents search from tool arguments.
|
|
14
|
+
* @param client - Dimensions client
|
|
15
|
+
* @param entityType - publications or grants
|
|
16
|
+
* @param args - Tool arguments (after field-alias resolution)
|
|
17
|
+
* @returns DSL query string
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildSimilarDocumentsDsl(client: DimensionsClient, entityType: SimilarDocumentsEntityType, args: Record<string, unknown>): string;
|
|
20
|
+
/**
|
|
21
|
+
* Registers the similar_documents tool with the MCP server.
|
|
22
|
+
* @param server - MCP server instance
|
|
23
|
+
* @param client - Dimensions client instance
|
|
24
|
+
*/
|
|
25
|
+
export declare function registerSimilarDocumentsTool(server: McpServer, client: DimensionsClient): void;
|
|
26
|
+
//# sourceMappingURL=similar-documents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"similar-documents.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/similar-documents.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAsB3D,6EAA6E;AAC7E,eAAO,MAAM,8BAA8B,qCAAsC,CAAC;AAElF,kDAAkD;AAClD,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC;AAQzF;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,0BAA0B,EACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,CAsCR;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAqI9F"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* similar_documents MCP tool — find publications/grants with similar topics via DSL.
|
|
3
|
+
* Uses concept extraction + weighted concepts search (not vector embeddings).
|
|
4
|
+
* @module mcp/tools/similar-documents
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { applyFilters, ExtendedWhereFilterSchema, parseEntityResponse, resolveSkipAndLimit, SCHEMA_LIMITS, searchResultKey, validateSearchPaginationPolicy, } from "../../dsl/index.js";
|
|
8
|
+
import { withFieldAliases } from "../middleware/field-aliases.js";
|
|
9
|
+
import { registerTrackedTool } from "../usage-tracking.js";
|
|
10
|
+
import { formatErrorResult, formatToolResult, READ_ONLY_API_ANNOTATIONS, withSearchPagination, } from "../utils.js";
|
|
11
|
+
import { PAGINATION_INPUT_SCHEMA, PAGINATION_OUTPUT_SCHEMA } from "./search-input.js";
|
|
12
|
+
/** Entity types that support the DSL similar_documents() search function. */
|
|
13
|
+
export const SIMILAR_DOCUMENTS_ENTITY_TYPES = ["publications", "grants"];
|
|
14
|
+
/** Year filter field per entity (publications use year; grants use start_year). */
|
|
15
|
+
const YEAR_FIELD = {
|
|
16
|
+
publications: "year",
|
|
17
|
+
grants: "start_year",
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Builds DSL for a similar_documents search from tool arguments.
|
|
21
|
+
* @param client - Dimensions client
|
|
22
|
+
* @param entityType - publications or grants
|
|
23
|
+
* @param args - Tool arguments (after field-alias resolution)
|
|
24
|
+
* @returns DSL query string
|
|
25
|
+
*/
|
|
26
|
+
export function buildSimilarDocumentsDsl(client, entityType, args) {
|
|
27
|
+
const text = String(args.text ?? "");
|
|
28
|
+
const builder = client.createQueryBuilder().search(entityType).forSimilar(text);
|
|
29
|
+
const yearField = YEAR_FIELD[entityType];
|
|
30
|
+
if (typeof args.yearFrom === "number") {
|
|
31
|
+
builder.where(yearField, ">=", args.yearFrom);
|
|
32
|
+
}
|
|
33
|
+
if (typeof args.yearTo === "number") {
|
|
34
|
+
builder.where(yearField, "<=", args.yearTo);
|
|
35
|
+
}
|
|
36
|
+
const filters = args.filters;
|
|
37
|
+
if (filters?.length) {
|
|
38
|
+
applyFilters(builder, filters);
|
|
39
|
+
}
|
|
40
|
+
const fields = args.fields;
|
|
41
|
+
if (fields?.length) {
|
|
42
|
+
builder.fields(fields);
|
|
43
|
+
}
|
|
44
|
+
const sortBy = typeof args.sortBy === "string" ? args.sortBy : "score";
|
|
45
|
+
builder.sort(sortBy, "desc");
|
|
46
|
+
// Default to 20 for similarity (top-N relevance), not the search_* default of 100.
|
|
47
|
+
const { skip, limit } = resolveSkipAndLimit({
|
|
48
|
+
skip: args.skip,
|
|
49
|
+
page: args.page,
|
|
50
|
+
limit: args.limit ?? 20,
|
|
51
|
+
pageSize: args.pageSize,
|
|
52
|
+
});
|
|
53
|
+
builder.limit(limit);
|
|
54
|
+
if (skip > 0) {
|
|
55
|
+
builder.skip(skip);
|
|
56
|
+
}
|
|
57
|
+
return builder.build();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Registers the similar_documents tool with the MCP server.
|
|
61
|
+
* @param server - MCP server instance
|
|
62
|
+
* @param client - Dimensions client instance
|
|
63
|
+
*/
|
|
64
|
+
export function registerSimilarDocumentsTool(server, client) {
|
|
65
|
+
registerTrackedTool(server, "similar_documents", {
|
|
66
|
+
description: "Find publications or grants with similar research topics based on abstract/description text. " +
|
|
67
|
+
"Uses Dimensions concept extraction and weighted concepts search (not vector embeddings). " +
|
|
68
|
+
"Prefer this over execute_dsl for similarity. For a known record: get_by_id / get_by_doi first, " +
|
|
69
|
+
"then pass its abstract/description as text. Supported entityType: publications, grants only.",
|
|
70
|
+
inputSchema: {
|
|
71
|
+
entityType: z
|
|
72
|
+
.enum(SIMILAR_DOCUMENTS_ENTITY_TYPES)
|
|
73
|
+
.describe("Entity type to search (publications or grants)"),
|
|
74
|
+
text: z
|
|
75
|
+
.string()
|
|
76
|
+
.min(1)
|
|
77
|
+
.describe("Abstract, description, or other prose to find similar documents for. " +
|
|
78
|
+
"Longer topical text works better than short keywords."),
|
|
79
|
+
limit: z
|
|
80
|
+
.number()
|
|
81
|
+
.int()
|
|
82
|
+
.min(1)
|
|
83
|
+
.max(SCHEMA_LIMITS.maxLimit)
|
|
84
|
+
.default(20)
|
|
85
|
+
.describe(`Maximum results to return (max ${SCHEMA_LIMITS.maxLimit}, default 20)`),
|
|
86
|
+
...PAGINATION_INPUT_SCHEMA,
|
|
87
|
+
fields: z
|
|
88
|
+
.array(z.string())
|
|
89
|
+
.optional()
|
|
90
|
+
.describe("Fields to return. Accepts aliases or DSL names. Use dimensions://fields/{entity} for the full list."),
|
|
91
|
+
filters: z
|
|
92
|
+
.array(ExtendedWhereFilterSchema)
|
|
93
|
+
.optional()
|
|
94
|
+
.describe("Additional where-clause filters"),
|
|
95
|
+
yearFrom: z
|
|
96
|
+
.number()
|
|
97
|
+
.int()
|
|
98
|
+
.optional()
|
|
99
|
+
.describe("Filter from this year inclusive (publications: year; grants: start_year)"),
|
|
100
|
+
yearTo: z
|
|
101
|
+
.number()
|
|
102
|
+
.int()
|
|
103
|
+
.optional()
|
|
104
|
+
.describe("Filter up to this year inclusive (publications: year; grants: start_year)"),
|
|
105
|
+
sortBy: z
|
|
106
|
+
.string()
|
|
107
|
+
.optional()
|
|
108
|
+
.describe("Sort field (default: score for relevance). Examples: score, times_cited, year, start_year."),
|
|
109
|
+
confirmLargeFetch: z
|
|
110
|
+
.boolean()
|
|
111
|
+
.optional()
|
|
112
|
+
.default(false)
|
|
113
|
+
.describe("Required when skip≥5000, page≥5, or limit=1000 with skip>0. See dimensions://schema/policy."),
|
|
114
|
+
},
|
|
115
|
+
outputSchema: {
|
|
116
|
+
entityType: z.enum(SIMILAR_DOCUMENTS_ENTITY_TYPES).describe("Entity type searched"),
|
|
117
|
+
totalCount: z.number().describe("Total matching records"),
|
|
118
|
+
returnedCount: z.number().describe("Records returned in this response"),
|
|
119
|
+
truncated: z.boolean().optional().describe("True when more results exist beyond this page"),
|
|
120
|
+
truncationWarning: z.string().optional().describe("Warning message when truncated"),
|
|
121
|
+
...PAGINATION_OUTPUT_SCHEMA,
|
|
122
|
+
publications: z
|
|
123
|
+
.array(z.record(z.string(), z.unknown()))
|
|
124
|
+
.optional()
|
|
125
|
+
.describe("Matching publications (when entityType is publications)"),
|
|
126
|
+
grants: z
|
|
127
|
+
.array(z.record(z.string(), z.unknown()))
|
|
128
|
+
.optional()
|
|
129
|
+
.describe("Matching grants (when entityType is grants)"),
|
|
130
|
+
},
|
|
131
|
+
annotations: READ_ONLY_API_ANNOTATIONS,
|
|
132
|
+
}, withFieldAliases({
|
|
133
|
+
entitySource: { kind: "dynamic", argName: "entityType" },
|
|
134
|
+
fieldArrayArgs: ["fields"],
|
|
135
|
+
fieldStringArgs: ["sortBy"],
|
|
136
|
+
filterArrayArgs: ["filters"],
|
|
137
|
+
}, async (args) => {
|
|
138
|
+
try {
|
|
139
|
+
const entityType = args.entityType;
|
|
140
|
+
const record = args;
|
|
141
|
+
const { skip, limit } = resolveSkipAndLimit({
|
|
142
|
+
skip: record.skip,
|
|
143
|
+
page: record.page,
|
|
144
|
+
limit: record.limit ?? 20,
|
|
145
|
+
});
|
|
146
|
+
validateSearchPaginationPolicy({
|
|
147
|
+
skip,
|
|
148
|
+
limit,
|
|
149
|
+
confirmLargeFetch: record.confirmLargeFetch,
|
|
150
|
+
});
|
|
151
|
+
const dsl = buildSimilarDocumentsDsl(client, entityType, {
|
|
152
|
+
...record,
|
|
153
|
+
limit,
|
|
154
|
+
});
|
|
155
|
+
const response = (await client.rawQuery(dsl));
|
|
156
|
+
const parsed = parseEntityResponse(response, entityType);
|
|
157
|
+
const rows = parsed.data;
|
|
158
|
+
const resultKey = searchResultKey(entityType);
|
|
159
|
+
return formatToolResult(withSearchPagination({
|
|
160
|
+
entityType,
|
|
161
|
+
totalCount: parsed.totalCount,
|
|
162
|
+
returnedCount: rows.length,
|
|
163
|
+
[resultKey]: rows,
|
|
164
|
+
}, parsed.totalCount, rows.length, skip, limit));
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
return formatErrorResult(error);
|
|
168
|
+
}
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=similar-documents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"similar-documents.js","sourceRoot":"","sources":["../../../src/mcp/tools/similar-documents.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -12,11 +12,13 @@ export const DSL_EXAMPLES_BY_ENTITY: Record<string, readonly string[]> = {
|
|
|
12
12
|
'search publications for "machine learning" return publications[id+title+doi] limit 10',
|
|
13
13
|
'search publications for "CRISPR" where year >= 2020 return publications[id+title+times_cited+year] sort by times_cited desc limit 25',
|
|
14
14
|
'search publications in title_only for "gene therapy" return publications[basics] limit 10',
|
|
15
|
+
'search publications for similar_documents("After spinal cord injury, macrophages infiltrate the lesion site") where year > 2015 return publications[id+title+year] sort by score desc limit 5',
|
|
15
16
|
"search publications return publications facet journal limit 20",
|
|
16
17
|
],
|
|
17
18
|
grants: [
|
|
18
19
|
'search grants for "cancer immunotherapy" return grants limit 10',
|
|
19
20
|
'search grants where funder_org_name = "National Institutes of Health" return grants[basics] limit 10',
|
|
21
|
+
'search grants for similar_documents("Cancer immunotherapy with checkpoint inhibitors and CAR-T") where start_year >= 2020 return grants[id+title] sort by score desc limit 5',
|
|
20
22
|
"search grants return grants aggregate funding_usd",
|
|
21
23
|
],
|
|
22
24
|
patents: [
|
|
@@ -164,6 +164,25 @@ export const USAGE_SCENARIOS: readonly UsageScenario[] = [
|
|
|
164
164
|
},
|
|
165
165
|
dslContains: ["large language model", "citations_per_year(2018, 2024)"],
|
|
166
166
|
},
|
|
167
|
+
{
|
|
168
|
+
id: "similar-documents",
|
|
169
|
+
goal: "Similar papers from an abstract",
|
|
170
|
+
prompt: "Find publications similar to this abstract about spinal cord injury macrophages.",
|
|
171
|
+
tool: "similar_documents",
|
|
172
|
+
args: {
|
|
173
|
+
entityType: "publications",
|
|
174
|
+
text: "After spinal cord injury, macrophages infiltrate the lesion site and contribute to both tissue damage and repair processes.",
|
|
175
|
+
yearFrom: 2016,
|
|
176
|
+
limit: 10,
|
|
177
|
+
fields: ["id", "title", "year"],
|
|
178
|
+
},
|
|
179
|
+
dslContains: [
|
|
180
|
+
"search publications for similar_documents(",
|
|
181
|
+
"year >= 2016",
|
|
182
|
+
"sort by score desc",
|
|
183
|
+
"limit 10",
|
|
184
|
+
],
|
|
185
|
+
},
|
|
167
186
|
{
|
|
168
187
|
id: "build-complex-query",
|
|
169
188
|
goal: "Build a complex query",
|
package/src/mcp/server.ts
CHANGED
|
@@ -27,6 +27,7 @@ import { registerLookupTools } from "./tools/lookup.js";
|
|
|
27
27
|
import { registerQueryTools } from "./tools/query.js";
|
|
28
28
|
import { registerSchemaTools, validateFieldAliases } from "./tools/schema.js";
|
|
29
29
|
import { registerSearchTools } from "./tools/search.js";
|
|
30
|
+
import { registerSimilarDocumentsTool } from "./tools/similar-documents.js";
|
|
30
31
|
import { initMcpUsageTracking } from "./usage-tracking.js";
|
|
31
32
|
|
|
32
33
|
/**
|
|
@@ -94,7 +95,7 @@ export function buildServerInstructions(schemaStore: SchemaStore): string {
|
|
|
94
95
|
[
|
|
95
96
|
"Workflow:",
|
|
96
97
|
"(1) Discover schema — read dimensions://schema/summary, dimensions://fields/{entity}, dimensions://examples/{source}, or describe_schema;",
|
|
97
|
-
"(2) Search — search_* for keyword discovery with filters; get_by_doi, get_by_pmid, get_by_id for known identifiers;",
|
|
98
|
+
"(2) Search — search_* for keyword discovery with filters; similar_documents for topic-similar pubs/grants from abstract text; get_by_doi, get_by_pmid, get_by_id for known identifiers;",
|
|
98
99
|
"(3) Analyze — facet_query, aggregate_query, citation_trend, funding_trend;",
|
|
99
100
|
"(4) Drill down — get_by_id, search_* with filters (e.g. researchers.id, research_orgs.id), facet_query for top researchers at an org.",
|
|
100
101
|
].join(" "),
|
|
@@ -105,12 +106,14 @@ export function buildServerInstructions(schemaStore: SchemaStore): string {
|
|
|
105
106
|
"search_organizations for institution lookup — prefer GRID id in filters when the name is ambiguous;",
|
|
106
107
|
"search_source_titles for journals / ISSN lookup (not articles); search_reports for technical reports;",
|
|
107
108
|
"search_funder_groups / search_research_org_groups for curated group name → member GRID ids;",
|
|
109
|
+
"similar_documents finds concept-similar publications/grants from prose (not embeddings); for a known ID, get_by_id then pass abstract/description as text;",
|
|
108
110
|
"facet_query supports yearFrom/yearTo for year-scoped facets.",
|
|
109
111
|
].join(" "),
|
|
110
112
|
[
|
|
111
113
|
"Query construction:",
|
|
112
114
|
"for ranked publication search (e.g. most-cited since 2020), use search_publications with query, yearFrom, sortBy (times_cited or total_citations), limit — do not hand-write execute_dsl;",
|
|
113
|
-
"use
|
|
115
|
+
"for similar-document lookup, use similar_documents — do not hand-write similar_documents() in execute_dsl;",
|
|
116
|
+
"use execute_dsl for boolean concept groups and remaining DSL special functions (classify, extract_concepts);",
|
|
114
117
|
"use execute_dsl only when structured tools are insufficient; DSL order is return ... sort by FIELD order limit N (never limit before sort).",
|
|
115
118
|
].join(" "),
|
|
116
119
|
[
|
|
@@ -138,6 +141,7 @@ function registerAllTools(
|
|
|
138
141
|
registerLookupTools(server, client);
|
|
139
142
|
registerQueryTools(server, client, schemaStore);
|
|
140
143
|
registerFunctionTools(server, client);
|
|
144
|
+
registerSimilarDocumentsTool(server, client);
|
|
141
145
|
registerAnalyticsTools(server, client, schemaStore);
|
|
142
146
|
registerSchemaTools(server, client, schemaContext);
|
|
143
147
|
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* similar_documents MCP tool — find publications/grants with similar topics via DSL.
|
|
3
|
+
* Uses concept extraction + weighted concepts search (not vector embeddings).
|
|
4
|
+
* @module mcp/tools/similar-documents
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import type { DimensionsClient } from "../../dsl/index.js";
|
|
10
|
+
import {
|
|
11
|
+
applyFilters,
|
|
12
|
+
type ExtendedWhereFilterInput,
|
|
13
|
+
ExtendedWhereFilterSchema,
|
|
14
|
+
parseEntityResponse,
|
|
15
|
+
resolveSkipAndLimit,
|
|
16
|
+
SCHEMA_LIMITS,
|
|
17
|
+
type StructuredEntityType,
|
|
18
|
+
searchResultKey,
|
|
19
|
+
validateSearchPaginationPolicy,
|
|
20
|
+
} from "../../dsl/index.js";
|
|
21
|
+
import { withFieldAliases } from "../middleware/field-aliases.js";
|
|
22
|
+
import { registerTrackedTool } from "../usage-tracking.js";
|
|
23
|
+
import {
|
|
24
|
+
formatErrorResult,
|
|
25
|
+
formatToolResult,
|
|
26
|
+
READ_ONLY_API_ANNOTATIONS,
|
|
27
|
+
withSearchPagination,
|
|
28
|
+
} from "../utils.js";
|
|
29
|
+
import { PAGINATION_INPUT_SCHEMA, PAGINATION_OUTPUT_SCHEMA } from "./search-input.js";
|
|
30
|
+
|
|
31
|
+
/** Entity types that support the DSL similar_documents() search function. */
|
|
32
|
+
export const SIMILAR_DOCUMENTS_ENTITY_TYPES = ["publications", "grants"] as const;
|
|
33
|
+
|
|
34
|
+
/** Entity type supported by similar_documents. */
|
|
35
|
+
export type SimilarDocumentsEntityType = (typeof SIMILAR_DOCUMENTS_ENTITY_TYPES)[number];
|
|
36
|
+
|
|
37
|
+
/** Year filter field per entity (publications use year; grants use start_year). */
|
|
38
|
+
const YEAR_FIELD: Record<SimilarDocumentsEntityType, string> = {
|
|
39
|
+
publications: "year",
|
|
40
|
+
grants: "start_year",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Builds DSL for a similar_documents search from tool arguments.
|
|
45
|
+
* @param client - Dimensions client
|
|
46
|
+
* @param entityType - publications or grants
|
|
47
|
+
* @param args - Tool arguments (after field-alias resolution)
|
|
48
|
+
* @returns DSL query string
|
|
49
|
+
*/
|
|
50
|
+
export function buildSimilarDocumentsDsl(
|
|
51
|
+
client: DimensionsClient,
|
|
52
|
+
entityType: SimilarDocumentsEntityType,
|
|
53
|
+
args: Record<string, unknown>,
|
|
54
|
+
): string {
|
|
55
|
+
const text = String(args.text ?? "");
|
|
56
|
+
const builder = client.createQueryBuilder().search(entityType).forSimilar(text);
|
|
57
|
+
|
|
58
|
+
const yearField = YEAR_FIELD[entityType];
|
|
59
|
+
if (typeof args.yearFrom === "number") {
|
|
60
|
+
builder.where(yearField, ">=", args.yearFrom);
|
|
61
|
+
}
|
|
62
|
+
if (typeof args.yearTo === "number") {
|
|
63
|
+
builder.where(yearField, "<=", args.yearTo);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const filters = args.filters as ExtendedWhereFilterInput[] | undefined;
|
|
67
|
+
if (filters?.length) {
|
|
68
|
+
applyFilters(builder, filters);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const fields = args.fields as string[] | undefined;
|
|
72
|
+
if (fields?.length) {
|
|
73
|
+
builder.fields(fields);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const sortBy = typeof args.sortBy === "string" ? args.sortBy : "score";
|
|
77
|
+
builder.sort(sortBy, "desc");
|
|
78
|
+
|
|
79
|
+
// Default to 20 for similarity (top-N relevance), not the search_* default of 100.
|
|
80
|
+
const { skip, limit } = resolveSkipAndLimit({
|
|
81
|
+
skip: args.skip as number | undefined,
|
|
82
|
+
page: args.page as number | undefined,
|
|
83
|
+
limit: (args.limit as number | undefined) ?? 20,
|
|
84
|
+
pageSize: args.pageSize as number | undefined,
|
|
85
|
+
});
|
|
86
|
+
builder.limit(limit);
|
|
87
|
+
if (skip > 0) {
|
|
88
|
+
builder.skip(skip);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return builder.build();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Registers the similar_documents tool with the MCP server.
|
|
96
|
+
* @param server - MCP server instance
|
|
97
|
+
* @param client - Dimensions client instance
|
|
98
|
+
*/
|
|
99
|
+
export function registerSimilarDocumentsTool(server: McpServer, client: DimensionsClient): void {
|
|
100
|
+
registerTrackedTool(
|
|
101
|
+
server,
|
|
102
|
+
"similar_documents",
|
|
103
|
+
{
|
|
104
|
+
description:
|
|
105
|
+
"Find publications or grants with similar research topics based on abstract/description text. " +
|
|
106
|
+
"Uses Dimensions concept extraction and weighted concepts search (not vector embeddings). " +
|
|
107
|
+
"Prefer this over execute_dsl for similarity. For a known record: get_by_id / get_by_doi first, " +
|
|
108
|
+
"then pass its abstract/description as text. Supported entityType: publications, grants only.",
|
|
109
|
+
inputSchema: {
|
|
110
|
+
entityType: z
|
|
111
|
+
.enum(SIMILAR_DOCUMENTS_ENTITY_TYPES)
|
|
112
|
+
.describe("Entity type to search (publications or grants)"),
|
|
113
|
+
text: z
|
|
114
|
+
.string()
|
|
115
|
+
.min(1)
|
|
116
|
+
.describe(
|
|
117
|
+
"Abstract, description, or other prose to find similar documents for. " +
|
|
118
|
+
"Longer topical text works better than short keywords.",
|
|
119
|
+
),
|
|
120
|
+
limit: z
|
|
121
|
+
.number()
|
|
122
|
+
.int()
|
|
123
|
+
.min(1)
|
|
124
|
+
.max(SCHEMA_LIMITS.maxLimit)
|
|
125
|
+
.default(20)
|
|
126
|
+
.describe(`Maximum results to return (max ${SCHEMA_LIMITS.maxLimit}, default 20)`),
|
|
127
|
+
...PAGINATION_INPUT_SCHEMA,
|
|
128
|
+
fields: z
|
|
129
|
+
.array(z.string())
|
|
130
|
+
.optional()
|
|
131
|
+
.describe(
|
|
132
|
+
"Fields to return. Accepts aliases or DSL names. Use dimensions://fields/{entity} for the full list.",
|
|
133
|
+
),
|
|
134
|
+
filters: z
|
|
135
|
+
.array(ExtendedWhereFilterSchema)
|
|
136
|
+
.optional()
|
|
137
|
+
.describe("Additional where-clause filters"),
|
|
138
|
+
yearFrom: z
|
|
139
|
+
.number()
|
|
140
|
+
.int()
|
|
141
|
+
.optional()
|
|
142
|
+
.describe("Filter from this year inclusive (publications: year; grants: start_year)"),
|
|
143
|
+
yearTo: z
|
|
144
|
+
.number()
|
|
145
|
+
.int()
|
|
146
|
+
.optional()
|
|
147
|
+
.describe("Filter up to this year inclusive (publications: year; grants: start_year)"),
|
|
148
|
+
sortBy: z
|
|
149
|
+
.string()
|
|
150
|
+
.optional()
|
|
151
|
+
.describe(
|
|
152
|
+
"Sort field (default: score for relevance). Examples: score, times_cited, year, start_year.",
|
|
153
|
+
),
|
|
154
|
+
confirmLargeFetch: z
|
|
155
|
+
.boolean()
|
|
156
|
+
.optional()
|
|
157
|
+
.default(false)
|
|
158
|
+
.describe(
|
|
159
|
+
"Required when skip≥5000, page≥5, or limit=1000 with skip>0. See dimensions://schema/policy.",
|
|
160
|
+
),
|
|
161
|
+
},
|
|
162
|
+
outputSchema: {
|
|
163
|
+
entityType: z.enum(SIMILAR_DOCUMENTS_ENTITY_TYPES).describe("Entity type searched"),
|
|
164
|
+
totalCount: z.number().describe("Total matching records"),
|
|
165
|
+
returnedCount: z.number().describe("Records returned in this response"),
|
|
166
|
+
truncated: z.boolean().optional().describe("True when more results exist beyond this page"),
|
|
167
|
+
truncationWarning: z.string().optional().describe("Warning message when truncated"),
|
|
168
|
+
...PAGINATION_OUTPUT_SCHEMA,
|
|
169
|
+
publications: z
|
|
170
|
+
.array(z.record(z.string(), z.unknown()))
|
|
171
|
+
.optional()
|
|
172
|
+
.describe("Matching publications (when entityType is publications)"),
|
|
173
|
+
grants: z
|
|
174
|
+
.array(z.record(z.string(), z.unknown()))
|
|
175
|
+
.optional()
|
|
176
|
+
.describe("Matching grants (when entityType is grants)"),
|
|
177
|
+
},
|
|
178
|
+
annotations: READ_ONLY_API_ANNOTATIONS,
|
|
179
|
+
},
|
|
180
|
+
withFieldAliases(
|
|
181
|
+
{
|
|
182
|
+
entitySource: { kind: "dynamic", argName: "entityType" },
|
|
183
|
+
fieldArrayArgs: ["fields"],
|
|
184
|
+
fieldStringArgs: ["sortBy"],
|
|
185
|
+
filterArrayArgs: ["filters"],
|
|
186
|
+
},
|
|
187
|
+
async (args) => {
|
|
188
|
+
try {
|
|
189
|
+
const entityType = args.entityType as SimilarDocumentsEntityType;
|
|
190
|
+
const record = args as Record<string, unknown>;
|
|
191
|
+
const { skip, limit } = resolveSkipAndLimit({
|
|
192
|
+
skip: record.skip as number | undefined,
|
|
193
|
+
page: record.page as number | undefined,
|
|
194
|
+
limit: (record.limit as number | undefined) ?? 20,
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
validateSearchPaginationPolicy({
|
|
198
|
+
skip,
|
|
199
|
+
limit,
|
|
200
|
+
confirmLargeFetch: record.confirmLargeFetch as boolean | undefined,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const dsl = buildSimilarDocumentsDsl(client, entityType, {
|
|
204
|
+
...record,
|
|
205
|
+
limit,
|
|
206
|
+
});
|
|
207
|
+
const response = (await client.rawQuery(dsl)) as Record<string, unknown>;
|
|
208
|
+
const parsed = parseEntityResponse(response, entityType as StructuredEntityType);
|
|
209
|
+
const rows = parsed.data as Record<string, unknown>[];
|
|
210
|
+
const resultKey = searchResultKey(entityType as StructuredEntityType);
|
|
211
|
+
|
|
212
|
+
return formatToolResult(
|
|
213
|
+
withSearchPagination(
|
|
214
|
+
{
|
|
215
|
+
entityType,
|
|
216
|
+
totalCount: parsed.totalCount,
|
|
217
|
+
returnedCount: rows.length,
|
|
218
|
+
[resultKey]: rows,
|
|
219
|
+
},
|
|
220
|
+
parsed.totalCount,
|
|
221
|
+
rows.length,
|
|
222
|
+
skip,
|
|
223
|
+
limit,
|
|
224
|
+
),
|
|
225
|
+
);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
return formatErrorResult(error);
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
),
|
|
231
|
+
);
|
|
232
|
+
}
|
|
@@ -8,6 +8,7 @@ import { registerAnalyticsTools } from "../../src/mcp/tools/analytics.js";
|
|
|
8
8
|
import { registerLookupTools } from "../../src/mcp/tools/lookup.js";
|
|
9
9
|
import { registerQueryTools } from "../../src/mcp/tools/query.js";
|
|
10
10
|
import { registerSearchTools } from "../../src/mcp/tools/search.js";
|
|
11
|
+
import { registerSimilarDocumentsTool } from "../../src/mcp/tools/similar-documents.js";
|
|
11
12
|
import { testSchemaStore } from "../helpers/schema-fixture.js";
|
|
12
13
|
import {
|
|
13
14
|
callTool,
|
|
@@ -34,11 +35,12 @@ describe("usage-scenarios", () => {
|
|
|
34
35
|
registerLookupTools(server as never, client as never);
|
|
35
36
|
registerAnalyticsTools(server as never, client as never, schemaStore);
|
|
36
37
|
registerQueryTools(server as never, client as never, schemaStore);
|
|
38
|
+
registerSimilarDocumentsTool(server as never, client as never);
|
|
37
39
|
});
|
|
38
40
|
|
|
39
|
-
it("documents
|
|
40
|
-
expect(USAGE_SCENARIOS).toHaveLength(
|
|
41
|
-
expect(new Set(USAGE_SCENARIOS.map((s) => s.id)).size).toBe(
|
|
41
|
+
it("documents twelve natural-language workflows", () => {
|
|
42
|
+
expect(USAGE_SCENARIOS).toHaveLength(12);
|
|
43
|
+
expect(new Set(USAGE_SCENARIOS.map((s) => s.id)).size).toBe(12);
|
|
42
44
|
});
|
|
43
45
|
|
|
44
46
|
for (const scenario of USAGE_SCENARIOS) {
|
|
@@ -10,6 +10,7 @@ import { lookupSuite } from "./lookup.integration.js";
|
|
|
10
10
|
import { querySuite } from "./query.integration.js";
|
|
11
11
|
import { resourcesSuite } from "./resources.integration.js";
|
|
12
12
|
import { searchSuite } from "./search.integration.js";
|
|
13
|
+
import { similarDocumentsSuite } from "./similar-documents.integration.js";
|
|
13
14
|
|
|
14
15
|
/** All integration test suites, in execution order. */
|
|
15
16
|
export const allSuites: readonly EvalSuite[] = [
|
|
@@ -17,6 +18,7 @@ export const allSuites: readonly EvalSuite[] = [
|
|
|
17
18
|
lookupSuite,
|
|
18
19
|
querySuite,
|
|
19
20
|
functionsSuite,
|
|
21
|
+
similarDocumentsSuite,
|
|
20
22
|
analyticsSuite,
|
|
21
23
|
resourcesSuite,
|
|
22
24
|
];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eval suite for similar_documents tool.
|
|
3
|
+
* @module test/integration/suites/similar-documents
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { arrayMinLength, fieldAtLeast, hasField, isSuccess } from "../assertions.js";
|
|
7
|
+
import type { EvalSuite } from "../types.js";
|
|
8
|
+
|
|
9
|
+
const SAMPLE_ABSTRACT =
|
|
10
|
+
"After spinal cord injury, macrophages infiltrate the lesion site and contribute to both tissue damage and repair processes. Understanding macrophage polarization could lead to novel therapeutic strategies.";
|
|
11
|
+
|
|
12
|
+
const SAMPLE_GRANT_TEXT =
|
|
13
|
+
"Development of novel cancer immunotherapy approaches using checkpoint inhibitors and CAR-T cell engineering for solid tumors.";
|
|
14
|
+
|
|
15
|
+
export const similarDocumentsSuite: EvalSuite = {
|
|
16
|
+
name: "similar_documents",
|
|
17
|
+
description: "Concept-based similar document search for publications and grants",
|
|
18
|
+
cases: [
|
|
19
|
+
{
|
|
20
|
+
name: "similar publications from abstract text",
|
|
21
|
+
tool: "similar_documents",
|
|
22
|
+
args: {
|
|
23
|
+
entityType: "publications",
|
|
24
|
+
text: SAMPLE_ABSTRACT,
|
|
25
|
+
yearFrom: 2016,
|
|
26
|
+
limit: 5,
|
|
27
|
+
fields: ["id", "title", "year"],
|
|
28
|
+
},
|
|
29
|
+
assertions: [
|
|
30
|
+
isSuccess(),
|
|
31
|
+
hasField("totalCount"),
|
|
32
|
+
fieldAtLeast("totalCount", 1),
|
|
33
|
+
arrayMinLength("publications", 1),
|
|
34
|
+
],
|
|
35
|
+
timeout: 60_000,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "similar grants from description text",
|
|
39
|
+
tool: "similar_documents",
|
|
40
|
+
args: {
|
|
41
|
+
entityType: "grants",
|
|
42
|
+
text: SAMPLE_GRANT_TEXT,
|
|
43
|
+
yearFrom: 2020,
|
|
44
|
+
limit: 5,
|
|
45
|
+
fields: ["id", "title"],
|
|
46
|
+
},
|
|
47
|
+
assertions: [isSuccess(), hasField("totalCount"), arrayMinLength("grants", 1)],
|
|
48
|
+
timeout: 60_000,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
package/test/server.test.ts
CHANGED
|
@@ -63,6 +63,7 @@ describe("createMcpServerAsync", () => {
|
|
|
63
63
|
expect(instructions).toContain("search_organizations for institution lookup");
|
|
64
64
|
expect(instructions).toContain("search_source_titles");
|
|
65
65
|
expect(instructions).toContain("search_reports");
|
|
66
|
+
expect(instructions).toContain("similar_documents");
|
|
66
67
|
expect(instructions).toContain("fetch_search_pages");
|
|
67
68
|
expect(instructions).toContain("dimensions://schema/policy");
|
|
68
69
|
});
|
|
@@ -137,6 +138,7 @@ describe("MCP protocol", () => {
|
|
|
137
138
|
const toolNames = tools.tools.map((t) => t.name);
|
|
138
139
|
expect(toolNames).toContain("search_publications");
|
|
139
140
|
expect(toolNames).toContain("fetch_search_pages");
|
|
141
|
+
expect(toolNames).toContain("similar_documents");
|
|
140
142
|
expect(toolNames).toContain("execute_dsl");
|
|
141
143
|
expect(toolNames).not.toContain("validate_dsl");
|
|
142
144
|
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the similar_documents MCP tool.
|
|
3
|
+
* @module test/tools/similar-documents
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
7
|
+
import { registerSimilarDocumentsTool } from "../../src/mcp/tools/similar-documents.js";
|
|
8
|
+
import {
|
|
9
|
+
callTool,
|
|
10
|
+
createMockClient,
|
|
11
|
+
createMockServer,
|
|
12
|
+
parseToolResult,
|
|
13
|
+
} from "../helpers/tool-test-harness.js";
|
|
14
|
+
|
|
15
|
+
/** API-shaped mock response for parseEntityResponse. */
|
|
16
|
+
function apiRows(
|
|
17
|
+
entity: string,
|
|
18
|
+
rows: Record<string, unknown>[],
|
|
19
|
+
totalCount?: number,
|
|
20
|
+
): Record<string, unknown> {
|
|
21
|
+
return {
|
|
22
|
+
[entity]: rows,
|
|
23
|
+
_stats: { total_count: totalCount ?? rows.length },
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const SAMPLE_ABSTRACT =
|
|
28
|
+
"After spinal cord injury, macrophages infiltrate the lesion site and contribute to both tissue damage and repair.";
|
|
29
|
+
|
|
30
|
+
describe("similar_documents tool", () => {
|
|
31
|
+
let handlers: ReturnType<typeof createMockServer>["handlers"];
|
|
32
|
+
let client: ReturnType<typeof createMockClient>;
|
|
33
|
+
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
const { server, handlers: h } = createMockServer();
|
|
36
|
+
client = createMockClient();
|
|
37
|
+
handlers = h;
|
|
38
|
+
registerSimilarDocumentsTool(server as never, client as never);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("registers similar_documents", () => {
|
|
42
|
+
expect(handlers.has("similar_documents")).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("builds similar_documents DSL with default score sort and limit 20", async () => {
|
|
46
|
+
client.rawQuery.mockResolvedValue(apiRows("publications", [{ id: "pub.1", title: "A" }], 1));
|
|
47
|
+
|
|
48
|
+
await callTool(handlers, "similar_documents", {
|
|
49
|
+
entityType: "publications",
|
|
50
|
+
text: SAMPLE_ABSTRACT,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
expect(client.rawQuery).toHaveBeenCalledTimes(1);
|
|
54
|
+
const dsl = client.rawQuery.mock.calls[0][0] as string;
|
|
55
|
+
expect(dsl).toContain("search publications for similar_documents(");
|
|
56
|
+
expect(dsl).toContain(SAMPLE_ABSTRACT);
|
|
57
|
+
expect(dsl).toContain("sort by score desc");
|
|
58
|
+
expect(dsl).toContain("limit 20");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("applies year filters on publications and custom limit/fields", async () => {
|
|
62
|
+
client.rawQuery.mockResolvedValue(apiRows("publications", [], 0));
|
|
63
|
+
|
|
64
|
+
await callTool(handlers, "similar_documents", {
|
|
65
|
+
entityType: "publications",
|
|
66
|
+
text: SAMPLE_ABSTRACT,
|
|
67
|
+
yearFrom: 2018,
|
|
68
|
+
yearTo: 2024,
|
|
69
|
+
limit: 5,
|
|
70
|
+
fields: ["id", "title", "year"],
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const dsl = client.rawQuery.mock.calls[0][0] as string;
|
|
74
|
+
expect(dsl).toContain("year >= 2018");
|
|
75
|
+
expect(dsl).toContain("year <= 2024");
|
|
76
|
+
expect(dsl).toContain("limit 5");
|
|
77
|
+
expect(dsl).toContain("return publications[id+title+year]");
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("uses start_year for grants year filters", async () => {
|
|
81
|
+
client.rawQuery.mockResolvedValue(apiRows("grants", [{ id: "grant.1" }], 1));
|
|
82
|
+
|
|
83
|
+
await callTool(handlers, "similar_documents", {
|
|
84
|
+
entityType: "grants",
|
|
85
|
+
text: "Cancer immunotherapy CAR-T solid tumors",
|
|
86
|
+
yearFrom: 2020,
|
|
87
|
+
limit: 5,
|
|
88
|
+
fields: ["id", "title"],
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const dsl = client.rawQuery.mock.calls[0][0] as string;
|
|
92
|
+
expect(dsl).toContain("search grants for similar_documents(");
|
|
93
|
+
expect(dsl).toContain("start_year >= 2020");
|
|
94
|
+
expect(dsl).toContain("return grants[id+title]");
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("formats publication results", async () => {
|
|
98
|
+
const pubs = [
|
|
99
|
+
{ id: "pub.1", title: "Paper A" },
|
|
100
|
+
{ id: "pub.2", title: "Paper B" },
|
|
101
|
+
];
|
|
102
|
+
client.rawQuery.mockResolvedValue(apiRows("publications", pubs, 2));
|
|
103
|
+
|
|
104
|
+
const result = await callTool(handlers, "similar_documents", {
|
|
105
|
+
entityType: "publications",
|
|
106
|
+
text: SAMPLE_ABSTRACT,
|
|
107
|
+
limit: 5,
|
|
108
|
+
});
|
|
109
|
+
const data = parseToolResult(result);
|
|
110
|
+
|
|
111
|
+
expect(result.isError).toBeUndefined();
|
|
112
|
+
expect(data.entityType).toBe("publications");
|
|
113
|
+
expect(data.totalCount).toBe(2);
|
|
114
|
+
expect(data.returnedCount).toBe(2);
|
|
115
|
+
expect(data.publications).toEqual(pubs);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("formats grant results", async () => {
|
|
119
|
+
const grants = [{ id: "grant.1", title: "Grant A" }];
|
|
120
|
+
client.rawQuery.mockResolvedValue(apiRows("grants", grants, 1));
|
|
121
|
+
|
|
122
|
+
const result = await callTool(handlers, "similar_documents", {
|
|
123
|
+
entityType: "grants",
|
|
124
|
+
text: "Climate adaptation funding",
|
|
125
|
+
limit: 5,
|
|
126
|
+
});
|
|
127
|
+
const data = parseToolResult(result);
|
|
128
|
+
|
|
129
|
+
expect(data.entityType).toBe("grants");
|
|
130
|
+
expect(data.grants).toEqual(grants);
|
|
131
|
+
expect(data.publications).toBeUndefined();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("applies extra filters", async () => {
|
|
135
|
+
client.rawQuery.mockResolvedValue(apiRows("publications", [], 0));
|
|
136
|
+
|
|
137
|
+
await callTool(handlers, "similar_documents", {
|
|
138
|
+
entityType: "publications",
|
|
139
|
+
text: SAMPLE_ABSTRACT,
|
|
140
|
+
filters: [{ field: "type", operator: "=", value: "article" }],
|
|
141
|
+
limit: 5,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const dsl = client.rawQuery.mock.calls[0][0] as string;
|
|
145
|
+
expect(dsl).toContain('type = "article"');
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("escapes quotes in text", async () => {
|
|
149
|
+
client.rawQuery.mockResolvedValue(apiRows("publications", [], 0));
|
|
150
|
+
|
|
151
|
+
await callTool(handlers, "similar_documents", {
|
|
152
|
+
entityType: "publications",
|
|
153
|
+
text: 'Text with "quotes" inside',
|
|
154
|
+
limit: 5,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const dsl = client.rawQuery.mock.calls[0][0] as string;
|
|
158
|
+
expect(dsl).toContain('similar_documents("Text with \\"quotes\\" inside")');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("handles API errors gracefully", async () => {
|
|
162
|
+
client.rawQuery.mockRejectedValueOnce(new Error("Similarity search failed"));
|
|
163
|
+
|
|
164
|
+
const result = await callTool(handlers, "similar_documents", {
|
|
165
|
+
entityType: "publications",
|
|
166
|
+
text: SAMPLE_ABSTRACT,
|
|
167
|
+
});
|
|
168
|
+
const data = parseToolResult(result);
|
|
169
|
+
|
|
170
|
+
expect(result.isError).toBe(true);
|
|
171
|
+
expect(data.error).toBe("Similarity search failed");
|
|
172
|
+
});
|
|
173
|
+
});
|
package/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/http-main.ts","./src/index.ts","./src/main.ts","./src/client/command.ts","./src/client/config.ts","./src/client/deployment-config.ts","./src/client/errors.ts","./src/client/http-client.ts","./src/client/index.ts","./src/client/internal-dsl-client.ts","./src/client/rate-limiter.ts","./src/client/request-retry.ts","./src/client/resolve-api-key-user.ts","./src/client/types.ts","./src/client/usage-context.ts","./src/client/usage-headers.ts","./src/client/auth/config-loaders.ts","./src/client/auth/factory.ts","./src/client/auth/index.ts","./src/client/auth/jwt-utils.ts","./src/client/auth/node.ts","./src/client/auth/schemas.ts","./src/client/auth/types.ts","./src/client/auth/decorators/index.ts","./src/client/auth/decorators/with-caching.ts","./src/client/auth/providers/index.ts","./src/client/auth/providers/jwt-auth-provider.ts","./src/client/config/index.ts","./src/client/config/loader.ts","./src/client/config/node.ts","./src/client/config/schemas.ts","./src/client/config/types.ts","./src/client/config/unified-loader.ts","./src/dsl/client.ts","./src/dsl/create-client.ts","./src/dsl/fluent-query-builder.ts","./src/dsl/index.ts","./src/dsl/pagination.ts","./src/dsl/query-builder.ts","./src/dsl/response-parser.ts","./src/dsl/usage-policy.ts","./src/dsl/commands/apply-filters.ts","./src/dsl/commands/index.ts","./src/dsl/commands/validate-input.ts","./src/dsl/commands/facet/index.ts","./src/dsl/commands/facet/schemas.ts","./src/dsl/commands/functions/ClassifyCommand.ts","./src/dsl/commands/functions/ExtractAffiliationsCommand.ts","./src/dsl/commands/functions/ExtractConceptsCommand.ts","./src/dsl/commands/functions/ExtractGrantsCommand.ts","./src/dsl/commands/functions/index.ts","./src/dsl/schema/cache.ts","./src/dsl/schema/extract.ts","./src/dsl/schema/index.ts","./src/dsl/schema/load.ts","./src/dsl/schema/store.ts","./src/dsl/schema/structured-entities.ts","./src/dsl/schema/summary.ts","./src/dsl/schema/types.ts","./src/dsl/schema/validation.ts","./src/dsl/types/buckets.ts","./src/dsl/types/common.ts","./src/dsl/types/entities.ts","./src/dsl/types/index.ts","./src/dsl/types/return-clauses.ts","./src/dsl/types/special-functions.ts","./src/dsl/types/vocabulary.ts","./src/dsl/utils/escape.ts","./src/dsl/utils/sanitize.ts","./src/dsl/utils/string-utils.ts","./src/dsl/utils/validate-field-name.ts","./src/mcp/batch-fetch.ts","./src/mcp/export-format.ts","./src/mcp/funder-org-names.ts","./src/mcp/http-server.ts","./src/mcp/server.ts","./src/mcp/shared-schema.ts","./src/mcp/usage-tracking.ts","./src/mcp/utils.ts","./src/mcp/examples/dsl-examples.ts","./src/mcp/examples/usage-scenarios.ts","./src/mcp/middleware/field-aliases.ts","./src/mcp/resources/schema.ts","./src/mcp/schema/context.ts","./src/mcp/schema/index.ts","./src/mcp/tools/analytics-filters.ts","./src/mcp/tools/analytics.ts","./src/mcp/tools/fetch-search-pages.ts","./src/mcp/tools/functions.ts","./src/mcp/tools/lookup.ts","./src/mcp/tools/query.ts","./src/mcp/tools/schema.ts","./src/mcp/tools/search-entity-metadata.ts","./src/mcp/tools/search-input.ts","./src/mcp/tools/search.ts"],"version":"5.9.3"}
|
|
1
|
+
{"root":["./src/http-main.ts","./src/index.ts","./src/main.ts","./src/client/command.ts","./src/client/config.ts","./src/client/deployment-config.ts","./src/client/errors.ts","./src/client/http-client.ts","./src/client/index.ts","./src/client/internal-dsl-client.ts","./src/client/rate-limiter.ts","./src/client/request-retry.ts","./src/client/resolve-api-key-user.ts","./src/client/types.ts","./src/client/usage-context.ts","./src/client/usage-headers.ts","./src/client/auth/config-loaders.ts","./src/client/auth/factory.ts","./src/client/auth/index.ts","./src/client/auth/jwt-utils.ts","./src/client/auth/node.ts","./src/client/auth/schemas.ts","./src/client/auth/types.ts","./src/client/auth/decorators/index.ts","./src/client/auth/decorators/with-caching.ts","./src/client/auth/providers/index.ts","./src/client/auth/providers/jwt-auth-provider.ts","./src/client/config/index.ts","./src/client/config/loader.ts","./src/client/config/node.ts","./src/client/config/schemas.ts","./src/client/config/types.ts","./src/client/config/unified-loader.ts","./src/dsl/client.ts","./src/dsl/create-client.ts","./src/dsl/fluent-query-builder.ts","./src/dsl/index.ts","./src/dsl/pagination.ts","./src/dsl/query-builder.ts","./src/dsl/response-parser.ts","./src/dsl/usage-policy.ts","./src/dsl/commands/apply-filters.ts","./src/dsl/commands/index.ts","./src/dsl/commands/validate-input.ts","./src/dsl/commands/facet/index.ts","./src/dsl/commands/facet/schemas.ts","./src/dsl/commands/functions/ClassifyCommand.ts","./src/dsl/commands/functions/ExtractAffiliationsCommand.ts","./src/dsl/commands/functions/ExtractConceptsCommand.ts","./src/dsl/commands/functions/ExtractGrantsCommand.ts","./src/dsl/commands/functions/index.ts","./src/dsl/schema/cache.ts","./src/dsl/schema/extract.ts","./src/dsl/schema/index.ts","./src/dsl/schema/load.ts","./src/dsl/schema/store.ts","./src/dsl/schema/structured-entities.ts","./src/dsl/schema/summary.ts","./src/dsl/schema/types.ts","./src/dsl/schema/validation.ts","./src/dsl/types/buckets.ts","./src/dsl/types/common.ts","./src/dsl/types/entities.ts","./src/dsl/types/index.ts","./src/dsl/types/return-clauses.ts","./src/dsl/types/special-functions.ts","./src/dsl/types/vocabulary.ts","./src/dsl/utils/escape.ts","./src/dsl/utils/sanitize.ts","./src/dsl/utils/string-utils.ts","./src/dsl/utils/validate-field-name.ts","./src/mcp/batch-fetch.ts","./src/mcp/export-format.ts","./src/mcp/funder-org-names.ts","./src/mcp/http-server.ts","./src/mcp/server.ts","./src/mcp/shared-schema.ts","./src/mcp/usage-tracking.ts","./src/mcp/utils.ts","./src/mcp/examples/dsl-examples.ts","./src/mcp/examples/usage-scenarios.ts","./src/mcp/middleware/field-aliases.ts","./src/mcp/resources/schema.ts","./src/mcp/schema/context.ts","./src/mcp/schema/index.ts","./src/mcp/tools/analytics-filters.ts","./src/mcp/tools/analytics.ts","./src/mcp/tools/fetch-search-pages.ts","./src/mcp/tools/functions.ts","./src/mcp/tools/lookup.ts","./src/mcp/tools/query.ts","./src/mcp/tools/schema.ts","./src/mcp/tools/search-entity-metadata.ts","./src/mcp/tools/search-input.ts","./src/mcp/tools/search.ts","./src/mcp/tools/similar-documents.ts"],"version":"5.9.3"}
|