academia-mcp 1.11.3__tar.gz → 1.11.4__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.11.3 → academia_mcp-1.11.4}/PKG-INFO +12 -8
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/README.md +6 -2
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/server.py +1 -1
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/__init__.py +1 -1
- academia_mcp-1.11.3/academia_mcp/tools/show_image.py → academia_mcp-1.11.4/academia_mcp/tools/image_processing.py +74 -6
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp.egg-info/PKG-INFO +12 -8
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp.egg-info/SOURCES.txt +2 -2
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp.egg-info/requires.txt +5 -5
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/pyproject.toml +6 -6
- academia_mcp-1.11.3/tests/test_show_image.py → academia_mcp-1.11.4/tests/test_image_processing.py +6 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_visit_webpage.py +0 -2
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/LICENSE +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/__init__.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/__main__.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/files.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/latex_templates/agents4science_2025/agents4science_2025.sty +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/latex_templates/agents4science_2025/agents4science_2025.tex +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/llm.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/pdf.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/py.typed +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/settings.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/anthology_search.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/arxiv_download.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/arxiv_search.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/bitflip.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/document_qa.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/hf_datasets_search.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/latex.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/py.typed +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/review.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/s2.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/speech_to_text.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/visit_webpage.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/web_search.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/tools/yt_transcript.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp/utils.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp.egg-info/dependency_links.txt +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp.egg-info/entry_points.txt +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/academia_mcp.egg-info/top_level.txt +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/setup.cfg +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_anthology_search.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_arxiv_download.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_arxiv_search.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_bitflip.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_document_qa.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_extract_json.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_hf_dataset_search.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_latex.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_review.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_s2.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_server.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_speech_to_text.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_web_search.py +0 -0
- {academia_mcp-1.11.3 → academia_mcp-1.11.4}/tests/test_yt_transcript.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: academia-mcp
|
3
|
-
Version: 1.11.
|
3
|
+
Version: 1.11.4
|
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
|
@@ -12,16 +12,14 @@ Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
13
13
|
Requires-Dist: mcp>=1.10.1
|
14
14
|
Requires-Dist: xmltodict>=0.14.0
|
15
|
-
Requires-Dist: types-xmltodict>=0.14.0
|
16
15
|
Requires-Dist: requests>=2.32.0
|
17
|
-
Requires-Dist: types-requests>=2.32.0
|
18
16
|
Requires-Dist: pypdf>=5.1.0
|
19
17
|
Requires-Dist: beautifulsoup4>=4.12.0
|
20
|
-
Requires-Dist: types-beautifulsoup4>=4.12.0
|
21
18
|
Requires-Dist: markdownify==0.14.1
|
19
|
+
Requires-Dist: types-xmltodict>=0.14.0
|
20
|
+
Requires-Dist: types-requests>=2.32.0
|
21
|
+
Requires-Dist: types-beautifulsoup4>=4.12.0
|
22
22
|
Requires-Dist: acl-anthology==0.5.2
|
23
|
-
Requires-Dist: markdown==3.7.0
|
24
|
-
Requires-Dist: types-markdown==3.7.0.20250322
|
25
23
|
Requires-Dist: huggingface-hub>=0.32.4
|
26
24
|
Requires-Dist: fire>=0.7.0
|
27
25
|
Requires-Dist: openai>=1.97.1
|
@@ -31,6 +29,8 @@ Requires-Dist: pymupdf>=1.26.4
|
|
31
29
|
Requires-Dist: pillow>=11.3.0
|
32
30
|
Requires-Dist: pydantic-settings>=2.6.0
|
33
31
|
Requires-Dist: youtube-transcript-api>=1.2.2
|
32
|
+
Requires-Dist: paddlepaddle>=3.2.0
|
33
|
+
Requires-Dist: paddleocr>=3.2.0
|
34
34
|
Dynamic: license-file
|
35
35
|
|
36
36
|
# Academia MCP
|
@@ -70,12 +70,16 @@ make install
|
|
70
70
|
### Quickstart
|
71
71
|
- Run over HTTP (default transport):
|
72
72
|
```bash
|
73
|
+
python -m academia_mcp --transport streamable-http
|
74
|
+
# OR
|
73
75
|
uv run -m academia_mcp --transport streamable-http
|
74
76
|
```
|
75
77
|
|
76
78
|
- Run over stdio (for local MCP clients like Claude Desktop):
|
77
79
|
```bash
|
78
80
|
python -m academia_mcp --transport stdio
|
81
|
+
# OR
|
82
|
+
uv run -m academia_mcp --transport stdio
|
79
83
|
```
|
80
84
|
|
81
85
|
Notes:
|
@@ -122,7 +126,7 @@ Availability notes:
|
|
122
126
|
- Set one or more of `EXA_API_KEY`, `BRAVE_API_KEY`, `TAVILY_API_KEY` to enable `web_search` and provider tools.
|
123
127
|
|
124
128
|
### Environment variables
|
125
|
-
Set as needed depending on which tools you use:
|
129
|
+
Set as needed, depending on which tools you use:
|
126
130
|
|
127
131
|
- `OPENROUTER_API_KEY`: required for LLM-related tools.
|
128
132
|
- `BASE_URL`: override OpenRouter base URL.
|
@@ -152,7 +156,7 @@ docker run --rm -p 5056:5056 \
|
|
152
156
|
academia_mcp
|
153
157
|
```
|
154
158
|
|
155
|
-
Or use existing image: `phoenix120/academia_mcp`
|
159
|
+
Or use existing image: [`phoenix120/academia_mcp`](https://hub.docker.com/repository/docker/phoenix120/academia_mcp)
|
156
160
|
|
157
161
|
### Examples
|
158
162
|
- [Comprehensive report screencast (YouTube)](https://www.youtube.com/watch?v=4bweqQcN6w8)
|
@@ -35,12 +35,16 @@ make install
|
|
35
35
|
### Quickstart
|
36
36
|
- Run over HTTP (default transport):
|
37
37
|
```bash
|
38
|
+
python -m academia_mcp --transport streamable-http
|
39
|
+
# OR
|
38
40
|
uv run -m academia_mcp --transport streamable-http
|
39
41
|
```
|
40
42
|
|
41
43
|
- Run over stdio (for local MCP clients like Claude Desktop):
|
42
44
|
```bash
|
43
45
|
python -m academia_mcp --transport stdio
|
46
|
+
# OR
|
47
|
+
uv run -m academia_mcp --transport stdio
|
44
48
|
```
|
45
49
|
|
46
50
|
Notes:
|
@@ -87,7 +91,7 @@ Availability notes:
|
|
87
91
|
- Set one or more of `EXA_API_KEY`, `BRAVE_API_KEY`, `TAVILY_API_KEY` to enable `web_search` and provider tools.
|
88
92
|
|
89
93
|
### Environment variables
|
90
|
-
Set as needed depending on which tools you use:
|
94
|
+
Set as needed, depending on which tools you use:
|
91
95
|
|
92
96
|
- `OPENROUTER_API_KEY`: required for LLM-related tools.
|
93
97
|
- `BASE_URL`: override OpenRouter base URL.
|
@@ -117,7 +121,7 @@ docker run --rm -p 5056:5056 \
|
|
117
121
|
academia_mcp
|
118
122
|
```
|
119
123
|
|
120
|
-
Or use existing image: `phoenix120/academia_mcp`
|
124
|
+
Or use existing image: [`phoenix120/academia_mcp`](https://hub.docker.com/repository/docker/phoenix120/academia_mcp)
|
121
125
|
|
122
126
|
### Examples
|
123
127
|
- [Comprehensive report screencast (YouTube)](https://www.youtube.com/watch?v=4bweqQcN6w8)
|
@@ -40,7 +40,7 @@ from academia_mcp.tools.bitflip import (
|
|
40
40
|
score_research_proposals,
|
41
41
|
)
|
42
42
|
from academia_mcp.tools.review import review_pdf_paper, download_pdf_paper
|
43
|
-
from academia_mcp.tools.
|
43
|
+
from academia_mcp.tools.image_processing import show_image, describe_image
|
44
44
|
from academia_mcp.tools.speech_to_text import speech_to_text
|
45
45
|
from academia_mcp.tools.yt_transcript import yt_transcript
|
46
46
|
|
@@ -14,7 +14,7 @@ from .web_search import web_search, tavily_web_search, exa_web_search, brave_web
|
|
14
14
|
from .visit_webpage import visit_webpage
|
15
15
|
from .bitflip import extract_bitflip_info, generate_research_proposals, score_research_proposals
|
16
16
|
from .review import review_pdf_paper, download_pdf_paper, review_pdf_paper_by_url
|
17
|
-
from .
|
17
|
+
from .image_processing import show_image, describe_image
|
18
18
|
from .speech_to_text import speech_to_text
|
19
19
|
from .yt_transcript import yt_transcript
|
20
20
|
|
@@ -1,16 +1,28 @@
|
|
1
|
+
import asyncio
|
1
2
|
import base64
|
2
|
-
|
3
|
+
import contextlib
|
4
|
+
import json
|
5
|
+
import logging
|
6
|
+
import os
|
7
|
+
import threading
|
3
8
|
from io import BytesIO
|
4
|
-
from
|
9
|
+
from pathlib import Path
|
5
10
|
from textwrap import dedent
|
11
|
+
from typing import Dict, List, Optional, Any
|
6
12
|
|
7
13
|
import httpx
|
14
|
+
from paddleocr import PaddleOCR # type: ignore
|
8
15
|
from PIL import Image
|
16
|
+
from pydantic import BaseModel
|
9
17
|
|
10
18
|
from academia_mcp.files import get_workspace_dir
|
19
|
+
from academia_mcp.llm import ChatMessage, llm_acall
|
11
20
|
from academia_mcp.settings import settings
|
12
|
-
from academia_mcp.llm import llm_acall, ChatMessage
|
13
21
|
|
22
|
+
paddlex_logger = logging.getLogger("paddlex")
|
23
|
+
paddleocr_logger = logging.getLogger("paddleocr")
|
24
|
+
paddlex_logger.setLevel(logging.ERROR)
|
25
|
+
paddleocr_logger.setLevel(logging.ERROR)
|
14
26
|
|
15
27
|
DESCRIBE_PROMPTS = {
|
16
28
|
"general": "Provide a general description of this image. Focus on the main subjects, colors, and overall scene.",
|
@@ -37,16 +49,64 @@ DESCRIBE_PROMPTS = {
|
|
37
49
|
- If layout is multi-column or tabular, reconstruct lines top-to-bottom, left-to-right; use line breaks between blocks.
|
38
50
|
- For any uncertain or low-confidence characters, mark with a '?' and include a note.
|
39
51
|
- After the raw extraction, provide a clean, normalized version (fixing obvious OCR artifacts) as a separate section.
|
40
|
-
Return
|
52
|
+
Return three sections:
|
53
|
+
[GENERAL IMAGE DESCRIPTION]
|
54
|
+
...
|
41
55
|
[RAW TRANSCRIPTION]
|
42
56
|
...
|
43
|
-
[NORMALIZED]
|
57
|
+
[NORMALIZED TRANSCRIPTION]
|
44
58
|
...
|
45
59
|
"""
|
46
60
|
),
|
47
61
|
}
|
48
62
|
|
49
63
|
|
64
|
+
class OCRBox(BaseModel): # type: ignore
|
65
|
+
poly: List[List[float]]
|
66
|
+
text: str
|
67
|
+
score: float
|
68
|
+
|
69
|
+
|
70
|
+
class OCRSingleton:
|
71
|
+
instance: Optional[PaddleOCR] = None
|
72
|
+
lock: threading.Lock = threading.Lock()
|
73
|
+
|
74
|
+
@classmethod
|
75
|
+
def get(cls) -> PaddleOCR:
|
76
|
+
if cls.instance is not None:
|
77
|
+
return cls.instance
|
78
|
+
with cls.lock:
|
79
|
+
if cls.instance is None:
|
80
|
+
with open(os.devnull, "w") as devnull:
|
81
|
+
with contextlib.redirect_stderr(devnull):
|
82
|
+
cls.instance = PaddleOCR(
|
83
|
+
use_doc_orientation_classify=False,
|
84
|
+
use_doc_unwarping=False,
|
85
|
+
use_textline_orientation=False,
|
86
|
+
)
|
87
|
+
return cls.instance
|
88
|
+
|
89
|
+
|
90
|
+
async def _run_ocr(path: str) -> Dict[str, Any]:
|
91
|
+
def _sync_ocr(path: str) -> Dict[str, Any]:
|
92
|
+
try:
|
93
|
+
ocr = OCRSingleton.get()
|
94
|
+
with open(os.devnull, "w") as devnull:
|
95
|
+
with contextlib.redirect_stderr(devnull):
|
96
|
+
result = ocr.predict(input=path)[0]
|
97
|
+
rec_texts = result["rec_texts"]
|
98
|
+
rec_scores = result["rec_scores"]
|
99
|
+
rec_polys = result["rec_polys"]
|
100
|
+
except Exception as e:
|
101
|
+
return {"error": str(e)}
|
102
|
+
items = []
|
103
|
+
for poly, text, score in zip(rec_polys, rec_texts, rec_scores):
|
104
|
+
items.append(OCRBox(poly=poly, text=text, score=score).model_dump())
|
105
|
+
return {"boxes": items}
|
106
|
+
|
107
|
+
return await asyncio.to_thread(_sync_ocr, path)
|
108
|
+
|
109
|
+
|
50
110
|
def show_image(path: str) -> Dict[str, str]:
|
51
111
|
"""
|
52
112
|
Reads an image from the specified URL or from the current work directory.
|
@@ -91,7 +151,7 @@ async def describe_image(
|
|
91
151
|
- "general": General description of the image
|
92
152
|
- "detailed": Detailed analysis of the image
|
93
153
|
- "chess": Analysis of a chess position
|
94
|
-
- "text": Extract and describe text or numbers
|
154
|
+
- "text": Extract and describe text or numbers with an OCR pipeline.
|
95
155
|
- "custom": Custom description based on user prompt
|
96
156
|
"""
|
97
157
|
image_base64 = show_image(path)["image_base64"]
|
@@ -116,4 +176,12 @@ async def describe_image(
|
|
116
176
|
messages=[ChatMessage(role="user", content=content)],
|
117
177
|
**llm_kwargs,
|
118
178
|
)
|
179
|
+
if description_type == "text":
|
180
|
+
ocr_response = await _run_ocr(path)
|
181
|
+
response = json.dumps(
|
182
|
+
{
|
183
|
+
"vlm_response": response,
|
184
|
+
"ocr_response": ocr_response if ocr_response else [],
|
185
|
+
}
|
186
|
+
)
|
119
187
|
return response
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: academia-mcp
|
3
|
-
Version: 1.11.
|
3
|
+
Version: 1.11.4
|
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
|
@@ -12,16 +12,14 @@ Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
13
13
|
Requires-Dist: mcp>=1.10.1
|
14
14
|
Requires-Dist: xmltodict>=0.14.0
|
15
|
-
Requires-Dist: types-xmltodict>=0.14.0
|
16
15
|
Requires-Dist: requests>=2.32.0
|
17
|
-
Requires-Dist: types-requests>=2.32.0
|
18
16
|
Requires-Dist: pypdf>=5.1.0
|
19
17
|
Requires-Dist: beautifulsoup4>=4.12.0
|
20
|
-
Requires-Dist: types-beautifulsoup4>=4.12.0
|
21
18
|
Requires-Dist: markdownify==0.14.1
|
19
|
+
Requires-Dist: types-xmltodict>=0.14.0
|
20
|
+
Requires-Dist: types-requests>=2.32.0
|
21
|
+
Requires-Dist: types-beautifulsoup4>=4.12.0
|
22
22
|
Requires-Dist: acl-anthology==0.5.2
|
23
|
-
Requires-Dist: markdown==3.7.0
|
24
|
-
Requires-Dist: types-markdown==3.7.0.20250322
|
25
23
|
Requires-Dist: huggingface-hub>=0.32.4
|
26
24
|
Requires-Dist: fire>=0.7.0
|
27
25
|
Requires-Dist: openai>=1.97.1
|
@@ -31,6 +29,8 @@ Requires-Dist: pymupdf>=1.26.4
|
|
31
29
|
Requires-Dist: pillow>=11.3.0
|
32
30
|
Requires-Dist: pydantic-settings>=2.6.0
|
33
31
|
Requires-Dist: youtube-transcript-api>=1.2.2
|
32
|
+
Requires-Dist: paddlepaddle>=3.2.0
|
33
|
+
Requires-Dist: paddleocr>=3.2.0
|
34
34
|
Dynamic: license-file
|
35
35
|
|
36
36
|
# Academia MCP
|
@@ -70,12 +70,16 @@ make install
|
|
70
70
|
### Quickstart
|
71
71
|
- Run over HTTP (default transport):
|
72
72
|
```bash
|
73
|
+
python -m academia_mcp --transport streamable-http
|
74
|
+
# OR
|
73
75
|
uv run -m academia_mcp --transport streamable-http
|
74
76
|
```
|
75
77
|
|
76
78
|
- Run over stdio (for local MCP clients like Claude Desktop):
|
77
79
|
```bash
|
78
80
|
python -m academia_mcp --transport stdio
|
81
|
+
# OR
|
82
|
+
uv run -m academia_mcp --transport stdio
|
79
83
|
```
|
80
84
|
|
81
85
|
Notes:
|
@@ -122,7 +126,7 @@ Availability notes:
|
|
122
126
|
- Set one or more of `EXA_API_KEY`, `BRAVE_API_KEY`, `TAVILY_API_KEY` to enable `web_search` and provider tools.
|
123
127
|
|
124
128
|
### Environment variables
|
125
|
-
Set as needed depending on which tools you use:
|
129
|
+
Set as needed, depending on which tools you use:
|
126
130
|
|
127
131
|
- `OPENROUTER_API_KEY`: required for LLM-related tools.
|
128
132
|
- `BASE_URL`: override OpenRouter base URL.
|
@@ -152,7 +156,7 @@ docker run --rm -p 5056:5056 \
|
|
152
156
|
academia_mcp
|
153
157
|
```
|
154
158
|
|
155
|
-
Or use existing image: `phoenix120/academia_mcp`
|
159
|
+
Or use existing image: [`phoenix120/academia_mcp`](https://hub.docker.com/repository/docker/phoenix120/academia_mcp)
|
156
160
|
|
157
161
|
### Examples
|
158
162
|
- [Comprehensive report screencast (YouTube)](https://www.youtube.com/watch?v=4bweqQcN6w8)
|
@@ -25,11 +25,11 @@ academia_mcp/tools/arxiv_search.py
|
|
25
25
|
academia_mcp/tools/bitflip.py
|
26
26
|
academia_mcp/tools/document_qa.py
|
27
27
|
academia_mcp/tools/hf_datasets_search.py
|
28
|
+
academia_mcp/tools/image_processing.py
|
28
29
|
academia_mcp/tools/latex.py
|
29
30
|
academia_mcp/tools/py.typed
|
30
31
|
academia_mcp/tools/review.py
|
31
32
|
academia_mcp/tools/s2.py
|
32
|
-
academia_mcp/tools/show_image.py
|
33
33
|
academia_mcp/tools/speech_to_text.py
|
34
34
|
academia_mcp/tools/visit_webpage.py
|
35
35
|
academia_mcp/tools/web_search.py
|
@@ -41,11 +41,11 @@ tests/test_bitflip.py
|
|
41
41
|
tests/test_document_qa.py
|
42
42
|
tests/test_extract_json.py
|
43
43
|
tests/test_hf_dataset_search.py
|
44
|
+
tests/test_image_processing.py
|
44
45
|
tests/test_latex.py
|
45
46
|
tests/test_review.py
|
46
47
|
tests/test_s2.py
|
47
48
|
tests/test_server.py
|
48
|
-
tests/test_show_image.py
|
49
49
|
tests/test_speech_to_text.py
|
50
50
|
tests/test_visit_webpage.py
|
51
51
|
tests/test_web_search.py
|
@@ -1,15 +1,13 @@
|
|
1
1
|
mcp>=1.10.1
|
2
2
|
xmltodict>=0.14.0
|
3
|
-
types-xmltodict>=0.14.0
|
4
3
|
requests>=2.32.0
|
5
|
-
types-requests>=2.32.0
|
6
4
|
pypdf>=5.1.0
|
7
5
|
beautifulsoup4>=4.12.0
|
8
|
-
types-beautifulsoup4>=4.12.0
|
9
6
|
markdownify==0.14.1
|
7
|
+
types-xmltodict>=0.14.0
|
8
|
+
types-requests>=2.32.0
|
9
|
+
types-beautifulsoup4>=4.12.0
|
10
10
|
acl-anthology==0.5.2
|
11
|
-
markdown==3.7.0
|
12
|
-
types-markdown==3.7.0.20250322
|
13
11
|
huggingface-hub>=0.32.4
|
14
12
|
fire>=0.7.0
|
15
13
|
openai>=1.97.1
|
@@ -19,3 +17,5 @@ pymupdf>=1.26.4
|
|
19
17
|
pillow>=11.3.0
|
20
18
|
pydantic-settings>=2.6.0
|
21
19
|
youtube-transcript-api>=1.2.2
|
20
|
+
paddlepaddle>=3.2.0
|
21
|
+
paddleocr>=3.2.0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "academia-mcp"
|
7
|
-
version = "1.11.
|
7
|
+
version = "1.11.4"
|
8
8
|
description = "MCP server that provides different tools to search for scientific publications"
|
9
9
|
readme = "README.md"
|
10
10
|
authors = [
|
@@ -19,16 +19,14 @@ classifiers = [
|
|
19
19
|
dependencies = [
|
20
20
|
"mcp>=1.10.1",
|
21
21
|
"xmltodict>=0.14.0",
|
22
|
-
"types-xmltodict>=0.14.0",
|
23
22
|
"requests>=2.32.0",
|
24
|
-
"types-requests>=2.32.0",
|
25
23
|
"pypdf>=5.1.0",
|
26
24
|
"beautifulsoup4>=4.12.0",
|
27
|
-
"types-beautifulsoup4>=4.12.0",
|
28
25
|
"markdownify==0.14.1",
|
26
|
+
"types-xmltodict>=0.14.0",
|
27
|
+
"types-requests>=2.32.0",
|
28
|
+
"types-beautifulsoup4>=4.12.0",
|
29
29
|
"acl-anthology==0.5.2",
|
30
|
-
"markdown==3.7.0",
|
31
|
-
"types-markdown==3.7.0.20250322",
|
32
30
|
"huggingface-hub>=0.32.4",
|
33
31
|
"fire>=0.7.0",
|
34
32
|
"openai>=1.97.1",
|
@@ -38,6 +36,8 @@ dependencies = [
|
|
38
36
|
"pillow>=11.3.0",
|
39
37
|
"pydantic-settings>=2.6.0",
|
40
38
|
"youtube-transcript-api>=1.2.2",
|
39
|
+
"paddlepaddle>=3.2.0",
|
40
|
+
"paddleocr>=3.2.0",
|
41
41
|
]
|
42
42
|
|
43
43
|
[dependency-groups]
|
academia_mcp-1.11.3/tests/test_show_image.py → academia_mcp-1.11.4/tests/test_image_processing.py
RENAMED
@@ -29,3 +29,9 @@ async def test_describe_image_base(test_image_url: str) -> None:
|
|
29
29
|
result = await describe_image(test_image_url)
|
30
30
|
assert result is not None
|
31
31
|
assert "Interrogator" in result
|
32
|
+
|
33
|
+
|
34
|
+
async def test_describe_image_text(test_image_url: str) -> None:
|
35
|
+
result = await describe_image(test_image_url, description_type="text")
|
36
|
+
assert result is not None
|
37
|
+
assert '"text": "Interrogator"' in result
|
@@ -7,7 +7,6 @@ def test_visit_webpage_basic() -> None:
|
|
7
7
|
assert content.id == "https://example.com/"
|
8
8
|
assert content.provider == "basic"
|
9
9
|
assert "Example Domain" in content.text
|
10
|
-
assert "illustrative" in content.text
|
11
10
|
|
12
11
|
|
13
12
|
def test_visit_webpage_exa() -> None:
|
@@ -16,7 +15,6 @@ def test_visit_webpage_exa() -> None:
|
|
16
15
|
assert content.id == "https://example.com/"
|
17
16
|
assert content.provider == "exa"
|
18
17
|
assert "Example Domain" in content.text
|
19
|
-
assert "illustrative" in content.text
|
20
18
|
|
21
19
|
|
22
20
|
def test_visit_webpage_pdf() -> None:
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|