zh-file-mcp
zh-file-mcp is a stdio-first MCP file gateway. It downloads files from configured business systems into the agent workspace and uploads local workspace files back to those systems.
It is intentionally generic: systems such as wpos are configured with JSON instead of hard-coded MCP tools.
Features
- Stdio MCP server for Cherry Studio, web-agent, and other MCP clients.
- Config-driven HTTP download, upload, list, and metadata requests.
- Cookie, bearer, custom header, static headers, and no-auth modes.
- Files are written under the MCP process working directory.
- Tool results return
relative_pathso agents can continue reading files. - Paths are constrained to the workspace.
- Large business IDs can be passed as strings to avoid JavaScript precision loss.
Tools
| Tool | Description |
|---|---|
get_workspace_info |
Show current working directory, download root, and configured systems. |
download_file |
Download a configured system file into the workspace. |
upload_file |
Upload a workspace file to a configured system. |
list_files |
List files from a configured system, if the system defines list. |
get_file_info |
Get file metadata, if the system defines file_info. |
Install
cd /Users/linchuanke/lck/zhonghui/zh-file-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
Verify:
/Users/linchuanke/lck/zhonghui/zh-file-mcp/.venv/bin/zh-file-mcp --help
After code changes, reinstall:
source .venv/bin/activate
pip install -e .
Version 0.1.3 and later allow extra to be passed either as an object or as a JSON object string. If MCP still reports extra Input should be a valid dictionary, the running MCP process is still using an older install; restart the MCP client and make sure its command points to this updated environment.
Environment
| Variable | Default | Description |
|---|---|---|
FILE_MCP_SYSTEMS_JSON |
- | Inline JSON systems config. Takes precedence over config file. |
FILE_MCP_SYSTEMS_CONFIG |
- | Path to a JSON systems config file. |
FILE_MCP_WORK_DIR |
process cwd | Optional explicit working directory. |
FILE_MCP_DOWNLOAD_DIR |
downloads |
Relative download root inside work dir. |
FILE_MCP_MAX_BYTES |
524288000 |
Max download/upload size in bytes. |
FILE_MCP_TIMEOUT_SECONDS |
60 |
HTTP request timeout. |
FILE_MCP_VERIFY_SSL |
true |
Verify HTTPS certificates. |
FILE_MCP_LOG_LEVEL |
INFO |
Logging level. |
AUTH_TOKEN |
- | Common business login token env used by examples. |
If neither FILE_MCP_SYSTEMS_JSON nor FILE_MCP_SYSTEMS_CONFIG is set, the server can still create a default wpos config from legacy WPOS_* variables. New deployments should prefer explicit systems config.
Cherry Studio Config
This is a single-file Cherry config using inline FILE_MCP_SYSTEMS_JSON:
{
"mcpServers": {
"zh-file-mcp": {
"command": "/Users/linchuanke/lck/zhonghui/zh-file-mcp/.venv/bin/zh-file-mcp",
"args": [],
"env": {
"AUTH_TOKEN": "你的tk值",
"FILE_MCP_WORK_DIR": "/Users/linchuanke/lck/zhonghui/cherry-workspace",
"FILE_MCP_DOWNLOAD_DIR": "input",
"FILE_MCP_SYSTEMS_JSON": "{\"systems\":{\"wpos\":{\"base_url\":\"http://wpos.dev.zhrdc.zhcpa.cn:8084\",\"auth\":{\"type\":\"cookie\",\"cookie_name\":\"tk\",\"token_env\":\"AUTH_TOKEN\"},\"download\":{\"method\":\"GET\",\"path\":\"/api/project/file/downloadGet\",\"params\":{\"projectId\":\"$project_id\",\"fileId\":\"$file_id\"},\"headers\":{\"download-source\":\"CLIENT\"}},\"upload\":{\"method\":\"POST\",\"path\":\"/api/project/file/upload\",\"content_type\":\"multipart\",\"file_field\":\"file\",\"params\":{\"projectId\":\"$project_id\",\"catalogId\":\"$catalog_id\",\"nameStrategy\":\"$name_strategy\"}},\"list\":{\"method\":\"GET\",\"path\":\"/wpos/api/project/file/listByParent\",\"params\":{\"projectId\":\"$project_id\",\"parentId\":\"$parent_id\"}},\"file_info\":{\"method\":\"GET\",\"path\":\"/api/project/file/get\",\"params\":{\"projectId\":\"$project_id\",\"fileId\":\"$file_id\"},\"unwrap\":\"data\"}}}}"
}
}
}
}
web-agent Config
For web-agent Docker images where zh-file-mcp is installed in the runtime image:
{
"name": "zh-file-mcp",
"type": "stdio",
"command": "zh-file-mcp",
"env": {
"AUTH_TOKEN": "${AUTH_TOKEN}",
"UV_INDEX_URL": "https://pypi.tuna.tsinghua.edu.cn/simple",
"FILE_MCP_DOWNLOAD_DIR": "downloads",
"FILE_MCP_SYSTEMS_JSON": "{\"systems\":{\"wpos\":{\"base_url\":\"http://wpos.dev.zhrdc.zhcpa.cn:8084\",\"auth\":{\"type\":\"cookie\",\"cookie_name\":\"tk\",\"token_env\":\"AUTH_TOKEN\"},\"download\":{\"method\":\"GET\",\"path\":\"/api/project/file/downloadGet\",\"params\":{\"projectId\":\"$project_id\",\"fileId\":\"$file_id\"},\"headers\":{\"download-source\":\"CLIENT\"}},\"upload\":{\"method\":\"POST\",\"path\":\"/api/project/file/upload\",\"content_type\":\"multipart\",\"file_field\":\"file\",\"params\":{\"projectId\":\"$project_id\",\"catalogId\":\"$catalog_id\",\"nameStrategy\":\"$name_strategy\"}},\"list\":{\"method\":\"GET\",\"path\":\"/wpos/api/project/file/listByParent\",\"params\":{\"projectId\":\"$project_id\",\"parentId\":\"$parent_id\"}},\"file_info\":{\"method\":\"GET\",\"path\":\"/api/project/file/get\",\"params\":{\"projectId\":\"$project_id\",\"fileId\":\"$file_id\"},\"unwrap\":\"data\"}}}}"
},
"tools": [
"get_workspace_info",
"download_file",
"upload_file",
"list_files",
"get_file_info"
],
"rewrite_workspace_paths": true
}
Do not set FILE_MCP_WORK_DIR in web-agent unless you have a specific reason. Let web-agent start MCP in the session workspace so downloaded files land in that session.
When deploying web-agent with the bare "command": "zh-file-mcp" form, rebuild or reinstall the runtime package after code changes. The extra string compatibility requires zh-file-mcp>=0.1.3; older images still expose extra as dict-only and will reject JSON strings before the tool function runs.
Systems Config
For readability, you can store systems config in a file and set FILE_MCP_SYSTEMS_CONFIG instead of using inline JSON.
Example file-mcp-systems.json:
{
"systems": {
"wpos": {
"base_url": "http://wpos.dev.zhrdc.zhcpa.cn:8084",
"auth": {
"type": "cookie",
"cookie_name": "tk",
"token_env": "AUTH_TOKEN"
},
"download": {
"method": "GET",
"path": "/api/project/file/downloadGet",
"params": {
"projectId": "$project_id",
"fileId": "$file_id"
},
"headers": {
"download-source": "CLIENT"
}
},
"upload": {
"method": "POST",
"path": "/api/project/file/upload",
"content_type": "multipart",
"file_field": "file",
"params": {
"projectId": "$project_id",
"catalogId": "$catalog_id",
"nameStrategy": "$name_strategy"
}
},
"list": {
"method": "GET",
"path": "/wpos/api/project/file/listByParent",
"params": {
"projectId": "$project_id",
"parentId": "$parent_id"
}
},
"file_info": {
"method": "GET",
"path": "/api/project/file/get",
"params": {
"projectId": "$project_id",
"fileId": "$file_id"
},
"unwrap": "data"
}
}
}
}
Prompt Examples
Check configuration:
调用 zh-file-mcp 的 get_workspace_info。
Download a wpos file:
用 zh-file-mcp 从系统 "wpos" 下载项目 "336" 的文件 "2069307013493440513",project_id 和 file_id 都必须按字符串传。下载完成后返回 relative_path 和 absolute_path。
Upload a file to wpos:
用 zh-file-mcp 把 "outputs/old.xlsx" 上传到系统 "wpos" 的项目 "336",upload_name 用 "old.xlsx",catalog_id 用 "目录ID",name_strategy 用 1。
List files:
用 zh-file-mcp 列出系统 "wpos" 项目 "336" 的目录 "目录ID" 下的文件。
Get metadata:
用 zh-file-mcp 查询系统 "wpos" 项目 "336" 的文件 "2069307013493440513" 的信息。
Upload Filename
upload_file uses the local filename by default. To force the filename stored by the target system, pass upload_name:
{
"system": "wpos",
"project_id": "336",
"file_path": "outputs/old20260623141153.xlsx",
"upload_name": "old.xlsx",
"catalog_id": "1234567890123456789",
"name_strategy": 1
}
For wpos, name_strategy is handled by wpos:
1: overwrite2: coexist with a generated name when there is a duplicate3: fail on duplicate
Large IDs
Many business IDs are larger than JavaScript's safe integer range. Always pass large IDs as strings:
{
"system": "wpos",
"project_id": "336",
"file_id": "2069307013493440513"
}
Auth Types
Supported auth configs:
{ "type": "cookie", "cookie_name": "tk", "token_env": "AUTH_TOKEN" }
{ "type": "bearer", "token_env": "OTHER_TOKEN" }
{ "type": "header", "header_name": "token", "token_env": "AUTH_TOKEN" }
{
"type": "headers",
"headers": {
"Cookie": "${WPOS_COOKIE}",
"X-Tenant": "${TENANT_ID}"
}
}
{ "type": "none" }
Template Variables
System configs can use:
$system$file_id$project_id$catalog_id$parent_id$upload_name$name_strategy$extra.xxx${ENV_NAME}
Build Wheel
cd /Users/linchuanke/lck/zhonghui/zh-file-mcp
source .venv/bin/activate
pip install build
rm -rf build dist src/zh_file_mcp.egg-info
python -m build --wheel
Install the generated wheel into the image that runs stdio MCP.
Metadata
Release files for zh-file-mcp 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zh_file_mcp-0.1.3.tar.gz | 18.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zh_file_mcp-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.1 kB
Release files / zh_file_mcp-0.1.3.tar.gz
| Download URL | zh_file_mcp-0.1.3.tar.gz |
|---|---|
| Size | 18.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f4ba1ffcfc16529f7ff652ddf375f9555652cb403fe51ed42121113c76c688b4
|
|
BLAKE2b-256 checksum How to use checksums |
23b3213b362cddbfc778b7e632dbfebe4e4b559be1511ca0a52d71e69b9608dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / zh_file_mcp-0.1.3-py3-none-any.whl
| Download URL | zh_file_mcp-0.1.3-py3-none-any.whl |
|---|---|
| Size | 18.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
af3fa2806d98c1656f15191d94cb950b68d4e0f5c80ec4d3e0178c6699e95d2e
|
|
BLAKE2b-256 checksum How to use checksums |
3484bb8d70fc61f503cb648a3a53a239dfbcad9de4a3e4d394a858fd5712e1df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|