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.
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/PKG-INFO +1 -1
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/server.py +4 -4
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/__init__.py +4 -4
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/latex.py +30 -26
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/PKG-INFO +1 -1
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/pyproject.toml +1 -1
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_latex.py +15 -7
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/LICENSE +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/README.md +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/__init__.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/__main__.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/files.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/latex_templates/agents4science_2025/agents4science_2025.sty +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/latex_templates/agents4science_2025/agents4science_2025.tex +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/llm.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/pdf.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/py.typed +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/anthology_search.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/arxiv_download.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/arxiv_search.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/bitflip.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/document_qa.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/hf_datasets_search.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/py.typed +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/review.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/s2_citations.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/visit_webpage.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/tools/web_search.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp/utils.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/SOURCES.txt +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/dependency_links.txt +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/entry_points.txt +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/requires.txt +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/academia_mcp.egg-info/top_level.txt +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/setup.cfg +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_anthology_search.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_arxiv_download.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_arxiv_search.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_bitflip.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_document_qa.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_extract_json.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_hf_dataset_search.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_review.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_s2_citations.py +0 -0
- {academia_mcp-1.7.4 → academia_mcp-1.8.1}/tests/test_visit_webpage.py +0 -0
- {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.
|
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
|
-
|
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(
|
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
|
-
|
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
|
-
"
|
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
|
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
|
-
|
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
|
-
"
|
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
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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.
|
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
|
@@ -3,10 +3,10 @@ import tempfile
|
|
3
3
|
from pathlib import Path
|
4
4
|
|
5
5
|
from academia_mcp.tools.latex import (
|
6
|
-
|
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
|
27
|
+
def test_latex_compile_latex_from_file() -> None:
|
28
28
|
template = json.loads(get_latex_template("agents4science_2025"))
|
29
|
-
|
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
|
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
|
-
|
42
|
-
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|