SkillTotal

Is Academia MCP server safe?

academia-mcp is an AI python_package analyzed by SkillTotal's deterministic static scanner. The scan found no malicious indicators, though 6 risky constructs are reported for review. It can: filesystem read, filesystem write, mcp tools detected, network egress and shell execution — capabilities are what the code can do, not a verdict on intent. Risk score 10/100 (low).

academia-mcp 1.13.4

python_package · https://github.com/IlyaGusev/academia_mcp
LOW
10
/ 100 malicious-risk
Snapshot · scanned Jun 20, 2026 · academia-mcp@1.13.4 · engine 0.18.0 / ruleset 19
No malicious indicators - review capabilities before installing
Notable — review in context (capabilities are not malware):
  • Python shell/command execution
  • Python filesystem read
  • Python filesystem write/delete

No malicious indicators found by static analysis.

Capabilities — what this component can do (not a risk score):
filesystem readfilesystem writemcp tools detectednetwork egressshell execution

Findings (6)

HIGHPython shell/command executionST-SHELL-PY

The component can run operating-system commands or spawn processes.

subprocess.run(
                    [
                        "latexmk",
                        "-pdf",
                        "-interaction=nonstopmode",
                        "-file-line-error",
                        "-diagnostics", …

Why it matters: Powerful and often legitimate — confirm the commands aren't built from untrusted input.

Fix: Confirm the command and its arguments are fully controlled and not derived from untrusted input; avoid shell=True.

MEDIUMServer bound to all network interfacesST-EXPOSE-BIND

A server is bound to all network interfaces (0.0.0.0), not just your own machine.

host: str = "0.0.0.0",

Why it matters: Without authentication, other hosts on the network can reach it.

Fix: Bind to 127.0.0.1 for local-only use, or require authentication and restrict access if remote exposure is intended.

MEDIUMPython filesystem readST-FS-PY-READ

The component reads files from disk.

with open(readme_path, "r", encoding="utf-8") as f:
template=template_path.read_text(), style=style_path.read_text()
latex_code = input_filename_path.read_text(encoding="utf-8")
log_content = log_path.read_text(encoding="utf-8", errors="ignore")
audio_file = BytesIO(open(full_audio_path, "rb").read())
with open(proxy_file_path, "r") as f:

Why it matters: Usually legitimate, but worth confirming it can't be steered into reading sensitive files.

Fix: Confirm which files are read and that paths cannot be influenced by untrusted input to reach sensitive locations.

MEDIUMPython filesystem write/deleteST-FS-PY-WRITE

The component writes or deletes files on disk.

with open(temp_path, "w") as f:
with open(output_path.resolve(), "wb") as fp:
with open(os.devnull, "w") as devnull:
with open(os.devnull, "w") as devnull:
with open(os.devnull, "w") as devnull:
tex_file_path.write_text(latex_code, encoding="utf-8")
shutil.copyfile(candidate, temp_dir_path / sty_name)
shutil.copyfile(bib_source_path, temp_dir_path / "references.bib")
(temp_dir_path / "temp.bbl").write_text(
                        "\\begin{thebibliography}{}\\end{thebibliography}"
                    )
shutil.move(str(pdf_path), str(output_pdf_path))

Why it matters: Usually legitimate, but worth confirming the paths can't be controlled by untrusted input.

Fix: Confirm which files are written/deleted and that paths cannot be influenced by untrusted input.

MEDIUMPython network egressST-NET-PY

The component makes outbound network requests.

response = httpx.get(path, timeout=10)
response = httpx.get(audio_path, timeout=10)
from urllib3.util.retry import Retry
retry_strategy = Retry(
        total=num_retries,
        backoff_factor=backoff_factor,
        status_forcelist=[429, 500, 502, 503, 504],
        allowed_methods=["POST"],
    )
session = requests.Session()
adapter = requests.adapters.HTTPAdapter(max_retries=retry_strategy)
retry_strategy = Retry(
        total=num_retries,
        backoff_factor=backoff_factor,
        status_forcelist=[429, 500, 502, 503, 504],
        allowed_methods=["GET"],
    )
session = requests.Session()
adapter = requests.adapters.HTTPAdapter(max_retries=retry_strategy)

Why it matters: Usually legitimate, but confirm the destinations are expected and no sensitive data leaves.

Fix: Confirm the destination hosts are expected and that no sensitive data is sent off-host.

LOWMCP tool surface detectedST-MCP-DETECTED

An MCP tool surface (manifest or tool definitions) was found.

Why it matters: Just context — review which tools it offers and their permissions.

Fix: Review the declared MCP tools and their permissions.

Check your own component

Run the same evidence-backed scan on any MCP server, agent skill, or package.

Scan your own component

Or get notified if this component's risk changes:

How we determine this: deterministic static analysis (regex + AST), evidence-anchored, no code execution. Methodology →