Harnios MCP
OfficialHarnios MCP
Harnios is a self-hosted, MCP-based storage system that gives every AI assistant you use — Claude, ChatGPT, Cursor, or anything else — a shared, persistent memory of your business: knowledge base, skills, projects, operational tables, and reports, all in one place. Connect a new tool once, and it reads and writes through the same store instead of starting from zero.
Under the hood, it's an autonomous, serverless system for running an AI-based Company OS. It can be deployed to serverless platforms like Vercel (or similar) or run locally on Node.js, and requires an external S3-compatible object storage backend — either your own, or a local self-hosted MinIO instance for development.
This repo pairs that local MinIO setup with the Next.js app that uses it. See specs/001-s3-self-hosted-storage/quickstart.md for a full end-to-end validation walkthrough.
The Next.js app (web editor + MCP server) lives entirely in frontend/ — that's the folder to point a future Vercel project's Root Directory setting at (see specs/006-frontend-folder-structure). Everything else at the repo root (docker-compose.yml, data/, scripts/) is local-dev infrastructure that isn't deployed.
Technical Overview
App:
frontend/is a single Next.js 16 (App Router) application in TypeScript, serving both the web editor UI and the MCP server from one deployable unit — no separate backend service.MCP server: built on
@modelcontextprotocol/sdk+mcp-handler, exposed as a Streamable HTTP endpoint at/mcp(see S3 Storage MCP Server below).Storage: all persisted state — files/directories exposed via MCP and the editor, plus OAuth clients/sessions and personal access tokens — lives in a single S3-compatible bucket, accessed via
@aws-sdk/client-s3. No database is used; the bucket is the datastore.Auth: two independent ways to authenticate to the MCP server — full OAuth 2.0 (for hosted AI assistants like ChatGPT/Claude adding it as a connector, spec 008-mcp-oauth) and owner-generated, non-expiring personal access tokens (for scripts/CLI tools/
.mcp.json, spec 013-mcp-token-auth). The web editor at/filesis gated by the same owner credential (spec 009-editor-login-gate).Statelessness: because all state lives in the S3 bucket rather than on local disk or in-memory, the app is safe to run as ephemeral serverless functions (e.g. on Vercel) — any instance can serve any request.
No code changes to switch storage backend: any S3-compatible provider works (self-hosted MinIO, AWS S3, or another compatible service) — swap it via environment variables only; see below.
Related MCP server: Tycana
Getting Started
This project includes a self-hosted, S3-compatible object storage service (MinIO) for local development. It runs entirely on your machine — no cloud account or credentials required.
Start it:
docker compose up -dThe S3 API is available at http://localhost:9000 and the web console at http://localhost:9001 (default credentials: minioadmin / minioadmin). Override the ports via MINIO_API_PORT / MINIO_CONSOLE_PORT (see .env.example) if either default port is already in use on your machine — startup will otherwise fail fast with a clear "port already in use" error rather than silently picking a different port.
Stop it:
docker compose stopAlways use docker compose (not the legacy docker-compose).
Buckets & Objects
No buckets are created automatically — create whatever buckets you need with any S3-compatible client (e.g. the MinIO Client mc or the AWS CLI) pointed at http://localhost:9000 using the credentials above. See quickstart.md for a full walkthrough.
Resetting local data
To permanently wipe all locally stored buckets/objects and start fresh:
./scripts/reset-storage.shThis stops the service, clears its data, and starts it back up with no buckets present.
Where the data lives
Storage data is bind-mounted to ./data/minio on the host (not a Docker-managed volume), so bucket/object structure is visible outside Docker. Note that MinIO stores each object's content wrapped in its own binary xl.meta format (small objects are inlined directly into it) rather than as a plain file — so you can browse the bucket/key folder layout under ./data/minio, but you can't open an object's content directly in a text editor from there. Use the S3 API (or the web console) to read/write actual content. This folder is git-ignored and owned by root on Linux hosts (MinIO's container runs as root); use ./scripts/reset-storage.sh rather than a manual rm -rf to clear it without needing sudo.
Configuring the app's storage connection
The Next.js app (frontend/) connects to any S3-compatible storage backend — not only the local MinIO instance above — via environment variables it reads at startup (see specs/007-s3-storage-config). These are separate from the repo-root .env.example above, which only configures the local MinIO container: Next.js loads env files from its own project root, so the app's own settings belong in frontend/.env.local, copied from frontend/.env.example:
cp frontend/.env.example frontend/.env.localThe defaults match the local MinIO instance started above. To point the app at a different S3-compatible provider, edit frontend/.env.local (endpoint, region, access key, secret key, bucket, and path-style vs. virtual-hosted-style addressing) and restart the app — no code changes required.
The configured bucket (S3_BUCKET) must already exist. The app validates the connection at startup and logs a clear warning if required settings are missing, the endpoint is unreachable, credentials are rejected, or the bucket doesn't exist — but it no longer refuses to start over this (spec 014-os-init-page superseding spec 007's original fail-fast behavior): every request is instead sent to /init until storage is reachable, so the app is always up to guide you through fixing it. For the local MinIO instance, create the bucket once via the web console (http://localhost:9001) or any S3-compatible CLI before starting the app — see specs/007-s3-storage-config/quickstart.md for the full walkthrough.
Connecting storage from the app (/init)
If storage isn't connected yet (missing configuration, unreachable endpoint, rejected credentials, or a missing bucket) — including a completely fresh clone or deploy with no configuration at all — every page redirects to /init, which shows a setup helper covering everything the app needs to run in one place: the storage connection, the owner sign-in credential, and an optional system name. Fill it in and it generates one ready-to-paste configuration snippet, plus plain instructions for applying it either locally (frontend/.env.local) or on a hosting provider (e.g. Vercel: Project → Settings → Environment Variables → paste). Nothing typed into this helper is ever sent to the server; apply the snippet yourself and restart/redeploy.
Once storage is connected and signed in as the owner (see below), /init also bootstraps a fresh Company OS skeleton on an empty bucket — one confirmation click, no questions asked — creating os/, data/, a root AGENTS.md, and os/skills/init.md. Either right after that or on any later visit once the structure already exists, /init shows the MCP server URL and OAuth instructions for connecting Claude or ChatGPT as a connector, plus a link to /files — connecting an assistant is the actual next step, since it's the assistant (reading os/skills/init.md) that interviews you and fills in the business's own details (os/identity.md and everything else), not this app. See specs/014-os-init-page for the full spec.
Running with external storage (no local MinIO)
The repo-root docker-compose.yml/MinIO setup above is only for local development convenience — it is not a dependency of the app itself. frontend/ runs against any S3-compatible bucket, so you can skip docker compose entirely and point it at storage you already have (AWS S3, or any other S3-compatible provider/self-hosted instance reachable from where the app runs).
Locally, against external storage:
cp frontend/.env.example frontend/.env.localFill in
S3_ENDPOINT,S3_REGION,S3_ACCESS_KEY_ID,S3_SECRET_ACCESS_KEY,S3_BUCKETfor your external provider (setS3_FORCE_PATH_STYLE=falseif it needs virtual-hosted-style addressing — most providers other than self-hosted MinIO do), and setOAUTH_OWNER_USERNAME/OAUTH_OWNER_PASSWORD.Make sure the bucket already exists (it's never created automatically).
cd frontend && npm install && npm run dev— nodocker compose upneeded.
Deployed serverless (e.g. Vercel):
Import the repo and set the project's Root Directory to
frontend/(see specs/006-frontend-folder-structure) — this repo has no root-levelpackage.json, onlyfrontend/is a deployable Next.js app.In the platform's environment variables UI (not a
.envfile — those aren't deployed), set the same variables listed infrontend/.env.example:S3_ENDPOINT,S3_REGION,S3_ACCESS_KEY_ID,S3_SECRET_ACCESS_KEY,S3_BUCKET,S3_FORCE_PATH_STYLE,OAUTH_OWNER_USERNAME,OAUTH_OWNER_PASSWORD, and optionallyMCP_BOOTSTRAP_PATH/OS_NAME.Deploy. Because all app state (files, OAuth clients, personal access tokens) lives in the external bucket rather than on local disk, the deployment is stateless and safe to run as ephemeral serverless functions — no persistent volume or database needed.
Once live,
/mcpand/fileswork exactly as in local dev, just at your deployment URL instead ofhttp://localhost:3000.
S3 Storage MCP Server
An MCP server exposes the configured storage above as filesystem-like tools (create/read/update/delete files; create/list/delete directories, recursively; move/rename either) — see specs/002-s3-mcp-server/contracts/mcp-tools.md for the full tool list, and specs/002-s3-mcp-server/quickstart.md for a runnable walkthrough.
Three additional tools — list_directory_tree, find_files_by_name, search_file_content — let a connected assistant map or search a large nested tree (e.g. a Company OS with many skills/policies folders) in a single call instead of one list_directory call per level; see specs/022-mcp-tree-search/contracts/mcp-tools-tree.md for the full contract, and specs/022-mcp-tree-search/quickstart.md for a runnable walkthrough.
Prerequisites: the storage backend must be running and reachable (e.g. docker compose up -d for local MinIO), its bucket must already exist, and frontend/.env.local must be set up per the section above.
Install dependencies once:
cd frontend
npm installStart the MCP server:
cd frontend
npm run devThis exposes the MCP endpoint (Streamable HTTP) at http://localhost:3000/mcp. It operates against a single, configured bucket (S3_BUCKET in frontend/.env.example, default mcp-storage) on whichever S3-compatible backend frontend/.env.local points at — separate from any bucket you create manually via the local-MinIO section above.
Dynamic tool descriptions from a bootstrap file
Optionally set MCP_BOOTSTRAP_PATH in frontend/.env.local (e.g. MCP_BOOTSTRAP_PATH=assistant/AGENTS.md) to a Markdown file already in storage. When set, every tool's description shown to a connecting client is prepended with guidance generated from that file's optional <!-- mcp-context: ... --> and <!-- mcp-triggers: ... --> HTML-comment markers — telling the client what the storage is for, when to use it, and to read the bootstrap file first. Edits to the file are picked up within about a minute, with no restart or redeploy. If the variable is unset, the file is missing, or neither marker is present, every tool simply falls back to its plain original description — see specs/010-dynamic-tool-descriptions/quickstart.md for a runnable walkthrough.
Managing which tools are active
Sign in as the owner and open /tools to see every tool's current active/disabled status, and to disable or re-enable any of them right there — no environment variable, no restart. A change is confirmed explicitly (naming the tool and the new status) before it's applied, and takes effect on the very next MCP request; the page also warns that AI assistant sessions already connected before the change may not see it until they reconnect. See specs/025-manage-tools-page/quickstart.md for a runnable walkthrough. (Earlier versions of this app used an MCP_DISABLED_TOOLS environment variable for this — spec 023-mcp-tool-toggle — which this page's storage-backed mechanism has superseded; that variable is no longer read.)
Connecting AI assistants (ChatGPT, Claude, etc.) via OAuth
The MCP server requires OAuth (spec 008-mcp-oauth) before any tool call is allowed — this is what lets you add it as a remote connector in hosted AI assistants. One-time setup, in addition to the storage setup above:
Set an owner sign-in credential in
frontend/.env.local(separate from the S3/MinIO credentials above — this one gates who can approve AI assistants, not storage access):OAUTH_OWNER_USERNAME=owner OAUTH_OWNER_PASSWORD=<choose a password>Start the server (
npm run dev) — it logs a clear warning at startup if these are missing (same as the storage settings above), but still starts; sign-in simply fails until they're set.
To add the server as a connector: in ChatGPT or Claude's "add connector"/"add MCP server" flow, point it at http://localhost:3000/mcp (or your deployed URL). The assistant discovers the OAuth flow automatically; you'll be prompted to sign in with the credential from step 1 and approve the connection. See specs/008-mcp-oauth/quickstart.md for the full walkthrough, including reviewing and revoking connected assistants at /settings/connected-apps.
Web File Explorer & Markdown Editor
A browser UI at /files (same app/dependencies as the MCP server above — docker compose up -d then npm run dev must both be running) lets you browse the MCP_STORAGE_BUCKET folder/file tree and edit existing files directly: .md files open in a split view (raw Markdown left, live-rendered preview right); other text files (.txt, .html, .xml, .css, .bpmn, .json, and more) open in a plain-text editor. Binary files (PDF, JPG/PNG, DOC/DOCX, XLS/XLSX, ZIP) are detected and shown with a clear "can't be edited here" message instead, with an Open/Download action to retrieve them regardless — PDFs and images open directly in a new browser tab. Uploads accept this same broad set of document, spreadsheet, image, diagram, and markup types (up to 25 MB per file), and every file in the tree shows an icon for its type. Saves are explicit (no autosave) — unsaved changes are indicated, and you're warned before navigating away or closing the tab with changes pending. A file's path is part of the URL itself (e.g. /files/notes/todo.md), so any file can be opened directly via a bookmarked or shared link (spec 018-editor-file-deep-link); the previous /editor URL still works and redirects here. See specs/003-web-file-editor/contracts/api-routes.md for the underlying API, specs/003-web-file-editor/quickstart.md for a full walkthrough, and specs/028-file-storage-upload for the mixed-file-type upload/view support.
/files requires signing in first, with the same owner credential used for the MCP connector flow above — a signed-out visit redirects to the sign-in screen, and a session started from either entry point covers both. See specs/009-editor-login-gate/quickstart.md for the full walkthrough.
Open it at: http://localhost:3000/files
License
Licensed under the PolyForm Internal Use License 1.0.0 — free to use, run, and modify for your own or your company's internal operations; distribution (including selling or offering a product/service based on it) requires a separate agreement with the copyright holder.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityAmaintenanceNucleus MCP provides a local, unified memory layer that synchronizes context and decisions across different AI tools like Cursor, Claude Desktop, and Windsurf. It enables cross-platform state management and persistent knowledge storage using a shared local brain.122064MIT
- Alicense-qualityDmaintenanceAI-native productivity backend that gives your AI assistant persistent memory, pattern awareness, and computed intelligence about your work. 14 MCP tools for task management, daily planning, weekly review, and personal context.MIT
- Alicense-qualityDmaintenanceA portable self-hosted memory layer for AI tools, storing context, memories, and handoffs for access from any MCP-compatible client.35MIT
- AlicenseAqualityBmaintenanceShared, versioned memory for your agents across Claude Code, Cursor, Kiro and Grok. One MCP server, sourced answers, full history.3MIT
Related MCP Connectors
User-owned memory for AI agents, Copilot, Claude, IDEs, CLIs, and chat apps over remote MCP.
Your memory, everywhere AI goes. Build knowledge once, access it via MCP anywhere.
One memory, every AI: Claude, ChatGPT, Perplexity, Gemini, Cursor, OpenClaw, Hermes, any MCP client.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/harnios/harnios-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server