Skip to main content

Adapt

Adapt is a FastAPI server that turns files in a directory into APIs and UIs.

  • Datasets (.csv, .xlsx, .xls, .parquet) become API endpoints and DataTables UIs
  • Legacy .xls workbooks are read-only. Modern .xlsx workbooks support CRUD operations.
  • Markdown/HTML become browsable pages
  • Media files become streaming endpoints and player/gallery UIs
  • Python files can register custom routers
  • Everything is searchable in one place via full-text /search
  • Everything is reachable by agentic tools via an MCP server at /mcp

Quick Start

pip install adapt-server
adapt addsuperuser --username admin /path/to/docroot
adapt serve /path/to/docroot

# Generate permissions for all discovered resources
adapt admin create-permissions /path/to/docroot __all__

# Everything below here can be done in the admin UI at
# http://localhost:8000/admin/ after logging in with the superuser account.
#
# Create a regular user
adapt admin create-user --username editor --password secret /path/to/docroot

# Reset an existing password and revoke that user's browser sessions
adapt admin change-password --username editor /path/to/docroot

# By default, the editor user has no permissions.
# See available groups (created by `adapt admin create-permissions`) and assign user to desired group
adapt admin list-groups /path/to/docroot
adapt admin add-to-group --username editor --group <group_name> /path/to/docroot

Useful URLs:

  • / landing page
  • /admin/ admin UI
  • /api/<resource> resource API
  • /ui/<resource> resource UI
  • /schema/<resource> resource schema
  • /search full-text search across every resource you can read
  • /mcp MCP server for agentic tools (see MCP Interface below)

What Adapt Generates

From files in your docroot, Adapt auto-discovers resources and mounts routes with extensionless URLs where possible.

Example:

data/
  employees.csv
  sales.xlsx
  video.mp4
  readme.md
  stats.py

Rough output:

  • /api/employees, /ui/employees, /schema/employees
  • /api/sales/<sheet>, /ui/sales/<sheet>
  • /media/video.mp4, /ui/video.mp4, /ui/media
  • /readme
  • /api/stats/*

Current Security Posture

This reflects the current implementation in the codebase.

In Place

  • Authentication: session cookies, API keys (X-API-Key), and inactive-user enforcement
  • Authorization: RBAC (users, groups, permissions), plus superuser bypass
  • Password security: PBKDF2 hashing with per-user salts
  • Password changes: self-service and administrator resets revoke all browser sessions for the user
  • Session security: expiration enforcement, sliding renewal, cleanup task
  • CSRF protection: enforced for cookie-authenticated unsafe methods (POST/PUT/PATCH/DELETE), including mixed session + API-key requests
  • Redirect hardening: login next paths are validated as local relative paths
  • Response hardening: CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, HSTS (when TLS is enabled)
  • Host header hardening: Trusted Host middleware
  • Data integrity: lock-based, atomic writes for mutable dataset plugins
  • Auditability: audit records for authentication, administration, and successful dataset mutations
  • Sensitive response cleanup: admin user APIs no longer expose password_hash

Important Deployment Notes

  • Use TLS in non-local environments (--tls-cert + --tls-key) so secure cookies and HSTS protections are effective.
  • API-key-only clients are exempt from CSRF checks by design; cookie-auth browser flows require CSRF tokens.

Core Features

  • Adaptive discovery and route generation
  • Dataset CRUD with schema exposure
  • Caching with invalidation on mutations
  • Built-in admin UI for users/groups/permissions/locks/cache/api keys/audit logs
  • Root-level file upload endpoint (POST /api/uploads) with permission checks and audit logging
  • Optional landing-page upload card for authenticated users with root write permission
  • Plugin architecture with companion overrides in .adapt/
  • Permission-filtered full-text search across every resource type
  • MCP server for agentic tool access, mounted alongside the REST API

Upload permission note:

  • Non-superusers need write permission on the document-root boundary.
  • In admin permission creation, use an empty resource (or __root__) with action write, then assign that permission through a group.

Full-Text Search

GET /search?q=<query> searches datasets, Markdown, HTML, and media metadata in one ranked list, filtered to what the caller may read — a query term that matches a resource you can't see never shows up, and never leaks via the result count either.

curl -H "X-API-Key: <key>" "http://localhost:8000/search?q=parental+leave"

The index refreshes incrementally on startup (search_on_startup, default true) and can be rebuilt on demand with adapt reindex <root>. See the API Reference for query parameters and result shape.

MCP Interface

Adapt mounts a Model Context Protocol server at /mcp, on the same host/port as everything else, exposing five tools that wrap the same permission checks and plugin methods as the REST API — list_resources, get_schema, read_resource, write_resource, and search. There's no separate process, no separate API surface, and no extra permission model to maintain.

Minimal walkthrough — create an account for the agent, grant it read access, mint an API key, and connect a client:

adapt addsuperuser /path/to/docroot --username admin
adapt serve /path/to/docroot &

adapt admin create-permissions /path/to/docroot __all__
adapt admin create-user /path/to/docroot --username agent --password <strong-password>
adapt admin add-to-group /path/to/docroot --username agent --group <resource>_readonly

Log in as agent and self-issue an API key from /profile (any authenticated user can create their own key — no superuser needed), then point a client at /mcp with that key:

# Claude Code CLI
claude mcp add --transport http adapt http://localhost:8000/mcp \
  --header "X-API-Key: <key>"
// Generic MCP client config (Claude Desktop and similar)
{
  "mcpServers": {
    "adapt": {
      "url": "http://localhost:8000/mcp",
      "headers": { "X-API-Key": "<key>" }
    }
  }
}

MCP checks authentication when a tool runs. Tool calls use the shared authentication resolver, which accepts a session cookie or an API key. API keys are the supported and recommended mechanism for MCP clients. Set mcp_enabled: false in .adapt/conf.json (or ADAPT_MCP_ENABLED=false) to remove /mcp entirely. For setup and troubleshooting, read the MCP guide. For dataset reads, sort is the column name and order must be asc or desc.

Dataset Mutation Envelope

For dataset endpoints, write operations use this payload structure:

{
  "action": "create|update|delete",
  "data": []
}

Use object data for update/delete as needed (for example, with _row_id).

CLI (Common Commands)

adapt serve <root> [--host ... --port ... --tls-cert ... --tls-key ... --reload --readonly --debug]
adapt check <root>
adapt addsuperuser <root> --username <name>
adapt list-endpoints <root>
adapt reindex <root> [--force]
adapt admin list-resources <root>
adapt admin create-permissions <root> __all__

Use --reload during development. Uvicorn watches Python files in the document root and restarts Adapt after a change.

Helm (Kubernetes)

A Helm chart is included at charts/adapt/.

Uploads are disabled by default. Enable them by passing the upload environment variables through Helm values so the container receives the same config as a local install.

Ephemeral (default — data lost on pod restart):

helm install adapt ./charts/adapt

Dynamic persistent volume (cluster provisions storage automatically):

helm install adapt ./charts/adapt \
  --set persistence.enabled=true \
  --set persistence.size=20Gi \
  --set persistence.storageClass=standard

Existing PVC (cluster admin creates the PVC beforehand):

# Cluster admin creates the PVC first, e.g.:
kubectl apply -f my-adapt-pvc.yaml

helm install adapt ./charts/adapt \
  --set persistence.enabled=true \
  --set persistence.existingClaim=my-adapt-pvc

Key persistence values:

Value Default Description
persistence.enabled false Enable durable storage at /data
persistence.existingClaim "" Name of a pre-created PVC to mount
persistence.storageClass "" StorageClass name; cluster default if empty
persistence.accessModes [ReadWriteOnce] PVC access modes
persistence.size 10Gi Storage request size
persistence.mountPath "" (uses adapt.rootPath) Mount path inside the container
persistence.annotations {} Annotations added to the PVC

Example upload settings in values.yaml:

env:
  - name: ADAPT_UPLOAD_ENABLED
    value: "true"
  - name: ADAPT_UPLOAD_MAX_SIZE_BYTES
    value: "10485760"
  - name: ADAPT_UPLOAD_ALLOWED_EXTENSIONS
    value: ".csv,.md,.txt"
  - name: ADAPT_UPLOAD_STRICT_MIME_SNIFFING
    value: "true"

When uploads are enabled, authenticated users with write permission on the document-root boundary see the upload card on / and can upload directly from the landing page.

Admin responsibility: the cluster admin must supply a matching StorageClass and sufficient quota before enabling dynamic provisioning. For ReadWriteOnce volumes, keep replicaCount=1 (the default).

Bootstrap a superuser automatically (requires persistence.enabled=true — see docs/manual/installation.md for why):

helm install adapt ./charts/adapt \
  --set persistence.enabled=true \
  --set bootstrapAdmin.enabled=true

kubectl get secret adapt-bootstrap-admin -o jsonpath='{.data.password}' | base64 -d && echo

Expose it without an Ingress controller (e.g. bare-metal/k3s):

helm install adapt ./charts/adapt --set service.type=NodePort --set service.nodePort=30080

charts/adapt/values-dev.yaml bundles persistence + bootstrap + a pinned NodePort together for local VM/k3s development — see docs/manual/installation.md.

Documentation

Read the full documentation at https://www.mcindi.com/adapt/.

Detailed docs live under docs/manual/.

Generated reference docs live under docs/reference/ and are published via MkDocs and GitHub Pages.

  • REST API reference: generated from app routes with an empty docroot
  • OpenAPI schema artifact: generated from that same common-surface schema
  • Python API reference: generated from docstrings and signatures

Build docs locally:

python -m pip install -e ".[dev]"
python -m pip install -r requirements-docs.txt
mkdocs build --strict

License

MIT. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

adapt_server-0.4.1.tar.gz (158.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

adapt_server-0.4.1-py3-none-any.whl (146.1 kB view details)

Uploaded Python 3

File details

Details for the file adapt_server-0.4.1.tar.gz.

File metadata

  • Download URL: adapt_server-0.4.1.tar.gz
  • Upload date:
  • Size: 158.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for adapt_server-0.4.1.tar.gz
Algorithm Hash digest
SHA256 5403613c3b5547351a4a7124efe4f915530cc0f51cd83f8c72c9cd4227a8ce3d
MD5 403f6e3812b465712b145aa8d5deb3c8
BLAKE2b-256 9fed409f918bf24a5ff25d110d4bd2c3c23382c0de1a29fca7d038b6302a3baa

See more details on using hashes here.

Provenance

The following attestation bundles were made for adapt_server-0.4.1.tar.gz:

Publisher: publish-pypi.yml on McIndi/adapt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file adapt_server-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: adapt_server-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 146.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for adapt_server-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a4115d90a2521b743e667a36db9b15d2bf8edef93934bcafa4ee3298a1d13160
MD5 04e1b44691de4ff2acc0c1be5a13ccd3
BLAKE2b-256 6f1cc35ba4485bfc6ced9f1a77eb4d95b47d76c36ee0e527f8b1a3ad343d6a19

See more details on using hashes here.

Provenance

The following attestation bundles were made for adapt_server-0.4.1-py3-none-any.whl:

Publisher: publish-pypi.yml on McIndi/adapt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.5.2

2 files

0.5.0

2 files

0.4.2

2 files

This release

0.4.1 This release

2 files

0.4.0

2 files

0.3.0

2 files

0.2.8

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.0

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page