Skip to content

Repository files navigation

FTP Agent

FTP Agent is a lightweight, self-hosted assistant for maintaining website content on PHP shared hosting. It turns plain-language tasks and optional reference documents into reviewable changes to HTML, Markdown, JSON, CSV, and text files.

It is designed for webspace accounts where deployment happens over FTP or SFTP, PHP is available, and long-running background processes are not. FTP is only used to deploy the application; the agent runs on the webspace and edits files within the same hosting account.

Status: Early public beta. Start on a staging site, keep independent backups, and require approval for production changes.

Features

  • Runs on PHP 8.2+ with no Composer dependencies.
  • Uses SQLite when available and falls back to a locked JSON-file queue.
  • Works through cron or a token-protected HTTPS worker endpoint.
  • Accepts optional .html, .md, .json, .csv, and .txt reference files.
  • Produces exact search-and-replace operations instead of executing generated code.
  • Restricts edits to configured directories, extensions, and file-size limits.
  • Provides administrator approval, signed backups, rollback, audit logs, and rate limiting.
  • Processes a single job per worker invocation to stay within shared-hosting limits.

How it works

  1. A user submits a content task from the dashboard or authenticated webhook.
  2. The worker reads a bounded set of relevant files and requests a structured edit plan from the configured language model.
  3. The task waits for administrator approval unless its trusted source is configured otherwise.
  4. The agent creates signed backups and applies only validated, deterministic edits.
  5. If an operation or validation fails, the affected files are restored automatically.

The agent never receives shell access, FTP credentials, arbitrary database access, or permission to execute model-generated PHP.

Requirements

  • PHP 8.2 or newer
  • PHP json and PDO extensions
  • pdo_sqlite, curl, and dom extensions recommended
  • Apache 2.4 with .htaccess, unless the document root can point directly to public/
  • HTTPS
  • A writable, private storage/ directory
  • An API key for an OpenAI-compatible Responses API
  • Cron or an external HTTPS scheduler for unattended processing

Installation

Clone the repository and create the local configuration:

git clone https://github.com/1x0f8/ftp-agent.git
cd ftp-agent
cp .env.example .env

Configure at least these values in .env:

APP_ENV=production
APP_URL=https://example.com/agent/public
SITE_ROOT=sites/website
LLM_API_KEY=your-provider-api-key
LLM_MODEL=gpt-5.6-terra
SESSION_COOKIE_SECURE=true

Generate a separate random value for APP_KEY, WEBHOOK_TOKEN, and WORKER_TOKEN:

php -r 'echo bin2hex(random_bytes(32)), PHP_EOL;'

Generate an administrator password hash:

php -r 'echo password_hash("replace-with-a-strong-password", PASSWORD_DEFAULT), PHP_EOL;'

Store the result as ADMIN_PASSWORD_HASH. Never commit .env or plaintext credentials.

Run the deployment checks before uploading:

php bin/doctor.php
php tests/smoke.php

Deployment

The safest layout exposes only public/ through the web server:

project root/
|-- .env
|-- bin/
|-- config/
|-- public/          <- web document root
|-- sites/
|-- src/
`-- storage/

If the hosting provider cannot change the document root, upload the complete project to a subdirectory such as /agent and access it through /agent/public/. The root .htaccess blocks direct HTTP access to private project files.

After deployment, verify that sensitive paths return 403 or 404:

/agent/.env
/agent/src/Http.php
/agent/config/sites.php
/agent/storage/tasks.sqlite
/agent/.git/config

If any of these paths returns file contents, take the deployment offline and fix the document root or Apache override configuration.

Worker setup

Run one task per minute and prune expired runtime data daily:

* * * * * /usr/bin/php /absolute/path/to/ftp-agent/bin/worker.php
17 3 * * * /usr/bin/php /absolute/path/to/ftp-agent/bin/prune.php

When cron is unavailable, configure an external scheduler to send an authenticated request:

curl -X POST 'https://example.com/agent/public/worker.php' \
  -H 'Authorization: Bearer YOUR_WORKER_TOKEN'

Keep the worker and webhook tokens different, and never place either token in a URL query string.

Webhook API

Create a task:

curl -X POST 'https://example.com/agent/public/webhook.php' \
  -H 'Authorization: Bearer YOUR_WEBHOOK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"type":"update_content","target":"website","instruction":"Update the opening hours in contact.html"}'

The response includes a task ID. Poll its status with the same bearer token:

curl 'https://example.com/agent/public/webhook.php?id=TASK_ID' \
  -H 'Authorization: Bearer YOUR_WEBHOOK_TOKEN'

Webhook-created tasks always require administrator approval.

Site targets

Targets are defined in config/sites.php. The default target points to the bundled sites/website/ demo page. Before production use, replace the demo content or point SITE_ROOT to a staging-site directory.

Keep target roots outside public/ when possible and allow only the file extensions the site needs. Uploaded documents are treated as untrusted reference content, not agent instructions.

Development

Start the local PHP server:

php -S 127.0.0.1:8765 -t public public/router.php

Run the test suite:

php tests/create-test-env.php
php bin/doctor.php
php tests/smoke.php

For the HTTP security tests, keep the local server running and execute:

TEST_BASE_URL=http://127.0.0.1:8765 \
TEST_ADMIN_PASSWORD=integration-test-password \
php tests/http-security.php

See CONTRIBUTING.md for contribution guidance and SECURITY.md before deploying the agent publicly.

Limitations

  • FTP Agent edits files located in the same hosting account; it is not a remote FTP client.
  • It does not edit Word documents, PDFs, images, or executable source files by default.
  • It is a focused content-maintenance tool, not a general-purpose coding agent.
  • Approval, off-site backups, staging, and access controls remain necessary for production use.

License

Released under the MIT License.

About

Lightweight self-hosted AI website content agent for PHP shared hosting

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages