Read-only mirror. This repository is a read-only split of the
artisan-build/sinkmonorepo. Issues and pull requests are disabled here — please open them on the monorepo.
The receive side of Sink. It is consumed by the Sink app and provides the ingest path, metadata parsing, object storage, and retention pruning. The inbox UI and body-blind MCP server land in later build steps.
composer require artisan-build/sink-serverThis package is consumed by the Sink app. See the Sink app README for environment setup.
POST /ingest accepts a sink-contracts envelope authenticated with Authorization: Bearer <token>.
Tokens are resolved through artisan-build/built-for-cloud. Valid envelopes are upserted by
idempotency_key, raw MIME is written to object storage, and a queued parse job extracts searchable
metadata.
GET /capabilities is unauthenticated and reports the supported envelope major versions.
Raw MIME is stored on SINK_DISK at raw/{app}/{idempotency_key}.eml. Attachments are extracted by
the parse worker and stored at attachments/{app}/{idempotency_key}/{n}-{filename}. Body text is not
persisted in database columns; bodies remain only in the raw MIME object.
Publish the config with:
php artisan vendor:publish --tag=sink-server-configUseful environment variables:
SINK_ROUTE_PREFIXdefaults to empty.SINK_QUEUE_CONNECTIONselects the parse queue connection.SINK_DISKfalls back toFILESYSTEM_DISK, thenlocal.SINK_DB_*configures an explicit Postgressinkconnection. When omitted,sinkmirrors the app default database connection so local sqlite and CI migrations keep working.SINK_RETENTION_DAYSdefaults to7.SINK_MAX_MESSAGESoptionally caps retained message count.SINK_MAX_TOTAL_BYTESoptionally caps retained raw MIME bytes.
sink:maintain runs sink:prune. The service provider schedules it hourly. Pruning deletes expired
messages and object-storage blobs, then enforces optional message-count and byte caps oldest-first.
MIT. See LICENSE.