@pipeworx/mcp-openreview 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/package.json +1 -1
- package/server.json +1 -1
- package/src/index.ts +16 -9
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
OpenReview MCP — ML conference submissions and reviews (API v2)
|
|
4
4
|
|
|
5
|
-
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to
|
|
5
|
+
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1163+ live data sources.
|
|
6
6
|
|
|
7
7
|
## Tools
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents
|
|
|
13
13
|
| `list_submissions` | Papers submitted to a venue. Pass the venue group id as venue_id. |
|
|
14
14
|
| `get_note` | Single note — paper, review, comment, decision, etc. |
|
|
15
15
|
| `get_paper` | Paper + all child notes (reviews, rebuttal, decision, metareview). Pass the forum id (= paper note id). |
|
|
16
|
-
| `search_notes` | Full-text search across notes. |
|
|
16
|
+
| `search_notes` | Full-text search across OpenReview notes (papers, reviews, decisions) by query string; optionally restrict to a content field (e.g. title, abstract) or filter by author signature; returns matching note ids, titles, and venues. |
|
|
17
17
|
|
|
18
18
|
## Quick Start
|
|
19
19
|
|
|
@@ -29,7 +29,7 @@ Add to your MCP client (Claude Desktop, Cursor, Windsurf, etc.):
|
|
|
29
29
|
}
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
Or connect to the full Pipeworx gateway for access to all
|
|
32
|
+
Or connect to the full Pipeworx gateway for access to all 1163+ data sources:
|
|
33
33
|
|
|
34
34
|
```json
|
|
35
35
|
{
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.pipeworx-io/openreview",
|
|
4
4
|
"title": "Openreview",
|
|
5
5
|
"description": "OpenReview MCP — ML conference submissions and reviews (API v2)",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.1",
|
|
7
7
|
"websiteUrl": "https://pipeworx.io/packs/openreview",
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/pipeworx-io/mcp-openreview",
|
package/src/index.ts
CHANGED
|
@@ -89,7 +89,7 @@ const tools: McpToolExport['tools'] = [
|
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
name: 'search_notes',
|
|
92
|
-
description: 'Full-text search across notes.',
|
|
92
|
+
description: 'Full-text search across OpenReview notes (papers, reviews, decisions) by query string; optionally restrict to a content field (e.g. title, abstract) or filter by author signature; returns matching note ids, titles, and venues.',
|
|
93
93
|
inputSchema: {
|
|
94
94
|
type: 'object',
|
|
95
95
|
properties: {
|
|
@@ -108,13 +108,17 @@ async function callTool(name: string, args: Record<string, unknown>): Promise<un
|
|
|
108
108
|
const apiKey = (args._apiKey as string | undefined)?.trim();
|
|
109
109
|
switch (name) {
|
|
110
110
|
case 'list_venues': {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
// The canonical anonymous-accessible venue list is the members array
|
|
112
|
+
// of the "venues" group (~4000 conferences/workshops).
|
|
113
|
+
const data = (await orGet(apiKey, `/groups?id=venues`)) as {
|
|
114
|
+
groups?: { members?: string[] }[];
|
|
115
|
+
};
|
|
116
|
+
const all = data.groups?.[0]?.members ?? [];
|
|
117
|
+
const query = (args.query as string | undefined)?.toLowerCase();
|
|
118
|
+
const filtered = query ? all.filter((id) => id.toLowerCase().includes(query)) : all;
|
|
119
|
+
const offset = Math.max(0, (args.offset as number) ?? 0);
|
|
120
|
+
const limit = Math.min(1000, Math.max(1, (args.limit as number) ?? 50));
|
|
121
|
+
return { total: filtered.length, venues: filtered.slice(offset, offset + limit) };
|
|
118
122
|
}
|
|
119
123
|
case 'get_venue':
|
|
120
124
|
return orGet(apiKey, `/groups?id=${encodeURIComponent(reqStr(args, 'group_id', '"ICLR.cc/2024/Conference"'))}`);
|
|
@@ -161,7 +165,10 @@ async function callTool(name: string, args: Record<string, unknown>): Promise<un
|
|
|
161
165
|
|
|
162
166
|
async function orGet(apiKey: string | undefined, path: string) {
|
|
163
167
|
const url = `${BASE}${path}`;
|
|
164
|
-
|
|
168
|
+
// A descriptive User-Agent — OpenReview's edge (Cloudflare) 403s the default
|
|
169
|
+
// Workers fetch UA, which surfaced as "unauthorized" from the gateway even
|
|
170
|
+
// though the endpoint is anonymous (works fine with a UA).
|
|
171
|
+
const headers: Record<string, string> = { Accept: 'application/json', 'User-Agent': 'pipeworx-mcp-openreview/1.0 (+https://pipeworx.io)' };
|
|
165
172
|
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
166
173
|
const res = await fetch(url, { headers });
|
|
167
174
|
if (res.status === 401 || res.status === 403) throw new Error('OpenReview: unauthorized');
|