MCP server · Org-owned · Audited from source
Unstract MCP server
by zipstack/unstractAGPL-3.0 licenceAudited 21 Sep 2026 · source 8f2d2c257ee3
Is it safe? No — BLOCK, grade F (46/100). It exposes 5 tools: 5 read, 0 write and 0 destructive. The audit recorded 56 findings (0 critical, 2 high, 15 medium, 34 low). Maintainer's description: LLM-Driven Extraction of Unstructured Data — Built for API Deployments & ETL Pipeline Workflows
Cite
Cite this page
ModelsAtlas. “Unstract MCP server (zipstack/unstract)”. Retrieved 21 Sep 2026. https://modelsatlas.com/mcp/zipstack/unstract
Why this is BLOCK. The audit found 0 critical and 2 high findings; the most severe is Code injection at backend/backend/settings/base.py:775. Each finding is listed below with its file and line.
Why this page is still public. People search for this server by name. Hiding it would leave them with the README's word alone; here they see what the code does. We list it so you can decide, and we do not show connect commands for BLOCK servers.
Trust audit
Audit 0.4.1 · full source read 21 Sep 2026
56 findings, listed below with the file and line each was found on. Grade A needs a sandboxed behavioural run too; this audit read the source only.
What the source does
- FilesystemDeclared10 observations
- NetworkDeclared10 observations
- ShellDeclared5 observations
- DependenciesNot pinnedSome ranges float
- SecretsFoundSee the findings
Findings (56)
Sorted by severity · the 25 most severe of 56 are listed
HIGHCode injectioncode.eval_exec · backend/backend/settings/base.py:775
exec(f"SOCIAL_AUTH_{key} = os.environ.get('{key}')")- Why
- evaluates text as code
- Fix
- remove; use a parser or a dispatch table
HIGHHard-coded secretssecret.db_uri · unstract/sdk1/src/unstract/sdk1/adapters/vectordb/supabase/src/supabase.py:83
Excerpt withheld: it is a secret, and we never print one.
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMCode injectioncode.dynamic_import · .claude/skills/connector-ops/scripts/verify_connector.py:70
module = importlib.import_module(module_path)
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMCode injectioncode.dynamic_import · .claude/skills/connector-ops/scripts/verify_connector.py:107
module = importlib.import_module(module_path)
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMCode injectioncode.dynamic_import · .claude/skills/connector-ops/scripts/verify_connector.py:161
module = importlib.import_module(module_path)
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMCode injectioncode.dynamic_import · backend/connector_processor/connector_processor.py:30
module = __import__(module_path, fromlist=[class_name])
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMInformation disclosuredisclose.log_secret · platform-service/src/unstract/platform_service/controller/platform.py:96
app.logger.error(f"Authentication failed. bearer token not found {token}")- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMInformation disclosuredisclose.log_secret · platform-service/src/unstract/platform_service/controller/platform.py:106
app.logger.error(f"Authentication failed. Invalid bearer token: {token}")- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMNetwork egressnet.beacon_words · backend/pipeline_v2/manager.py:52
callback_url = settings.DJANGO_APP_BACKEND_URL + reverse(
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMNetwork egressnet.beacon_words · backend/pipeline_v2/manager.py:58
RequestConstants.URL: callback_url,
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMNetwork egressnet.raw_ip · backend/backend/settings/dev.py:16
"http://127.0.0.1:3000",
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMHard-coded secretssecret.db_uri · backend/mcp_server/tests/test_redaction.py:42
Excerpt withheld: it is a secret, and we never print one.
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMHard-coded secretssecret.db_uri · backend/mcp_server/tests/test_redaction.py:245
Excerpt withheld: it is a secret, and we never print one.
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMHard-coded secretssecret.db_uri · backend/mcp_server/tests/test_redaction.py:311
Excerpt withheld: it is a secret, and we never print one.
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMHard-coded secretssecret.db_uri · backend/mcp_server/tests/test_redaction.py:312
Excerpt withheld: it is a secret, and we never print one.
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMHard-coded secretssecret.generic · frontend/src/index.jsx:38
Excerpt withheld: it is a secret, and we never print one.
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMHard-coded secretssecret.generic · workers/tests/test_notification_terminal_refusal.py:117
Excerpt withheld: it is a secret, and we never print one.
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWCode injectioncode.dynamic_import · backend/dashboard_metrics/tests/test_aggregation_dispatch.py:130
mod = importlib.import_module(_SPLIT_MIGRATION)
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWCode injectioncode.eval_exec · backend/api_v2/tests/test_api_key_create_target.py:130
exec(compile(body, str(PERMISSION_MODULE), "exec"), namespace)
- Why
- evaluates text as code
- Fix
- remove; use a parser or a dispatch table
LOWCode injectioncode.eval_exec · backend/api_v2/tests/test_api_key_create_target.py:349
exec(compile(body, str(VIEW_MODULE), "exec"), namespace)
- Why
- evaluates text as code
- Fix
- remove; use a parser or a dispatch table
LOWCode injectioncode.eval_exec · backend/prompt_studio/prompt_studio_registry_v2/tests/test_registry_tool_delete_guards.py:122
exec(compile(body, str(PERMISSION_MODULE), "exec"), namespace)
- Why
- evaluates text as code
- Fix
- remove; use a parser or a dispatch table
Tools it exposes
5 declared in source · 0 destructive
| Tool | What it does | Risk |
|---|---|---|
Engineering | team | read |
deleteEverything | No description in the source | read |
doThing | d | read |
extractSomething | No description in the source | read |
probeTool | No description in the source | read |
Safer alternatives
dbt-labs/dbt-mcp
A MCP (Model Context Protocol) server for interacting with dbt.
glifxyz/glif-mcp-server
Deprecated — use the hosted Glif MCP server at https://glif.app/mcp
glifxyz/glif-mcp-server
Glif's hosted MCP server, plugin and skills for creating images, video and audio. Works with Claude, ChatGPT, Codex, Cursor and more.
Audit history
- ✕BLOCK F 46 / 100
Source changed, verdict held ·
8f2d2c257ee3 - ✕BLOCK F 46 / 100
First audit ·
054107987385
README badge
Badges show the current verdict, BLOCK included
A badge cannot be hidden by the maintainer while the verdict is BLOCK. Fix the findings, push, and the re-audit updates it.
Questions about Unstract MCP server
What is the Unstract MCP server?
What tools does Unstract expose?
Is Unstract safe to connect to an agent?
What credentials does Unstract need?
How current is this page?
I already installed Unstract. What should I do?
Can the verdict change?
Sources
- zipstack/unstract on GitHub — the source we read, its licence, stars and activityObserved · 21 Sep 2026
- ModelsAtlas trust audit — BLOCK verdict for commit 8f2d2c257ee3Observed · 21 Sep 2026
Spotted something wrong? Report a correction · Methodology
Keep going in your AI
Opens with this page as the source. We add nothing else to the prompt.
- What is the Unstract MCP server?
- What tools does Unstract expose?
- Is Unstract safe to connect to an agent?