EmCP is a self-hosted Model Context Protocol host built on Rails 8, based on the railsapp template.
Operator UI uses session login (User). MCP clients authenticate with ApiKey Bearer tokens and/or per-server OAuth 2.1 (PKCE). Integration code still lives under servers/<code>/ as STI subclasses of McpServer.
The previous Sinatra host is archived under
legacy/on this branch for reference while the port is validated. Do not merge tomainuntil this branch is green.
cp .env.example .env # or set vars below
bundle install
bin/rails db:prepare
bin/rails db:seed
bin/devKeep only deploy-critical secrets in .kamal/secrets / deploy.yml (RAILS_MASTER_KEY, Google OmniAuth, APP_HOST).
Put the rest in a single file on the server volume (not in git):
# on the deploy host
install -m 600 /dev/stdin /data/emcp/storage/.env < .env # from your machine via scp/sshThat file is mounted at /rails/storage/.env and loaded at boot for web + worker. Existing Kamal/env values are not overridden.
| Variable | Purpose |
|---|---|
EMCP_PUBLIC_URL |
Public base URL (no trailing slash), used in MCP/OAuth metadata |
EMCP_USER1_PASSWORD |
Password for seeded operator user1@emcp.local (dev default: emcp-dev-password) |
API_KEY_HMAC_SECRET_KEY |
HMAC secret for ApiKey digests |
- Email:
user1@emcp.local - Password:
EMCP_USER1_PASSWORD(or the development default) - Integrations:
/or/servers - Auth per server:
/servers/<code>/auth
Endpoint per integration:
${EMCP_PUBLIC_URL}/servers/<code>/mcp
ApiKey (static Bearer) — in console:
User.find_by(email: "user1@emcp.local").api_key!
# => "tkn_usr_..."Send Authorization: Bearer tkn_usr_....
OAuth 2.1 — discovery:
/.well-known/oauth-authorization-server/servers/<code>/.well-known/oauth-protected-resource/servers/<code>/mcp
McpServer(AR + STI) owns host behavior formerly inlib/emcp/integration.rbservers/<code>/server.rbregisters withEmcp.register_integration(...)and overrides tools/auth- Credentials: encrypted columns +
storage/mcp/<code>/files for CLI compat - MCP OAuth clients/tokens: AR tables (
mcp_oauth_*)
Same set as before: HEY, Basecamp, Fatture in Cloud, Google Workspace, Toggl Track, Bluesky, Twitter/X, TeslaMate. See each servers/*/README.md.
bin/rails test test/models/mcp_server_test.rb test/services/mcp_oauth_provider_test.rb test/controllers/mcp_serversPrefer Kamal from the railsapp template (config/deploy.yml). Wire API_KEY_HMAC_SECRET_KEY, EMCP_PUBLIC_URL, and EMCP_USER1_PASSWORD into secrets. Keep TeslaMate/Postgres and CLI binaries available to the app container as needed.