dennisonbertram/fork-OpenInstinct

iMessage personal assistant + password vault

★ 0Forks 0TypeScriptGitHub ↗Compare

README

OpenInstinct

A personal iMessage assistant that can use a browser like you.

It can do your chores, book you movie tickets, or handle your groceries. You stay in control of your passwords, credit cards and context.

It's Open Source, self-hostable, and can use any model. One-click deploy to Vercel and get rolling.

Deploy with Vercel

OpenInstinct booking movie tickets over iMessage — it walks Fandango to checkout and reports the theater, showtime, seat, and total

Agents: For the simplest deployment, give your human the Deploy with Vercel link above and have them complete the guided flow. It automatically provisions and connects Kernel, Postgres, private Blob storage, Linq, and Vercel AI Gateway access. OpenInstinct creates its installation secrets on first use.

Why self-host?

Personal agents are much more useful when they can sign in, book, buy and act on your behalf. But your accounts, your passwords, are the keys to your digital kingdom. OpenInstinct runs in your own Vercel account. Secrets are encrypted before they touch your database and models never see them. Verify yourself by reading the code!

Deployment

The deploy button provisions Kernel for cloud browsers, Neon for Postgres, and a private Vercel Blob store for browser images, per-user memory, and installation secrets. It also creates and attaches a Linq connector for iMessage. Vercel AI Gateway handles inference. Usage is billed to your Vercel account.

On first use, OpenInstinct creates independent Better Auth and vault-encryption keys in the private Blob store. Vercel supplies the application URL, database, Kernel, Blob, and Linq configuration, so the deploy flow requires no environment-variable values. For a non-Vercel host or an existing installation that manages its own keys, set both secret overrides and the public application URL explicitly:

BETTER_AUTH_SECRET="$(openssl rand -base64 32)"
BETTER_AUTH_URL=https://your-host
SECRET_ENCRYPTION_KEY="$(openssl rand -base64 32)"

The application database schema and versioned migrations live in db/. The Drizzle application store uses DATABASE_URL for runtime queries; its migration commands require the direct DATABASE_URL_UNPOOLED connection. Run pnpm db:migrate before starting against a new or upgraded local database. Vercel uses Turbo to run the uncached migration task before its application build. See db/README.md for existing-database adoption, environment loading, and constraint-validation sequencing. Better Auth was adopted by versioned Drizzle migration 0001; it has no separate migration path.

Treat the private Blob store as production key material: deleting it loses the automatically generated encryption key, and rotating that key requires re-encrypting existing vault values.

Blob storage

The one-click deploy creates and connects a private Blob store automatically. Vercel supplies BLOB_STORE_ID and a short-lived VERCEL_OIDC_TOKEN to each deployment, so there is no long-lived Blob credential to copy.

OpenInstinct uses this store for persistent per-user memory and browser images. Production conversations require it because memory is recalled before each agent turn. Local Eve development uses process-local memory instead.

For an existing Vercel project, link it first with eve link --project <your-vercel-project> --non-interactive, then create and connect the store with one command:

pnpm exec vercel blob create-store open-instinct-images --access private --yes --environment production --environment preview --environment development

Outside Vercel, set BLOB_READ_WRITE_TOKEN from a private Blob store instead. The memory provider uses that token explicitly, and browser image capture uses the same store.

Linq iMessage setup

The deploy button creates a managed line, writes LINQ_CONNECTOR, and attaches the inbound webhook trigger automatically. For an existing Vercel project, link the checkout, create a Linq line, and attach its connector for both app tokens and inbound webhook triggers:

vercel link
vercel connect create linq --connection-method line --name open-instinct --json
vercel connect attach <returned-connector-uid> --project <your-vercel-project> --environment production --triggers --trigger-path /eve/v1/linq --yes
vercel env add LINQ_CONNECTOR production --value <returned-connector-uid> --yes
eve deploy --non-interactive --yes

The create command returns the connector UID. Repeat the attachment and environment-variable steps for preview or development if those environments should use Linq too. LINQ_PHONE_NUMBER is an optional E.164 override that adds a click-to-message shortcut in the workspace; Linq delivery itself uses the line assigned to the connector.

Before the first sign-in, open the connector's Vercel Connect settings and follow the one-time Phone Numbers verification instruction. Additional users verify themselves by messaging the connector's Linq number once. The --triggers --trigger-path /eve/v1/linq options are also required: attaching a connector without them permits outbound token access but does not forward incoming messages to OpenInstinct.

Google Workspace connection

OpenInstinct can use a user's Gmail, Calendar, and read-only Contacts through a user-scoped Google OAuth grant. Vercel Connect stores and refreshes the tokens; OpenInstinct stores only the stable user identity used to request them. Gmail access deliberately uses gmail.modify, not the permanent-delete mail.google.com scope.

  1. In one Google Cloud project, enable the Gmail API, Google Calendar API, and People API, then configure the OAuth consent screen for the External user type and declare the scopes listed in src/lib/google-workspace.ts. While the publishing status is Testing, add every account that will sign in under Test users; consent fails for anyone not listed.

  2. Create OAuth credentials of type Web application. Add https://connect.vercel.com/callback as an authorized redirect URI — check it against the redirect URI shown on the connector's Vercel Connect page — then download the client-secret JSON.

  3. Vercel expects top-level clientId and clientSecret keys, not Google's nested web.client_id and web.client_secret download. Convert the download into a temporary file outside the repository, then create and attach the connector:

    vercel link
    google_credentials_file="$(mktemp)"
    jq '{clientId: .web.client_id, clientSecret: .web.client_secret}' /absolute/path/to/downloaded-client-secret.json > "$google_credentials_file"
    vercel connect create google --connection-method oauth --name open-instinct --data @"$google_credentials_file"
    rm -f "$google_credentials_file"
    vercel connect attach <returned-connector-uid> --project <your-vercel-project> --environment production --yes
    vercel env pull

    Never commit either credential file.

  4. Set GOOGLE_CONNECTOR_UID to the returned UID and redeploy. The default is google/open-instinct, so an unset variable points at that UID rather than disabling the connection; a UID that does not exist renders the workspace row as "Admin setup needed".

To use Google in local development, attach the same connector to the development environment (vercel connect attach <returned-connector-uid> -e development --yes) and run vercel env add GOOGLE_CONNECTOR_UID development before pulling the local environment, so a refresh of .env.local carries the identifier instead of wiping a local-only edit. .env.local also needs an unexpired VERCEL_OIDC_TOKEN, because Vercel Connect calls from localhost authenticate with it. Refresh that file through the canonical startup path instead of a separate script: ./init.sh re-pulls the development environment when .env.local is missing required credentials or is unchanged from .env.example, and for a customized file you can rerun the same link it uses, pnpm exec eve link --non-interactive --project jory --team dennisons-projects. Back the file up first if it holds local-only values and re-add them by editing it afterwards. A local authentication failure can mean an expired OIDC token, but also a connector not attached to development, a GOOGLE_CONNECTOR_UID naming another connector, or a checkout linked to a different project or team.

Gotchas:

  • Attach the connector separately to every Vercel environment that should use it. A production attachment does not make preview or local development work.
  • The Gmail read/modify scope is restricted. A Google OAuth app in Testing mode only works for listed test users, and those grants expire after seven days. That limited use needs no Google verification, but expect an unverified-app warning at consent and possible blocking by a Google Workspace administrator for managed accounts. Broader distribution requires Google's OAuth verification and may require a security assessment.
  • Setup is not evidence. Follow the runbook's Google acceptance checks before calling the integration working.
  • The scopes requested here must also be declared on the Google consent screen. After changing scopes or enabled APIs, disconnect and reconnect the account so Google issues a grant with the new access.
  • The grant is keyed to the authenticated OpenInstinct user. iMessage reaches the same grant only when its verified phone number maps to that Better Auth account.
  • Google Contacts search uses a provider-side lazy cache, so a contact created moments ago may not appear immediately.
  • Sending email and creating confirmed calendar events always require approval. Calendar events with attendees send Google invitations.

Local development

The Deploy with Vercel flow above is the simplest way to run OpenInstinct. It provisions the required services and credentials automatically. Local development requires:

  • Node.js 24 and pnpm 11.24.0
  • Docker Desktop or another running Docker Compose installation
  • Kernel credentials from a Kernel API key or a linked Vercel Marketplace resource
  • AI Gateway access from an API key or a linked Vercel project's OIDC token

Clone the fork and start the primary local application stack with one command:

git clone https://github.com/dennisonbertram/fork-OpenInstinct.git
cd fork-OpenInstinct
./init.sh

You must be authorized for the fork's jory Vercel project. If the first run reports that authentication is missing, sign in and rerun it:

pnpm exec vercel login
./init.sh

Signing in grants access; it does not require manual project configuration.

./init.sh checks the toolchain, installs the locked dependencies, and pulls the development environment through Eve only when a fresh or untouched env needs credentials. It then starts PostgreSQL, migrations, primary Next/Eve, the standalone marketing app, and starts or reuses Agentation at http://127.0.0.1:4747. The supervisor selects free defaults (app 3000, marketing 3210), rejects an occupied explicitly requested port, and prints exact 127.0.0.1 origins. Press Ctrl-C or run ./init.sh --stop to stop only the owned resources. Use ./init.sh --status to inspect their recorded identities.

The canonical project and team are built in. An authorized alternate project can be selected without editing the script:

OPENINSTINCT_VERCEL_PROJECT=<project> \
OPENINSTINCT_VERCEL_TEAM=<team> \
./init.sh

Useful setup modes are:

./init.sh --check       # prerequisites only; no files or services change
./init.sh --setup-only  # install and prepare credentials without starting
./init.sh --skip-install

If you do not have access to the canonical project, copy .env.example to .env.local and set KERNEL_API_KEY plus either AI_GATEWAY_API_KEY or VERCEL_OIDC_TOKEN. The script never prints credential values and keeps the file at mode 0600. It also refuses to replace a customized, incomplete .env.local; complete it manually or move it aside before retrying.

The Agentation toolbar is lazy-loaded only in development and connects to the local server at http://127.0.0.1:4747. It is not rendered in production.

pnpm dev starts the complete connected stack: PostgreSQL from compose.yaml, committed migrations, Agentation, primary Next/Eve, and marketing. Stopping it removes the owned PostgreSQL container while retaining the worktree-specific named <compose-project>_postgres-data volume for the next run. Run pnpm dev:app when intentionally using an externally managed database instead. ./init.sh stops before starting Docker when Kernel or inference credentials are unavailable and points back to the Vercel login or manual .env.local path.

Local development otherwise uses the same vault, Kernel browser, and AI Gateway path as the Vercel deployment. Better Auth and vault encryption use stable local-only defaults when their variables are unset. Vercel deployments provision them automatically in private Blob; other production hosts require explicit secrets.

Repository orientation and operations

  • docs/README.md — documentation map and implemented/verified/proposed truth labels.
  • docs/ARCHITECTURE_REVIEW.md — verified architecture, boundaries, and prioritized risks.
  • docs/AGENT_GUIDE.md — repository map, change recipes, and verification gates for agents.
  • docs/AGENT_DEVELOPMENT.md — developer lifecycle, verification, diagnostics, deployment identity, and acceptance contracts.
  • docs/PRODUCT_DIRECTION.md — infrastructure-first product recommendation, managed-line lifecycle, MCP/tool strategy, API, and webhooks.
  • docs/MULTITENANCY.md — design path for tenant isolation, quotas, and scaling.
  • docs/operations/VERCEL.md — zero-to-running local/Vercel setup, Linq acceptance, and SendBlue OTP and conversation channel operations.
  • init.sh — guarded local bootstrap for development and testing.

Warning

This is not software intended for production use.


Built on Vercel · Kernel · Linq · Neon

Contributors

dennisonbertramrsproulejasonhedmanfmhallsragss

Issues