mcpg-plugin-backend-ftp MCP server
2026년 11월 10일 커밋MCP 도구와 리소스를 사용하여 FTP 또는 FTPS를 통해 AI 클라이언트가 파일을 목록화, 읽기 및 쓰기를 수행할 수 있도록 합니다.
다른 이름 mcpg-dev/mcpg-plugin-backend-ftp
- 스타
- 0
- Tools
- 1
- 다운로드, 30일
- —
- 최신 버전
- —
- 마지막 커밋
- 2026년 11월 10일
- 라이선스
- Apache-2.0
mcpg-plugin-backend-ftp MCP란?
mcpg-plugin-backend-ftp은(는) MCP server입니다. MCP 도구와 리소스를 사용하여 FTP 또는 FTPS를 통해 AI 클라이언트가 파일을 목록화, 읽기 및 쓰기를 수행할 수 있도록 합니다. 1개 도구를 제공합니다. 예: name.
프로젝트 README에서 생성된 요약
mcpg-plugin-backend-ftp MCP server 정보
이 백엔드 플러그인은 AI 클라이언트가 FTP 또는 FTPS를 통해 원격 파일을 관리할 수 있게 해줍니다. MCP 도구와 리소스를 사용하여 디렉토리 내용을 나열하거나, 특정 파일을 읽거나, 원격 서버에 새로운 데이터를 쓰는 방법을 제공합니다. 서버는 보안 연결을 위해 pure-Rust TLS 스택을 사용하며, 기본적으로 explicit AUTH-TLS를 사용하여 시스템 라이브러리에 의존하지 않고도 데이터 보호를 보장합니다.
개발자는 특정 호스트, 포트 및 사용자 자격 증명으로 서버를 구성할 수 있으며, 이는 gateway secret-resolver를 통해 해결됩니다. 무단 액세스를 방지하기 위해 플러그인은 설정된 기본 디렉토리를 벗어나려는 모든 경로 세그먼트를 거부합니다. 또한 효율적인 데이터 전송 관리를 위해 max_bytes 설정을 통한 크기 제한 기능을 포함하고 있습니다.
수동 파일 작업 외에도 이 플러그인은 변경 사항을 감시하기 위한 디렉토리 폴링 전략을 지원합니다. 이를 통해 AI 클라이언트는 특정 경로 내에서 파일이 추가, 삭제 또는 수정될 때 알림을 받을 수 있습니다. 이는 자동화된 워크플로에서 인바운드 데이터 드롭을 모니터링하거나 아웃바운드 파일 전송을 추적하는 데 적합합니다.
활용 사례
- 1인바운드 파일 드롭 모니터링디렉토리 감시를 설정하여 파트너 인박스에 새 파일이 도착할 때마다 알림을 받습니다.
프로젝트의 README를 바탕으로 작성되었습니다. 모든 활용 사례는 해당 내용의 인용문과 대조하여 확인합니다.
mcpg-plugin-backend-ftp MCP 도구 1
README에서 감지됨name
| name | — |
구성
FTP_TEST_HOST
| 이름 | 설명 | 유형 |
|---|---|---|
| FTP_TEST_HOST | — |
자동 검사
2026년 11월 14일에 실행됨전체 보고서 →아직 인증되지 않았습니다. 서버는 80점 이상의 점수, 심각한 결함 없음, 그리고 검사에 충분한 데이터를 갖추어야 합니다. 검사 방식 · 점수를 높이기 위해 수정할 항목
- 소스 저장소 연결 및 접근 가능mcpg-dev/mcpg-plugin-backend-ftp is public and reachablegithub.com/mcpg-dev/mcpg-plugin-backend-ftp ↗통과
- 패키지가 이 저장소를 소스로 명시검사되지 않음
- 빌드 출처(Sigstore 증명)검사되지 않음
- 오픈 소스 라이선스 (OSI)Apache-2.0spdx.org/licenses/Apache-2.0.html ↗통과
- 최근 1년 내 커밋 또는 릴리스Last commit or release 2026-11-10github.com/mcpg-dev/mcpg-plugin-backend-ftp ↗통과
- OpenSSF Scorecard검사되지 않음
- 패키지 이름이 인기 패키지와 유사하지 않음검사되지 않음
- 패키지 및 해당 종속성에 중요한 보안 권고 없음검사되지 않음
- 모델에 대한 숨겨진 지침 없음1 tool description and the README read; no override phrases, credential paths or hidden characters통과
- 파괴적인 도구에 라벨 표시됨No tool named like delete, drop or exec통과
- 원격 엔드포인트가 MCP 핸드셰이크에 응답검사되지 않음
README
GitHub에서 보기mcpg-plugin-backend-ftp
FTP / FTPS file-integration backend binding plugin for mcpg (kind: ftp).
Lists a directory, reads a file, or writes a file over FTP — with explicit
AUTH-TLS (FTPS) required by default — as MCP tools and resources.
Transport is suppaftp on a pure-Rust rustls (ring) TLS stack — no
OpenSSL / native-tls. Complements the sftp backend.
How it works
One binding = one operation = one MCP tool (or resource):
op |
Behaviour | Returns | Mutates? |
|---|---|---|---|
list (default) |
List a directory's entries. | { entries, count } |
no (read-only) |
get |
Read a file (capped at max_bytes). |
{ content, size } |
no (read-only) |
put |
Write a file from the content (base64) / text argument. |
{ written } |
yes |
The target path comes from the call's path argument, joined under the
operator-configured path base — .. segments are rejected before any
FTP call, so a caller cannot escape the base. A connection is opened per call.
Configuration
| Field | Type | Default | Notes |
|---|---|---|---|
op |
list|get|put |
list |
The operation. put mutates; list/get are read-only. |
host |
string (required) | — | FTP host. Operator-configured. |
port |
int | 21 |
FTP control port. |
user |
string (required) | — | FTP login user. |
password |
string (required) | — | Resolved via the gateway secret-resolver (${env.X} / vault://…). Per-caller cred:// is not supported. |
path |
string | "" |
Base dir the caller path joins under ("" = the login's default dir). |
tls |
bool | true |
Require explicit FTPS (AUTH TLS). Set false only for plaintext FTP on a trusted network. |
max_bytes |
int | 10485760 |
Cap on bytes read (get) / written (put). |
timeout_ms |
int | 15000 |
connect + auth + operation timeout. |
surface |
tool|resource |
tool |
MCP surface. tool keeps the tool envelope; resource exposes files as MCP resources. |
uri |
string | ftp://{path} |
resource surface URI template; {path} is filled with each file's path. Ignored on the tool surface. |
As a list/get tool
mcp:
capabilities:
tools:
- name: dropbox.read
description: Read a file from the partner drop directory.
input_schema:
type: object
properties: { path: { type: string } }
required: [path]
backend:
kind: ftp
op: get
host: "ftp.partner.example.com"
user: "svc-mcpg"
password: "${env.FTP_PASSWORD}"
tls: true # require FTPS (default)
path: "/outbound"
As a put tool
backend:
kind: ftp
op: put
host: "ftp.partner.example.com"
user: "svc-mcpg"
password: "${env.FTP_PASSWORD}"
path: "/inbound"
# the tool's `content` (base64) or `text` argument becomes the file body
As a resource surface
With surface: resource the binding exposes the path directory as MCP
resources instead of a tool:
resources/listenumeratespathinto one resource per file (dirs / symlinks skipped). Each resource'surifills theuritemplate with the file path,nameis the filename,mimeTypederives from the extension, anddescriptioncarries the byte size.resources/readrecovers the file path from the requesteduri(via the sameuritemplate),gets the file undermax_bytes, and returns it as{contents:[{uri, text|blob, mimeType}]}—textfor valid UTF-8,blob(base64) for binary.- Completion of the
{path}template variable lists the directory and returns the entry names that start with the typed prefix.
The ..-traversal reject still applies to every resolved path.
mcp:
capabilities:
resources:
- uri: ftp://outbound
name: Partner outbound drop
backend:
kind: ftp
surface: resource # expose files as MCP resources
uri: "ftp://{path}" # uri template (default)
host: "ftp.partner.example.com"
user: "svc-mcpg"
password: "${env.FTP_PASSWORD}"
tls: true
path: "/outbound" # directory listed + read under
A resources/read for ftp://outbound/report.csv recovers the file path
outbound/report.csv, fetches it, and returns:
{
"contents": [
{ "uri": "ftp://outbound/report.csv", "mimeType": "text/csv", "text": "a,b\n1,2\n" }
]
}
Response envelope
{
"toolName": "dropbox.list",
"profile": "dropbox.list",
"request": { "op": "list", "host": "ftp.partner.example.com", "path": "" },
"response": { // op: list
"entries": [ { "name": "report.csv", "type": "file", "size": 4096 } ],
"count": 1, "content": null, "size": null, "written": null, "durationMs": 80
},
"downstreamError": null, // non-null ⇒ isError:true (ftp_error / transport_error)
"downstreamErrors": [],
"error": null
}
op: get populates content ({text} / {base64}) + size; op: put
populates written.
Security
- Path-traversal defense. The caller
pathis joined under the base with..segments rejected before any FTP call. - FTPS by default. Explicit AUTH-TLS is required unless
tls: falseis set; plaintext is opt-in (trusted-network only). - No plaintext secrets. The
passwordresolves through the gateway secret-resolver; per-callercred://is rejected. - Size cap.
get/putare bounded bymax_bytes. - Pure-Rust TLS. rustls (ring) — no OpenSSL / native-tls.
Build / test
cargo build -p mcpg-plugin-backend-ftp
cargo test -p mcpg-plugin-backend-ftp # unit tests
cargo test -p mcpg-plugin-backend-ftp --features integration-tests # against a live FTP server
cargo clippy -p mcpg-plugin-backend-ftp --all-targets -- -D warnings
The integration suite targets an operator-provided FTP/FTPS server (gated on
FTP_TEST_HOST / FTP_TEST_USER / FTP_TEST_PASSWORD, optional
FTP_TEST_PORT / FTP_TEST_PATH / FTP_TEST_TLS) and is skipped when
FTP_TEST_HOST is unset. MCPG_REQUIRE_SERVICE=1 makes a missing server a
failure; the CI row Event sources / file-shares sets it and starts the
server on 127.0.0.1. A containerised server is not started by the suite
because FTP passive-mode advertises a server-chosen data port that
testcontainers' random host-port remapping cannot rewrite. A server on the
host network works; Pure-FTPd advertises passive ports 30000-30009.
docker run -d --rm --name ftp-it --network host \
-e PUBLICHOST=127.0.0.1 -e FTP_USER_NAME=testuser -e FTP_USER_PASS=testpass \
-e FTP_USER_HOME=/home/testuser \
stilliard/pure-ftpd:trixie-1.0.50@sha256:6435d108eb3fad29730f1b6748c1d49f3fa13e5d0fb49979ec3e0e96c5dbd94a
FTP_TEST_HOST=127.0.0.1 FTP_TEST_USER=testuser FTP_TEST_PASSWORD=testpass \
cargo test -p mcpg-plugin-backend-ftp --features integration-tests
Besides the put → list → get round-trip, the suite runs an ftp_dir_poll
event source through a create, a modification, a delete and a restart.
Directory watch (ftp_dir_poll)
This plugin also ships a watch_strategy entity (kind ftp_dir_poll) that
watches a directory by polling. FTP has no native change-push channel, so
each listing opens one connection, runs LIST on the watched directory (and
its subdirectories with recursive), and compares the files with the last
listing the gateway stored. A resource watch gets
notifications/resources/updated when a file is added, removed, or modified;
an MCP Events source gets each such file as the shared object.changed event
(see MCP Events, "Files and objects").
Time precision.
LISTreports a file's time to the minute at best. Adds, removes, renames, size changes and time changes are detected; an overwrite that keeps the size within the same minute is not.
| Field | Type | Default | Notes |
|---|---|---|---|
host |
string (required) | — | FTP host. |
port |
int | 21 |
FTP control port. |
user |
string (required) | — | FTP login user (alias: username). |
password |
string (required) | — | Resolved via the gateway secret-resolver (${env.X} / vault://…); cred:// is rejected. |
path |
string | "" |
Directory to watch ("" = login dir; .. rejected). Alias: root. |
tls |
bool | true |
Require explicit FTPS (AUTH TLS). |
interval_ms |
int | 60000 |
Listing cadence (at least 250 ms). |
timeout_ms |
int | 10000 |
Budget of one listing: connect and every directory. |
recursive |
bool | false |
Go into subdirectories, at most 1000 of them. |
pattern |
string | — | Keep only the files whose path relative to the directory matches this glob: * stays in a directory, ** crosses them (**/*.csv). |
max_files |
int | 10000 |
Most files listed (1 to 100000); past it the first in path order are kept, with a warning. |
start_at |
now | existing |
now |
now: the files there at a first start are the baseline. existing: each is reported as created. |
snapshot_bytes |
int | 131072 |
Largest snapshot of the listing an event carries, for an exact restart (at most 196608). |
max_in_flight |
int | 256 |
Most changes emitted ahead of the gateway's acknowledgements (1 to 1000). |
ack_timeout_ms |
int | 60000 |
How long a change waits for its acknowledgement before it is offered again. |
Keys are file paths relative to path, with / between parts; location
is ftp://host:port/<directory>, without credentials. A directory that
cannot be listed fails the whole listing, and the next interval tries again,
so a part that cannot be read is never reported as deleted. An unreachable
server does not fail the watch: it is listed again at the next interval.
As a resource watch:
mcp:
capabilities:
resources:
- uri: ftp://partner/inbox
name: Partner inbox
watch:
strategy:
type: plugin
kind: ftp_dir_poll
host: "ftp.partner.example.com"
user: "svc-mcpg"
password: "${env.FTP_PASSWORD}"
path: "/inbound"
interval_ms: 30000
As an MCP Events source, each file as object.changed:
mcp:
capabilities:
events:
- name: partner.inbox
description: A file arrived in, changed in, or left the partner inbox.
source:
watch:
strategy:
type: plugin
kind: ftp_dir_poll
host: "ftp.partner.example.com"
user: "svc-mcpg"
password: "${env.FTP_PASSWORD}"
path: "/inbound"
recursive: true
event_type: object.changed
Scope / deferred
- Public-key / client-cert auth — v1 is password auth.
- Implicit FTPS (port 990) — v1 is explicit AUTH-TLS; implicit is deprecated upstream.
- Recursive / streaming transfers, rename/mkdir/rm — v1 is single-file
list/get/put. - Connection pooling — v1 connects per call.
mcpg-plugin-backend-ftp MCP 질문
mcpg-plugin-backend-ftp MCP는 어떤 도구를 제공하나요?
1개 도구를 제공합니다. 예: name.
서버를 사용하여 파일 변경 사항을 감시할 수 있나요?
네, FTP 서버를 폴링하여 파일이 추가, 삭제 또는 수정되었는지 감지하는 디렉토리 감시 전략을 포함하고 있습니다.
경로 탐색(path traversal) 공격에 대한 방어 기능이 있나요?
네, 플러그인은 호출자가 설정된 기본 경로를 벗어나는 것을 방지하기 위해 FTP 호출 전에 '..' 세그먼트를 거부합니다.
이 서버를 통해 AI가 수행할 수 있는 작업은 무엇인가요?
서버는 디렉토리 항목 목록화, 파일 읽기(get) 및 파일 쓰기(put)를 지원합니다.