academia-mcp 1.7.4__tar.gz → 1.8.1__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.
Files changed (46) hide show
  1. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/PKG-INFO +1 -1
  2. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/server.py +4 -4
  3. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/__init__.py +4 -4
  4. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/latex.py +30 -26
  5. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/PKG-INFO +1 -1
  6. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/pyproject.toml +1 -1
  7. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_latex.py +15 -7
  8. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/LICENSE +0 -0
  9. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/README.md +0 -0
  10. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/__init__.py +0 -0
  11. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/__main__.py +0 -0
  12. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/files.py +0 -0
  13. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/latex_templates/agents4science_2025/agents4science_2025.sty +0 -0
  14. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/latex_templates/agents4science_2025/agents4science_2025.tex +0 -0
  15. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/llm.py +0 -0
  16. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/pdf.py +0 -0
  17. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/py.typed +0 -0
  18. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/anthology_search.py +0 -0
  19. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/arxiv_download.py +0 -0
  20. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/arxiv_search.py +0 -0
  21. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/bitflip.py +0 -0
  22. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/document_qa.py +0 -0
  23. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/hf_datasets_search.py +0 -0
  24. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/py.typed +0 -0
  25. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/review.py +0 -0
  26. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/s2_citations.py +0 -0
  27. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/visit_webpage.py +0 -0
  28. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/web_search.py +0 -0
  29. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/utils.py +0 -0
  30. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/SOURCES.txt +0 -0
  31. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/dependency_links.txt +0 -0
  32. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/entry_points.txt +0 -0
  33. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/requires.txt +0 -0
  34. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/top_level.txt +0 -0
  35. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/setup.cfg +0 -0
  36. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_anthology_search.py +0 -0
  37. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_arxiv_download.py +0 -0
  38. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_arxiv_search.py +0 -0
  39. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_bitflip.py +0 -0
  40. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_document_qa.py +0 -0
  41. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_extract_json.py +0 -0
  42. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_hf_dataset_search.py +0 -0
  43. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_review.py +0 -0
  44. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_s2_citations.py +0 -0
  45. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_visit_webpage.py +0 -0
  46. {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_web_search.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: academia-mcp
3
- Version: 1.7.4
3
+ Version: 1.8.1
4
4
  Summary: MCP server that provides different tools to search for scientific publications
5
5
  Author-email: Ilya Gusev <phoenixilya@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/IlyaGusev/academia_mcp
@@ -13,10 +13,10 @@ from .tools.hf_datasets_search import hf_datasets_search
13
13
  from .tools.anthology_search import anthology_search
14
14
  from .tools.document_qa import document_qa
15
15
  from .tools.latex import (
16
- compile_latex_from_file,
17
- compile_latex_from_str,
16
+ compile_latex,
18
17
  get_latex_template,
19
18
  get_latex_templates_list,
19
+ read_pdf,
20
20
  )
21
21
  from .tools.web_search import web_search, tavily_web_search, exa_web_search, brave_web_search
22
22
  from .tools.visit_webpage import visit_webpage
@@ -64,12 +64,12 @@ def run(
64
64
  server.add_tool(s2_get_references)
65
65
  server.add_tool(hf_datasets_search)
66
66
  server.add_tool(anthology_search)
67
- server.add_tool(compile_latex_from_file)
68
- server.add_tool(compile_latex_from_str)
67
+ server.add_tool(compile_latex)
69
68
  server.add_tool(get_latex_template)
70
69
  server.add_tool(get_latex_templates_list)
71
70
  server.add_tool(visit_webpage)
72
71
  server.add_tool(download_pdf_paper)
72
+ server.add_tool(read_pdf)
73
73
 
74
74
  if not disable_web_search_tools:
75
75
  if os.getenv("TAVILY_API_KEY"):
@@ -5,10 +5,10 @@ from .hf_datasets_search import hf_datasets_search
5
5
  from .s2_citations import s2_get_references, s2_get_citations
6
6
  from .document_qa import document_qa
7
7
  from .latex import (
8
- compile_latex_from_file,
9
- compile_latex_from_str,
8
+ compile_latex,
10
9
  get_latex_template,
11
10
  get_latex_templates_list,
11
+ read_pdf,
12
12
  )
13
13
  from .web_search import web_search, tavily_web_search, exa_web_search, brave_web_search
14
14
  from .visit_webpage import visit_webpage
@@ -23,8 +23,7 @@ __all__ = [
23
23
  "s2_get_citations",
24
24
  "hf_datasets_search",
25
25
  "document_qa",
26
- "compile_latex_from_file",
27
- "compile_latex_from_str",
26
+ "compile_latex",
28
27
  "get_latex_template",
29
28
  "get_latex_templates_list",
30
29
  "web_search",
@@ -37,4 +36,5 @@ __all__ = [
37
36
  "score_research_proposals",
38
37
  "review_pdf_paper",
39
38
  "download_pdf_paper",
39
+ "read_pdf",
40
40
  ]
@@ -7,6 +7,7 @@ from pathlib import Path
7
7
 
8
8
 
9
9
  from academia_mcp.files import get_workspace_dir, DEFAULT_LATEX_TEMPLATES_DIR_PATH
10
+ from academia_mcp.pdf import parse_pdf_file
10
11
 
11
12
 
12
13
  def get_latex_templates_list() -> str:
@@ -45,7 +46,7 @@ def get_latex_template(template_name: str) -> str:
45
46
  return json.dumps({"template": template_path.read_text(), "style": style_path.read_text()})
46
47
 
47
48
 
48
- def compile_latex_from_file(
49
+ def compile_latex(
49
50
  input_filename: str, output_filename: str = "output.pdf", timeout: int = 60
50
51
  ) -> str:
51
52
  """
@@ -62,24 +63,8 @@ def compile_latex_from_file(
62
63
  if not input_filename_path.exists():
63
64
  input_filename_path = Path(get_workspace_dir()) / input_filename
64
65
  assert input_filename_path.exists(), f"Input file {input_filename} does not exist"
65
- with open(input_filename_path, "r", encoding="utf-8") as file:
66
- latex_code = file.read()
67
- return compile_latex_from_str(latex_code, output_filename, timeout)
66
+ latex_code = input_filename_path.read_text(encoding="utf-8")
68
67
 
69
-
70
- def compile_latex_from_str(
71
- latex_code: str, output_filename: str = "output.pdf", timeout: int = 60
72
- ) -> str:
73
- """
74
- Compile a latex code.
75
-
76
- Returns a string with the result of the compilation.
77
-
78
- Args:
79
- latex_code: The latex code to compile.
80
- output_filename: The path to the output pdf file.
81
- timeout: The timeout for the compilation. 60 seconds by default.
82
- """
83
68
  if shutil.which("pdflatex") is None:
84
69
  return "pdflatex is not installed or not found in PATH."
85
70
 
@@ -115,12 +100,21 @@ def compile_latex_from_str(
115
100
  except Exception:
116
101
  pass
117
102
 
103
+ try:
104
+ bib_source_path = input_filename_path.parent / "references.bib"
105
+ if bib_source_path.exists():
106
+ shutil.copyfile(bib_source_path, temp_dir_path / "references.bib")
107
+ except Exception:
108
+ pass
109
+
118
110
  try:
119
111
  subprocess.run(
120
112
  [
121
- "pdflatex",
113
+ "latexmk",
114
+ "-pdf",
122
115
  "-interaction=nonstopmode",
123
116
  "-file-line-error",
117
+ "-diagnostics",
124
118
  tex_filename,
125
119
  ],
126
120
  cwd=str(temp_dir_path),
@@ -133,13 +127,10 @@ def compile_latex_from_str(
133
127
  return f"Compilation timed out after {timeout} seconds"
134
128
  except subprocess.CalledProcessError as e:
135
129
  combined_output = (e.stdout or "") + "\n" + (e.stderr or "")
136
- error_lines = [
137
- line
138
- for line in combined_output.split("\n")
139
- if ("error" in line.lower() or "!" in line)
140
- ]
141
- if error_lines:
142
- return "Compilation failed. LaTeX errors:\n" + "\n".join(error_lines)
130
+ log_path = temp_dir_path / "temp.log"
131
+ if log_path.exists():
132
+ log_content = log_path.read_text(encoding="utf-8", errors="ignore")
133
+ combined_output = combined_output + "\n\ntemp.log content:\n" + log_content
143
134
  return f"Compilation failed. Full LaTeX output:\n{combined_output}"
144
135
 
145
136
  pdf_path = temp_dir_path / pdf_filename
@@ -154,3 +145,16 @@ def compile_latex_from_str(
154
145
  )
155
146
  except Exception as e:
156
147
  return f"Compilation failed due to an unexpected error: {e}"
148
+
149
+
150
+ def read_pdf(pdf_path: str) -> str:
151
+ """
152
+ Read a PDF file to text from the file system.
153
+
154
+ Args:
155
+ pdf_path: The path to the pdf file in the working directory.
156
+
157
+ Returns a JSON-serialized list of strings where each string is a page of the pdf file.
158
+ """
159
+ full_path = Path(get_workspace_dir()) / pdf_path
160
+ return json.dumps(parse_pdf_file(full_path))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: academia-mcp
3
- Version: 1.7.4
3
+ Version: 1.8.1
4
4
  Summary: MCP server that provides different tools to search for scientific publications
5
5
  Author-email: Ilya Gusev <phoenixilya@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/IlyaGusev/academia_mcp
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "academia-mcp"
7
- version = "1.7.4"
7
+ version = "1.8.1"
8
8
  description = "MCP server that provides different tools to search for scientific publications"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -3,10 +3,10 @@ import tempfile
3
3
  from pathlib import Path
4
4
 
5
5
  from academia_mcp.tools.latex import (
6
- compile_latex_from_file,
7
- compile_latex_from_str,
6
+ compile_latex,
8
7
  get_latex_template,
9
8
  get_latex_templates_list,
9
+ read_pdf,
10
10
  )
11
11
 
12
12
 
@@ -24,13 +24,19 @@ def test_latex_get_latex_template() -> None:
24
24
  assert result["style"] is not None
25
25
 
26
26
 
27
- def test_latex_compile_latex_from_str() -> None:
27
+ def test_latex_compile_latex_from_file() -> None:
28
28
  template = json.loads(get_latex_template("agents4science_2025"))
29
- result = compile_latex_from_str(template["template"], "test.pdf")
29
+ with tempfile.TemporaryDirectory() as temp_dir:
30
+ temp_dir_path = Path(temp_dir)
31
+ tex_filename = "temp.tex"
32
+ tex_file_path = temp_dir_path / tex_filename
33
+ pdf_filename = "test.pdf"
34
+ tex_file_path.write_text(template["template"], encoding="utf-8")
35
+ result = compile_latex(str(tex_file_path), pdf_filename)
30
36
  assert "Compilation successful" in result
31
37
 
32
38
 
33
- def test_latex_compile_latex_from_file() -> None:
39
+ def test_latex_read_pdf() -> None:
34
40
  template = json.loads(get_latex_template("agents4science_2025"))
35
41
  with tempfile.TemporaryDirectory() as temp_dir:
36
42
  temp_dir_path = Path(temp_dir)
@@ -38,5 +44,7 @@ def test_latex_compile_latex_from_file() -> None:
38
44
  tex_file_path = temp_dir_path / tex_filename
39
45
  pdf_filename = "test.pdf"
40
46
  tex_file_path.write_text(template["template"], encoding="utf-8")
41
- result = compile_latex_from_file(str(tex_file_path), pdf_filename)
42
- assert "Compilation successful" in result
47
+ compile_latex(str(tex_file_path), pdf_filename)
48
+ read_result = json.loads(read_pdf(pdf_filename))
49
+ assert read_result
50
+ assert "Page 1" in read_result[0]
File without changes
File without changes
File without changes