priorwork-mcp 0.1.0__tar.gz

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.
@@ -0,0 +1,58 @@
1
+ # Ignore NeurIPS papers directory
2
+ *_papers/
3
+ *_paper_hashes.json
4
+ paper_sections_index*
5
+
6
+ # Data directories (PDFs, indexes, text store)
7
+ data/
8
+ tests/test_data/
9
+
10
+ # Ignore environment files
11
+ .env
12
+ .env.*
13
+
14
+ # Python virtual environment
15
+ .venv/
16
+ venv/
17
+ ENV/
18
+
19
+ # Python cache files
20
+ __pycache__/
21
+ *.py[cod]
22
+ *$py.class
23
+
24
+ # Package build artifacts
25
+ *.egg-info/
26
+ build/
27
+ dist/
28
+
29
+ # Index files (large)
30
+ *.zip
31
+ *.index
32
+ test_index*/
33
+ paper_index_gte_temp/
34
+
35
+ # Log files
36
+ *.log
37
+
38
+ # macOS system files
39
+ .DS_Store
40
+ .DS_Store?
41
+ ._*
42
+ .Spotlight-V100
43
+ .Trashes
44
+ ehthumbs.db
45
+ Thumbs.db # Exclude PDFs from git tracking
46
+ tests/test_data/citation_test_pdfs/*.pdf
47
+
48
+ # Temporary and generated files
49
+ .coverage
50
+ coverage.xml
51
+ test_confidence_display.py
52
+
53
+ # Test generation script (one-time use, requires full corpus)
54
+ generate_citation_test.py
55
+
56
+ # IDE settings
57
+ .vscode/
58
+ usage.db
@@ -0,0 +1,77 @@
1
+ Metadata-Version: 2.4
2
+ Name: priorwork-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for priorwork.fyi — academic ML paper search for Claude Code and Cursor
5
+ Project-URL: Homepage, https://priorwork.fyi
6
+ Project-URL: Repository, https://github.com/stefanmagureanu/Steference-review
7
+ License: MIT
8
+ Keywords: academic-search,machine-learning,mcp,model-context-protocol,papers,semantic-search
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
14
+ Requires-Python: >=3.9
15
+ Requires-Dist: httpx>=0.24.0
16
+ Requires-Dist: mcp>=1.2.0
17
+ Description-Content-Type: text/markdown
18
+
19
+ # priorwork-mcp
20
+
21
+ MCP server for [priorwork.fyi](https://priorwork.fyi) — semantic search over 114,000+ papers
22
+ from major ML, NLP, and Computer Vision conferences (NeurIPS, CVPR, ICML, ICLR, ACL, EMNLP,
23
+ ICCV, AISTATS, and more), directly from Claude Code, Cursor, or any MCP client.
24
+
25
+ ## Tools
26
+
27
+ | Tool | Description |
28
+ |---|---|
29
+ | `search_papers` | Semantic search from a natural-language query — returns ranked papers with authors, venue, year, similarity score, download URL, and abstract snippet |
30
+ | `search_by_pdf_url` | Give it a public PDF link (e.g. an arXiv PDF) and get semantically similar papers from the index |
31
+ | `list_indexes` | List the available paper indexes and their sizes |
32
+
33
+ ## Setup
34
+
35
+ ### Claude Code
36
+
37
+ ```bash
38
+ claude mcp add priorwork -- uvx priorwork-mcp
39
+ ```
40
+
41
+ ### Cursor / other MCP clients
42
+
43
+ Add to your MCP configuration:
44
+
45
+ ```json
46
+ {
47
+ "mcpServers": {
48
+ "priorwork": {
49
+ "command": "uvx",
50
+ "args": ["priorwork-mcp"]
51
+ }
52
+ }
53
+ }
54
+ ```
55
+
56
+ ## Configuration
57
+
58
+ Configuration is via environment variables (pass with `-e KEY=value` in `claude mcp add`,
59
+ or an `"env"` block in JSON configs):
60
+
61
+ | Variable | Required | Description |
62
+ |---|---|---|
63
+ | `PRIORWORK_API_KEY` | No | API key from priorwork.fyi (enables authenticated features) |
64
+ | `PRIORWORK_API_URL` | No | Override the API base URL (default `https://priorwork.fyi`) |
65
+
66
+ ## Example
67
+
68
+ > "Find prior work on spatiotemporal forecasting with graph neural networks"
69
+
70
+ ```
71
+ 1. Taming Local Effects in Graph-based Spatiotemporal Forecasting — Andrea Cini, et al. (2023 · NeurIPS) [score: 0.802]
72
+ 2. FourierGNN: Rethinking Multivariate Time Series Forecasting from a Pure Graph Perspective — ...
73
+ ```
74
+
75
+ ## License
76
+
77
+ MIT
@@ -0,0 +1,59 @@
1
+ # priorwork-mcp
2
+
3
+ MCP server for [priorwork.fyi](https://priorwork.fyi) — semantic search over 114,000+ papers
4
+ from major ML, NLP, and Computer Vision conferences (NeurIPS, CVPR, ICML, ICLR, ACL, EMNLP,
5
+ ICCV, AISTATS, and more), directly from Claude Code, Cursor, or any MCP client.
6
+
7
+ ## Tools
8
+
9
+ | Tool | Description |
10
+ |---|---|
11
+ | `search_papers` | Semantic search from a natural-language query — returns ranked papers with authors, venue, year, similarity score, download URL, and abstract snippet |
12
+ | `search_by_pdf_url` | Give it a public PDF link (e.g. an arXiv PDF) and get semantically similar papers from the index |
13
+ | `list_indexes` | List the available paper indexes and their sizes |
14
+
15
+ ## Setup
16
+
17
+ ### Claude Code
18
+
19
+ ```bash
20
+ claude mcp add priorwork -- uvx priorwork-mcp
21
+ ```
22
+
23
+ ### Cursor / other MCP clients
24
+
25
+ Add to your MCP configuration:
26
+
27
+ ```json
28
+ {
29
+ "mcpServers": {
30
+ "priorwork": {
31
+ "command": "uvx",
32
+ "args": ["priorwork-mcp"]
33
+ }
34
+ }
35
+ }
36
+ ```
37
+
38
+ ## Configuration
39
+
40
+ Configuration is via environment variables (pass with `-e KEY=value` in `claude mcp add`,
41
+ or an `"env"` block in JSON configs):
42
+
43
+ | Variable | Required | Description |
44
+ |---|---|---|
45
+ | `PRIORWORK_API_KEY` | No | API key from priorwork.fyi (enables authenticated features) |
46
+ | `PRIORWORK_API_URL` | No | Override the API base URL (default `https://priorwork.fyi`) |
47
+
48
+ ## Example
49
+
50
+ > "Find prior work on spatiotemporal forecasting with graph neural networks"
51
+
52
+ ```
53
+ 1. Taming Local Effects in Graph-based Spatiotemporal Forecasting — Andrea Cini, et al. (2023 · NeurIPS) [score: 0.802]
54
+ 2. FourierGNN: Rethinking Multivariate Time Series Forecasting from a Pure Graph Perspective — ...
55
+ ```
56
+
57
+ ## License
58
+
59
+ MIT
@@ -0,0 +1,138 @@
1
+ """MCP server for priorwork.fyi — academic ML paper search.
2
+
3
+ Set PRIORWORK_API_KEY to your API key from priorwork.fyi.
4
+ Set PRIORWORK_API_URL to override the base URL (optional).
5
+ """
6
+
7
+ import os
8
+ import httpx
9
+ from mcp.server.fastmcp import FastMCP
10
+
11
+ API_URL = os.getenv("PRIORWORK_API_URL", "https://priorwork.fyi").rstrip("/")
12
+ API_KEY = os.getenv("PRIORWORK_API_KEY", "")
13
+
14
+ mcp = FastMCP("priorwork")
15
+
16
+
17
+ def _headers() -> dict:
18
+ return {"X-API-Key": API_KEY} if API_KEY else {}
19
+
20
+
21
+ def _format_results(results: list) -> str:
22
+ if not results:
23
+ return "No results found."
24
+ lines = []
25
+ for i, r in enumerate(results, 1):
26
+ title = r.get("title", "Unknown title")
27
+ authors = r.get("authors", "")
28
+ year = r.get("year", "")
29
+ venue = r.get("conference") or r.get("venue", "")
30
+ score = r.get("similarity", r.get("score", 0))
31
+ url = r.get("download_url") or r.get("url", "")
32
+ abstract = r.get("abstract", "")
33
+
34
+ header = f"{i}. {title}"
35
+ if authors:
36
+ header += f" — {authors}"
37
+ meta = " · ".join(filter(None, [str(year) if year else "", venue]))
38
+ if meta:
39
+ header += f" ({meta})"
40
+ header += f" [score: {score:.3f}]"
41
+ lines.append(header)
42
+ if url:
43
+ lines.append(f" {url}")
44
+ if abstract:
45
+ lines.append(f" {abstract[:250].strip()}...")
46
+ lines.append("")
47
+ return "\n".join(lines).strip()
48
+
49
+
50
+ def _flatten_results(data: dict) -> list:
51
+ # PDF search responses nest results per uploaded file: {"files": [{"results": [...]}]}
52
+ if isinstance(data.get("files"), list):
53
+ flat: list = []
54
+ for f in data["files"]:
55
+ if isinstance(f, dict):
56
+ flat.extend(f.get("results") or [])
57
+ return flat
58
+ results = data.get("results", [])
59
+ if isinstance(results, dict):
60
+ flat = []
61
+ for v in results.values():
62
+ flat.extend(v if isinstance(v, list) else [])
63
+ return flat
64
+ return results
65
+
66
+
67
+ @mcp.tool()
68
+ def search_papers(query: str, max_results: int = 10) -> str:
69
+ """Search for academic ML papers semantically related to a text query.
70
+
71
+ Returns a ranked list of papers with titles, authors, year, venue,
72
+ similarity score, download URL, and abstract snippet.
73
+
74
+ Args:
75
+ query: Natural language description of the research topic or question.
76
+ max_results: Number of results to return (1-10, default 10).
77
+ """
78
+ max_results = max(1, min(10, max_results))
79
+ with httpx.Client(timeout=30) as client:
80
+ resp = client.post(
81
+ f"{API_URL}/api/query",
82
+ json={"query": query, "max_results": max_results},
83
+ headers=_headers(),
84
+ )
85
+ resp.raise_for_status()
86
+ return _format_results(_flatten_results(resp.json()))
87
+
88
+
89
+ @mcp.tool()
90
+ def search_by_pdf_url(url: str, max_results: int = 10) -> str:
91
+ """Search for academic ML papers related to a paper at a given PDF URL.
92
+
93
+ Downloads the PDF from the URL (e.g. an arXiv PDF link), extracts its
94
+ content, and returns semantically similar papers from the index.
95
+
96
+ Args:
97
+ url: Public URL to a PDF file (http or https).
98
+ max_results: Number of results to return (1-10, default 10).
99
+ """
100
+ max_results = max(1, min(10, max_results))
101
+ with httpx.Client(timeout=60) as client:
102
+ resp = client.post(
103
+ f"{API_URL}/api/search/pdf-url",
104
+ json={"url": url, "max_results": max_results},
105
+ headers=_headers(),
106
+ )
107
+ resp.raise_for_status()
108
+ return _format_results(_flatten_results(resp.json()))
109
+
110
+
111
+ @mcp.tool()
112
+ def list_indexes() -> str:
113
+ """List the paper indexes available on priorwork.fyi and their paper counts."""
114
+ with httpx.Client(timeout=10) as client:
115
+ resp = client.get(f"{API_URL}/api/indexes", headers=_headers())
116
+ resp.raise_for_status()
117
+ data = resp.json()
118
+ indexes = data.get("indexes", [])
119
+ if not indexes:
120
+ return "No indexes available."
121
+ lines = []
122
+ for idx in indexes:
123
+ name = idx.get("name", "unknown")
124
+ count = idx.get("paper_count", "?")
125
+ provider = idx.get("provider", "")
126
+ line = f" - {name}: {count:,} papers" if isinstance(count, int) else f" - {name}: {count} papers"
127
+ if provider:
128
+ line += f" ({provider})"
129
+ lines.append(line)
130
+ return "Available indexes:\n" + "\n".join(lines)
131
+
132
+
133
+ def main():
134
+ mcp.run()
135
+
136
+
137
+ if __name__ == "__main__":
138
+ main()
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "priorwork-mcp"
7
+ version = "0.1.0"
8
+ description = "MCP server for priorwork.fyi — academic ML paper search for Claude Code and Cursor"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = {text = "MIT"}
12
+ keywords = ["mcp", "model-context-protocol", "academic-search", "machine-learning", "papers", "semantic-search"]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Science/Research",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
19
+ ]
20
+ dependencies = [
21
+ "mcp>=1.2.0",
22
+ "httpx>=0.24.0",
23
+ ]
24
+
25
+ [project.scripts]
26
+ priorwork-mcp = "priorwork_mcp:main"
27
+
28
+ [project.urls]
29
+ Homepage = "https://priorwork.fyi"
30
+ Repository = "https://github.com/stefanmagureanu/Steference-review"
31
+
32
+ [tool.hatch.build.targets.wheel]
33
+ packages = ["priorwork_mcp.py"]
34
+
35
+ [tool.hatch.build.targets.sdist]
36
+ include = ["priorwork_mcp.py", "README.md", "pyproject.toml"]