# Discord
Source: https://docs.getcore.me/access-core/channels/discord
Chat with CORE's Meta Agent in Discord
## Overview
Access CORE's Meta Agent directly in Discord. Chat with your agent in any server or via DM, take actions across your apps, and search your memory - all without leaving Discord.
**Coming Soon**: Discord integration is currently in development.
## Help Us Prioritize
We're building Discord support based on user demand. If you'd like to see this feature, please: ๐ **Comment +1** on [GitHub Issue #428](https://github.com/RedPlanetHQ/core/issues/428)
Your feedback helps us prioritize which channels to build next!
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support** or to share your Slack integration ideas!
# Email
Source: https://docs.getcore.me/access-core/channels/email
Email your Meta Agent for asynchronous assistance
## Overview
Send emails to **[brain@getcore.me](mailto:brain@getcore.me)** and get intelligent responses from CORE's Agent. Perfect for longer requests, asynchronous workflows, or when you're already in your email client.
## Getting Started
Simply email **[brain@getcore.me](mailto:brain@getcore.me)** from your registered email address. Your agent will:
1. Process your request
2. Search your memory if needed
3. Take actions across your connected apps
4. Reply with results and context
## How It Works
1. **Compose or forward** an email to [brain@getcore.me](mailto:brain@getcore.me) from your registered account
2. **Add your instructions** in the email body (or just forward with a quick note)
3. **Include context** by forwarding email threads, attaching files, or referencing past conversations
4. **Get intelligent replies** with drafted responses, action confirmations, or requested information
**Email Forwarding Workflow:**
When you forward an email to [brain@getcore.me](mailto:brain@getcore.me), CORE preserves the entire thread context, making it perfect for:
* Setting reminders to follow up
* Extracting action items and creating tasks
* Getting summaries of long threads
* Drafting context-aware responses
* Saving important discussions to memory
## Use Cases
**Scenario**: Never forget to follow up on important emails
```
To: brain@getcore.me
Subject: Fwd: Q1 Budget Approval
[Forward the email thread]
Remind me to follow up on this if I don't hear back by Friday.
```
CORE saves the email context to memory and will remind you at the right time, with full context of the original thread.
**Scenario**: Write emails that need information from other tools
```
To: brain@getcore.me
Subject: Draft response to client
I need to respond to Sarah's email about the API migration timeline.
Please draft a response that includes:
- Current status from Linear project "API Migration"
- Completed PRs from GitHub in the last week
- Any blockers mentioned in #engineering Slack channel
```
CORE gathers information from your connected apps and drafts a complete, context-aware email response.
**Scenario**: Turn email discussions into trackable tasks
```
To: brain@getcore.me
Subject: Fwd: Meeting notes - Product roadmap
[Forward the email with meeting notes]
Extract all action items from this email and:
- Create Linear issues for each task
- Assign them to the people mentioned
- Add them to the "Q1 Roadmap" project
- Reply with a summary of created tasks
```
CORE processes the email, creates tasks across your tools, and confirms what was done.
**Scenario**: Catch up on lengthy discussions quickly
```
To: brain@getcore.me
Subject: Fwd: Re: Re: Re: Design system discussion (24 messages)
[Forward the long email thread]
Summarize this thread for me:
- What's the current decision?
- Who's responsible for what?
- What are the next steps?
```
Perfect for when you're cc'd on a long thread and need the TL;DR without reading 50+ messages.
**Scenario**: Pull context from past conversations to answer emails
```
To: brain@getcore.me
Subject: Need context on authentication work
John is asking about the authentication system we built last quarter.
Find all the details:
- Original design decisions from Slack/memory
- Related GitHub PRs
- Documentation in Notion
Then draft a reply explaining the current architecture and why we chose it.
```
CORE searches your memory and connected tools, then drafts an informed response.
**Scenario**: Get help organizing your inbox
```
To: brain@getcore.me
Subject: Triage my action items
[Forward 5-10 emails that need responses]
Which of these emails need urgent attention and why?
For each:
- Priority level
- Why it matters
- Suggested response or action
```
CORE analyzes each email with context from your memory and suggests how to prioritize.
**Scenario**: Convert emails into delegated work without leaving your inbox
```
To: brain@getcore.me
Subject: Fwd: Bug report from customer
[Forward customer email about bug]
Create a high-priority Linear bug issue with:
- Title: "Customer report: [extract from email]"
- Description: [full customer report]
- Assign to: engineering on-call
- Send a Slack message to #bugs channel
- Draft a reply to customer saying we're investigating
```
CORE handles the entire workflow and gives you a draft customer response to review.
**Scenario**: Get detailed reports for email responses
```
To: brain@getcore.me
Subject: Weekly update for investors
Create a weekly update email covering:
- What shipped (GitHub releases + Linear completed issues)
- Team velocity (last 3 sprints from Linear)
- Customer feedback highlights (from support emails)
- Next week's priorities (from Linear current sprint)
Make it investor-friendly and concise.
```
CORE compiles data from multiple sources and drafts a polished update email.
## Example Emails
**Forward to Set Reminder:**
```
To: brain@getcore.me
Subject: Fwd: Partnership proposal from Acme Corp
[Forwarded email thread]
Set a reminder to follow up on this next Tuesday if they haven't responded.
Also save this to memory under "partnership opportunities."
```
**Draft Response with Context:**
```
To: brain@getcore.me
Subject: Help draft reply to CEO
The CEO just asked about our API rate limiting strategy.
Draft a response that includes:
- Current limits and why we chose them
- Any recent discussions about changing them (check Slack #engineering)
- Related GitHub issues or PRs
```
**Extract Action Items from Thread:**
```
To: brain@getcore.me
Subject: Fwd: Kickoff meeting notes
[Forwarded meeting notes email]
Extract all action items, create Linear issues for each,
and send a summary to #project-alpha Slack channel.
```
**Get Context for Email Reply:**
```
To: brain@getcore.me
Subject: Need pricing discussion context
Michael is asking about enterprise pricing.
Find our previous discussions about pricing tiers and
draft a response explaining our current structure.
```
## Response Time
* **Simple queries**: Usually within 1-2 minutes
* **Complex requests**: May take 5-10 minutes for thorough analysis
* **Batch operations**: Depends on number of actions (you'll get progress updates)
## Tips for Email Workflows
* **Forward liberally**: Forward any email thread to CORE for context, reminders, or drafting replies
* **Use subject lines**: Put key instructions in the subject for quick processing
* **Set follow-up reminders**: Never forget to circle back - just forward and ask for a reminder
* **Draft before sending**: Ask CORE to draft responses that need context from other tools
* **Batch forward**: Send multiple emails at once and ask for prioritization or summaries
* **Include deadlines**: "Remind me Friday" or "Follow up in 3 days" works naturally
* **Reference people naturally**: Use @mentions or names, CORE will map them to your contacts
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Google Chat
Source: https://docs.getcore.me/access-core/channels/google-chat
Chat with CORE's Agent in Google Chat
## Overview
Access CORE's Agent directly in Google Chat. Perfect for teams using Google Workspace, chat with your agent in spaces or via DM, take actions across your apps, and search your memory.
**Coming Soon**: Google Chat integration is currently in development.
## Help Us Prioritize
We're building Google Chat support based on user demand. If you'd like to see this feature, please: ๐ **Comment +1** on [GitHub Issue #429](https://github.com/RedPlanetHQ/core/issues/429)
Your feedback helps us prioritize which channels to build next!
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support** or to share your Slack integration ideas!
# iMessage
Source: https://docs.getcore.me/access-core/channels/imessage
Chat with CORE's Agent via iMessage
## Overview
Access CORE's Agent directly through iMessage. Get instant answers, take actions across your apps, and search your memory - all from your iPhone, iPad, or Mac.
**Private Beta**: iMessage access is currently in private beta. [Join the waitlist](https://getcore.me/whatsapp) to get early access.
## Join The Waitlist
1. [Join the waitlist](https://getcore.me/whatsapp) to get early access
2. Once approved, you'll receive an onboarding invite.
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Signal
Source: https://docs.getcore.me/access-core/channels/signal
Chat with CORE's Agent on Signal
## Overview
Access CORE's Agent directly through Signal. Get instant answers, take actions across your apps, and search your memory - all from your favorite messaging app.
**Coming Soon**: Signal integration is currently in development.
## Help Us Prioritize
We're building Signal support based on user demand. If you'd like to see this feature, please: ๐ **Comment +1** on [GitHub Issue #430](https://github.com/RedPlanetHQ/core/issues/430)
Your feedback helps us prioritize which channels to build next!
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support** or to share your Slack integration ideas!
# Slack
Source: https://docs.getcore.me/access-core/channels/slack
Chat with CORE's Agent in Slack
## Overview
Access CORE's Agent directly in Slack. Chat with your agent in any channel or via DM, take actions across your apps, and search your memory - all without leaving Slack.
## How to Access
You can interact with the CORE agent in two ways:
* **Mention in channels**: Use `@core` in any channel where the app is added
* **Direct message**: Open a DM with the CORE app and chat directly
The CORE app must be added to a channel before you can mention it there. Invite the app by typing `/invite @core` in the channel.
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support** or to share your Slack integration ideas!
# Telegram
Source: https://docs.getcore.me/access-core/channels/telegram
Chat with CORE's Agent on Telegram
## Overview
Access CORE's Agent directly through Telegram. Get instant answers, take actions across your apps, and search your memory - all from your favorite messaging app.
**Coming Soon**: Telegram integration is currently in development.
## Help Us Prioritize
We're building Telegram support based on user demand. If you'd like to see this feature, please: ๐ **Comment +1** on [GitHub Issue #427](https://github.com/RedPlanetHQ/core/issues/427)
Your feedback helps us prioritize which channels to build next!
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support** or to share your Slack integration ideas!
# Web Dashboard
Source: https://docs.getcore.me/access-core/channels/web-dashboard
Chat with CORE's Agent through the web interface
## Overview
Access CORE's Agent directly through CORE dashboard. The web dashboard provides a full-featured chat interface where you can have natural conversations, search your memory, and take actions across all your connected apps.
## Getting Started
1. Visit [app.getcore.me](https://app.getcore.me)
2. Sign in with your account
3. Go to Chat section and start chatting with Butler.
## Features
Chat naturally with your agent about anything - ask questions, give commands, or just think out loud. Your agent remembers everything.
Search through your entire memory graph to find past conversations, decisions, and context instantly.
Create Linear issues, send Slack messages, update Notion pages, and more - all through conversation.
Share images, screenshots, and files with your agent for context-aware assistance.
## Use Cases
**Scenario**: Start your day by chatting with CORE
```
"What did I work on yesterday? What's on my plate today?
Create a Linear issue for the bug John mentioned in Slack."
```
Your agent will search memory for yesterday's context, check your Linear tasks, and create new issues as needed.
**Scenario**: Remember details from past projects
```
"What were the main technical decisions we made for the authentication system last month?
Find the GitHub PRs related to it."
```
Your agent searches through past conversations, code reviews, and decisions to give you complete context.
**Scenario**: Automate tasks across multiple apps
```
"Find all open GitHub issues assigned to me, create a Linear epic to track them,
and send a summary to the #engineering Slack channel."
```
Your agent uses multiple toolkit integrations to complete complex workflows in one conversation.
**Scenario**: Find information quickly
```
"What was the API endpoint we used for webhooks?
Show me the conversation where we discussed it."
```
Instant access to past technical discussions and decisions without searching through multiple tools.
## Tips
* **Be conversational**: Talk naturally - your agent understands context and nuance
* **Reference the past**: Ask about previous conversations and decisions freely
* **Chain actions**: Combine multiple tasks in one message for complex workflows
* **Use memory search**: The search function is powerful for finding specific context
## Privacy & Security
* All conversations are encrypted
* Your data is never used for training
* You control what gets stored in memory
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# WhatsApp
Source: https://docs.getcore.me/access-core/channels/whatsapp
Chat with CORE's Agent on WhatsApp
## Overview
Access CORE's Agent directly through WhatsApp. Get instant answers, take actions across your apps, and search your memory - all from your phone. Perfect for on-the-go productivity.
**Private Beta**: WhatsApp access is currently in private beta. [Join the waitlist](https://getcore.me/whatsapp) to get early access.
## Join The Waitlist
1. [Join the waitlist](https://getcore.me/whatsapp) to get early access
2. Once approved, you'll receive an onboarding invite.
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Overview
Source: https://docs.getcore.me/access-core/overview
Connect CORE to messaging apps and AI providers
Your butler is one brain with multiple access points. Talk to it from messaging apps, or plug it into your AI tools to give them persistent memory and actions.
## Two Ways to Use CORE
### Talk to Your Butler
Message your butler directly through messaging apps. Ask questions, manage your apps, get summaries, spin up a Claude Code or browser session on your machine โ all through chat, from any device.
Full-featured chat interface in your browser
Email [brain@getcore.me](mailto:brain@getcore.me) for asynchronous assistance
Private Beta - Join waitlist
Private Beta - Join waitlist
Coming Soon
Coming Soon
Coming Soon
Coming Soon
Coming Soon
***
### Extend Your Butler to Your Dev Tools
Your butler's memory and toolkit can reach into any MCP-compatible AI tool โ Claude Code, Cursor, Windsurf, and more. Connect once and every tool shares the same brain: same memory, same context, same action layer, wherever you're building.
AI-powered IDE with persistent project context
Coding agent with memory and app actions
Add CORE memory to GitHub Copilot
AI IDE with persistent memory layer
Desktop AI assistant with full memory
Capture ChatGPT & Gemini conversations
IDEs, coding agents, terminal tools, desktop apps, and more.
***
## Which Should I Use?
| | Channels | Dev Tools |
| ------------ | ---------------------------------------------------------- | ------------------------------------------------------------ |
| **What** | Chat directly with your butler | Your butler's memory + actions inside your coding tools |
| **Best for** | Tasks, mobile access, managing apps, proactive automations | Coding workflows, persistent project context, in-IDE actions |
Use both โ memory is shared across everything. One butler, everywhere you work.
# Add Data to Ingestion Queue
Source: https://docs.getcore.me/api-reference/add-data-to-ingestion-queue
/openapi.json post /api/v1/add
Add data to the ingestion queue for processing. Content will be analyzed
and facts will be extracted into the knowledge graph.
# Create Webhook
Source: https://docs.getcore.me/api-reference/create-webhook
/openapi.json post /api/v1/webhooks
Create webhook configuration for real-time notifications
# Delete Log Entry
Source: https://docs.getcore.me/api-reference/delete-log-entry
/openapi.json delete /api/v1/logs/{logId}
Delete a specific log entry and associated episode if it exists
# Get Episode Facts
Source: https://docs.getcore.me/api-reference/get-episode-facts
/openapi.json get /api/v1/episodes/{episodeId}/facts
Get facts/statements for a specific episode
# Get Ingestion Logs
Source: https://docs.getcore.me/api-reference/get-ingestion-logs
/openapi.json get /api/v1/logs
View ingestion queue status and processing logs
# Get Specific Log
Source: https://docs.getcore.me/api-reference/get-specific-log
/openapi.json get /api/v1/logs/{logId}
Retrieve detailed information about a specific ingestion log
# Get User Profile
Source: https://docs.getcore.me/api-reference/get-user-profile
/openapi.json get /api/profile
Get user profile information via OAuth2 authentication
# Get Webhook
Source: https://docs.getcore.me/api-reference/get-webhook
/openapi.json get /api/v1/webhooks/{id}
Get webhook configuration details
# List Labels
Source: https://docs.getcore.me/api-reference/list-labels
/openapi.json get /api/v1/labels
Get list of all labels in the authenticated user's workspace
# OAuth2 Authorization Decision
Source: https://docs.getcore.me/api-reference/oauth2-authorization-decision
/openapi.json post /oauth/authorize
Handle user's allow/deny decision for OAuth2 authorization
# OAuth2 Authorization Endpoint
Source: https://docs.getcore.me/api-reference/oauth2-authorization-endpoint
/openapi.json get /oauth/authorize
OAuth2 authorization endpoint supporting authorization code flow with PKCE.
Requires user to be logged in via session cookie.
# OAuth2 Token Endpoint
Source: https://docs.getcore.me/api-reference/oauth2-token-endpoint
/openapi.json post /oauth/token
Exchange authorization code for access token, or refresh an existing token.
Supports both JSON and form-encoded requests.
# OAuth2 Token Introspection
Source: https://docs.getcore.me/api-reference/oauth2-token-introspection
/openapi.json get /oauth/tokeninfo
Get information about the current access token
# OAuth2 User Info Endpoint
Source: https://docs.getcore.me/api-reference/oauth2-user-info-endpoint
/openapi.json get /oauth/userinfo
Get authenticated user information
# Search Knowledge Graph
Source: https://docs.getcore.me/api-reference/search-knowledge-graph
/openapi.json post /api/v1/search
Perform advanced semantic search with graph traversal capabilities.
Supports temporal filtering, entity type filtering, and relevance scoring.
# Update Webhook
Source: https://docs.getcore.me/api-reference/update-webhook
/openapi.json put /api/v1/webhooks/{id}
Update webhook configuration
# Resend
Source: https://docs.getcore.me/channels/email-resend
Add resend as your email channel for your instance
This guide covers setting up the email channel using [Resend](https://resend.com) for inbound and outbound email communication with CORE.
## Overview
The email channel allows users to interact with CORE by sending emails. CORE processes incoming emails, runs them through the AI pipeline, and sends replies back via email.
**Capabilities:**
* Inbound email processing via Resend webhooks
* Outbound email replies via Resend API
* Plain text email responses
**Limitations:**
* No typing indicators (email doesn't support this)
* No acknowledge messages (no intermediate "processing..." emails)
* No email threading via Message-ID/In-Reply-To headers (threading is subject-line based only)
* Plain text replies only (no rich HTML formatting in AI responses)
* No attachment support
* No webhook signature verification (see Security Notes)
## Prerequisites
1. A [Resend](https://resend.com) account
2. A verified domain in Resend for sending emails
3. Resend Inbound configured to receive emails
## Environment Variables
Add these to your `.env` file:
```bash theme={null}
# Required: Set transport to resend
EMAIL_TRANSPORT=resend
# Required: Your Resend API key
RESEND_API_KEY=re_xxxxxxxxxx
# Required: The email address that receives inbound emails
# This must match your Resend inbound configuration
FROM_EMAIL=brain@yourdomain.com
```
## Resend Configuration
### 1. Get Your API Key
1. Go to [Resend Dashboard](https://resend.com/api-keys)
2. Create a new API key with **full access** (needed for both sending and receiving)
3. Copy the key to `RESEND_API_KEY`
### 2. Verify Your Domain
1. Go to [Resend Domains](https://resend.com/domains)
2. Add your domain and follow DNS verification steps
3. Wait for verification to complete
### 3. Configure Inbound Email
1. Go to [Resend Inbound](https://resend.com/inbound)
2. Set up an inbound address (e.g., `brain@yourdomain.com`)
3. Add MX records as instructed by Resend
4. Configure the webhook endpoint:
```
https://your-core-domain.com/api/v1/channels/email
```
5. Select the `email.received` event type
### 4. Set FROM\_EMAIL
Set `FROM_EMAIL` to match your inbound email address:
```bash theme={null}
FROM_EMAIL=brain@yourdomain.com
```
This is used to:
* Filter incoming emails (only emails addressed to this address are processed)
* Set the Reply-To header on outbound emails
## Webhook Route
Inbound emails are received at:
```
POST /api/v1/channels/email
```
The webhook handler:
1. Validates the event type is `email.received`
2. Checks the recipient matches `FROM_EMAIL`
3. Fetches the full email body from Resend API
4. Looks up the sender by email address in your user database
5. Routes the message through the CORE AI pipeline
6. Sends a reply to the sender
## How It Works
### Inbound Flow
1. User sends email to `brain@yourdomain.com`
2. Resend receives the email and sends a webhook to `/api/v1/channels/email`
3. CORE fetches the email body using `resend.emails.receiving.get(email_id)`
4. If the sender is a registered user, the message is processed
5. AI generates a response
6. Response is sent back via email
### Outbound Flow
1. AI generates a response
2. CORE sends email via `resend.emails.send()`
3. Subject is prefixed with `Re: ` if replying to a thread
## User Registration
Only registered users can interact via email. The sender's email address must exist in the CORE user database with an associated workspace.
Emails from unknown senders are logged but not processed.
## File Locations
| File | Purpose |
| ----------------------------------------------------- | -------------------- |
| `apps/webapp/app/services/channels/email/inbound.ts` | Webhook parsing |
| `apps/webapp/app/services/channels/email/outbound.ts` | Reply sending |
| `apps/webapp/app/services/channels/email/index.ts` | Channel registration |
| `packages/emails/src/transports/resend.ts` | Resend transport |
| `apps/webapp/app/routes/api.v1.channels.$channel.tsx` | Webhook route |
## Troubleshooting
### Emails not being received
1. Check Resend Inbound logs for delivery status
2. Verify MX records are correctly configured
3. Confirm webhook URL is accessible from the internet
4. Check `FROM_EMAIL` matches the inbound address
### Emails received but not processed
1. Verify sender is a registered user in CORE
2. Check logs for "Email from unknown sender" warnings
3. Confirm user has an associated workspace
### Replies not being sent
1. Check `RESEND_API_KEY` has send permissions
2. Verify domain is verified in Resend
3. Check application logs for Resend API errors
### Empty email body
1. Some email clients send HTML-only emails
2. The handler extracts `text` first, then falls back to `html`
3. Check Resend logs to see the raw email content
## Security Notes
* **No webhook signature verification**: The `RESEND_WEBHOOK_SECRET` environment variable is defined but not currently implemented. Anyone who knows your webhook URL could potentially send fake events.
* **Sender validation**: Only processes emails from registered users, which provides some protection.
* **Recipient filtering**: Only processes emails addressed to `FROM_EMAIL`.
## Comparison with Other Channels
| Feature | Email | WhatsApp | Slack |
| -------------------- | --------------- | -------- | ----- |
| Typing indicators | No | No | Yes |
| Acknowledge messages | No | Yes | Yes |
| Rich formatting | No (plain text) | Limited | Yes |
| Thread tracking | Subject-based | Yes | Yes |
| Attachments | No | Yes | Yes |
# Slack
Source: https://docs.getcore.me/channels/slack
Message your butler directly in Slack: DMs or @mentions.
Once set up, you can DM your butler in Slack or @mention it in any channel. It reads your message, runs through its memory and toolkit, and replies in the thread.
**What you need:** A Slack workspace where you can create and install apps.
***
## Step 1: Create a Slack App
1. Go to [api.slack.com/apps](https://api.slack.com/apps) โ **Create New App** โ **From scratch**
2. Name it (e.g. "CORE Butler") and pick your workspace โ **Create App**
***
## Step 2: Configure OAuth scopes
Go to **OAuth & Permissions** in the sidebar.
**Bot Token Scopes**: add all of these:
| Scope | Why |
| ------------------- | ------------------------- |
| `app_mentions:read` | Receive @mention events |
| `chat:write` | Send messages and replies |
| `im:history` | Read DM history |
| `im:read` | Access DM channels |
| `im:write` | Open DM conversations |
| `users:read` | Look up user info |
| `channels:read` | Access channel metadata |
**User Token Scopes**: add these for full activity sync:
`channels:history`, `channels:read`, `channels:write`, `chat:write`, `groups:history`, `groups:read`, `groups:write`, `im:history`, `im:read`, `im:write`, `mpim:history`, `mpim:read`, `mpim:write`, `reactions:read`, `reactions:write`, `search:read`, `stars:read`, `team:read`, `users:read`
**Redirect URL**: under **Redirect URLs**, add:
```
https://your-domain.com/api/v1/integrations/slack/callback
```
***
## Step 3: Enable Event Subscriptions
Go to **Event Subscriptions** โ toggle **Enable Events** on.
**Request URL:**
```
https://your-domain.com/api/v1/channels/slack
```
Slack will send a challenge request: your CORE instance must be running and reachable for it to verify.
**Subscribe to bot events**: add both:
* `app_mention`: fires when someone @mentions your bot in a channel
* `message.im`: fires when someone DMs your bot
Save changes.
***
## Step 4: Set the signing secret
Go to **Basic Information** โ **App Credentials** โ copy the **Signing Secret**.
Add to your `.env`:
```env theme={null}
SLACK_SIGNING_SECRET=your-signing-secret-here
```
Restart CORE:
```bash theme={null}
docker compose restart webapp
```
***
## Step 5: Connect in CORE dashboard
1. Open your CORE dashboard โ **Integrations** โ find **Slack** โ click **Connect**
2. You'll be redirected to Slack's OAuth page: authorise the app
3. The app is now installed in your workspace with both a bot token and your user token
***
## Step 6: Talk to your butler
**Via DM:**
Open Slack โ find your app under **Apps** in the sidebar โ send a message directly.
**Via @mention:**
Go to any channel โ type `/invite @YourAppName` to add the bot โ then use `@YourAppName your message` in any message.
**Verify it's working:**
```
@YourAppName what are my open GitHub issues?
```
Your butler should reply in the thread within a few seconds.
# Telegram
Source: https://docs.getcore.me/channels/telegram
Message your butler directly on Telegram via a dedicated bot.
Once set up, you can message your butler through any Telegram bot you create. CORE registers the webhook automatically: no manual Telegram configuration needed beyond creating the bot.
This channel is available in [PR #739](https://github.com/RedPlanetHQ/core/pull/739). Make sure your instance is running that version or later.
**What you need:** A publicly reachable CORE instance (`APP_ORIGIN` must be set in your `.env`).
***
## Step 1: Create a Telegram bot
1. Open Telegram โ search for **@BotFather** โ `/start`
2. Send `/newbot` โ follow the prompts (pick a display name and a username ending in `bot`)
3. BotFather replies with your **bot token**: copy it, you'll need it in Step 3
***
## Step 2: Ensure your instance is publicly reachable
Telegram needs to send webhook events to your CORE instance. Confirm `APP_ORIGIN` is set to your public URL in `.env`:
```env theme={null}
APP_ORIGIN=https://your-domain.com
```
CORE uses this to construct the webhook URL it registers with Telegram:
```
https://your-domain.com/webhooks/telegram?channelId=
```
> For local development, use a tunnel like [ngrok](https://ngrok.com): `ngrok http 3033` and set `APP_ORIGIN` to the tunnel URL.
***
## Step 3: Create the channel via the CORE API
CORE stores the bot token in the channel record and **automatically registers the webhook** with Telegram when you create the channel.
Get your API token from the CORE dashboard โ **Settings** โ **API**, then run:
```bash theme={null}
curl -X POST https://your-domain.com/api/v1/channels \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"name": "My Telegram",
"type": "telegram",
"config": { "bot_token": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" },
"isDefault": true
}'
```
A successful response returns `{ "success": true, "channelId": "..." }`.
At this point, CORE has called Telegram's `/setWebhook` with your channel ID: no further Telegram configuration is needed.
***
## Step 4: Talk to your butler
Open Telegram โ search for your bot by username โ send a message:
```
What are my open GitHub issues?
```
Your butler replies directly in the chat.
***
## Managing the channel
**List channels:**
```bash theme={null}
curl https://your-domain.com/api/v1/channels \
-H "Authorization: Bearer "
```
**Delete a channel** (also deregisters the Telegram webhook automatically):
```bash theme={null}
curl -X DELETE https://your-domain.com/api/v1/channels/ \
-H "Authorization: Bearer "
```
# Memory
Source: https://docs.getcore.me/concepts/memory
Pointer to the memory documentation.
CORE's memory is a temporal knowledge graph. Episodes are the raw ingested content. Entities are nodes (people, projects, technologies, etc.). Statements are atomic facts classified by aspect. Labels scope queries.
Primitives, storage, and retrieval.
Query classification, hybrid search, and ranking.
Ingestion pipeline from raw input to statements.
Enums, MCP tools, and vector namespaces.
# Agent
Source: https://docs.getcore.me/concepts/meta-agent
The orchestrator โ triggers, memory, tools, and execution
## What is the Agent?
The Agent is CORE's brain. It sits between you and everything CORE knows and can do: memory, toolkit, connected apps, and the gateway. When you send a message or a trigger fires, it figures out what's needed, pulls the right context, takes the right actions, and responds. Every conversation gets ingested back into memory, so CORE gets sharper the more you use it.
You can reach it via voice, scratchpad, WhatsApp, Slack, the web dashboard, or through any MCP-compatible agent like Claude Code or Cursor. Same brain, same memory, regardless of where you start.
***
## How It Works
Two paths into CORE โ messages from you, and triggers that fire automatically. Both converge on the same intelligence.
```mermaid theme={null}
flowchart TD
MSG["๐ฌ Your message\nWhatsApp ยท Slack ยท Email ยท Web ยท API"]
TRG["โฐ Automated trigger\nReminder ยท Webhook ยท Scheduled job"]
CASE["โ CASE โ Decision Agent\nAnalyses trigger ยท builds ActionPlan\nwhat to do ยท tone ยท whether to message"]
AGENT["โก Agent\nReads ActionPlan ยท loads Persona\ndecides which tools to call"]
subgraph orch["Orchestrator โ routes & coordinates all tool calls"]
MEMR["โข memory_explorer\nSearch knowledge graph for\nrelevant context ยท past decisions ยท relationships"]
TOOLS["โฃ Toolkit\nExecute the specific actions\nsearch_emails ยท get_calendar ยท create_issue ยท โฆ"]
GW["โฃ Gateways (if needed)\nClaude Code ยท Browser ยท Custom agents"]
end
MEM[("๐ง Memory\nKnowledge Graph")]
SYNTH["โค Agent synthesizes\nCombines memory context + tool results"]
RESP["Response delivered\nvia your preferred channel"]
INGEST["โฅ memory_ingest\nSummarised conversation stored\nback to knowledge graph"]
MSG --> AGENT
TRG --> CASE
CASE -->|"ActionPlan"| AGENT
AGENT --> orch
MEMR <-->|"read"| MEM
orch --> SYNTH
SYNTH --> RESP
SYNTH --> INGEST
INGEST -->|"write"| MEM
```
### Step by step
When you send a message, here's what happens:
The agent loads your conversation history and persona document - a living summary of your preferences, directives, expertise, and decisions generated from your memory.
It analyzes your message and decides what's needed: information from memory, live data from apps, web search, or an action to execute.
The agent has two core tools:
* **gather\_context** (READ) โ routes to 3 specialized explorers:
* *Memory Explorer* โ searches your knowledge graph for past conversations, decisions, preferences
* *Integration Explorer* โ queries live data from connected apps (emails, calendar, issues)
* *Web Explorer* โ searches the web for real-time information
* **take\_action** (WRITE) โ executes actions in your connected apps via the Integration Explorer
The agent synthesizes results into a response. After responding, the conversation is automatically ingested into your memory graph - building context for future interactions.
***
## It Can Spawn Other Agents
The Agent isn't limited to its own capabilities. It can spin up other agents on your behalf โ a Claude Code or Codex session to write code, a browser session to research something โ all triggered from whatever channel you're on.
You're outside, a production bug comes in. You message CORE on WhatsApp: "Fix the auth timeout issue in the API." CORE spins up a Claude Code session via the gateway, pulls the relevant context from memory, and starts working on the fix โ while you're still on your phone.
***
## Reminders and Scheduled Actions
The agent can execute actions at scheduled times - one-time or recurring. This isn't just "send me a notification." The agent runs the full workflow: searches memory for your rules and preferences, gathers context from connected apps, and takes actions.
**Daily email triage:** Every morning at 10am, the agent wakes up, goes through your inbox, and handles emails based on your email management skills stored in memory - drafting responses, flagging priorities, archiving noise.
**Overnight monitoring:** You tell the agent to watch Sentry while you sleep. A critical error comes in at 3am. The agent evaluates it, spins up a Claude Code session to investigate and fix the issue, then sends you a summary when you wake up.
**Weekly lead research:** Every Monday, the agent researches LinkedIn for leads matching your ICP, compiles them into a Google Sheet with notes, and sends it to your sales channel on Slack - ready for your team's morning standup.
All of this from a single message on WhatsApp: "Every Monday at 9am, find 10 new leads matching our ICP on LinkedIn, add them to the Leads sheet, and share it on #sales in Slack."
***
## How to Access
Email, Slack, Telegram, Discord, and more
***
## Next Steps
How the knowledge graph stores and organizes your information
How actions work across your connected apps
# Scratchpad
Source: https://docs.getcore.me/concepts/scratchpad
Your daily page โ write [ ] tasks and CORE picks them up within minutes
## What it is
The Scratchpad is the daily page CORE creates for you the moment you log in. One page per day, scoped to your local timezone. It's a collaborative block editor (paragraphs, headings, lists, tasks, code blocks, tables) backed by Yjs, so it autosaves and survives across devices without a save button.
You can use it like any notes app โ but CORE is watching. There are two ways to put it to work.
***
## Two ways to engage CORE
Type `[ ]` to start a checkbox item. The line becomes a real task the moment you stop typing โ within \~2 minutes CORE picks it up and starts working on it. You'll see its progress on the task's badge right inside the scratchpad.
Type `@butler` followed by an instruction. After a short idle pause CORE reads the paragraph, runs your request, and replies as a comment attached to that paragraph โ so the answer lives next to the question.
The split is intentional: tasks are *work CORE should run on its own and report back when done*; mentions are *a question or instruction you want answered right here in the page*.
***
## How `[ ]` tasks work
A `[ ]` line isn't just text formatting โ it's bound to a real Task in CORE the instant you create it.
* Typing `[ ]` (or using the `Task` slash command) inserts a checkbox item, creates a Task row with `source: "daily"`, and links it to the scratchpad.
* The text you type becomes the task title. Edits autosave to the task as you type.
* The task shows a badge with the next scheduled run time. Within roughly two minutes CORE claims it and starts execution.
* Click the task's display id (e.g. `T-142`) to jump to its full task page โ descriptions, subtasks, activity log, runs.
* Check the box to mark it Done. Uncheck to send it back to Todo.
* Delete the line and the task is cleaned up automatically โ *unless* you've already typed a title or CORE has added context, in which case the task is preserved and you can find it on the tasks list.
This is why a Scratchpad task "just works" โ you write a checkbox, it's now a tracked unit of work CORE will pick up and report back on, and you didn't have to leave the page to make any of that happen.
***
## How `@butler` mentions work
`@butler` is for answers you want inline. Type it followed by an instruction, keep writing, and a few seconds after you stop, CORE reads the paragraph, runs the request, and posts a comment on the paragraph with what it found or did.
A few things worth knowing:
* The mention text (minus `@butler`) is what CORE sees as your instruction โ keep the rest of the paragraph self-contained.
* A comment shows up right on that paragraph; click it to expand the response and to open the underlying conversation if you want to follow up in chat.
* Each mention is processed once โ the butler tracks which paragraphs it has already answered on, so editing unrelated text won't re-trigger it. Edit the paragraph itself if you want a fresh reply.
Use `@butler` for things you want answered *now and visible in context*: "@butler what did Manoj say last time about the partnership?" / "@butler summarize my open Linear issues."
***
## Widgets in the side panel
Open the **Widgets** button in the daily header to dock a widget panel alongside the page. It's the same widget system as the [Overview](/concepts/widgets) page, but the layout is scoped to the Scratchpad โ useful when you want a calendar, your inbox, or a Linear queue visible while you plan the day. Layouts persist per workspace.
You can also embed a widget *inline* in the page itself: type `/` and pick a widget from the slash menu to drop it as a block. Inline widgets carry their own per-block config and travel with whatever you write around them.
***
## Why a daily page (not one big page)
A new page every day forces a clean break: yesterday's open loops are still in memory and searchable, but they're not staring at you. CORE treats today as the source of truth for what's currently top-of-mind, which is what makes the `[ ]` and `@butler` flows feel light โ CORE has a small, fresh surface to reason about instead of an ever-growing journal.
# Toolkit
Source: https://docs.getcore.me/concepts/toolkit
How CORE takes actions across your connected apps
## Taking actions across your apps
The Toolkit is CORE's hands. While the Agent thinks and Memory remembers, the Toolkit actually *does things* โ creates issues, drafts emails, schedules meetings, sends messages โ across all your connected apps.
You connect each app once. After that, every interface to CORE (WhatsApp, web dashboard, Claude Code, Cursor) can use those integrations. One connection, available everywhere.
**What a multi-step action looks like:** A user emails reporting a bug โ CORE creates a Todoist task, spins up a Claude Code session with context from memory, writes a fix, and opens a PR. You come back to a summary and a link. One message, multiple tools, coordinated automatically.
***
## How It Works
### 1. You Connect Apps
From the [CORE Dashboard](https://app.getcore.me), connect the apps you use daily. Each integration authenticates via OAuth โ no API keys to manage.
### 2. CORE Decides What to Use
When you ask CORE to do something, the Agent figures out which integration(s) to use:
```
You: "Create a GitHub issue for the auth bug and tell Sarah on Slack"
Agent:
โ Uses GitHub integration to create issue with context from memory
โ Uses Slack integration to DM Sarah with a link to the issue
```
### 3. Actions Execute with Context
Every action includes context from your memory. When CORE creates a Linear issue, it includes relevant discussion history. When it drafts an email, it knows your tone and past correspondence.
***
## What's Available
**Gmail** ยท **Slack** ยท **Discord** ยท **Zoho Mail**
Send messages, draft emails, search conversations
**Linear** ยท **Todoist** ยท **Google Tasks**
Create issues, update tasks, track progress
**GitHub** ยท **GitHub Analytics**
Create issues, manage PRs, review code, track metrics
**Google Calendar** ยท **Cal.com**
Schedule events, check availability, manage invites
**Notion** ยท **Google Docs** ยท **Google Sheets**
Search, create, and update documents and data
**HubSpot**
Manage contacts, deals, and customer data
See the [Toolkit documentation](/toolkit/overview) for detailed actions available per integration.
***
## How Toolkit Reaches Your AI Agents
Toolkit actions are exposed to AI agents through a single MCP endpoint. Instead of configuring separate MCP servers per app, you connect CORE once and any MCP-compatible agent (Claude Code, Cursor, Windsurf, etc.) gets the full toolkit with on-demand tool loading.
See the [Toolkit Overview](/toolkit/overview) for details on how on-demand tool loading works and MCP configuration.
***
## Next Steps
See all available integrations and their actions
Configure which integrations to expose via MCP
How the Agent decides which tools to use
# Widgets
Source: https://docs.getcore.me/concepts/widgets
Embeddable views that pull live data from your connected integrations into CORE
## What they are
Widgets are small, embeddable UIs that each integration ships with. They render *inside* CORE โ your Overview page, the Scratchpad's side panel, or as inline blocks in any page โ but the data they show is fetched live from the connected service.
A Linear integration might ship a "My issues" widget. A Calendar integration might ship "Today" and "Next meeting." A Notion integration might ship "Recent pages." When you connect the integration, the widgets show up automatically in the picker โ you don't install them separately.
***
## Where widgets render
The dashboard at `/overview` is a freeform widget grid. Pick widgets from your connected integrations, drag to size and arrange. The layout is workspace-scoped โ visible to everyone in the workspace.
Open the **Widgets** button on the daily page to dock a separate widget grid alongside your scratchpad. Useful when you want context (calendar, inbox, queue) visible while planning.
Type `/` in any page and pick a widget from the slash menu. The widget becomes a block in your document and travels with whatever you write around it.
The Overview grid and the Scratchpad panel each store their layout independently, so you can build a "dashboard" on Overview and still have a focused, smaller set on the Scratchpad without them fighting.
***
## How widgets get their data
Widgets aren't bundled into CORE โ they're loaded from the integration's own frontend at runtime. When you drop a widget in:
1. CORE looks up the integration's widget bundle URL from its installed spec.
2. The bundle is loaded once and cached in your browser.
3. CORE renders the widget with a context object containing the widget's configuration plus credentials it needs to call the underlying service.
This means widgets always reflect what the integration team has shipped โ no extension store to manage, no version pinning, no separate auth flow.
***
## Configuring a widget
Some widgets accept config โ a Linear "Issues" widget might let you pick a team or filter, a Calendar widget might let you choose which calendars to show. Config is declared by the integration via a schema, and CORE renders the form for you when you first add the widget.
Click the gear icon on a widget's header to edit its config any time. Config is stored on the cell (Overview, Scratchpad panel) or on the block (inline page widget), so the same widget type can appear multiple times with different settings โ for example, three Linear "Issues" widgets each scoped to a different project.
***
## Using widgets
* **Overview** โ go to `/overview`, click **Add widget**, pick from the list of widgets exposed by your connected integrations. Drag corners to resize, drag the body to move. Layout autosaves.
* **Scratchpad** โ open `/daily`, click **Widgets** in the page header, and the same picker appears for the side panel.
* **Inline** โ in any page, place your cursor on an empty line, type `/`, and search for the widget by name. It'll render as a block; resize is per widget.
Removing a widget from the Overview/Scratchpad grid drops it from your layout but leaves the integration connected. Removing an inline widget deletes the block but does not affect the integration either.
***
## Widgets and the butler
The butler doesn't render widgets โ it talks to the same integrations through the [Toolkit](/concepts/toolkit). Think of widgets as the *visual* surface and the toolkit as the *action* surface for the same set of connected apps. If your Linear integration ships an "Issues" widget, the same connection lets the Agent run "show me my open Linear issues" via tools โ the widget just gives you a passive, always-on view of the same data.
This is why widgets and the agent stay in sync automatically: they share the integration's auth and connection, so adding or removing an integration affects both at once.
# Browser
Source: https://docs.getcore.me/gateway/browser
Automate browsers with pre-configured profiles and sessions for authentication and automation
## Overview
The Browser capability lets CORE control browsers on your machine using [Playwright](https://playwright.dev/) under the hood. Profiles persist login state on disk; sessions bind a running browser instance to a profile.
Login once per profile, and CORE can access authenticated pages without re-authenticating.
***
## Concepts
| Concept | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Profile** | Permanent identity stored on disk (`~/.corebrain/browser-profiles//`). Holds cookies, localStorage, and auth state. |
| **Session** | Named binding between a task and a profile. Multiple sessions can reference different profiles. |
***
## Setup
### 1. Install Playwright Chromium
```bash theme={null}
corebrain browser install
```
Downloads the Chromium binary and creates default profiles: `personal`, `work`, `misc`.
### 2. Create a Profile
```bash theme={null}
corebrain browser create-profile personal
```
Maximum **5 profiles** allowed.
### 3. Create a Session
```bash theme={null}
corebrain browser create-session my_task --profile personal
```
Maximum **10 sessions** allowed.
### 4. Open (Login)
```bash theme={null}
# Open in headed mode to log in manually
corebrain browser open my_task --headed
# Open at a specific URL
corebrain browser open my_task --url https://github.com --headed
```
Once logged in, the profile persists auth state. Future opens (headless or headed) will remain authenticated.
***
## CLI Reference
### Profiles
```bash theme={null}
# Create a profile
corebrain browser create-profile
# Delete a profile (also removes bound sessions and profile directory)
corebrain browser delete-profile
```
### Sessions
```bash theme={null}
# Create a session bound to a profile
corebrain browser create-session --profile
# List configured sessions
corebrain browser list-sessions
# Delete a session (removes config only; profile data preserved)
corebrain browser delete-session
```
### Open / Close
```bash theme={null}
# Open a session (headless by default)
corebrain browser open
# Open in headed (visible) mode
corebrain browser open --headed
# Open at a specific URL
corebrain browser open --url https://example.com
# Close a running session (profile data preserved)
corebrain browser close-session
# Close all running sessions
corebrain browser close --all
```
### Browser Executable
```bash theme={null}
# Interactive browser selection
corebrain browser set-browser
# Use Brave (auto-detected)
corebrain browser set-browser brave
# Use Chrome (auto-detected)
corebrain browser set-browser chrome
# Use system default (bundled Chromium)
corebrain browser set-browser default
# Use custom browser path
corebrain browser set-browser custom /path/to/browser
```
### Status
```bash theme={null}
corebrain browser status
```
***
## Gateway Tools
When the gateway is running, CORE can control the browser with these tools:
| Tool | Description |
| ------------------------ | ------------------------------------------------------ |
| `browser_navigate` | Navigate to a URL in a session |
| `browser_snapshot` | Get an ARIA accessibility snapshot of the current page |
| `browser_click` | Click an element by ref |
| `browser_fill` | Fill an input field |
| `browser_type` | Type text into a field |
| `browser_press_key` | Press a keyboard key |
| `browser_select_option` | Select a dropdown option |
| `browser_screenshot` | Take a screenshot |
| `browser_scroll` | Scroll the page |
| `browser_go_back` | Navigate back |
| `browser_go_forward` | Navigate forward |
| `browser_wait_for` | Wait for a load state |
| `browser_evaluate` | Execute JavaScript in the page |
| `browser_close_session` | Close a running session |
| `browser_close_all` | Close all running sessions |
| `browser_list_sessions` | List configured sessions |
| `browser_create_session` | Create a session |
| `browser_delete_session` | Delete a session |
Profile and browser executable management is CLI-only.
***
## Agent vs Manual Control
**Important:** The gateway and CLI maintain separate in-memory session maps (different processes). Do not use `corebrain browser open` for a session that the agent will also control โ it will cause a profile directory lock conflict.
| Use case | How to open |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Agent-controlled automation | Let the agent call `browser_navigate` โ it launches the browser in-process. |
| Webapp live view | Click the session in the webapp's *Browser* tab. The webapp calls `POST /api/browser/launch` (always headless) and streams CDP via the `/api/browser/cdp/:session` WebSocket proxy โ works the same way for laptop and Docker gateways. |
| Manual login / handoff | `corebrain browser open --headed` from the gateway machine itself. |
***
## Use Cases
**Authenticated scraping:** Create a `linkedin` session bound to your `personal` profile, log in once. CORE can research leads on LinkedIn anytime.
**Form automation:** CORE fills out repetitive forms โ expense reports, time tracking, support tickets โ using stored login sessions.
**Multi-account management:** Create separate profiles (`work`, `personal`). CORE switches between them seamlessly via different sessions.
***
## Headed Mode (Manual Handoff)
By default, browsers run in headless mode. To take manual control or watch what CORE is doing:
**Example prompts:**
* "Open LinkedIn in headed mode so I can take over"
* "Start a headed browser session for the checkout flow"
* "I need to intervene โ open this in headed mode"
**Troubleshooting headed mode:** If the browser doesn't appear, close all sessions first:
1. Ask: "Close all browser sessions"
2. Then: "Open \[URL] in headed mode with session \[name]"
***
## Recommended Browser
We recommend [Brave](https://brave.com/) as your automation browser. Brave is Chromium-based, works seamlessly with Playwright, and includes built-in ad blocking that makes automation cleaner and faster.
```bash theme={null}
# macOS
brew install --cask brave-browser
# Linux (Debian/Ubuntu)
sudo apt install brave-browser
# Windows
winget install Brave.Brave
```
Then configure CORE to use it:
```bash theme={null}
corebrain browser set-browser brave
```
# Coding
Source: https://docs.getcore.me/gateway/coding
Spawn and manage coding agent sessions from anywhere
## Overview
The Coding capability lets CORE spawn coding agents โ Claude Code or Codex CLI โ on your gateway. Start a coding session from WhatsApp, watch it stream in the webapp's terminal tab, resume it days later, and keep working.
Sessions are owned by the agent itself: their transcripts live wherever the agent writes them (`~/.claude` for Claude Code, `~/.codex/sessions/...` for Codex). The gateway tracks running PTYs and re-spawns from disk on resume.
***
## Supported Agents
| Agent name | Binary | Notes |
| ------------- | -------- | -------------------------------------------------------------- |
| `claude-code` | `claude` | Anthropic's CLI coding agent. `ANTHROPIC_API_KEY` skips OAuth. |
| `codex-cli` | `codex` | OpenAI's CLI coding agent. `OPENAI_API_KEY` skips OAuth. |
The system is template-driven (`AGENT_TEMPLATES` in the CLI) โ adding a new agent means adding a template entry and start/resume args.
The gateway auto-detects agent binaries on `PATH` even if they aren't yet configured, so the webapp's *Configure + Log in* dialog can show a one-click setup. Configured agents appear in `manifest.agents`; detected-but-unconfigured ones in `manifest.availableAgents`.
***
## Setup
```bash theme={null}
corebrain coding setup
```
Walks you through picking an agent, locating its binary, and (optionally) logging it in. To set the default agent used when the LLM doesn't pass one explicitly:
```bash theme={null}
corebrain coding setup --default claude-code
```
In Docker the binaries are pre-installed and auto-configured on first boot โ set `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` to skip the OAuth log-in step.
***
## Gateway Tools
These are the tools exposed to LLM callers via the manifest. They map directly to per-tool routes (`POST /api/coding/`).
### `coding_ask`
Send a prompt to a coding agent. Omit `sessionId` to start a new session; include it to continue an existing one.
```jsonc theme={null}
{
"agent": "claude-code", // optional โ defaults to configured default
"dir": "/Users/me/repos/api", // must be inside a `coding`-scoped folder
"prompt": "Fix the auth timeout bug",
"sessionId": "abc-123", // optional โ continues a prior session
"model": "claude-sonnet-4-6", // optional override
"systemPrompt": "...", // optional, new sessions only
"worktree": false, // create an isolated git worktree
"baseBranch": "main", // required when worktree=true
"branch": "fix/auth-timeout" // required when worktree=true
}
```
When `worktree` is `true` the gateway handles `git worktree add` itself โ do **not** describe worktree setup in the prompt. Use `coding_read_session` afterwards to read what the agent did.
### `coding_read_session`
Read structured conversation turns (user / assistant) from a session.
```jsonc theme={null}
{ "sessionId": "abc-123" }
```
The response carries a `status` of `"initializing"`, `"running"`, `"completed"`, or `"failed"` so callers can distinguish "agent still booting" from "agent exited without writing".
### `coding_close_session` / `coding_close_all`
Stop a running session (or every running session) and clean up worktrees.
```jsonc theme={null}
{ "sessionId": "abc-123" }
```
### `coding_list_sessions`
List sessions sorted by most recent. Reads from each agent's on-disk transcripts, not just sessions this gateway started.
```jsonc theme={null}
{
"agent": "claude-code", // optional filter
"since": "2026-01-01", // optional ISO date
"limit": 20,
"offset": 0
}
```
### `coding_search_sessions`
Search past sessions by title or first-message content.
```jsonc theme={null}
{
"query": "auth timeout",
"dir": "/Users/me/repos/api", // optional restriction
"limit": 10
}
```
### `coding_list_agents`
List configured agents and which one is the default. No params.
***
## Webapp-Only Primitives
The webapp also calls two non-LLM routes to drive the live terminal pane:
* `POST /api/coding/spawn` โ allocate or resume a PTY without sending a prompt. Used by the *Open terminal* / *Reconnect* affordances. Returns `{ sessionId, pid, status: "new" | "reconnect" | "resumed" }`.
* `WS /api/coding/coding_xterm_session?session_id=โฆ` โ attach to a session's PTY. Auto-resumes the agent if the PTY is gone but the on-disk transcript still exists.
xterm WebSocket frames:
```jsonc theme={null}
// server โ client
"raw PTY bytes as text framesโฆ"
{ "kind": "exit", "exitCode": 0, "signal": null }
// client โ server
"raw text input"
{ "kind": "input", "data": "echo hi\n" }
{ "kind": "resize", "cols": 120, "rows": 40 }
```
See [`packages/gateway-protocol/README.md`](https://github.com/RedPlanetHQ/core/blob/main/packages/gateway-protocol/README.md) for the full route table.
***
## Folder Scope
`coding_ask` and `/api/coding/spawn` validate `dir` against registered folders. The path must resolve into a folder that includes the `coding` scope:
```bash theme={null}
corebrain folder add /Users/me/repos/api --scopes files,coding,exec
```
When zero folders are registered the gateway runs in permissive mode (matches the laptop dev experience). Once you register one, scope is enforced everywhere.
***
## Worktrees
Setting `worktree: true` on `coding_ask` makes the gateway:
1. Resolve `dir` to its git repo.
2. Create `git worktree add ../ ` for the new branch.
3. Run the agent inside that worktree so changes never touch your working tree.
4. Clean up the worktree on `coding_close_session`.
This is the safest way to run autonomous "go fix X" sessions while you keep using the same repo.
***
## Session Lifecycle
`coding_ask` with no `sessionId` allocates a UUID and spawns the agent in `dir`. For Codex, the agent picks its own UUID โ the gateway re-keys to match so future lookups find the right transcript.
The PTY is alive; output streams to the xterm WS and the agent's transcript file. `coding_read_session` returns turns with `status: "running"`.
A new `coding_ask` (or webapp reconnect) with the same `sessionId` either re-attaches to the live PTY or re-spawns the agent with `--resume `.
The agent exits naturally (`status: "completed"`) or you call `coding_close_session`.
***
## Use Cases
**Remote bug fixing:** "Fix the payment processing error in `checkout.ts`." CORE spawns `coding_ask` against your `api` folder. You watch it from the webapp terminal pane.
**Async code reviews:** "Review the changes in the auth PR and suggest improvements." CORE starts a session, calls `coding_read_session` after a `sleep` tool call, and summarises.
**Automated refactoring:** "Migrate all API routes from Express to Hono." Run with `worktree: true` so the agent works on its own branch.
**Night shifts:** Set a reminder: "At 2am, run the database migration script and report any errors." A scheduled action calls `exec_command` and `coding_ask` together.
# Docker
Source: https://docs.getcore.me/gateway/deployment/docker
Run the gateway on a server, VPS, or always-on Docker host via a wizard-driven docker-compose deploy.
Pick this when you have a machine you control and want an always-on gateway. Public URL via Tailscale Funnel, Cloudflare Tunnel, or your own reverse proxy.
## Prereqs
* Docker installed (Docker Desktop or engine).
* Node 20+ for the CLI.
```bash theme={null}
npm install -g @redplanethq/corebrain
corebrain login
```
## Deploy
```bash theme={null}
corebrain gateway setup --kind docker
```
The wizard:
1. Drops `docker-compose.yaml` and `.env` into `~/.corebrain/gateways//`.
2. Optionally prompts for `CLAUDE_CODE_OAUTH_TOKEN`, `OPENAI_API_KEY`, `GITHUB_TOKEN` so the coding and git slots work out of the box.
3. Optionally exposes the host via Tailscale Funnel (re-uses any existing Tailscale install).
4. Runs `docker compose up -d`.
5. Prints the public URL and offers to auto-register with CORE.
If you'd rather use your own reverse proxy (Cloudflare, nginx, Caddy), pick "no tunnel" in the wizard and point your proxy at the host's port `7787`.
## Grab the security key
The `gwk_...` value is generated during setup and written to `~/.corebrain/gateways//.env`. Grab it here:
```bash theme={null}
grep COREBRAIN_GATEWAY_SECURITY_KEY ~/.corebrain/gateways//.env
```
You'll paste it into the UI in the next step and, if you use the LLM proxy, again as the BYOK API key.
## Register in the CORE app
If you answered **yes** to the wizard's "Add to CORE?" prompt, the gateway is already registered โ skip to Verify.
Otherwise, in the webapp:
1. **Sidebar โ Gateways โ + New gateway**.
2. Pick **Docker**.
3. Paste the **Base URL** and the **Security key** from step above.
4. Submit.
Status should flip to **Connected** within a few seconds.
## Verify
```bash theme={null}
corebrain gateway list
```
Or, in the CORE app, ask in any conversation: *"List my gateways."*
## Manage the container
```bash theme={null}
cd ~/.corebrain/gateways/
docker compose logs -f # tail logs
docker compose restart # restart after env changes
docker compose down # stop
```
## Register a folder
Point the gateway at directories on the Docker host that it should have access to:
```bash theme={null}
corebrain folder add /path/on/host --scopes files,coding,exec
```
See the [scope reference](/gateway/overview#folders-and-scopes) for what each scope allows.
## Troubleshooting
**Gateway shows as Unreachable in the webapp**: confirm the URL in the webapp is what your reverse proxy / tunnel exposes, not the container's internal `http://localhost:7787`.
**`docker compose up` failed with port conflict**: another service is on 7787. Edit `.env` to set `COREBRAIN_GATEWAY_HTTP_PORT` to a free port, and adjust your reverse proxy accordingly.
**Rotating the security key**: change `COREBRAIN_GATEWAY_SECURITY_KEY` in `.env`, run `docker compose up -d`, then update the gateway's key in **Sidebar โ Gateways โ Edit** in the webapp.
**Lost the key entirely**: it's still in `.env` โ `grep COREBRAIN_GATEWAY_SECURITY_KEY ~/.corebrain/gateways//.env`.
# Local (Native)
Source: https://docs.getcore.me/gateway/deployment/local
Run the gateway as a launchd/systemd service on your laptop or workstation, exposed via Tailscale or ngrok.
Pick this when the gateway should run on your own machine with full access to browsers, shells, and local folders. A tunnel is required so CORE's cloud can reach `127.0.0.1`.
## Prereqs
Node 20+ on macOS, Linux, or WSL.
```bash theme={null}
npm install -g @redplanethq/corebrain
corebrain login
```
`corebrain login` opens your browser, authenticates against your CORE workspace, and stores a PAT in `~/.corebrain/preferences.json`.
## Option A โ Tailscale Funnel
Stable URL tied to your tailnet. Good for days/weeks of uptime.
### Install Tailscale
```bash theme={null}
# macOS
brew install --cask tailscale
# Linux
curl -fsSL https://tailscale.com/install.sh | sh
```
Verify: `tailscale version`.
### Bring Tailscale up
```bash theme={null}
sudo tailscale up
tailscale status # this device should show as active
```
### Enable Funnel for this device
In the [Tailscale admin console](https://login.tailscale.com/admin/acls):
1. **DNS โ HTTPS Certificates:** turn on.
2. **Access Controls:** add a Funnel grant.
```hujson theme={null}
"nodeAttrs": [
{ "target": ["autogroup:member"], "attr": ["funnel"] }
]
```
Reference: [Tailscale Funnel docs](https://tailscale.com/kb/1223/funnel).
### Install + register the gateway
```bash theme={null}
corebrain gateway setup --kind native
corebrain gateway register --tunnel tailscale
```
The first command installs the gateway as a launchd (macOS) or systemd (Linux) service. The second runs `tailscale funnel --bg 7787`, captures the public URL (`https://..ts.net`), generates a security key, and prints both.
## Option B โ ngrok
Fastest possible setup (one auth token, public URL in seconds). Free-tier URLs change on every restart, so this path is best for short-lived sessions or paid ngrok accounts.
### Install ngrok
```bash theme={null}
# macOS
brew install ngrok
# Linux / Windows: see https://ngrok.com/download
```
### Add your auth token
Sign in at [dashboard.ngrok.com](https://dashboard.ngrok.com), copy the auth token:
```bash theme={null}
ngrok config add-authtoken
```
Without this step ngrok starts but the public URL fails the TLS handshake (`ERR_NGROK_4018`).
### Install + register the gateway
```bash theme={null}
corebrain gateway setup --kind native
corebrain gateway register --tunnel ngrok
```
The register command runs `ngrok http 7787` in the background, captures the public HTTPS URL, generates a security key, and prints both.
## Register in the CORE app
The security key is shown **once** โ copy it now. Then:
1. In the CORE webapp โ **Sidebar โ Gateways โ + New gateway**.
2. Pick **Native**.
3. Paste the **Base URL** and **Security key**, submit.
Status should flip to **Connected** within a few seconds. If it shows **Unreachable**, verify the tunnel is up (`tailscale status` or the ngrok dashboard).
## Verify
```bash theme={null}
corebrain gateway status # this machine's gateway
corebrain gateway list # every gateway your workspace knows about
```
## Register a folder (recommended)
Until you register at least one folder, the gateway runs in permissive first-run mode. Once you register one, scope is enforced everywhere.
```bash theme={null}
corebrain folder add . --scopes files,coding,exec
```
| Scope | What it allows |
| -------- | -------------------------------------------------------------------------------------------------------- |
| `files` | `files_read`, `files_write`, `files_edit`, `files_glob`, `files_grep` and the file browser in the webapp |
| `coding` | `coding_ask` and interactive coding sessions targeting paths inside this folder |
| `exec` | `exec_command` working directories |
## Troubleshooting
**`tailscale not found on PATH`**: install via `brew install --cask tailscale` (macOS) or the official installer (Linux). `brew install tailscale` only installs the daemon helper, not the CLI binary.
**`tailscale funnel started but no public URL appeared within 5s`**: Funnel isn't yet enabled for this device. Re-check the admin console (HTTPS certs + Funnel grant) and retry.
**`ngrok did not expose a public URL within 15s`**: usually a missing auth token. Run `ngrok config add-authtoken ` and retry.
**Gateway shows as Unreachable**: confirm the tunnel is alive and the URL in the webapp matches what `corebrain gateway status` prints.
**Lost the security key**: run `corebrain gateway register` to generate a new one, then update **Sidebar โ Gateways โ Edit** in the webapp.
For a deeper troubleshooting matrix, see [Tunnels](/gateway/tunnels).
# Railway
Source: https://docs.getcore.me/gateway/deployment/railway
Managed cloud gateway โ Railway provisions the URL and runs the container for you.
Pick this when you want a fully managed cloud gateway with no infra of your own.
## Option 1 โ One-click deploy
Click the button below. Railway prompts for env vars, provisions the service and a public domain, and the security key appears in the deploy logs on first boot.
[](https://railway.com/deploy/core-gateway)
### Railway env vars
| Variable | What to fill in | How to get it |
| -------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `COREBRAIN_API_URL` | URL of your CORE instance, e.g. `https://app.getcore.me`. | Use the hosted instance URL, or your self-hosted domain. No trailing slash. |
| `COREBRAIN_API_KEY` | A Personal Access Token (PAT) for your CORE workspace. | In the CORE webapp: avatar โ **Settings โ API keys โ New token**. Copy the value once; it's not shown again. |
| `COREBRAIN_GATEWAY_NAME` | Display name for this gateway, e.g. `railway-prod`. | Pick anything. Shows up in **Sidebar โ Gateways** so you can tell multiple gateways apart. |
| `COREBRAIN_GATEWAY_SECURITY_KEY` | *Recommended: pin your own value here.* | Generate with `echo "gwk_$(openssl rand -base64 32 \| tr -d '=' \| tr '/+' '_-')"` and paste the same value here and into the CORE app later. If you leave it blank, the gateway generates one on first boot and prints it to the deploy logs (banner: `CoreBrain Gateway, security key generated`). |
| `GITHUB_TOKEN` | A GitHub Personal Access Token. | Required by the template, but only used if the gateway will clone private repos or commit on your behalf. Create at [github.com/settings/tokens](https://github.com/settings/tokens) โ classic, scopes `repo` + `read:user`. Fine-grained PATs also work (`Contents: Read & write`, plus `Account โ Profile: Read-only`). If you don't need private-repo access, paste any valid PAT; the gateway boots either way. |
| `ANTHROPIC_API_KEY` *(optional)* | API key for Anthropic. | Lets `claude-code` skip the OAuth login flow. Get it at [console.anthropic.com](https://console.anthropic.com). Skip if you'll log Claude Code in manually later. |
| `OPENAI_API_KEY` *(optional)* | API key for OpenAI. | Lets `codex-cli` skip OAuth. Get it at [platform.openai.com/api-keys](https://platform.openai.com/api-keys). |
| `CLAUDE_CODE_OAUTH_TOKEN` *(optional)* | OAuth token for Claude Code. | Alternative to `ANTHROPIC_API_KEY` if you already have an OAuth token from a prior `claude` login. |
### After Railway deploys
1. Open the service in Railway โ **Deployments โ View logs**.
2. Get the security key:
* If you pinned `COREBRAIN_GATEWAY_SECURITY_KEY`, use that value.
* Otherwise find the banner `CoreBrain Gateway, security key generated` and copy the `gwk_...` value.
3. Copy the public domain Railway provisioned (under **Settings โ Networking โ Public Networking**).
## Option 2 โ CLI-driven
```bash theme={null}
npm install -g @redplanethq/corebrain
corebrain login
corebrain gateway setup --kind railway
```
The wizard detects (or installs) the Railway CLI, runs `railway init` and `railway deploy -t core-gateway`, provisions a public domain, and prints the URL + security key.
## Register in the CORE app
1. **Sidebar โ Gateways โ + New gateway**.
2. Pick **Railway**.
3. Paste the **Base URL** (Railway public domain) and **Security key**.
4. Submit.
Status should flip to **Connected** within a few seconds.
## Rotating the security key
Change `COREBRAIN_GATEWAY_SECURITY_KEY` in the Railway service's env vars and redeploy. The gateway detects the new value on boot and overwrites the persisted hash. Update the key in **Sidebar โ Gateways โ Edit** in the webapp to match.
## Verify
In the CORE app, ask in any conversation: *"List my gateways."*
Or from your laptop with the CLI:
```bash theme={null}
corebrain gateway list
```
## LLM subscription proxy
The Railway image ships the [LLM proxy](/gateway/subscription-proxy) at `/llmproxy/v1`. After registering, run `corebrain gateway llmproxy --login claude` (or `codex` / `antigravity` / `xai`) from your laptop to point CORE at your Claude Max, ChatGPT Codex, Antigravity, or xAI Grok subscription.
# Exec
Source: https://docs.getcore.me/gateway/exec
Execute shell commands on your machine with security controls
## Overview
The Exec capability lets CORE run shell commands on your machine. This is powerful but requires careful configuration - you control exactly which commands are allowed through allow/deny patterns.
***
## Security Model
Commands are validated against three layers before execution:
1. **Built-in deny list** โ common-sense blocks like `rm -rf /`, `sudo`, `curl โฆ | bash`. Skipped only if `allowUnsafe: true`.
2. **User deny patterns** โ checked next; takes precedence over allow.
3. **User allow patterns** โ if configured, the command must match at least one. If empty, all non-denied commands are allowed.
In addition, when at least one folder is registered the `dir` parameter must resolve into a folder with the `exec` scope โ otherwise the call fails with `FOLDER_SCOPE_DENIED`.
***
## Configuration
Configure exec patterns through the CLI:
```bash theme={null}
corebrain exec config
```
Or set them in your gateway slots configuration.
### Pattern Format
Patterns use the format `Bash()`:
```
Bash(git *) # Allow all git commands
Bash(npm run *) # Allow npm run scripts
Bash(ls *) # Allow ls commands
Bash(*) # Allow everything (use with caution)
```
### Example Configuration
```json theme={null}
{
"exec": {
"allow": [
"Bash(git *)",
"Bash(npm run *)",
"Bash(ls *)",
"Bash(cat *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(sudo *)"
],
"defaultDir": "/Users/me/projects"
}
}
```
***
## Gateway Tool
### exec\_command
Execute a shell command:
```json theme={null}
{
"command": "git status",
"dir": "/Users/me/projects/myapp",
"timeout": 30000
}
```
| Parameter | Required | Description |
| --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `command` | Yes | The command to execute |
| `dir` | No | Working directory. Must resolve into an `exec`-scoped registered folder when folders exist. Falls back to `ExecConfig.defaultDir` (deprecated) otherwise. |
| `timeout` | No | Timeout in milliseconds (default: 30000) |
### Response
```json theme={null}
{
"success": true,
"result": {
"command": "git status",
"dir": "/Users/me/projects/myapp",
"exitCode": 0,
"stdout": "On branch main\nnothing to commit, working tree clean",
"stderr": null
}
}
```
***
## Use Cases
**Git operations:** CORE checks branch status, creates commits, pushes changes:
```
"Check if there are uncommitted changes in the API repo"
```
**Build and test:** Run build scripts and test suites:
```
"Run the test suite and tell me if anything fails"
```
**System checks:** Query system state:
```
"How much disk space is left on my machine?"
```
**File operations:** Read and process files:
```
"Show me the last 50 lines of the server log"
```
***
## Recommended Patterns
### Development Workflow
```json theme={null}
{
"allow": [
"Bash(git *)",
"Bash(npm *)",
"Bash(pnpm *)",
"Bash(yarn *)",
"Bash(cargo *)",
"Bash(make *)"
]
}
```
### Read-Only Access
```json theme={null}
{
"allow": [
"Bash(ls *)",
"Bash(cat *)",
"Bash(head *)",
"Bash(tail *)",
"Bash(grep *)",
"Bash(find *)"
]
}
```
### Always Deny
```json theme={null}
{
"deny": [
"Bash(rm -rf *)",
"Bash(sudo *)",
"Bash(chmod 777 *)",
"Bash(curl * | bash)",
"Bash(wget * | bash)"
]
}
```
***
## Notes
* Commands run with your user permissions (the user the gateway service runs as).
* Output is captured and returned (`stdout`, `stderr`, `exitCode`).
* Long-running commands should set `timeout`.
* Commands that require user input will hang โ avoid interactive commands. Use `coding_ask` with the appropriate agent for interactive flows.
* The `exec` slot can be turned off entirely in `corebrain gateway config` โ disabled slots are not just hidden in the manifest, their HTTP route is not registered at all.
# Integrations
Source: https://docs.getcore.me/gateway/integrations
Manage integrations on your CORE instance from the CLI
The `corebrain` CLI lets you manage integrations on your connected CORE instance โ including self-hosted deployments.
## Commands
| Command | Description |
| -------------------------------------- | ------------------------------------- |
| `corebrain integrations add` | Register a new custom integration |
| `corebrain integrations list` | List all integrations on the instance |
| `corebrain integrations remove [slug]` | Remove a workspace integration |
## Self-Hosted Instances
When logged into a self-hosted instance, these commands register integrations directly on that instance. Make sure you've pointed the CLI at your own URL:
```bash theme={null}
corebrain login
# Enter your self-hosted instance URL when prompted
```
All subsequent `corebrain integrations` commands will operate against that instance.
For full details on the interactive add wizard, listing, and removal, see [Adding Integrations to Your Instance](/integrations/adding-to-instance).
For building integration packages from scratch, see [Building Integrations](/integrations/building-integrations).
# Notion
Source: https://docs.getcore.me/gateway/load/notion
Browse and ingest Notion pages into CORE's memory from the CLI
## Overview
`corebrain load notion` lets you pick pages from your Notion workspace and ingest them into CORE's memory. Once ingested, the content becomes part of CORE's context and can be referenced in future conversations.
```bash theme={null}
corebrain load notion
```
Requires Notion to be connected in your CORE workspace before running.
***
## How It Works
Make sure Notion is connected in your CORE workspace at **Settings โ Integrations**.
```bash theme={null}
corebrain load notion
```
The CLI checks your Notion connection and opens an interactive page browser.
* Type in the search box and press `enter` to filter pages
* Press `tab` or `โ` to move focus to the list
* Navigate with `โโ`
* Press `space` to select / deselect a page
* Select as many pages as you want
With pages selected, press `enter` to ingest them. The CLI fetches each page's content and stores it in CORE's memory.
***
## After Ingestion
After ingesting, you'll see a summary of how many pages succeeded or failed, and a menu to:
* **Continue loading** โ go back and select more pages
* **Remove all (reset)** โ clear the list and start fresh
* **Exit** โ close the tool
***
## Notes
* Only pages you have access to in Notion will appear
* If a page has no content, the title is stored as a fallback
* More load sources (e.g. Confluence, Google Docs) will be added over time
# Gateway
Source: https://docs.getcore.me/gateway/overview
Run a local agent on your machine that connects CORE to your development environment
## What is the Gateway?
The Gateway is a local Fastify HTTP server (default port `7787`) bundled into the `@redplanethq/corebrain` CLI. It runs on your laptop, on a Docker host you control, or on Railway, and exposes your **browser**, **coding agents**, **shell**, and a registered set of **folders** to CORE over an authenticated HTTP + WebSocket API.
CORE never touches your machine directly. Every action CORE takes on your environment, opening a tab, running a test, editing a file, spawning Claude Code, goes through this gateway. It's the bridge between CORE's cloud intelligence and your local environment.
> **Looking for the runbook?** See [Gateway Setup](/gateway/setup) for a linear, copy-pasteable guide. This page is the conceptual overview.
***
## Why connect a Gateway?
Without a gateway, CORE is a memory and reasoning layer in the cloud. With one, CORE can act on your actual machine and accounts. Concrete examples:
Message CORE on WhatsApp, "Fix the auth timeout in the API." CORE spawns Claude Code on your gateway, pulls context from memory, and works on the bug while you're on the train.
Log in to LinkedIn once on your `personal` Playwright profile. CORE can research leads, scrape your dashboards, or drive a checkout flow without you re-authenticating.
Watch a coding session stream into the webapp's terminal pane in real time, attach, type, and resize, with a Chrome DevTools-style live view of the browser running alongside.
"Every morning at 9am, run the test suite and summarize failures." A reminder fires `exec_command` against your repo and posts the result back to your channel of choice.
The gateway is what turns CORE from "an LLM that remembers" into "an assistant that gets things done on your stack."
***
## What does it expose?
The gateway advertises a **manifest** of capability slots. Each slot can be turned off in `corebrain gateway config`; disabled slots aren't just hidden, their HTTP routes are not registered.
| Slot | Tools exposed | Use this for |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| **Browser** | `browser_navigate`, `browser_snapshot`, `browser_click`, `browser_fill`, `browser_type`, `browser_press_key`, `browser_select_option`, `browser_screenshot`, `browser_scroll`, `browser_go_back`, `browser_go_forward`, `browser_wait_for`, `browser_evaluate`, `browser_create_session`, `browser_list_sessions`, `browser_delete_session`, `browser_close_session`, `browser_close_all` | Authenticated scraping, form automation, dashboard reads, live browser viewing in the webapp |
| **Coding** | `coding_ask`, `coding_read_session`, `coding_list_sessions`, `coding_search_sessions`, `coding_list_agents`, `coding_close_session`, `coding_close_all` | Spawn or resume Claude Code / Codex sessions remotely; isolated git worktrees for autonomous work |
| **Exec** | `exec_command` | Shell commands gated by allow/deny patterns and folder scopes |
| **Files** | `files_read`, `files_write`, `files_edit`, `files_glob`, `files_grep` | File reads, edits, glob, ripgrep, all scoped to registered folders |
| **Utils** (always on) | `sleep` | Pause between polling tool calls |
In addition the gateway exposes a few HTTP routes the webapp uses directly:
* `GET /manifest`: full capability manifest the webapp reads on every poll.
* `WS /api/coding/coding_xterm_session`: terminal stream for coding sessions and the per-gateway shell.
* `WS /api/browser/cdp/:session`: Chrome DevTools Protocol proxy for the live browser viewer.
* `POST /api/folders/local`, `POST /api/folders/git`, `DELETE /api/folders/:idOrName`: folder management.
* `POST /api/shell/spawn`: general-purpose PTY for the shell tab.
Every request requires `Authorization: Bearer gwk_`. There is no localhost bypass, the same flow applies whether the gateway is on `127.0.0.1`, behind a tunnel, or on a public Docker host.
For the protocol details and a route-by-route reference, see [`packages/gateway-protocol/README.md`](https://github.com/RedPlanetHQ/core/blob/main/packages/gateway-protocol/README.md).
***
## Install (quick path)
For the full step-by-step including Tailscale / ngrok install, see [Gateway Setup](/gateway/setup).
```bash theme={null}
npm install -g @redplanethq/corebrain
corebrain login
```
```bash theme={null}
corebrain gateway setup
```
Pick where the gateway should run:
* **Native**: this machine. Installs a launchd (macOS) / systemd (Linux) service and gives full access to local browser, shells, and folders. Native gateways listen on `127.0.0.1` and need a tunnel (Tailscale or ngrok) before CORE's cloud can reach them. See [Tunnels](/gateway/tunnels) or the [Setup runbook](/gateway/setup) for the tunnel install steps you must run first.
* **Docker**: local or remote Docker host. Drops `docker-compose.yaml` + `.env` into `~/.corebrain/gateways//` (templates fetched from `main` so they stay in sync), runs `docker compose up -d`, and optionally exposes via [Tailscale Funnel](/gateway/tunnels).
* **Railway**: managed cloud. Detects (or installs) the Railway CLI, runs `railway init` + `railway deploy -t core-gateway`, and provisions a public domain.
For docker / railway the wizard also prompts (optional) for `CLAUDE_CODE_OAUTH_TOKEN`, `OPENAI_API_KEY`, and `GITHUB_TOKEN` so the coding + git slots work out of the box.
Native installs need a tunnel before the cloud can reach them:
```bash theme={null}
corebrain gateway register --tunnel tailscale
# or
corebrain gateway register --tunnel ngrok
# or, bring your own URL:
corebrain gateway register --tunnel none --baseUrl https://gateway.example.com
```
The CLI prints a `baseUrl` and a `securityKey` (`gwk_...`). **The raw key is shown exactly once.**
This is the step that links the gateway to your workspace. Without it, the gateway is reachable but CORE doesn't know it exists.
1. Open [https://app.getcore.me](https://app.getcore.me) (or your self-hosted instance).
2. **Sidebar โ Gateways โ + New gateway**.
3. Paste the **Base URL** and the **Security key** from the CLI output.
4. Click **Submit**. The gateway should show **Connected** within a few seconds.
```bash theme={null}
corebrain gateway list # all gateways your workspace knows about
corebrain gateway status # native gateway on this machine
corebrain gateway status # any gateway by id
```
### Skipping the wizard
`corebrain gateway setup --kind native|docker|railway` jumps straight into one path. Useful for headless installs and CI.
### One-click Railway deploy
[](https://railway.com/deploy/core-gateway)
Railway prompts for the env vars, provisions the service + public domain, and the security key appears in the deploy logs on first boot. You still need to paste the URL + key into **Sidebar โ Gateways** in the CORE app (Step 4 above).
The required env vars:
* `COREBRAIN_API_URL`: your CORE instance URL (e.g. `https://app.getcore.me`)
* `COREBRAIN_API_KEY`: a Personal Access Token from the webapp
* `COREBRAIN_GATEWAY_NAME`: name shown in the webapp
* `COREBRAIN_GATEWAY_SECURITY_KEY`: *(optional)* leave empty and Railway will auto-generate one
***
## Gateway Commands
### Top-level (work on any gateway)
| Command | Use this when |
| -------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `corebrain login` | First-time setup, or after rotating your Personal Access Token. |
| `corebrain gateway setup` | Spinning up a new gateway from scratch (interactive wizard). |
| `corebrain gateway setup --kind native\|docker\|railway` | Headless install / CI / scripted setup. |
| `corebrain gateway list` | Checking which gateways your CORE workspace knows about, across all your machines. |
| `corebrain gateway status` | Quick health check of the native gateway running on this machine. |
| `corebrain gateway status ` | Inspecting any gateway's manifest, slot config, and tunnel state by id. |
### Native gateway lifecycle (this machine only)
| Command | Use this when |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `corebrain gateway register` | After `setup`, to generate the URL + security key and (optionally) start a tunnel. Also used to **rotate** the key if it leaks or is lost. |
| `corebrain gateway register --tunnel tailscale\|ngrok\|none` | Picking how the gateway is exposed. `none` means you supply your own URL. |
| `corebrain gateway start` | Installing the gateway as a system service so it boots with the machine. |
| `corebrain gateway start --foreground` | Debugging the gateway attached to your terminal (Docker / ad-hoc). |
| `corebrain gateway stop` | Shutting the service down and tearing down the managed tunnel. |
| `corebrain gateway restart` | Picking up a config change or recovering from a hung process. |
| `corebrain gateway config` | Toggling slots (browser / coding / exec / files), changing exec patterns, registering folders. |
The `folder`, `browser`, `coding`, and `exec` command groups configure the native gateway's slots and only run when one is set up on this machine. They print a redirect to `corebrain gateway setup` otherwise.
### Folders and scopes
| Command | Use this when |
| -------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `corebrain folder add ` | Granting the gateway access to a directory. Scopes default to `files,coding,exec`. |
| `corebrain folder add --scopes coding,exec` | Pinning narrower scopes (e.g. read-only, or coding-only). |
| `corebrain folder list` | Auditing what the gateway is allowed to touch. |
### Browser (Playwright)
| Command | Use this when |
| -------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `corebrain browser install` | First-time install of the Playwright Chromium binary (or refreshing it). |
| `corebrain browser create-profile ` | Creating a new persistent identity (cookies, localStorage). Max 5 profiles. |
| `corebrain browser create-session --profile ` | Binding a named task (e.g. `linkedin`) to a profile. Max 10 sessions. |
| `corebrain browser open --headed` | Logging in manually so the profile captures auth state. |
| `corebrain browser set-browser brave\|chrome\|default\|custom` | Switching the executable used by Playwright. |
| `corebrain browser status` | Inspecting session list and current browser binary. |
See [Browser](/gateway/browser) for the full reference.
### Coding (Claude Code, Codex)
| Command | Use this when |
| ---------------------------------------------- | ------------------------------------------------------------------- |
| `corebrain coding setup` | Adding a coding agent (claude-code or codex-cli) and logging it in. |
| `corebrain coding setup --default claude-code` | Setting which agent runs when callers don't specify one. |
See [Coding](/gateway/coding) for the full reference and the `coding_ask` payload shape.
### Exec (shell)
| Command | Use this when |
| ----------------------- | ------------------------------------------------------------------------------ |
| `corebrain exec config` | Editing the allow / deny pattern list (e.g. `Bash(git *)`, `Bash(npm run *)`). |
See [Exec](/gateway/exec) for the security model.
***
## Folders and scopes
Folders are registered paths the gateway is allowed to touch. Each folder carries one or more scopes:
| Scope | Allows |
| -------- | ------------------------------------------------------------- |
| `files` | `files_*` tools and the file-system browser in the webapp |
| `coding` | `coding_ask` / interactive sessions targeting paths inside it |
| `exec` | `exec_command` working dirs |
When at least one folder is registered, a request that names a path outside any matching-scope folder is rejected with `FOLDER_SCOPE_DENIED` / `PATH_OUTSIDE_FOLDER`. With zero folders registered the gateway runs in permissive first-run mode.
```bash theme={null}
# Register the current directory with all three scopes
corebrain folder add .
# Or pin scopes
corebrain folder add /Users/me/repos/api --scopes coding,exec
# Or clone a repo through the API (Docker hosts)
curl -X POST $GATEWAY/api/folders/git \
-H "Authorization: Bearer $KEY" \
-d '{"url":"https://github.com/RedPlanetHQ/core.git"}'
```
***
## Security
* **Bearer-only auth.** The gateway stores `sha256(securityKey)` on disk; the webapp encrypts the raw key at rest. Constant-time comparison; no localhost bypass.
* **Slot toggles.** Disabled slots are not just hidden, their HTTP routes are not registered, so a leaked key still cannot hit them.
* **Folder scopes.** Coding / exec / files tools are pinned to registered folders with the matching scope.
* **Exec patterns.** `exec_command` validates each command against allow / deny globs (`Bash()`) plus a built-in deny list for unsafe primitives.
* **Browser profiles.** Stored locally; auth state never leaves your machine.
* **Tunnels for native gateways.** Native installs always need HTTPS to be reachable from CORE's cloud. Use Tailscale Funnel, ngrok, or your own reverse proxy. See [Tunnels](/gateway/tunnels).
All traffic between CORE and the gateway is authenticated; use HTTPS or a tunnel for non-loopback deployments.
***
## Environment Variables (Headless / Docker)
When running without an interactive `corebrain login` flow, the gateway reads:
| Variable | Purpose |
| -------------------------------- | ------------------------------------------------------------ |
| `COREBRAIN_API_URL` | CORE instance URL |
| `COREBRAIN_API_KEY` | Personal access token |
| `COREBRAIN_GATEWAY_NAME` | Gateway name shown in the webapp |
| `COREBRAIN_GATEWAY_DESCRIPTION` | Optional gateway description |
| `COREBRAIN_GATEWAY_SECURITY_KEY` | Bearer key. Auto-generated and printed once if absent. |
| `COREBRAIN_GATEWAY_HTTP_PORT` | Port to listen on (default `7787`) |
| `COREBRAIN_DEFAULT_WORKSPACE` | Auto-registered as a folder with `files,coding,exec` scopes |
| `COREBRAIN_DEPLOY_MODE` | `native` or `docker`, surfaces in the manifest for UI gating |
| `ANTHROPIC_API_KEY` | Lets `claude-code` skip OAuth |
| `OPENAI_API_KEY` | Lets `codex-cli` skip OAuth |
| `GITHUB_TOKEN` | Used by `POST /api/folders/git` to clone private repos |
Bootstrap is idempotent. Values you set manually inside the container are never overwritten.
***
## Where next?
* [Gateway Setup runbook](/gateway/setup): linear copy-paste guide from zero to connected.
* [Tunnels](/gateway/tunnels): Tailscale Funnel and ngrok deep-dive.
* [Browser](/gateway/browser), [Coding](/gateway/coding), [Exec](/gateway/exec): per-capability references.
* [Gateway protocol README](https://github.com/RedPlanetHQ/core/blob/main/packages/gateway-protocol/README.md): full HTTP / WebSocket reference.
# Search
Source: https://docs.getcore.me/gateway/search
Search your CORE memory from the terminal
The `corebrain search` command gives you an interactive terminal UI to search documents stored in your CORE instance's memory.
## Usage
```bash theme={null}
corebrain search
```
## Interface
The command opens an interactive TUI with two modes:
**Search mode**
* Type a query and press `Enter` to search
* Results appear as a list below the search box, showing title, source, and labels
* Up to 20 results are returned per query
**Document view**
* Press `Enter` on a result to open the full document content
* Scroll through content with `โ` / `โ` or `j` / `k`
* Page through with `PgUp` / `PgDn`
* Press `q` or `Esc` to go back to results
## Keyboard Shortcuts
| Key | Action |
| ---------------------- | ------------------------------------------- |
| `Enter` | Submit search / open document |
| `โ` / `โ` or `j` / `k` | Navigate results / scroll document |
| `Tab` | Switch focus between search box and results |
| `PgUp` / `PgDn` | Page scroll in document view |
| `q` / `Esc` | Back / exit |
## Self-Hosted Instances
When logged into a self-hosted instance, `corebrain search` queries memory on that instance. Make sure you are logged in with your instance URL:
```bash theme={null}
corebrain login
# Enter your instance URL when prompted
```
# Gateway Setup
Source: https://docs.getcore.me/gateway/setup
Pick where the gateway will run โ local, Docker, or Railway โ and follow the matching runbook.
**For agents reading this page:** ask the user which of the three deployment options they want, then jump straight to that page's runbook and execute the fenced bash blocks in order. Do not claim success until the user confirms the gateway shows **Connected** in **Sidebar โ Gateways** in the CORE app.
The gateway can run in three places. Pick one and follow that page end-to-end.
| Choice | Pick this when | Runbook |
| ------------------ | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| **Local (Native)** | Should run on your laptop / workstation with full local access. Tunnels via Tailscale or ngrok. | [Deployment โ Local](/gateway/deployment/local) |
| **Docker** | You have a server, VPS, or always-on Docker host. Public URL via Tailscale Funnel or your own reverse proxy. | [Deployment โ Docker](/gateway/deployment/docker) |
| **Railway** | You want a managed cloud gateway with no infra of your own. | [Deployment โ Railway](/gateway/deployment/railway) |
Every path installs the CLI, provisions the gateway, generates a `gwk_...` security key, and finishes by asking you to paste the URL + key into **Sidebar โ Gateways โ + New gateway** in the CORE app.
For the conceptual overview of what the gateway is and what it can do, see [Gateway Overview](/gateway/overview). For tunnel-only details (Tailscale, ngrok, custom URLs), see [Tunnels](/gateway/tunnels).
## Common next steps
Once the gateway is registered and shows **Connected**:
* [Register a folder](/gateway/overview#folders-and-scopes) so the gateway has scoped access to your files, coding sessions, and shell.
* [Use your Claude / Codex subscription](/gateway/subscription-proxy) via the built-in LLM proxy (Docker and Railway images only).
* Explore capabilities: [Browser](/gateway/browser), [Coding](/gateway/coding), [Exec](/gateway/exec).
# Use Your Claude / Codex Subscription
Source: https://docs.getcore.me/gateway/subscription-proxy
Point CORE at your Claude Max, ChatGPT Codex, Antigravity, or xAI Grok subscription โ no API credits needed.
If you already pay for Claude Max, a ChatGPT plan that includes Codex, Google Antigravity, or xAI Grok, you can point CORE at your subscription instead of buying separate API credits. The CoreBrain Gateway ships a subscription proxy that exposes an OpenAI-compatible API and translates to each provider under the hood.
Subscription plans are licensed for **interactive** use. Providers can rate-limit or revoke tokens if they detect headless usage. Fine for personal self-host; risky if you're serving other users. When in doubt, use real API keys.
## Four steps
### 1. Deploy the gateway
The LLM proxy ships with the container image, so pick one of the container deployments:
* [Deployment โ Docker](/gateway/deployment/docker) โ your own server or VPS.
* [Deployment โ Railway](/gateway/deployment/railway) โ managed cloud.
Both paths end with a **Base URL** and a `gwk_...` **security key**. Keep both handy โ you'll paste them into the UI in step 2 and reuse the same security key as the BYOK API key in step 4.
### 2. Add the gateway in the UI
In the CORE webapp: **Sidebar โ Gateways โ + New gateway**. Pick the deployment kind you used in step 1 (Docker or Railway), then paste the URL and security key.
### 3. Log in to your subscription
```bash theme={null}
corebrain gateway llmproxy --login claude
```
Pick the gateway you just added when prompted. Follow the printed OAuth URL โ for Claude / Codex / Antigravity the browser redirect is caught automatically; for xAI you'll type a short device code shown in the terminal.
Repeat with `--login codex`, `--login antigravity`, or `--login xai` for other providers.
### 4. Wire it into CORE
In the webapp: **Settings โ Models โ + New API key**. Choose **OpenAI** and fill in:
* **Base URL** โ `https:///llmproxy/v1`
* **API key** โ the same security key from step 1
Then pick a model with the `openai/` prefix. Examples:
| Model | Routes to |
| -------------------------- | --------------- |
| `openai/claude-sonnet-4-6` | Claude Max |
| `openai/claude-opus-4-7` | Claude Max |
| `openai/gpt-5.5` | ChatGPT / Codex |
| `openai/gemini-2.0-flash` | Antigravity |
| `openai/grok-2-latest` | xAI |
Get the exact list of available models by hitting the proxy's model endpoint:
```bash theme={null}
curl -s https:///llmproxy/v1/models \
-H "Authorization: Bearer " | jq
```
## When a token expires
Just re-run the same login command:
```bash theme={null}
corebrain gateway llmproxy --login claude
```
The proxy auto-rotates access tokens as long as the refresh token stays valid; when it doesn't, re-login. Tokens live on the gateway's persistent volume, so container restarts never blow them away.
## Under the hood
The gateway embeds [CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI), which handles the OAuth flow for each subscription and re-shapes the requests into each provider's native protocol behind a single OpenAI-compatible surface at `/llmproxy/v1`. That's why one Base URL + one API key covers Claude, Codex, Antigravity, and xAI.
Other proxies exposing the same OpenAI-compatible shape work with the same wire-up if you'd rather run them yourself:
* **[Vercel AI Gateway](https://vercel.com/docs/ai-gateway/coding-agents/claude-code)** โ first-party pass-through for Claude Max via `ANTHROPIC_BASE_URL`. No self-hosting.
* **[ai-cli-proxy-api](https://github.com/ben-vargas/ai-cli-proxy-api)** โ variant that supports Factory and Amp CLIs alongside ChatGPT Plus/Pro and Claude Pro/Max.
# TUI
Source: https://docs.getcore.me/gateway/tui/overview
Interactive terminal UI for chatting with CORE and managing tasks, integrations, and conversations
## Overview
Running `corebrain` with no subcommand opens the interactive TUI โ a full terminal interface for talking to CORE directly from your machine.
```bash theme={null}
corebrain
```
You get a persistent chat session with an editor at the bottom. Type `/` to see available slash commands.
***
## Slash Commands
| Command | Description |
| --------------- | ---------------------------------------------- |
| `/resume` | Browse and resume a previous conversation |
| `/tasks` | View and manage your tasks |
| `/integrations` | View and manage connected integrations |
| `/dashboard` | Open the CORE web dashboard in your browser |
| `/clear` | Clear the current conversation and start fresh |
| `/exit` | Exit CORE |
***
## Features
### Resume
`/resume` opens a searchable list of past conversations.
* Navigate with `โโ`
* Press `f` to toggle between All sources and CLI-only conversations
* Press `enter` to load a conversation and continue where you left off
* Press `esc` to cancel
Conversations paginate automatically โ more load as you scroll toward the end of the list.
***
### Integrations
`/integrations` shows your connected integration accounts and all available integrations.
* Press `tab` to switch between **Installed** and **All** tabs
* Navigate with `โโ`
* Press `enter` to open the selected integration in the CORE dashboard
* Press `esc` to close
The **Installed** tab shows accounts you've connected, with a green dot for active accounts. The **All** tab lists every available integration โ connected ones are marked with a green dot.
# Tunnels
Source: https://docs.getcore.me/gateway/tunnels
Expose a gateway running on your laptop to CORE over Tailscale Funnel or ngrok
When the gateway runs on `127.0.0.1` it is only reachable from the same machine. To let CORE call it from the cloud โ without opening a port on your router or putting the gateway on a public host โ register it through a tunnel. The CLI ships first-class support for **Tailscale Funnel** and **ngrok**, and `corebrain gateway register` will start, track, and tear down the tunnel for you.
If your gateway already has a public URL (Railway, Fly, Cloudflare in front of a Docker host, etc.), you don't need this โ pick **none** at register time and paste the URL yourself.
***
## Choosing a tunnel
Stable URL tied to your tailnet. Best when the gateway will run for days or weeks, or when you already use Tailscale. Free for personal use.
Fastest to set up โ one auth token and you have an HTTPS URL in seconds. Free-tier URLs change on every restart; paid plans give you a stable subdomain.
Either way, traffic is HTTPS-terminated by the tunnel and the gateway still requires `Authorization: Bearer gwk_` on every request.
***
## Tailscale Funnel
### Prerequisites
If you don't already have Tailscale, install from [tailscale.com/download](https://tailscale.com/download) or run:
```bash theme={null}
# macOS
brew install --cask tailscale
# Linux
curl -fsSL https://tailscale.com/install.sh | sh
```
On macOS, `brew install tailscale` (no `--cask`) only installs the daemon helper. Use `--cask` or the App Store / `.pkg` build to get the CLI binary on `PATH`.
Verify:
```bash theme={null}
tailscale version
```
```bash theme={null}
sudo tailscale up
```
Funnel is a per-tailnet feature; your account needs to be the owner, or an admin must have enabled it for you. Confirm the device is connected before moving on:
```bash theme={null}
tailscale status
```
The current device should appear as `active`.
Open the Tailscale admin console โ **DNS** โ **HTTPS Certificates** (turn on) โ **Access Controls** โ add a Funnel ACL grant for the device, e.g.:
```hujson theme={null}
"nodeAttrs": [
{ "target": ["autogroup:member"], "attr": ["funnel"] }
]
```
Full reference: Tailscale Funnel docs.
### Register the gateway
```bash theme={null}
corebrain gateway register --tunnel tailscale
```
Under the hood this runs `tailscale funnel --bg ` and reads the public URL from `tailscale funnel status`. The URL has the shape `https://..ts.net` and persists across reboots as long as the device stays in your tailnet.
The CLI stores the funnel's PID under your gateway preferences, so `corebrain gateway stop` shuts the funnel down with the service.
### Troubleshooting
* **`tailscale not found on PATH`** โ install the CLI and re-run. On macOS Homebrew users, `brew install tailscale` only installs the daemon helper; for the CLI binary install the App Store / `.pkg` build or use `brew install --cask tailscale`.
* **`tailscale funnel started but no public URL appeared within 5s`** โ Funnel is not yet enabled for this device. Check the admin console (HTTPS certs + Funnel grant) and try again.
* **Funnel works but CORE can't reach the gateway** โ confirm the gateway is bound to `0.0.0.0` (it is by default) and that the port matches `corebrain gateway status`.
***
## ngrok
### Prerequisites
macOS:
```bash theme={null}
brew install ngrok
```
Linux / Windows: see ngrok.com/download. Verify:
```bash theme={null}
ngrok version
```
Sign in at dashboard.ngrok.com, copy your authtoken, then:
```bash theme={null}
ngrok config add-authtoken
```
Without this step ngrok will start, but the public URL will fail TLS handshake with `ERR_NGROK_4018`.
### Register the gateway
```bash theme={null}
corebrain gateway register --tunnel ngrok
```
The CLI runs `ngrok http ` in the background and queries ngrok's local API on `127.0.0.1:4040` to discover the public HTTPS URL. The URL is captured as your gateway's `baseUrl` and the ngrok process PID is tracked alongside it.
`corebrain gateway stop` will SIGTERM the ngrok process so the public endpoint stops pointing at a dead port.
### Stable URLs
Free-tier ngrok URLs change every restart, which means re-pasting the URL in **Sidebar โ Gateways** every time you reboot. To avoid that:
* **Reserved domain (paid):** create one in the ngrok dashboard, then run ngrok manually with `ngrok http --domain=.ngrok.app ` and register with `--tunnel none --baseUrl https://.ngrok.app`.
* **Static TCP / edge:** also supported via `--tunnel none` โ anything that gives you a fixed `https://...` URL works.
### Troubleshooting
* **`ngrok did not expose a public URL within 15s`** โ the most common cause is a missing authtoken. Run `ngrok config add-authtoken โฆ`.
* **`bind: address already in use` on 4040** โ another ngrok process is already running. Kill it (`pkill ngrok`) before re-registering.
* **Free-tier "interstitial" page** โ ngrok shows a one-time browser warning page on free URLs. CORE's requests are HTTP API calls and bypass it; you only see it in your browser.
***
## Bring your own URL
Pick this when the gateway already has a stable public address โ Railway, Fly, Render, Cloudflare Tunnel, an internal load balancer, etc.
```bash theme={null}
corebrain gateway register --tunnel none --baseUrl https://my-gateway.example.com
```
No subprocess is started; the CLI just records the URL and prints the security key. You are responsible for making sure that URL terminates HTTPS and forwards to the gateway port (default `7787`).
***
## After register: link the gateway in the CORE app
Whichever tunnel you pick, the last step is the same. The CLI prints something like:
```
name: my-laptop
baseUrl: https://my-laptop.tail-scale.ts.net
securityKey: gwk_aBcDeFg... โ only shown ONCE
Paste baseUrl + securityKey into CORE โ Sidebar โ Gateways.
```
Open [https://app.getcore.me](https://app.getcore.me) (or your self-hosted instance), go to **Sidebar โ Gateways โ + New gateway**, and paste both values. The gateway should show **Connected** within a few seconds.
If you ever rotate the tunnel or run `corebrain gateway register` again, the security key changes; update **Sidebar โ Gateways โ Edit** in the webapp with the new pair.
For the full end-to-end runbook (CLI install, login, register, paste, verify, register folders), see [Gateway Setup](/gateway/setup).
***
## Inspecting and stopping a tunnel
```bash theme={null}
corebrain gateway status # shows tunnel kind + pid
corebrain gateway stop # stops the gateway and the tunnel
corebrain gateway register # re-run to swap to a different tunnel
```
If you need to swap tunnels mid-session โ say from ngrok to Tailscale โ run `corebrain gateway stop`, then `corebrain gateway register --tunnel `. The CLI generates a fresh security key on every register; paste the new pair into **Sidebar โ Gateways โ Edit** in the webapp.
***
## Security notes
* The tunnel only carries HTTPS โ your security key never traverses plaintext.
* The gateway still validates `Authorization: Bearer โฆ` on every request. A leaked tunnel URL alone cannot reach any tool.
* Slot toggles (`corebrain gateway config`) are enforced at the route layer โ disabling Browser, Coding, or Exec removes their HTTP routes entirely, so a stolen key still cannot hit them through the tunnel.
* Both Tailscale Funnel and ngrok log connection metadata. If that's a concern for your threat model, prefer Tailscale (private-by-default tailnet, with Funnel as an explicit opt-in) or self-host with `--tunnel none`.
# Getting Started
Source: https://docs.getcore.me/getting-started
Install and run your personal AI OS in minutes. Open source, self-hosted, yours forever.
CORE is your personal AI OS. It watches your apps and AI sessions, remembers what matters across every conversation, and acts โ directly in your tools or by spawning coding and browser agents โ without you staying in the loop for every step.
***
## Choose your path
| I want to... | How |
| ------------------------- | ------------------------------------------------ |
| Try it on my machine | Run the one-step install below (requires Docker) |
| Deploy on a server or VPS | One-click Railway deploy |
| Use the Mac app | [Join the waitlist](https://www.getcore.me/) |
***
## Install and start CORE
```bash theme={null}
npm install -g @redplanethq/corebrain && corebrain setup
```
The setup wizard asks for an install directory, AI provider, API key, and chat model. It generates secrets, starts the stack, and opens `http://localhost:3033`.
Most local installs take a few minutes once Docker is running.
**Requirements:** Docker 20.10+, Docker Compose 2.20+, 4 vCPU / 8GB RAM
**Or deploy on Railway:**
[](https://railway.com/deploy/core)
[Full self-hosting guide โ](/self-hosting/setup)
***
## Connect a gateway
The gateway is what lets CORE drive coding agents, your browser, and terminal commands โ even when your laptop is closed.
```bash theme={null}
corebrain login
corebrain gateway setup
```
Run this on your laptop, a Docker host, or a Railway service. Once it's connected, CORE can spawn Claude Code or Codex sessions, run terminal commands, and open PRs on your behalf.
***
## Your first task
Once CORE is running:
1. Open the **Scratchpad** โ your daily page at `http://localhost:3033`
2. Type `[ ] Summarize my open GitHub issues` (or any task you'd normally handle yourself)
3. CORE picks it up within 3 minutes, gathers context from your connected apps and memory, and drafts a plan
4. Approve the plan โ CORE runs it and brings back the result
That's the core loop: you write what needs doing, CORE owns it end to end.
***
## CORE in action
### Say it, come back to a PR.
Press Ctrl+Option, speak: *"Fix the race condition in the checkout flow from issue #312."*
CORE loads the issue, pulls related commits and Slack threads, drafts a plan, and runs a Claude Code session. You come back to a diff.
### Write it at night, review it in the morning.
Scratchpad: `[ ] Work through tonight's backlog starting at 11pm`
CORE pulls from Linear, GitHub, and memory, prioritizes, and works through it while you sleep. Smooth runs are waiting for your review. Stuck sessions come back with one tight question, not a stalled tab.
### Message it from anywhere.
WhatsApp from the airport: *"Ship the auth refactor."*
CORE already knows the branch, the context, and your preferences. It is running in Railway. It kicks off the session before you board.
### Investigate alerts before they become incidents.
Sentry fires at 2am. CORE investigates, pulls related traces and prior incidents from memory, proposes a fix, and pings you on Slack: "Issue #847, fix proposed, awaiting your review." You approve from your phone.
### Get a brief that already knows your week.
Recurring task, every morning at 8am. CORE pulls from email, GitHub, Linear, and Slack, surfaces what actually needs attention, skips what does not, and turns follow-ups into tasks automatically.
***
## Next steps
50+ connectors โ GitHub, Linear, Slack, Gmail, and more.
How CORE remembers across every tool and conversation.
Reusable instructions that fire automatically based on context.
# Local setup
Source: https://docs.getcore.me/guides/local-setup
## Getting Started
### Prerequisites
* [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/)
* Node.js 18+ & pnpm
### Setup
1. Fork this repository
2. Clone your fork locally and install dependencies
```bash theme={null}
git clone https://github.com/RedPlanetHQ/core.git
cd core
pnpm install
```
3. Copy `.env.example` to `.env` and add your **OPENAI\_API\_KEY**.
4. Start docker services
```bash theme={null}
cd hosting/docker
docker-compose up -d postgres redis neo4j
cd ../..
```
5. Start the server
```bash theme={null}
pnpm dev
```
The application will be running at `http//:localhost:3033`
# Adding Integrations to Your Instance
Source: https://docs.getcore.me/integrations/adding-to-instance
Register custom integrations on your self-hosted CORE instance using the CLI
On a self-hosted instance, you can register custom integrations directly via the `corebrain` CLI without touching the source code.
## Prerequisites
Make sure you are logged into your self-hosted instance:
```bash theme={null}
corebrain login
# When prompted, enter your instance URL (e.g. https://your-domain.com)
```
## Commands
| Command | Description |
| -------------------------------------- | -------------------------------------------- |
| `corebrain integrations add` | Register a new integration on your instance |
| `corebrain integrations list` | List all integrations (global and workspace) |
| `corebrain integrations remove [slug]` | Remove a workspace integration |
## Adding an Integration
Run the interactive wizard:
```bash theme={null}
corebrain integrations add
```
You will be prompted for:
* **Name**: Display name for the integration
* **Description**: Short description of what it connects to
* **Slug**: Unique identifier (e.g. `my-service`)
* **Auth type**: `API Key` or `OAuth2`
* **Source URL**: Documentation or homepage URL for the service
* **Trigger type**: `Webhook` (receives events) or `Schedule` (periodic sync)
* **Sync interval**: If schedule-based: every 15, 20, or 30 minutes
The CLI builds a spec from your answers and registers the integration via the API.
## Listing Integrations
```bash theme={null}
corebrain integrations list
```
Returns all integrations split into **Workspace** (custom, created via CLI) and **Global** (built-in) integrations.
## Removing an Integration
```bash theme={null}
corebrain integrations remove
```
Presents an interactive selector of removable workspace integrations. Global (built-in) integrations cannot be removed.
You can also pass a slug directly:
```bash theme={null}
corebrain integrations remove my-service
```
## Further Reading
For building full integration packages with webhook handlers and schedule runners, see [Building Integrations](/integrations/building-integrations).
# MCP Hub
Source: https://docs.getcore.me/integrations/mcp-hub-guide
## MCP Hub Integration
**New to building integrations?** Start with our [step-by-step contributor guide](/opensource/building-integrations) for a quick overview.
The MCP Hub allows integrations to expose tools that AI agents can use. This reference guide covers MCP configuration and tool implementation.
## What is MCP Hub?
The MCP (Model Context Protocol) Hub is a centralized way for integrations to expose tools to AI agents. When an integration connects an MCP server, those tools become available to any AI agent using Core.
**Example flows:**
* Agent uses GitHub integration's `create_issue` tool to file a bug
* Agent uses Slack integration's `send_message` tool to notify a team
* Agent uses Linear integration's `create_task` tool to assign work
## MCP Configuration
Configure MCP in your integration's `spec.json`:
### HTTP-based MCP
For services with existing HTTP MCP servers:
```json theme={null}
{
"mcp": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${config:access_token}",
"Content-Type": "application/json",
"X-Custom-Header": "${config:custom_value}"
}
}
}
```
**Key points:**
* `type: "http"` - Specifies HTTP transport
* `url` - The MCP server endpoint
* `headers` - HTTP headers for authentication and configuration
* `${config:access_token}` - Placeholder replaced with user's OAuth token at runtime
* Any `${config:key}` placeholder pulls from the user's integration config
### Stdio-based MCP
For command-line MCP servers:
```json theme={null}
{
"mcp": {
"type": "stdio",
"url": "https://integrations.heysol.ai/slack/mcp/slack-mcp-server",
"args": [],
"env": {
"SLACK_MCP_XOXP_TOKEN": "${config:access_token}",
"SLACK_MCP_ADD_MESSAGE_TOOL": true,
"SLACK_WORKSPACE_ID": "${config:team_id}"
}
}
}
```
**Key points:**
* `type: "stdio"` - Specifies stdio transport (command-line)
* `url` - Binary/executable URL or path
* `args` - Command-line arguments array
* `env` - Environment variables passed to the process
* Placeholders work in env vars too
## Configuration Placeholders
The `${config:key}` syntax pulls values from the user's integration configuration:
### Setup Phase
When user completes OAuth, you set the config:
```typescript theme={null}
// account-create.ts
export async function integrationCreate(data: any) {
const { oauthResponse } = data;
return [{
type: 'account',
data: {
accountId: user.id.toString(),
config: {
access_token: oauthResponse.access_token,
refresh_token: oauthResponse.refresh_token,
team_id: user.team_id,
custom_setting: 'value',
// This config is accessible in MCP as ${config:*}
mcp: {
tokens: {
access_token: oauthResponse.access_token
}
}
}
}
}];
}
```
### Runtime Phase
Core replaces placeholders when connecting to MCP server:
```json theme={null}
// Before replacement (spec.json)
{
"mcp": {
"type": "http",
"url": "https://api.service.com/mcp/",
"headers": {
"Authorization": "Bearer ${config:access_token}",
"X-Team-ID": "${config:team_id}"
}
}
}
// After replacement (runtime)
{
"mcp": {
"type": "http",
"url": "https://api.service.com/mcp/",
"headers": {
"Authorization": "Bearer xoxp-actual-token-here",
"X-Team-ID": "T12345"
}
}
}
```
## HTTP MCP Server Example (GitHub)
### spec.json
```json theme={null}
{
"name": "GitHub extension",
"key": "github",
"description": "Manage GitHub repositories and issues",
"icon": "github",
"auth": {
"OAuth2": {
"token_url": "https://github.com/login/oauth/access_token",
"authorization_url": "https://github.com/login/oauth/authorize",
"scopes": ["repo", "user"]
}
},
"mcp": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${config:access_token}",
"Content-Type": "application/json"
}
}
}
```
### Available Tools
When Core connects to GitHub's MCP server, these tools become available:
* `github_create_issue` - Create a new issue
* `github_search_code` - Search code across repositories
* `github_create_pull_request` - Create a new PR
* `github_list_commits` - List commits for a repository
Agents can now call these tools:
```typescript theme={null}
// Agent calls this internally
await mcpClient.callTool('github_create_issue', {
owner: 'user',
repo: 'project',
title: 'Bug: Login fails',
body: 'Steps to reproduce...'
});
```
## Stdio MCP Server Example (Slack)
### spec.json
```json theme={null}
{
"name": "Slack extension",
"key": "slack",
"description": "Connect your workspace to Slack",
"icon": "slack",
"auth": {
"OAuth2": {
"token_url": "https://slack.com/api/oauth.v2.access",
"authorization_url": "https://slack.com/oauth/v2/authorize",
"scopes": ["chat:write", "channels:read", "users:read"]
}
},
"mcp": {
"type": "stdio",
"url": "https://integrations.heysol.ai/slack/mcp/slack-mcp-server",
"args": [],
"env": {
"SLACK_MCP_XOXP_TOKEN": "${config:access_token}",
"SLACK_MCP_ADD_MESSAGE_TOOL": true
}
}
}
```
### Available Tools
The Slack MCP server exposes:
* `slack_send_message` - Send message to channel
* `slack_list_channels` - List workspace channels
* `slack_add_reaction` - React to a message
* `slack_get_users` - Get workspace users
## Building Your Own MCP Server
If your service doesn't have an existing MCP server, you can build one:
### 1. Use the MCP SDK
```typescript theme={null}
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server(
{
name: 'my-service-mcp',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
// Define your tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'create_task',
description: 'Create a new task',
inputSchema: {
type: 'object',
properties: {
title: { type: 'string' },
description: { type: 'string' },
},
required: ['title'],
},
},
],
};
});
// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === 'create_task') {
const result = await createTask(args.title, args.description);
return {
content: [{ type: 'text', text: `Created task: ${result.id}` }],
};
}
throw new Error(`Unknown tool: ${name}`);
});
// Start server
const transport = new StdioServerTransport();
await server.connect(transport);
```
### 2. Authentication
Get tokens from environment variables:
```typescript theme={null}
const accessToken = process.env.MY_SERVICE_TOKEN;
if (!accessToken) {
throw new Error('MY_SERVICE_TOKEN not provided');
}
// Use token in API calls
const response = await fetch('https://api.myservice.com/tasks', {
headers: {
Authorization: `Bearer ${accessToken}`
}
});
```
### 3. Expose in spec.json
```json theme={null}
{
"mcp": {
"type": "stdio",
"url": "/path/to/your-mcp-server",
"args": [],
"env": {
"MY_SERVICE_TOKEN": "${config:access_token}"
}
}
}
```
## MCP Tool Best Practices
### 1. Clear Tool Descriptions
```json theme={null}
{
"name": "create_issue",
"description": "Create a new GitHub issue in a repository. Returns the issue number and URL.",
"inputSchema": {
"type": "object",
"properties": {
"owner": {
"type": "string",
"description": "Repository owner (username or organization)"
},
"repo": {
"type": "string",
"description": "Repository name"
},
"title": {
"type": "string",
"description": "Issue title (required, max 256 characters)"
},
"body": {
"type": "string",
"description": "Issue description in markdown format"
}
},
"required": ["owner", "repo", "title"]
}
}
```
### 2. Return Structured Data
```typescript theme={null}
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const result = await createIssue(args);
return {
content: [
{
type: 'text',
text: `Created issue #${result.number}: ${result.html_url}`
},
{
type: 'resource',
resource: {
uri: result.html_url,
mimeType: 'text/html',
text: JSON.stringify(result)
}
}
],
};
});
```
### 3. Error Handling
```typescript theme={null}
server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
const result = await performAction(args);
return {
content: [{ type: 'text', text: `Success: ${result}` }],
};
} catch (error) {
return {
content: [{
type: 'text',
text: `Error: ${error.message}`
}],
isError: true,
};
}
});
```
### 4. Rate Limiting
```typescript theme={null}
let lastCallTime = 0;
const MIN_INTERVAL = 1000; // 1 second between calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const now = Date.now();
if (now - lastCallTime < MIN_INTERVAL) {
await new Promise(resolve =>
setTimeout(resolve, MIN_INTERVAL - (now - lastCallTime))
);
}
lastCallTime = Date.now();
// Proceed with tool call
});
```
## Testing MCP Tools
### 1. Test with MCP Inspector
```bash theme={null}
npx @modelcontextprotocol/inspector node your-mcp-server.js
```
### 2. Test with Claude Desktop
Add to Claude Desktop config:
```json theme={null}
{
"mcpServers": {
"your-service": {
"command": "node",
"args": ["/path/to/your-mcp-server.js"],
"env": {
"MY_SERVICE_TOKEN": "test-token"
}
}
}
}
```
### 3. Test Tool Calls
```typescript theme={null}
// In your integration tests
const client = new Client({
name: 'test-client',
version: '1.0.0'
}, {
capabilities: {
tools: {}
}
});
await client.connect(transport);
const tools = await client.listTools();
console.log('Available tools:', tools);
const result = await client.callTool('create_task', {
title: 'Test task'
});
console.log('Tool result:', result);
```
## Common Patterns
### Dynamic Tool Listing
Generate tools based on user's account:
```typescript theme={null}
server.setRequestHandler(ListToolsRequestSchema, async () => {
const user = await getUserFromToken(accessToken);
const projects = await getProjects(user.id);
// Generate tool for each project
const tools = projects.map(project => ({
name: `create_task_${project.id}`,
description: `Create task in ${project.name}`,
inputSchema: {
type: 'object',
properties: {
title: { type: 'string' }
}
}
}));
return { tools };
});
```
### Composite Actions
Combine multiple API calls into one tool:
```typescript theme={null}
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === 'create_issue_with_assignee') {
// 1. Create issue
const issue = await createIssue(args.title, args.body);
// 2. Assign user
await assignIssue(issue.number, args.assignee);
// 3. Add labels
await addLabels(issue.number, args.labels);
return {
content: [{
type: 'text',
text: `Created and configured issue #${issue.number}`
}],
};
}
});
```
## Security Considerations
1. **Token Scoping** - Only request OAuth scopes needed for MCP tools
2. **Input Validation** - Validate all tool parameters before use
3. **Rate Limiting** - Implement rate limits to prevent abuse
4. **Error Messages** - Don't expose sensitive data in error messages
5. **Token Storage** - Tokens are securely encrypted in Core's database
## Next Steps
* [Build a Complete Integration](/integrations/building-integrations)
* [View MCP SDK Documentation](https://modelcontextprotocol.io/docs)
* [See Example MCP Servers](https://github.com/modelcontextprotocol/servers)
* [Explore GitHub MCP Server](https://github.com/github/github-mcp-server)
# Schedule based
Source: https://docs.getcore.me/integrations/schedule-based-guide
## Schedule-Based Sync Integrations
**New to building integrations?** Start with our [step-by-step contributor guide](/opensource/building-integrations) for a quick overview.
Schedule-based integrations run on a cron schedule to poll external APIs and fetch new activities. This reference guide uses GitHub as the detailed example.
## When to Use Schedule-Based Sync
Choose schedule-based integrations when:
* The service doesn't provide webhook events
* You want to batch process multiple API calls
* The service has rate limits that require careful timing
* Real-time sync isn't critical (5-15 minute delays acceptable)
* You need to poll multiple endpoints and aggregate data
## Architecture Overview
```
Cron Schedule (every 5-15 min)
โ
SYNC Event Triggered
โ
Fetch New Activities
โ
Compare with Last Sync Time
โ
Create Activity Messages
โ
Update State with New Sync Time
โ
Knowledge Graph
```
## Key Concepts
### State Management
Schedule-based integrations maintain state between runs:
```typescript theme={null}
interface GitHubSettings {
lastSyncTime?: string; // Last time we synced notifications
lastUserEventTime?: string; // Last time we synced user events
username?: string; // GitHub username
}
```
State is persisted by returning a `state` message:
```typescript theme={null}
return [
// ... activity messages
{
type: 'state',
data: {
lastSyncTime: new Date().toISOString(),
lastUserEventTime: new Date().toISOString(),
username: 'octocat'
}
}
];
```
### Pagination
Handle large datasets by paginating through results:
```typescript theme={null}
let page = 1;
let hasMorePages = true;
while (hasMorePages) {
const data = await fetchData(page);
if (!data || data.length === 0) {
hasMorePages = false;
break;
}
// Process data
for (const item of data) {
// Create activities
}
// Check if more pages exist
if (data.length < perPage) {
hasMorePages = false;
} else {
page++;
}
}
```
### Incremental Sync
Only fetch new data since last sync:
```typescript theme={null}
const lastSyncTime = state.lastSyncTime || getDefaultSyncTime(); // 24 hours ago
// Use lastSyncTime to filter API requests
const notifications = await fetch(
`https://api.github.com/notifications?since=${lastSyncTime}`
);
```
## Full Example: GitHub Integration
### spec.json
```json theme={null}
{
"name": "GitHub extension",
"key": "github",
"description": "Plan, track, and manage your projects in GitHub",
"icon": "github",
"schedule": {
"frequency": "*/5 * * * *" // Run every 5 minutes
},
"auth": {
"OAuth2": {
"token_url": "https://github.com/login/oauth/access_token",
"authorization_url": "https://github.com/login/oauth/authorize",
"scopes": [
"user",
"public_repo",
"repo",
"notifications",
"read:org"
],
"scope_separator": ","
}
},
"mcp": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${config:access_token}",
"Content-Type": "application/json"
}
}
}
```
### index.ts
```typescript theme={null}
import { handleSchedule } from './schedule';
import { integrationCreate } from './account-create';
import {
IntegrationCLI,
IntegrationEventPayload,
IntegrationEventType,
Spec,
} from '@redplanethq/sdk';
export async function run(eventPayload: IntegrationEventPayload) {
switch (eventPayload.event) {
case IntegrationEventType.SETUP:
return await integrationCreate(eventPayload.eventBody);
case IntegrationEventType.SYNC:
// Handle scheduled sync
return await handleSchedule(eventPayload.config, eventPayload.state);
default:
return { message: `Unknown event type: ${eventPayload.event}` };
}
}
class GitHubCLI extends IntegrationCLI {
constructor() {
super('github', '1.0.0');
}
protected async handleEvent(eventPayload: IntegrationEventPayload): Promise {
return await run(eventPayload);
}
protected async getSpec(): Promise {
return {
name: 'GitHub extension',
key: 'github',
// ... rest of spec
};
}
}
function main() {
const githubCLI = new GitHubCLI();
githubCLI.parse();
}
main();
```
### schedule.ts
```typescript theme={null}
import { getUserEvents, getGithubData } from './utils';
interface GitHubActivityCreateParams {
text: string;
sourceURL: string;
}
interface GitHubSettings {
lastSyncTime?: string;
lastUserEventTime?: string;
username?: string;
}
function createActivityMessage(params: GitHubActivityCreateParams) {
return {
type: 'activity',
data: {
text: params.text,
sourceURL: params.sourceURL,
},
};
}
function getDefaultSyncTime(): string {
// Default to 24 hours ago
return new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
}
async function processNotifications(
accessToken: string,
lastSyncTime: string,
username: string
): Promise {
const activities = [];
// Filter for relevant notification reasons
const allowedReasons = [
'assign',
'review_requested',
'mention',
'state_change',
'author',
'comment',
'team_mention',
];
let page = 1;
let hasMorePages = true;
while (hasMorePages) {
try {
// Fetch notifications with pagination
const notifications = await getGithubData(
`https://api.github.com/notifications?page=${page}&per_page=50&all=true&since=${lastSyncTime}`,
accessToken
);
if (!notifications || notifications.length === 0) {
hasMorePages = false;
break;
}
// Check if more pages exist
if (notifications.length < 50) {
hasMorePages = false;
} else {
page++;
}
// Process each notification
for (const notification of notifications) {
try {
// Filter by allowed reasons
if (!allowedReasons.includes(notification.reason)) {
continue;
}
const repository = notification.repository;
const subject = notification.subject;
// Fetch detailed data for the notification
let githubData: any = {};
if (subject.url) {
try {
githubData = await getGithubData(subject.url, accessToken);
} catch (error) {
continue; // Skip if we can't fetch details
}
}
const url = githubData.html_url || notification.subject.url || '';
const isIssue = subject.type === 'Issue';
const isPR = subject.type === 'PullRequest';
let title = '';
// Build contextual activity based on notification reason
switch (notification.reason) {
case 'assign':
title = `${isIssue ? 'Issue' : 'PR'} #${githubData.number} assigned to ${username} in ${repository.full_name}: ${githubData.title}`;
break;
case 'review_requested':
title = `${username} requested to review PR #${githubData.number} in ${repository.full_name}: ${githubData.title}`;
break;
case 'mention':
title = `${githubData.user?.login} mentioned ${username} in ${repository.full_name} ${isIssue ? 'issue' : 'PR'} #${githubData.number}: ${githubData.body}`;
break;
case 'comment':
title = `${githubData.user?.login} commented on ${isIssue ? 'issue' : 'PR'} #${githubData.number} in ${repository.full_name}: ${githubData.body}`;
break;
case 'state_change':
const stateInfo = githubData.state ? `to ${githubData.state}` : '';
title = `${githubData.user?.login} changed ${isIssue ? 'issue' : 'PR'} #${githubData.number} state ${stateInfo} in ${repository.full_name}: ${githubData.title}`;
break;
default:
title = `GitHub notification for ${username} in ${repository.full_name}`;
break;
}
if (title && url) {
activities.push(createActivityMessage({
text: title,
sourceURL: url,
}));
}
} catch (error) {
// Silently skip errors for individual notifications
continue;
}
}
} catch (error) {
hasMorePages = false;
}
}
return activities;
}
async function processUserEvents(
username: string,
accessToken: string,
lastUserEventTime: string
): Promise {
const activities = [];
let page = 1;
let hasMorePages = true;
while (hasMorePages) {
try {
// Fetch user events (PRs, issues they created)
const userEvents = await getUserEvents(username, page, accessToken, lastUserEventTime);
if (!userEvents || userEvents.length === 0) {
hasMorePages = false;
break;
}
if (userEvents.length < 30) {
hasMorePages = false;
} else {
page++;
}
for (const event of userEvents) {
try {
let title = '';
const sourceURL = event.html_url || '';
switch (event.type) {
case 'pr':
title = `${username} created PR #${event.number}: ${event.title}`;
break;
case 'issue':
title = `${username} created issue #${event.number}: ${event.title}`;
break;
case 'pr_comment':
title = `${username} commented on PR #${event.number}: ${event.title}`;
break;
case 'issue_comment':
title = `${username} commented on issue #${event.number}: ${event.title}`;
break;
default:
title = `GitHub activity: ${event.title || 'Unknown'}`;
break;
}
if (title && sourceURL) {
activities.push(createActivityMessage({
text: title,
sourceURL: sourceURL,
}));
}
} catch (error) {
continue;
}
}
} catch (error) {
hasMorePages = false;
}
}
return activities;
}
export async function handleSchedule(config: any, state: any) {
try {
const integrationConfiguration = config;
// Check for valid access token
if (!integrationConfiguration?.access_token) {
return [];
}
// Get settings or initialize
let settings = (state || {}) as GitHubSettings;
// Default to 24 hours ago if no last sync times
const lastSyncTime = settings.lastSyncTime || getDefaultSyncTime();
const lastUserEventTime = settings.lastUserEventTime || getDefaultSyncTime();
// Fetch user info to get username
let user;
try {
user = await getGithubData('https://api.github.com/user', integrationConfiguration.access_token);
} catch (error) {
return [];
}
if (!user) {
return [];
}
// Update username in settings
if (!settings.username && user.login) {
settings.username = user.login;
}
// Collect all messages
const messages = [];
// Process notifications
try {
const notificationActivities = await processNotifications(
integrationConfiguration.access_token,
lastSyncTime,
settings.username || 'user'
);
messages.push(...notificationActivities);
} catch (error) {
// Continue even if notifications fail
}
// Process user events
if (settings.username) {
try {
const userEventActivities = await processUserEvents(
settings.username,
integrationConfiguration.access_token,
lastUserEventTime
);
messages.push(...userEventActivities);
} catch (error) {
// Continue even if user events fail
}
}
// Update last sync times
const newSyncTime = new Date().toISOString();
// Add state message to persist settings
messages.push({
type: 'state',
data: {
...settings,
lastSyncTime: newSyncTime,
lastUserEventTime: newSyncTime,
},
});
return messages;
} catch (error) {
return [];
}
}
```
## Best Practices
### 1. State Management
Always persist state to track sync progress:
```typescript theme={null}
// Load state at start
let settings = (state || {}) as Settings;
const lastSyncTime = settings.lastSyncTime || getDefaultSyncTime();
// ... fetch and process data
// Save state at end
messages.push({
type: 'state',
data: {
...settings,
lastSyncTime: new Date().toISOString(),
}
});
```
### 2. Default Sync Window
On first sync, fetch last 24 hours of data:
```typescript theme={null}
function getDefaultSyncTime(): string {
return new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
}
const lastSyncTime = settings.lastSyncTime || getDefaultSyncTime();
```
### 3. Efficient Pagination
Stop paginating when no more data:
```typescript theme={null}
while (hasMorePages) {
const data = await fetchData(page, perPage);
// No data left
if (!data || data.length === 0) {
hasMorePages = false;
break;
}
// Process data...
// Less than full page means no more data
if (data.length < perPage) {
hasMorePages = false;
} else {
page++;
}
}
```
### 4. Error Resilience
Continue processing even if individual items fail:
```typescript theme={null}
for (const item of items) {
try {
// Process item
const activity = await processItem(item);
activities.push(activity);
} catch (error) {
// Log but continue
console.error('Failed to process item:', error);
continue; // Don't let one failure stop everything
}
}
```
### 5. Rate Limit Handling
Respect API rate limits:
```typescript theme={null}
async function fetchWithRetry(url: string, accessToken: string, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, {
headers: { Authorization: `Bearer ${accessToken}` }
});
if (response.status === 429) {
// Rate limited - wait and retry
const retryAfter = response.headers.get('Retry-After') || 60;
await sleep(parseInt(retryAfter) * 1000);
continue;
}
return await response.json();
} catch (error) {
if (i === retries - 1) throw error;
await sleep(1000 * (i + 1)); // Exponential backoff
}
}
}
```
### 6. Multiple Data Sources
Fetch from multiple endpoints and aggregate:
```typescript theme={null}
const messages = [];
// Fetch from multiple sources in parallel
const [notifications, pullRequests, issues] = await Promise.all([
processNotifications(accessToken, lastSyncTime),
processPullRequests(accessToken, lastSyncTime),
processIssues(accessToken, lastSyncTime)
]);
// Aggregate all activities
messages.push(...notifications, ...pullRequests, ...issues);
// Add state
messages.push({ type: 'state', data: newState });
return messages;
```
### 7. Schedule Configuration
Choose appropriate sync frequency:
```json theme={null}
{
"schedule": {
"frequency": "*/5 * * * *" // Every 5 minutes - real-time feel
"frequency": "*/15 * * * *" // Every 15 minutes - balance
"frequency": "0 * * * *" // Every hour - low volume
}
}
```
## Handling Account Setup
Set initial sync schedule during OAuth:
```typescript theme={null}
// account-create.ts
export async function integrationCreate(data: any) {
const { oauthResponse } = data;
const user = await getGithubData(
'https://api.github.com/user',
oauthResponse.access_token
);
return [{
type: 'account',
data: {
accountId: user.id.toString(),
config: {
access_token: oauthResponse.access_token,
refresh_token: oauthResponse.refresh_token,
mcp: { tokens: { access_token: oauthResponse.access_token } }
},
settings: {
username: user.login,
schedule: {
frequency: '*/15 * * * *' // Can customize per user
}
}
}
}];
}
```
## Testing Schedule-Based Integrations
1. **Manual Trigger**: Call SYNC event handler directly with test state
2. **Time Travel**: Mock date/time to simulate different sync scenarios
3. **State Testing**: Test with various lastSyncTime values
4. **Pagination**: Test with large datasets requiring multiple pages
5. **Error Scenarios**: Test with network failures, rate limits, invalid tokens
## Performance Optimization
### Batch API Calls
```typescript theme={null}
// Bad: Sequential calls
for (const id of ids) {
const data = await fetchData(id);
process(data);
}
// Good: Parallel calls with limit
const chunks = chunkArray(ids, 10); // Process 10 at a time
for (const chunk of chunks) {
const results = await Promise.all(chunk.map(id => fetchData(id)));
results.forEach(process);
}
```
### Cache Frequently Used Data
```typescript theme={null}
const userCache = new Map();
async function getUserDetails(userId: string, accessToken: string) {
if (userCache.has(userId)) {
return userCache.get(userId);
}
const user = await fetch(`https://api.github.com/users/${userId}`, {
headers: { Authorization: `Bearer ${accessToken}` }
});
userCache.set(userId, user);
return user;
}
```
## Next Steps
* [Build a Webhook-Based Integration](/integrations/webhook-based-guide)
* [Add MCP Tools to Your Integration](/integrations/mcp-hub-guide)
* [View Integration Examples](https://github.com/redplanethq/echo/tree/main/integrations)
# Webhook based
Source: https://docs.getcore.me/integrations/webhook-based-guide
## Webhook-Based Integrations
**New to building integrations?** Start with our [step-by-step contributor guide](/opensource/building-integrations) for a quick overview.
Webhook-based integrations receive HTTP callbacks from external services for real-time synchronization. This reference guide uses Slack as the detailed example.
## When to Use Webhooks
Choose webhook-based integrations when:
* The service provides real-time webhook events
* You need instant synchronization (chat messages, notifications)
* Events are user-triggered and need immediate capture
* The service has robust webhook infrastructure
## Architecture Overview
```
External Service (Slack)
โ
Webhook Event
โ
Core Webhook Endpoint
โ
Integration IDENTIFY โ Extract user ID
โ
Integration PROCESS โ Create activity
โ
Knowledge Graph
```
## Event Flow
### 1. SETUP Event
When a user connects their account via OAuth:
```typescript theme={null}
// account-create.ts
export async function integrationCreate(data: any) {
const { oauthResponse } = data;
// Get user info from service
const user = await getSlackUserInfo(oauthResponse.access_token);
return [{
type: 'account',
data: {
accountId: user.user_id,
config: {
access_token: oauthResponse.access_token,
refresh_token: oauthResponse.refresh_token,
// Pass token to MCP tools
mcp: { tokens: { access_token: oauthResponse.access_token } }
},
settings: {
username: user.user,
team_id: user.team_id
}
}
}];
}
```
### 2. IDENTIFY Event
When a webhook event arrives, extract the user identifier for routing:
```typescript theme={null}
// index.ts
case IntegrationEventType.IDENTIFY:
// Extract user ID from Slack event
return [{
type: 'identifier',
data: eventPayload.eventBody.event.event.user ||
eventPayload.eventBody.event.event.message.user
}];
```
This tells Core which user's knowledge graph to update with the activity.
### 3. PROCESS Event
Process the webhook event and create activity messages:
```typescript theme={null}
// create-activity.ts
export const createActivityEvent = async (eventData: any, config: any) => {
const event = eventData.event;
const accessToken = config.access_token;
// Handle different event types
if (event.type === 'reaction_added' && event.reaction === 'eyes') {
// User reacted with ๐ emoji - capture for knowledge graph
// 1. Get the original message
const message = await getMessage(accessToken, event.item.channel, event.item.ts);
// 2. Get user details and channel info
const [userDetails, channelInfo] = await Promise.all([
getUserDetails([message.user], accessToken),
getConversationInfo(accessToken, event.item.channel)
]);
// 3. Build contextual description
const text = `User ${userDetails[0].real_name} reacted with eyes emoji ` +
`in channel ${channelInfo.name}. Content: '${message.text}'`;
// 4. Get permalink for deep linking
const permalink = await getPermalink(accessToken, event.item.channel, event.item.ts);
// 5. Return activity message
return [{
type: 'activity',
data: {
text,
sourceURL: permalink.data.permalink
}
}];
}
if (event.type === 'message') {
// Handle message events
const text = `Message in channel: '${event.text}'`;
const permalink = await getPermalink(accessToken, event.channel, event.ts);
return [{
type: 'activity',
data: {
text,
sourceURL: permalink.data.permalink
}
}];
}
// Return empty array for unhandled events
return [];
};
```
## Full Example: Slack Integration
### spec.json
```json theme={null}
{
"name": "Slack extension",
"key": "slack",
"description": "Connect your workspace to Slack",
"icon": "slack",
"auth": {
"OAuth2": {
"token_url": "https://slack.com/api/oauth.v2.access",
"authorization_url": "https://slack.com/oauth/v2/authorize",
"scopes": [
"channels:read",
"channels:history",
"chat:write",
"reactions:read",
"reactions:write",
"users:read",
"users.profile:read"
],
"scope_identifier": "user_scope",
"scope_separator": ","
}
},
"mcp": {
"type": "stdio",
"url": "https://integrations.heysol.ai/slack/mcp/slack-mcp-server",
"args": [],
"env": {
"SLACK_MCP_XOXP_TOKEN": "${config:access_token}",
"SLACK_MCP_ADD_MESSAGE_TOOL": true
}
}
}
```
### index.ts
```typescript theme={null}
import { integrationCreate } from './account-create';
import { createActivityEvent } from './create-activity';
import {
IntegrationCLI,
IntegrationEventPayload,
IntegrationEventType,
Spec,
} from '@redplanethq/sdk';
export async function run(eventPayload: IntegrationEventPayload) {
switch (eventPayload.event) {
case IntegrationEventType.SETUP:
return await integrationCreate(eventPayload.eventBody);
case IntegrationEventType.IDENTIFY:
// Extract user ID from Slack event
return [{
type: 'identifier',
data: eventPayload.eventBody.event.event.user ||
eventPayload.eventBody.event.event.message.user,
}];
case IntegrationEventType.PROCESS:
// Process webhook event
return createActivityEvent(
eventPayload.eventBody.eventData,
eventPayload.config
);
default:
return [{ type: 'error', data: `Unknown event type: ${eventPayload.event}` }];
}
}
class SlackCLI extends IntegrationCLI {
constructor() {
super('slack', '1.0.0');
}
protected async handleEvent(eventPayload: IntegrationEventPayload): Promise {
return await run(eventPayload);
}
protected async getSpec(): Promise {
// Return spec configuration
return {
name: 'Slack extension',
key: 'slack',
// ... rest of spec
};
}
}
function main() {
const slackCLI = new SlackCLI();
slackCLI.parse();
}
main();
```
### create-activity.ts
```typescript theme={null}
import axios from 'axios';
interface SlackActivityCreateParams {
text: string;
sourceURL: string;
}
function createActivityMessage(params: SlackActivityCreateParams) {
return {
type: 'activity',
data: {
text: params.text,
sourceURL: params.sourceURL,
},
};
}
async function getMessage(accessToken: string, channel: string, ts: string) {
const result = await axios.get('https://slack.com/api/conversations.history', {
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
params: {
channel,
latest: ts,
inclusive: true,
limit: 1,
},
});
return result.data.messages?.[0];
}
async function getConversationInfo(accessToken: string, channel: string) {
const result = await axios.get('https://slack.com/api/conversations.info', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
params: { channel },
});
return result.data.channel;
}
async function getPermalink(accessToken: string, channel: string, ts: string) {
return await axios.get(
`https://slack.com/api/chat.getPermalink?channel=${channel}&message_ts=${ts}`,
{
headers: { Authorization: `Bearer ${accessToken}` },
}
);
}
export const createActivityEvent = async (eventData: any, config: any) {
const event = eventData.event;
if (!config) {
throw new Error('Integration configuration not found');
}
const accessToken = config.access_token;
// Handle reaction_added events
if (event.type === 'reaction_added' && event.reaction === 'eyes') {
const channel = event.item.channel;
const ts = event.item.ts;
// Fetch message and context
const [eventMessage, conversationInfo] = await Promise.all([
getMessage(accessToken, channel, ts),
getConversationInfo(accessToken, channel)
]);
// Build activity text
const text = `User reacted with eyes emoji in channel ${conversationInfo.name}. ` +
`Content: '${eventMessage.text}'`;
// Get permalink
const permalinkResponse = await getPermalink(accessToken, channel, ts);
return [createActivityMessage({
text,
sourceURL: permalinkResponse.data.permalink
})];
}
// Handle message events
if (event.type === 'message') {
const text = `Message in channel: '${event.text}'`;
const permalinkResponse = await getPermalink(accessToken, event.channel, event.ts);
return [createActivityMessage({
text,
sourceURL: permalinkResponse.data.permalink
})];
}
// Return empty array for unhandled events
return [];
};
```
## Best Practices
### 1. Event Filtering
Only process events that are relevant to the user's knowledge graph:
```typescript theme={null}
// Good: Filter for specific reactions that indicate importance
if (event.type === 'reaction_added' && event.reaction === 'eyes') {
// This is important, capture it
}
// Good: Filter for direct messages
if (conversationInfo.is_im) {
// Direct message is usually important
}
// Bad: Capture every message (too noisy)
if (event.type === 'message') {
// This creates too much noise
}
```
### 2. Context Enrichment
Provide rich context by fetching related data:
```typescript theme={null}
// Fetch related data in parallel for efficiency
const [userDetails, channelInfo, message] = await Promise.all([
getUserDetails([userId], accessToken),
getConversationInfo(accessToken, channelId),
getMessage(accessToken, channelId, timestamp)
]);
// Build descriptive activity
const text = `${userDetails[0].real_name} mentioned you in ` +
`${channelInfo.is_private ? 'private' : 'public'} channel ` +
`${channelInfo.name}: "${message.text}"`;
```
### 3. Deep Linking
Always provide sourceURL for navigation back to the original content:
```typescript theme={null}
const permalinkResponse = await axios.get(
`https://slack.com/api/chat.getPermalink?channel=${channel}&message_ts=${ts}`,
{ headers: { Authorization: `Bearer ${accessToken}` } }
);
return [{
type: 'activity',
data: {
text,
sourceURL: permalinkResponse.data.permalink // Essential!
}
}];
```
### 4. Error Handling
Handle errors gracefully without breaking the integration:
```typescript theme={null}
export const createActivityEvent = async (eventData: any, config: any) => {
try {
// Process event
const activities = await processEvent(eventData, config);
return activities;
} catch (error) {
console.error('Error processing webhook:', error);
// Return empty array instead of throwing
return [];
}
};
```
### 5. User Identification
Properly extract user IDs for different event types:
```typescript theme={null}
case IntegrationEventType.IDENTIFY:
// Handle different event structures
const userId = eventPayload.eventBody.event.event.user || // reactions, messages
eventPayload.eventBody.event.event.message.user || // threaded messages
eventPayload.eventBody.event.event.item.user; // other events
return [{ type: 'identifier', data: userId }];
```
## Testing Webhooks Locally
To test webhooks during development:
1. **Use ngrok** for local tunneling:
```bash theme={null}
ngrok http 3000
```
2. **Configure webhook URL** in service (Slack):
```
https://your-ngrok-url.ngrok.io/webhooks/slack
```
3. **Test events** by triggering actions in Slack
4. **Check logs** for event payloads and processing
## Common Event Types
### Slack
* `message` - New message posted
* `reaction_added` - Emoji reaction added
* `reaction_removed` - Emoji reaction removed
* `member_joined_channel` - User joined channel
* `app_mention` - Bot was mentioned
### Discord
* `MESSAGE_CREATE` - New message
* `MESSAGE_REACTION_ADD` - Reaction added
* `GUILD_MEMBER_ADD` - Member joined server
### Linear
* `Issue` - Issue created/updated
* `Comment` - Comment added
* `IssueLabel` - Label changed
## Next Steps
* [Build a Schedule-Based Integration](/integrations/schedule-based-guide)
* [Add MCP Tools to Your Integration](/integrations/mcp-hub-guide)
* [View Full SDK Reference](https://github.com/redplanethq/sdk)
# Introduction
Source: https://docs.getcore.me/introduction
Your personal AI OS โ always on, always watching, open source and self-hosted.
Not a chatbot you open. An AI that is always on, always watching.
Name it. Shape it. Connect it to everything you use. Reach it however you work.
Open source, self-hosted, yours forever.
***
## What CORE does
CORE watches activity across your connected apps and AI sessions. An email arrives from a client, a GitHub issue gets assigned, a Sentry alert fires, a meeting ends โ CORE sees it, checks your memory and the skills you have set, and either handles it or surfaces it for your judgment. You do not trigger it. It notices on its own.
It remembers what matters. Not just what you said, but what you decided, when, and why โ across every tool and conversation. Install the CORE plugin in Claude Code, Codex, or Cursor and your agent sessions get watched too, so the next task CORE picks up already knows what happened in your last session.
When it acts, it acts directly. It can reply to emails, update Linear issues, file GitHub PRs, send Slack messages, run terminal commands, drive a browser, and spawn a Claude Code or Codex session โ from any interface, even when your laptop is closed. The gateway is what makes this possible: it runs on your machine or in Docker and Railway, keeping CORE operational around the clock.
Where it acts on its own and where it waits for your call is yours to set, per task, per app, per action.
***
## Four ways to reach it
A chatbot has one interface. An OS has many.
Press **Ctrl+Option** on Mac and say what needs doing. CORE runs it in the background without breaking your flow.
Open your daily page and write `[ ] Fix the auth bug from issue #47`. CORE picks it up within 3 minutes, loads context from your repo and memory, and drafts a plan.
WhatsApp, Slack, Telegram. Send a task from the airport, from your phone, from bed. CORE has your full context regardless of where the message comes from.
Open the dashboard and talk directly. When you want a back-and-forth before delegating.
One AI, four surfaces, the same memory and context behind all of them.
***
## Make it yours
Give it a name. Choose how it speaks. Set the rules it follows everywhere.
Pick from built-in personalities โ TARS's dry efficiency, Alfred's loyal formality, Hudson's warm practicality โ or write your own. The personality carries into every task it runs, every plan it drafts, every message it sends on your behalf.
Choose its voice for spoken interactions. From then on, it sounds and behaves like the AI you configured, across every interface.
***
## What's inside CORE
| | |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Memory** | Temporal knowledge graph across every tool and conversation. Preferences, decisions, goals, and directives โ so every task starts with context loaded. |
| **Tasks** | One-shot or recurring work units with your spec, CORE's plan, live state, and a dedicated chat thread. Each task can spawn coding, browser, or terminal sessions. |
| **Connectors** | 50+ apps through one MCP endpoint, plus webhook triggers for proactive automation. GitHub, Linear, Jira, Slack, Gmail, Calendar, Sentry, Notion, Todoist, and more. |
| **Skills** | Reusable instructions that fire automatically based on context โ "always pull related Linear issues before planning a fix," "run tests before opening a PR." 100+ built-in, or write your own. |
| **Gateway** | Runs Claude Code, Codex, browser agents, and terminal commands on your machine or in Docker and Railway, so CORE keeps working when your laptop is closed. |
| **Model agnostic** | Bring your own provider: Anthropic, OpenAI, or open-weight models. Self-host the full stack for full isolation. |
***
## Get started
Install and run CORE in minutes. Self-hosted, your data stays with you.
Full deployment guide โ Docker, Railway, or your own infrastructure.
How CORE remembers what matters across every tool and conversation.
How CORE drives coding agents, browsers, and terminal commands.
# Authentication
Source: https://docs.getcore.me/mcp/authentication
Two ways to authenticate with CORE's MCP endpoint
CORE supports two authentication methods for MCP access.
## Methods
### 1. OAuth Flow (Recommended)
Follows the [MCP specification](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization) for standard OAuth authentication.
* Web-based authentication flow
* Tokens auto-refresh and can be revoked
* Best for production environments
### 2. API Key
Direct authentication using API keys from CORE dashboard.
* Generate from [CORE Dashboard](https://app.getcore.me) โ Settings โ API Keys
* Simple setup for development and testing
* Include in Authorization header: `Bearer your-api-key-here`
## Setup
See provider-specific guides for configuration:
* [Claude AI](/providers/claude)
* [Cursor](/providers/cursor)
* [VS Code](/providers/vscode)
* [Zed](/providers/zed)
## Dashboard
Monitor authentication at [app.getcore.me](https://app.getcore.me) โ Settings โ MCP
# Configuration
Source: https://docs.getcore.me/mcp/configuration
Configure CORE's MCP endpoint with query parameters
CORE's MCP endpoint supports flexible configuration through query parameters.
## Base URL
```
https://app.getcore.me/api/v1/mcp
```
## Parameters
### Required
**source** - Identifies your connection in the dashboard
```
?source=Claude
?source=Cursor
?source=VSCode
```
### Optional
**integrations** - Specify which integrations to include
```
&integrations=github,linear
&integrations=linear
```
**no\_integrations** - Disable all integrations (CORE tools only)
```
&no_integrations=true
```
## Examples
**All integrations:**
```
https://app.getcore.me/api/v1/mcp?source=Claude
```
**Specific integrations:**
```
https://app.getcore.me/api/v1/mcp?source=Cursor&integrations=github,linear
```
**CORE tools only:**
```
https://app.getcore.me/api/v1/mcp?source=VSCode&no_integrations=true
```
## Setup in AI Tools
See provider-specific setup guides:
* [Claude AI](/providers/claude)
* [Cursor](/providers/cursor)
* [VS Code](/providers/vscode)
* [Zed](/providers/zed)
## Dashboard
Monitor connections at [app.getcore.me](https://app.getcore.me) โ Settings โ MCP
# Statement Aspects
Source: https://docs.getcore.me/memory/aspects
The closed enum CORE uses to classify every fact in memory and route searches.
## What aspects are
Aspects are a closed enum that classifies every fact stored in CORE memory. The search router uses them to filter results: a query is mapped to one or more aspects, and only statements tagged with those aspects are returned. The full set is defined as `StatementAspects` in `packages/types/src/graph/graph.entity.ts`.
## The 12 aspects
| Aspect | Captures | Example statement | Used for |
| -------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- | ---------------------------------- |
| `Identity` | Who they are: role, location, affiliation (slow-changing) | "Manik works at Red Planet" | Role, company, background |
| `Knowledge` | What they know: expertise, skills, understanding | "Expert in TypeScript and React" | Skill level, technical depth |
| `Belief` | Why they think that way: values, opinions, reasoning | "Values simplicity over complexity in code" | Design and architectural reasoning |
| `Preference` | How they want things: likes, dislikes, style choices | "Prefers pnpm over npm" | Tooling, style, setup choices |
| `Habit` | What they do regularly: recurring behaviors, routines | "Reviews PRs every morning before standup" | Routines, recurring workflows |
| `Goal` | What they want to achieve: future targets, aims | "Launch MVP by Q2 2026" | Planning, prioritization |
| `Task` | One-time commitments: follow-ups, promises, action items | "Send the contract draft to Sarah by Friday" | Open action items, follow-ups |
| `Directive` | Rules and automation: always do X, notify when Y, remind me to Z | "Always run tests before creating a PR" | Enforced rules and triggers |
| `Decision` | Choices made, conclusions reached | "Chose Neo4j for graph storage because of traversal performance" | Past choices and their reasoning |
| `Event` | Specific occurrences with timestamps | "Started auth refactor on Jan 15, 2026" | Temporal queries |
| `Problem` | Blockers, issues, challenges | "Hit rate limits with GitHub API when syncing 50+ repos" | Debugging, constraint planning |
| `Relationship` | Connections between people | "Works with Sarah on CORE project" | Team and collaborator graph |
## Voice aspects vs graph aspects
The 12 aspects are split into two storage paths, defined by the `VOICE_ASPECTS` subset in `packages/types/src/graph/graph.entity.ts`.
Voice aspects (`Directive`, `Preference`, `Habit`, `Belief`, `Goal`, `Task`) represent the user's voice. They are stored as complete, non-decomposed statements in the Aspects Store. Queries scoped to these aspects return whole statements as written.
The other six (`Identity`, `Knowledge`, `Decision`, `Event`, `Problem`, `Relationship`) are graph aspects. They are decomposed into atomic subject, predicate, object triples in Neo4j. Queries scoped to these aspects return triples rather than full statements.
## How aspects route searches
The router's `extractAspects()` function classifies an incoming query and returns `aspects: string[]`, where each value is one of the 12 enum strings above. The `aspect_query` handler then scopes its graph traversal by those aspects plus any matched labels. Agents calling `memory_search` do not pass aspects directly: classification is performed internally by the router and handlers.
## Aspect combinations by task
| What the agent is doing | Aspects surfaced |
| ----------------------- | -------------------------------------- |
| Writing code | `Preference`, `Directive`, `Knowledge` |
| Code review | `Preference`, `Directive` |
| Architectural decision | `Decision`, `Belief`, `Problem` |
| Debugging | `Problem`, `Knowledge`, `Decision` |
| Planning features | `Goal`, `Decision`, `Directive` |
| Tracking follow-ups | `Task`, `Directive`, `Goal` |
| Explaining concepts | `Knowledge`, `Identity` |
# Entity Types
Source: https://docs.getcore.me/memory/entity_types
The 11 entity types CORE extracts, how they are deduplicated, and how they flow through search.
## What entities are
Entities are nodes in the memory graph. Statements link entities together to form facts like "Sarah works at Red Planet". When the same entity is mentioned across multiple episodes, CORE deduplicates it by name normalization plus vector similarity in the `ENTITY` namespace, so all references resolve to a single node.
## The 11 entity types
CORE defines 11 entity types in `EntityTypes` (`packages/types/src/graph/graph.entity.ts`). Only named, searchable entities are extracted, no generic vocabulary.
| Type | Captures | Examples |
| -------------- | ------------------ | -------------------------------------------- |
| `Person` | People | Sarah, John, Dr. Chen, Mike |
| `Organization` | Companies, teams | Google, Red Planet, Design Team |
| `Place` | Locations | Bangalore, San Francisco, Office HQ |
| `Event` | Occurrences | React Conference, Q2 Planning, Sprint Review |
| `Project` | Work initiatives | CORE, MVP, Website Redesign |
| `Task` | Tracked items | CORE-123, Issue #456, TODO-789 |
| `Technology` | Tools, frameworks | TypeScript, PostgreSQL, React, Neo4j |
| `Product` | Products, services | iPhone, Slack, ChatGPT, Figma |
| `Standard` | Methodologies | OAuth 2.0, REST API, Agile, SOLID |
| `Concept` | Abstract topics | Fat Loss, Code Review, Search Pipeline |
| `Predicate` | Relationships | "works at", "lives in", "manages" |
## Predicate is special
`Predicate` represents relationship edges, not standalone nodes. It is used when a statement asserts a connection between two other entities, such as `works_at`, `lives_in`, or `manages`. A `Predicate` does not appear as a node you would search for directly; it labels an edge in the graph.
## How entities are extracted and resolved
During ingestion CORE extracts entities from episode text and classifies each one into one of the 11 types. New mentions are deduplicated against existing entities by name normalization plus vector similarity in the `ENTITY` namespace (`packages/providers/src/vector/constants.ts`). When the same entity appears in multiple episodes, the new mention is linked to the existing node automatically, so the graph grows without producing duplicate nodes for "Sarah", "Sarah Chen", and "@sarah".
## How entities flow through search
When a search query mentions an entity by name, the router populates `entityHints`. Search handlers such as `entity_lookup`, `relationship`, `aspect_query`, and `temporal` embed each hint and search the `ENTITY` vector namespace to resolve the hint to one or more entity UUIDs. The handler then graph-fetches connected episodes and statements from those nodes, so a query for "Sarah" returns everything attached to the resolved `Person` entity, not just literal name matches.
## Integration-sourced entities
Entities from connected apps are classified into one of the 11 types above, not separate types. A GitHub repository becomes a `Project`. A GitHub issue or Linear issue becomes a `Task`. A Slack channel becomes a `Place` or `Organization` depending on context. A Gmail contact becomes a `Person`. Integrations are sources of episodes, the entity schema is the same regardless of source.
# How CORE Ingests Memory
Source: https://docs.getcore.me/memory/how-core-ingests
The ingestion pipeline that turns raw content into Episodes, Entities, Statements, and embeddings.
## Pipeline overview
Ingestion turns raw content into structured primitives: `Episode`, `Entity`, `Statement`. Statements are classified by aspect, then routed to one of two stores. Embeddings are written alongside for retrieval.
```mermaid theme={null}
flowchart LR
CONV["Conversation or event\nchat, integration event, upload"]
EP["โ Episode created\nraw content preserved verbatim\n+ timestamp, source, channel, labels"]
ENT["โก Entity extraction\n11 entity types\ndedupe via name normalization\n+ vector similarity in ENTITY namespace"]
STMT["โข Statement extraction\nfacts classified into 1 of 12 aspects"]
SPLIT{"โฃ Storage split\nby aspect type"}
AS[("Aspects Store\nvoice aspects:\nDirective, Preference, Habit,\nBelief, Goal, Task")]
NEO[("Neo4j\ngraph aspects as SPO triples:\nIdentity, Knowledge, Decision,\nEvent, Problem, Relationship")]
EMB["โค Embeddings\nENTITY, STATEMENT, EPISODE,\nLABEL, ASPECT namespaces"]
CONV --> EP --> ENT --> STMT --> SPLIT
SPLIT -->|voice| AS
SPLIT -->|graph| NEO
AS --> EMB
NEO --> EMB
```
Both stores link back to the source `Episode`, so any retrieved fact can be traced to the original content.
## Stage 1: Episode creation
Raw content becomes an `Episode`. The original text is preserved verbatim as the source of truth.
Metadata captured at this stage:
* `timestamp`: when the content occurred
* `source`: integration or entry point (Slack, GitHub, Gmail, Butler, MCP, upload)
* `channel`: sub-source identifier (channel name, repo, thread)
* `labels`: applied automatically based on context, or set by the agent at ingestion time
## Stage 2: Entity extraction
CORE extracts entities from the episode and assigns each one of 11 types (see [entity types](/memory/entity_types)): `Person`, `Organization`, `Place`, `Event`, `Project`, `Task`, `Technology`, `Product`, `Standard`, `Concept`, `Predicate`.
Deduplication runs in two passes:
1. Name normalization, so "Sarah", "sarah", "@sarah" collapse.
2. Vector similarity in the `ENTITY` namespace, so "Sarah Chen" and "Sarah" resolve when context confirms a match.
The resolved entity becomes the canonical node referenced by all later statements.
## Stage 3: Statement extraction
Facts are extracted from the episode as discrete statements. Each statement is classified into one of 12 aspects (see [aspects](/memory/aspects)): `Identity`, `Knowledge`, `Belief`, `Preference`, `Habit`, `Goal`, `Task`, `Directive`, `Decision`, `Event`, `Problem`, `Relationship`.
The aspect determines where the statement is stored in the next stage.
## Stage 4: Storage
CORE splits statements across two stores based on aspect:
**Voice aspects** go to the Aspects Store as complete, non-decomposed statements: `Directive`, `Preference`, `Habit`, `Belief`, `Goal`, `Task`. These represent what the user speaks (rules, preferences, beliefs, goals, habits, tasks) and are kept whole so the original phrasing survives.
**Graph aspects** go to Neo4j as subject-predicate-object (SPO) triples: `Identity`, `Knowledge`, `Decision`, `Event`, `Problem`, `Relationship`. Decomposition into triples enables structured graph traversal and relationship queries.
Both stores link every statement back to the source `Episode`, preserving provenance.
## Stage 5: Embeddings
During ingestion, embeddings are written to five vector namespaces:
* `ENTITY`: entity dedupe and resolution
* `STATEMENT`: statement dedupe and similarity search
* `EPISODE`: episode similarity, used as a fallback path in retrieval
* `LABEL`: label matching during search routing
* `ASPECT`: aspect dedupe in the Aspects Store
V2 search uses these for label routing, entity resolution, and similarity fallback when graph traversal does not return a direct hit.
## Conflict handling
### Entity resolution
When the same person or concept appears under different surface forms ("Sarah", "Sarah Chen", "@sarah", "[sarah@company.com](mailto:sarah@company.com)"), CORE resolves them to a single entity using name normalization plus vector similarity in the `ENTITY` namespace. Searching for "Sarah" surfaces everything connected to her, not just exact name matches.
### Contradiction handling
When a new statement contradicts an existing one, CORE does not overwrite. It creates a temporal chain: the old statement gets an `invalidAt` timestamp, and the new statement becomes current. Search returns the current state by default, with history accessible: "Currently prefers GraphQL (as of Feb 10), previously preferred REST."
## Worked example
Input episode:
```
Episode (Slack DM, 2026-02-10):
"Sarah and I decided to use Neo4j for the new graph service.
I prefer pnpm over npm because of better TypeScript support."
```
Extracted entities:
* `Sarah`: `Person`
* `Neo4j`: `Technology`
* `pnpm`: `Technology`
* `npm`: `Technology`
* `TypeScript`: `Technology`
Extracted statements:
* `Decision`: "Use Neo4j for the new graph service" โ graph aspect, stored in Neo4j as an SPO triple
* `Preference`: "Prefers pnpm over npm" โ voice aspect, stored in the Aspects Store
* `Belief`: "pnpm has better TypeScript support" โ voice aspect, stored in the Aspects Store
All three statements link back to the same source `Episode`, so retrieval can return the original Slack DM as evidence.
## Ingestion entry points
* **Automatic via integrations**: GitHub, Slack, Linear, Gmail, and other connected apps stream events into ingestion in real time or via scheduled syncs.
* **Butler conversations**: chats with the Butler are auto-ingested.
* **Manual dashboard upload**: drop documents or paste content directly.
* **Programmatic via MCP**: any connected AI agent can call the `memory_ingest` tool to push raw content.
## Related
* [How CORE Searches](/memory/how-core-searches)
* [Statement aspects](/memory/aspects)
* [Entity types](/memory/entity_types)
* [Labels](/memory/labels)
# How CORE Searches Memory
Source: https://docs.getcore.me/memory/how-core-searches
The V2 search pipeline: label routing, LLM aspect extraction, handler dispatch, merge and rerank.
## Pipeline overview
CORE V2 search routes a query through two stages before any episode retrieval: a vector lookup against topic labels, then a structured LLM call that extracts aspects, query type, temporal scope, and entity hints. A handler is dispatched per `queryType`. Results are merged, optionally reranked, and trimmed to a token budget.
```mermaid theme={null}
flowchart LR
QUERY["User query"]
subgraph router["Stage 1: Router"]
L["searchLabels()\nvector search on LABEL namespace"]
A["extractAspects()\nstructured LLM call\nreturns aspects, queryType,\ntemporal, entityHints, labels"]
L --> A
end
GATE{"shouldSearch &&\nconfidence >= 0.2"}
subgraph handlers["Stage 2: Handler dispatch by queryType"]
H1["aspect_query"]
H2["entity_lookup"]
H3["temporal"]
H4["temporal_facets"]
H5["exploratory"]
H6["relationship"]
end
POST["Stage 3:\nmerge + dedupe\nCohere rerank (optional)\napplyTokenBudget"]
RESULT["Episodes or facets"]
QUERY --> router --> GATE
GATE -->|yes| handlers --> POST --> RESULT
GATE -->|no| RESULT
```
## Stage 1: Intent routing
The router lives in `apps/webapp/app/services/search-v2/router.ts` and runs two sequential steps.
First, `searchLabels()` embeds the query and runs vector search against the `LABEL` namespace. The similarity threshold comes from `SEARCH_LABEL_VECTOR_THRESHOLD`. Matched labels are returned as `matchedLabels`.
Second, `extractAspects()` calls an LLM with the query and the matched labels as context. The LLM returns a structured object:
```json theme={null}
{
"aspects": ["string"],
"queryType": "aspect_query | entity_lookup | temporal | temporal_facets | exploratory | relationship",
"temporal": {
"type": "string",
"days": 0,
"startDate": "string | null",
"endDate": "string | null"
},
"shouldSearch": true,
"entityHints": ["string"],
"selectedLabels": ["string"],
"lookupMode": "attribute | broad",
"attributeHint": "string | null",
"facets": ["string"],
"confidence": 0.0
}
```
The full router result also includes `matchedLabels` (from the label vector search) and `routingTimeMs`.
`shouldProceedWithSearch()` short-circuits the pipeline when `shouldSearch === false` or `confidence < 0.2`. In that case no handler runs and an empty result is returned.
## Stage 2: Handler dispatch
Handlers live in `apps/webapp/app/services/search-v2/handlers.ts`. Dispatch is by `queryType`.
### `aspect_query`
Triggered when the query is about a topic, behavior, or category (for example "my views on remote work"). `handleAspectQuery` runs three calls in parallel:
* `getEpisodesForAspect`: graph query scoped by `labelIds`, `aspects`, and temporal range.
* `getEpisodesViaEntityHints`: resolves each entity hint via vector search on the `ENTITY` namespace, then fetches episodes from the graph.
* `getEpisodesViaVectorSearch`: vector search on episode embeddings, only when `labelIds.length === 0` (no label match to scope by).
Returns a deduped list of episodes.
### `entity_lookup`
Triggered when the query targets a specific entity (for example "what is my wife's name"). `handleEntityLookup` resolves each entry in `entityHints` via vector search on the `ENTITY` namespace. Then it branches on `lookupMode`:
* `attribute`: returns the entity with the requested attribute, using `attributeHint` to select the field.
* `broad`: returns episodes that mention the entity.
Returns either an entity record with a specific attribute or a list of episodes.
### `temporal`
Triggered when the query has an explicit time scope (for example "what did I do last week"). `handleTemporal` runs in parallel:
* `getEpisodesForTemporal`: graph query scoped by `labelIds` and the temporal range.
* Entity-hint path: vector on `ENTITY`, then graph fetch, with the time filter applied to results.
* Vector fallback: episode vector search, with the time filter applied.
Returns deduped episodes within the time range.
### `temporal_facets`
Triggered when the query asks for an aggregate over a time range (for example "what topics did I discuss this month"). `handleTemporalFacets` aggregates facets (topics, entities, aspects) over the range and returns counts. It does not return episodes.
### `exploratory`
Triggered for broad recall queries (for example "summarize recent work"). `handleExploratory` queries the `Document` table for compacted session rows scoped by `labelIds`. It also runs the entity-hint path and the vector fallback in parallel.
Returns compacted session documents plus any matching episodes.
### `relationship`
Triggered when the query connects two or more entities (for example "how do Alice and Bob know each other"). `handleRelationship` requires `entityHints.length >= 2`. Each hint is resolved via vector search on the `ENTITY` namespace, then graph traversal finds connecting statements.
Returns statements that link the entities.
## Stage 3: Merge, rerank, budget
After a handler returns:
1. Merge and dedupe episodes across the parallel sub-results.
2. If `options.enableReranking` is true, `applyCohereEpisodeReranking` reorders episodes using a Cohere rerank model.
3. `applyTokenBudget` trims the episode list to fit the configured token limit, preserving rerank order.
The final payload contains the trimmed episode list, any entity or facet results from the handler, and routing metadata.
## Worked examples
### Aspect query
Input: `"what is my view on code review"`.
Router output (compact):
```json theme={null}
{
"queryType": "aspect_query",
"aspects": ["preferences", "opinions"],
"selectedLabels": ["engineering", "code-review"],
"entityHints": [],
"shouldSearch": true,
"confidence": 0.82
}
```
Handler: `handleAspectQuery` runs `getEpisodesForAspect` scoped by the resolved `labelIds` and aspects. No entity hints, so the entity path is skipped. Because labels matched, the vector fallback is skipped.
Returns: deduped episodes about code review preferences.
### Entity lookup, attribute mode
Input: `"what is my wife's birthday"`.
Router output:
```json theme={null}
{
"queryType": "entity_lookup",
"entityHints": ["wife"],
"lookupMode": "attribute",
"attributeHint": "birthday",
"aspects": [],
"shouldSearch": true,
"confidence": 0.91
}
```
Handler: `handleEntityLookup` resolves `"wife"` via vector search on the `ENTITY` namespace, then returns the matched entity with the `birthday` attribute populated.
Returns: an entity record with the requested attribute.
### Temporal query
Input: `"what did I work on last week"`.
Router output:
```json theme={null}
{
"queryType": "temporal",
"temporal": { "type": "relative", "days": 7, "startDate": null, "endDate": null },
"selectedLabels": ["work"],
"entityHints": [],
"aspects": ["activities"],
"shouldSearch": true,
"confidence": 0.78
}
```
Handler: `handleTemporal` runs `getEpisodesForTemporal` scoped by `labelIds` and the seven day range, plus the vector fallback with the same time filter applied.
Returns: deduped episodes within the last seven days.
## V1 fallback
Workspace versioning is checked in `apps/webapp/app/services/agent/memory.ts`. When `workspace.version === "V3"`, only V2 runs. For any other version, V2 runs first and the legacy V1 path runs as a fallback when V2 returns empty. V1 uses BM25, vector search, and BFS graph traversal.
V2 itself does not use BM25. All V2 retrieval is graph plus vector.
## Related concepts
* [Query types](/memory/query_types)
* [Statement aspects](/memory/aspects)
* [Entity types](/memory/entity_types)
* [Labels](/memory/labels)
* [How CORE ingests](/memory/how-core-ingests)
# Labels
Source: https://docs.getcore.me/memory/labels
Workspace-scoped tags that act as the primary scoping mechanism for V2 search
## What labels are
Labels are workspace-scoped tags applied to episodes, sessions, and documents. They are flat (no hierarchies, no nesting) and unique per workspace. Each label has a name, an optional description, and a color.
## How labels scope search
Labels are the primary scoping mechanism in V2 search. The router (`apps/webapp/app/services/search-v2/router.ts`) embeds the query and runs vector search against the `LABEL` namespace defined in `packages/providers/src/vector/constants.ts`. The similarity threshold is controlled by `env.SEARCH_LABEL_VECTOR_THRESHOLD`.
The matched labels are passed to the LLM aspect-extraction step, which returns `selectedLabels: string[]`, the labels actually relevant to the query intent. The LLM is forbidden from inventing label names not in the matched list.
Handlers then call `getMatchedLabelIds()` to produce the final label set: LLM-selected labels take priority, with a fallback to score-threshold filtering when the LLM picks none. Graph traversal is then scoped by `labelIds`.
When the workspace has no labels, or no label vector clears the threshold, handlers fall back to `getEpisodesViaVectorSearch()` against the `EPISODE` namespace. Labels are the fast path, vector-on-episodes is the recall safety net.
## Creating labels
Labels are created from the CORE dashboard at Settings, Labels. Set a name, optional description, and color. They are available in the workspace immediately and can be applied to content during ingestion or after the fact.
## Filtering with labels at query time
The MCP `memory_search` tool accepts `labelIds` as an option. Passing `labelIds` force-scopes the search to those labels and bypasses router selection, useful when the caller already knows the relevant project, client, or topic.
## Examples
A multi-project workspace might use labels like:
```
- "Project: TaskMaster" (blue)
- "Project: CORE Features" (green)
- "Client: Acme Corp" (purple)
- "Topic: Authentication" (red)
- "Topic: Performance" (orange)
```
Keep names concise and consistent. Two to four labels per episode is typical.
## Related
* [How CORE searches](/memory/how-core-searches)
* [Query types](/memory/query_types)
# Memory overview
Source: https://docs.getcore.me/memory/overview
The memory primitives, storage layout, and how they connect.
## Primitives
* `Episode`: atomic unit of ingested content. One conversation, email, or sync becomes one episode. The original content is preserved as the source of truth.
* `Entity`: node in the graph. 11 types are defined (`Person`, `Organization`, `Place`, `Event`, `Project`, `Task`, `Technology`, `Product`, `Standard`, `Concept`, `Predicate`). See [entity types](/memory/entity_types).
* `Statement`: atomic fact extracted from an episode, classified by aspect. 12 aspects are defined (`Identity`, `Knowledge`, `Belief`, `Preference`, `Habit`, `Goal`, `Task`, `Directive`, `Decision`, `Event`, `Problem`, `Relationship`).
* `Aspect`: the classification tag on a statement. See [aspects](/memory/aspects).
* `Label`: workspace-scoped tag on episodes, sessions, and documents. Has an embedding in the `LABEL` vector namespace and is the primary scoping mechanism for V2 search. See [labels](/memory/labels).
## Storage layout
Statements split across two stores by aspect:
* Graph aspects (`Identity`, `Knowledge`, `Decision`, `Event`, `Problem`, `Relationship`) are decomposed into subject, predicate, object triples and stored in Neo4j. The `Predicate` entity type represents the edges, not the nodes.
* Voice aspects (`VOICE_ASPECTS`: `Directive`, `Preference`, `Habit`, `Belief`, `Goal`, `Task`) are stored as complete statements in the Aspects Store, since they carry meaning that does not decompose cleanly into triples.
Episodes are stored as documents, linked to the entities and statements they produced.
Embeddings live across six vector namespaces: `ENTITY`, `STATEMENT`, `EPISODE`, `COMPACTED_SESSION`, `LABEL`, `ASPECT`.
## How memory grows
Memory grows automatically through connected integrations (each sync produces episodes) and through conversations with the Butler (every exchange is ingested).
Manual additions come through three paths: uploading documents from the dashboard, calling the MCP `memory_ingest` tool, or sending content directly to the Butler ("Save my last 10 emails"). See [how CORE ingests](/memory/how-core-ingests).
## How memory is retrieved
The MCP `memory_search` tool runs the V2 pipeline. A router classifies the query into one of 6 query types: `aspect_query`, `entity_lookup` (with `attribute` or `broad` modes), `temporal`, `temporal_facets`, `exploratory`, `relationship`. The router uses vector search on the `LABEL` namespace plus an LLM aspect extraction step. Each query type dispatches to a dedicated handler, results are merged, optionally reranked with Cohere, and trimmed to a token budget.
V2 does not use BM25. Workspaces with `version !== "V3"` fall back to a legacy V1 pipeline that combines BM25, vector search, and BFS graph traversal when V2 returns empty. See [how CORE searches](/memory/how-core-searches) and [query types](/memory/query_types).
## How memory handles conflicts
Entities are deduped by name normalization plus vector similarity in the `ENTITY` namespace, so "Sarah", "Sarah Chen", and "sarah\_chen" collapse to one node when context supports it.
Contradicting facts form a temporal chain. When a new statement conflicts with an existing one, the old statement is marked as superseded with an end timestamp, and the new statement becomes current. History is preserved, not overwritten.
## Related
* [How CORE searches](/memory/how-core-searches)
* [How CORE ingests](/memory/how-core-ingests)
* [Aspects](/memory/aspects)
* [Entity types](/memory/entity_types)
* [Query types](/memory/query_types)
* [Labels](/memory/labels)
* [Reference](/memory/reference)
# Query Types
Source: https://docs.getcore.me/memory/query_types
The 6 query types the CORE search router classifies every query into, and what each handler returns.
## How classification works
The CORE search router (`apps/webapp/app/services/search-v2/router.ts`) classifies every incoming query into one of 6 query types and dispatches it to a dedicated handler. Classification uses vector search on the `LABEL` namespace to find matched labels, plus LLM aspect extraction to identify aspect intent. The router also returns `shouldSearch: boolean` to skip search entirely when appropriate. See `how-core-searches` for the full pipeline.
## The 6 query types
### aspect\_query
Trigger: the user wants facts of a specific aspect type (preferences, decisions, directives, goals, and similar).
Example queries:
* "What are my coding preferences?"
* "Show my decisions about auth"
* "What directives have I set for code review?"
Router fills `aspects: string[]` with the matched aspect enum values. Handler `handleAspectQuery` runs graph traversal scoped by matched labels and aspects, plus entity-hint resolution and vector fallback. Returns statements grouped by aspect.
### entity\_lookup
Trigger: the user wants information about a specific named entity. Router sets `lookupMode` to one of two values:
* `attribute`: the query asks for a specific field of the entity. Router sets `attributeHint` (for example `"phone"`, `"email"`, `"team"`). Examples: "What is John's phone number?", "Sarah's email?". Handler returns the entity node with that attribute.
* `broad`: the query asks generally about the entity. Examples: "Who is Sarah?", "Tell me about X", "anything about airbnb email". Handler returns episodes where the entity appears.
Example queries:
* "What is John's phone number?" (`attribute`, `attributeHint: "phone"`)
* "Who is Sarah?" (`broad`)
* "Anything about the airbnb email?" (`broad`)
In both modes, entity hints are resolved via vector search on the `ENTITY` namespace before traversal.
### temporal
Trigger: the query is bounded by time.
Example queries:
* "What happened last week?"
* "What did we decide yesterday?"
* "Show my work from January"
Router fills `temporal: { type: "recent" | "range" | "before" | "after" | "all", days, startDate, endDate }`. Handler `handleTemporal` runs label-plus-time graph traversal, the entity-hint path, and vector fallback in parallel. Returns episodes within the time bound.
### temporal\_facets
Trigger: the user wants aggregates over a time range, not specific episodes.
Example queries:
* "What topics did I speak about last week?"
* "Who are the people I spoke about this month?"
* "What decisions and goals came up last month?"
Router fills `facets: ("topics" | "entities" | "aspects")[]` along with the temporal bounds. Handler returns counts grouped by facet, not episodes.
### exploratory
Trigger: broad topic queries with no specific entity, aspect, or time anchor.
Example queries:
* "Search implementation in CORE"
* "Authentication architecture"
* "Catch me up on recent work"
Handler queries compacted session documents scoped by matched labels, plus the entity-hint path and vector fallback. Returns session summaries and related statements.
### relationship
Trigger: a connection between 2 or more entities. Requires at least 2 entity hints.
Example queries:
* "How do I know Sarah?"
* "How is the payment service related to Stripe?"
* "What is the connection between TypeScript and CORE?"
Handler resolves each entity hint via vector search on the `ENTITY` namespace, then performs graph traversal for statements connecting them. Returns the connecting statements.
## When no search runs
The router can decide `shouldSearch: false` for greetings or unrelated chat (for example "Hello!" or "What's the weather?"). When this happens, the search pipeline short-circuits and returns empty without dispatching to any handler.
## Related
* `how-core-searches`: the full search pipeline that wraps this router.
* `aspects`: the aspect enum values used by `aspect_query` and `temporal_facets`.
* `entity_types`: the entity kinds resolved during `entity_lookup` and `relationship`.
* `labels`: the `LABEL` namespace used during classification.
# Memory reference
Source: https://docs.getcore.me/memory/reference
Canonical identifiers, enums, tool names, and shapes for CORE memory.
## When to use this page
Quick lookup for exact identifiers. For conceptual explanations, see the linked pages.
## Statement aspects
CORE classifies every statement into one of 12 aspects. Six are stored as complete statements in the Aspects Store (`VOICE_ASPECTS`). The other six are decomposed into SPO triples and written to Neo4j.
| Aspect | Group | Storage |
| -------------- | ----- | ------------- |
| `Identity` | graph | Neo4j SPO |
| `Knowledge` | graph | Neo4j SPO |
| `Belief` | voice | Aspects Store |
| `Preference` | voice | Aspects Store |
| `Habit` | voice | Aspects Store |
| `Goal` | voice | Aspects Store |
| `Task` | voice | Aspects Store |
| `Directive` | voice | Aspects Store |
| `Decision` | graph | Neo4j SPO |
| `Event` | graph | Neo4j SPO |
| `Problem` | graph | Neo4j SPO |
| `Relationship` | graph | Neo4j SPO |
See [memory/aspects](/memory/aspects) for the full aspect model.
## Entity types
CORE recognizes 11 entity types when extracting statements.
| Type | Description | Example |
| -------------- | --------------------------------------- | -------------------------------- |
| `Person` | A human individual. | `Sarah Chen` |
| `Organization` | A company, team, group, or institution. | `CORE`, `Acme Inc.` |
| `Place` | A physical or virtual location. | `San Francisco`, `the warehouse` |
| `Event` | A bounded occurrence in time. | `Q3 launch`, `team offsite` |
| `Project` | A named initiative or workstream. | `Project Atlas` |
| `Task` | A unit of work or todo. | `Ship the docs rewrite` |
| `Technology` | A tool, framework, language, or system. | `Neo4j`, `Postgres` |
| `Product` | A shippable product or service. | `CORE Memory` |
| `Standard` | A protocol, spec, or norm. | `MCP`, `OAuth2` |
| `Concept` | An abstract idea, topic, or category. | `latency`, `retention` |
| `Predicate` | A relation type used in SPO triples. | `works_on`, `lives_in` |
See [memory/entity\_types](/memory/entity_types) for usage in extraction.
## Query types
The router classifies every incoming query into one of 6 query types. Each type has a dedicated handler in `apps/webapp/app/services/search-v2/handlers.ts`.
| Type | Handler | Returns |
| -------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------- |
| [`aspect_query`](/memory/query_types#aspect_query) | aspect handler | Statements from the Aspects Store filtered by aspect group. |
| [`entity_lookup`](/memory/query_types#entity_lookup) | entity lookup handler | Facts about a specific entity (broad) or a specific attribute (attribute mode). |
| [`temporal`](/memory/query_types#temporal) | temporal handler | Statements scoped to a time window. |
| [`temporal_facets`](/memory/query_types#temporal_facets) | temporal facets handler | Aggregated facets over a time window across topics, entities, or aspects. |
| [`exploratory`](/memory/query_types#exploratory) | exploratory handler | Broad hybrid search across statements, episodes, and the graph. |
| [`relationship`](/memory/query_types#relationship) | relationship handler | SPO triples and connections between entities. |
## Vector namespaces
CORE writes embeddings into 6 named namespaces. The TypeScript constant lives in `packages/providers/src/vector/constants.ts`.
| Namespace | String value | Used for |
| ------------------- | ------------------- | ----------------------------------------------- |
| `ENTITY` | `entity` | Entity name embeddings, dedupe, and resolution. |
| `STATEMENT` | `statement` | Statement fact embeddings. |
| `EPISODE` | `episode` | Episode content embeddings. |
| `COMPACTED_SESSION` | `compacted_session` | Compacted session summary embeddings. |
| `LABEL` | `label` | Label embeddings used for search routing. |
| `ASPECT` | `voice_aspect` | Voice aspect dedupe in the Aspects Store. |
## Router output shape
The router (`apps/webapp/app/services/search-v2/router.ts`) returns a `RouterOutput` object that downstream handlers consume.
```json theme={null}
{
"matchedLabels": [{ "labelId": "string", "labelName": "string", "score": 0.85 }],
"aspects": ["Preference", "Decision"],
"queryType": "aspect_query",
"temporal": { "type": "recent", "days": 7, "startDate": null, "endDate": null },
"shouldSearch": true,
"entityHints": ["Sarah", "CORE"],
"selectedLabels": ["Project: CORE"],
"lookupMode": "broad",
"attributeHint": null,
"facets": [],
"confidence": 0.85,
"routingTimeMs": 420
}
```
### Fields
| Field | Type | Meaning |
| ---------------- | ---------------------------------------- | ---------------------------------------------------------------------------- |
| `matchedLabels` | array of `{ labelId, labelName, score }` | Labels resolved from the query via vector search. `score` is the similarity. |
| `aspects` | array of aspect strings | Aspects the query targets. Subset of the 12 aspect identifiers. |
| `queryType` | one of the 6 query types | Selected handler. |
| `temporal` | object | Time filter. See `## Temporal filter`. |
| `shouldSearch` | boolean | If `false`, the router decided no search is needed. |
| `entityHints` | array of strings | Entity name hints extracted from the query. |
| `selectedLabels` | array of strings | Human-readable label names chosen for the search. |
| `lookupMode` | `"attribute"` or `"broad"` | Only set when `queryType` is `entity_lookup`. |
| `attributeHint` | string or `null` | Field name when `lookupMode` is `"attribute"`. |
| `facets` | array of facet dimension strings | Only set when `queryType` is `temporal_facets`. |
| `confidence` | number `0..1` | Router confidence in the classification. |
| `routingTimeMs` | number | Wall time spent in the router. |
## Temporal filter
The `temporal` object on the router output describes a time window.
| `type` value | Semantics |
| ------------ | ------------------------------------------ |
| `"recent"` | Use `days` as a rolling window ending now. |
| `"range"` | Use both `startDate` and `endDate`. |
| `"before"` | Use `endDate` as an upper bound. |
| `"after"` | Use `startDate` as a lower bound. |
| `"all"` | No time filter. |
Field semantics:
| Field | Used when | Format |
| ----------- | --------------------------------- | ---------------------- |
| `days` | `type` is `"recent"` | integer number of days |
| `startDate` | `type` is `"range"` or `"after"` | ISO 8601 date string |
| `endDate` | `type` is `"range"` or `"before"` | ISO 8601 date string |
## Lookup modes
Only applies when `queryType` is `entity_lookup`.
| `lookupMode` | Behavior | `attributeHint` |
| ------------- | --------------------------------------------- | ------------------------------------------------------ |
| `"broad"` | Return general facts about the entity. | `null` |
| `"attribute"` | Return only facts about a specific attribute. | Field name string, e.g. `"phone"`, `"email"`, `"team"` |
## Facet dimensions
Only applies when `queryType` is `temporal_facets`. The `facets` array contains one or more of:
| Dimension | Aggregates over |
| ------------ | ------------------------------------------ |
| `"topics"` | Topic labels in the time window. |
| `"entities"` | Entities mentioned in the time window. |
| `"aspects"` | Aspect classifications in the time window. |
## MCP memory tools
CORE exposes three memory tools over MCP, defined in `apps/webapp/app/utils/mcp/memory.ts`.
| Tool name | Purpose | Key parameters |
| ------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `memory_search` | Search the knowledge graph. | `query` (string), optional `labelIds` (array), optional `endUserIds` (array of counterparty identifiers), optional time range, optional `limit` |
| `memory_ingest` | Push content into memory. | content payload |
| `memory_about_user` | Return profile-like info about the user. | none |
## Workspace version and search path
CORE supports two search paths gated by `workspace.version` (see `apps/webapp/app/services/agent/memory.ts`).
| `workspace.version` | Search behavior |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `"V3"` | V2 search only. No V1 fallback. |
| Any other value | V2 first. If V2 returns empty, fall back to V1 (BM25 + vector + BFS hybrid in `apps/webapp/app/services/search.server.ts`). |
Related environment variables:
| Variable | Effect |
| ------------------------------- | -------------------------------------------- |
| `SEARCH_LABEL_VECTOR_THRESHOLD` | Candidate threshold for label vector search. |
## Related concepts
* [memory/overview](/memory/overview)
* [memory/how-core-searches](/memory/how-core-searches)
* [memory/how-core-ingests](/memory/how-core-ingests)
* [memory/aspects](/memory/aspects)
* [memory/entity\_types](/memory/entity_types)
* [memory/query\_types](/memory/query_types)
* [memory/labels](/memory/labels)
# Migrating from V1
Source: https://docs.getcore.me/migrating-from-v1
Step-by-step guide to migrate your CORE instance from V1 to V2
## What's New in V2
### Provider-Based Architecture
V2 introduces a flexible provider-based system for vector and graph storage, giving you the freedom to choose and switch between different backends:
* **Vector Providers**: pgvector (more coming soon)
* **Graph Providers**: Neo4j (more coming soon)
This architectural change makes CORE more adaptable to your infrastructure needs and allows us to support additional providers in the future.
### Massive Performance Improvements
By migrating embeddings to pgvector, we've achieved significant performance gains:
* **Query Response Time**: Reduced from \~26 seconds to \~1 second
* **26x faster** embedding retrieval for memory operations
* Improved overall system responsiveness
The pgvector integration leverages PostgreSQL's proven reliability while providing vector similarity search capabilities that are essential for AI memory operations.
***
## Migration Steps
> **Warning:**
> This migration process involves database operations that will temporarily take your CORE instance offline. Make sure to plan accordingly and inform your users if applicable.
### Prerequisites
* Docker installed and running
* Access to your CORE instance
* Sufficient disk space for database dump
***
### Step 1: Backup Your Database
First, create a complete backup of your existing database:
```bash theme={null}
docker exec core-postgres pg_dump -U docker -d core > database_dump.sql
```
This command will create a SQL dump file containing all your data. Store this file safely as it's your backup.
***
### Step 2: Remove Old PostgreSQL Volume
Stop the PostgreSQL container:
```bash theme={null}
docker stop core-postgres
```
Remove the old PostgreSQL volume:
```bash theme={null}
docker volume rm docker_postgres_data
```
> **Note:** If you're using a different volume name, you can list all volumes with `docker volume ls` to find the correct one.
***
### Step 3: Update Configuration Files
Pull the latest `docker-compose.yaml` from the repository or update your existing file to include the new PostgreSQL 18 with pgvector support.
Add the following environment variables to your `.env` file:
```bash theme={null}
GRAPH_PROVIDER=neo4j
VECTOR_PROVIDER=pgvector
```
These variables configure CORE to use Neo4j for graph storage and pgvector for vector embeddings.
***
### Step 4: Start PostgreSQL Container
Start the PostgreSQL container with the new configuration:
```bash theme={null}
docker-compose up -d postgres
```
Wait for PostgreSQL to fully initialize (check with `docker logs core-postgres`).
***
### Step 5: Restore Database
Drop the existing database (if it exists) and create a fresh one:
```bash theme={null}
# Drop the existing database
docker exec core-postgres dropdb -U docker --if-exists core
# Create a fresh database
docker exec core-postgres createdb -U docker core
```
Now restore your data from the backup:
```bash theme={null}
cat database_dump.sql | docker exec -i core-postgres psql -U docker -d core
```
***
### Step 6: Start CORE Application
Start all CORE services:
```bash theme={null}
docker-compose up -d
```
***
### Step 7: Automatic Embedding Migration
When CORE starts for the first time after the migration, it will automatically:
1. Detect embeddings stored in Neo4j
2. Migrate them to pgvector for each user
3. Update all references to use the new vector storage
This process happens automatically in the background. You can monitor the migration progress in the application logs:
```bash theme={null}
docker logs -f core-app
```
***
## Rollback
If you encounter issues, you can rollback by:
1. Stopping all containers: `docker-compose down`
2. Restoring the old volume or reverting configuration changes
3. Using your `database_dump.sql` backup to restore the previous state
***
## Troubleshooting
### Migration Takes Too Long
The embedding migration time depends on the amount of data stored. For large datasets, this process may take several minutes. Monitor the logs to ensure progress is being made.
### Connection Errors
If you encounter connection errors after migration:
* Verify PostgreSQL is running: `docker ps | grep postgres`
* Check PostgreSQL logs: `docker logs core-postgres`
* Ensure environment variables are correctly set in `.env`
***
## Support
If you encounter issues during migration:
* Check the [GitHub Issues](https://github.com/redplanethq/core/issues) for similar problems
* Join our community discussions
# Building Integrations
Source: https://docs.getcore.me/opensource/building-integrations
CORE is open-source and welcomes community contributions. You can build integrations for any service to extend CORE's capabilities.
## What You Can Build
**Project Management:**
* Jira, ClickUp, Trello, Asana (similar to our Linear integration)
* Task tools: create/update/search issues, manage projects
**Analytics & Insights:**
* GitLab Analytics, Bitbucket Analytics (similar to our GitHub Analytics)
* Metric tools: get stats, generate reports, track KPIs
**Communication:**
* Microsoft Teams, Discord DMs (similar to our Slack integration)
* Messaging tools: send messages, manage channels
**Any service with an API** - if it has OAuth/API key auth, you can integrate it.
## How Integrations Work
Every CORE integration provides **two essential capabilities:**
1. **Activity Sync** - Capture relevant events โ knowledge graph
* Schedule-based: Poll API every 5-15 mins (GitHub, Linear)
* Webhook-based: Real-time events (Slack, Discord)
2. **MCP Tools** - Enable AI agents to take actions
* Required for all integrations
* Examples: create\_issue, send\_message, search\_code
## Quick Start
### Step 1: Choose Integration Type
**Schedule-Based** (for APIs without webhooks):
```
Use when: Service has REST API, no webhooks
Examples: GitHub, Linear, Todoist
Structure: index.ts, account-create.ts, schedule.ts, mcp/
```
**Webhook-Based** (for real-time events):
```
Use when: Service provides webhook events
Examples: Slack, Discord, Linear webhooks
Structure: index.ts, account-create.ts, create-activity.ts, identify.ts, mcp/
```
### Step 2: Set Up Project Structure
```bash theme={null}
# Fork and clone CORE repository
git clone https://github.com/YOUR-USERNAME/core.git
cd core/integrations
# Create your integration directory
mkdir your-service
cd your-service
# Copy structure from similar integration
cp -r ../linear/* . # For schedule-based
# OR
cp -r ../slack/* . # For webhook-based
# Install dependencies
npm install
```
### Step 3: Implement OAuth (account-create.ts)
```typescript theme={null}
// src/account-create.ts
export async function integrationCreate(data: any) {
const { oauthResponse } = data;
// Get user info from service API
const user = await getUser(oauthResponse.access_token);
return [
{
type: "account",
data: {
accountId: user.id,
config: {
access_token: oauthResponse.access_token,
refresh_token: oauthResponse.refresh_token,
},
settings: {
username: user.username,
// Add service-specific settings
},
},
},
];
}
```
### Step 4: Implement Activity Sync
**For Schedule-Based (schedule.ts):**
```typescript theme={null}
export async function handleSchedule(config: any, state: any) {
const lastSync = state?.lastSyncTime || getDefault24HoursAgo();
const activities = [];
// Fetch new data since last sync
const items = await fetchItems(config.access_token, lastSync);
// Create activity messages
for (const item of items) {
activities.push({
type: "activity",
data: {
text: `${item.user} created issue #${item.number}: ${item.title}`,
sourceURL: item.url,
},
});
}
// Save state for next sync
activities.push({
type: "state",
data: { lastSyncTime: new Date().toISOString() },
});
return activities;
}
```
**For Webhook-Based (create-activity.ts + identify.ts):**
```typescript theme={null}
// identify.ts - Extract user ID for routing
export async function identify(integration: any, eventBody: any) {
return [
{
type: "identifier",
data: eventBody.event.user,
},
];
}
// create-activity.ts - Process webhook event
export async function createActivityEvent(eventData: any, config: any) {
const event = eventData.event;
const text = `${event.user} mentioned you: ${event.message}`;
const url = await getPermalink(config.access_token, event.id);
return [
{
type: "activity",
data: { text, sourceURL: url },
},
];
}
```
### Step 5: Implement MCP Tools (Required)
```typescript theme={null}
// src/mcp/index.ts
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
// Define tool schemas
const CreateIssueSchema = z.object({
title: z.string().describe("Issue title"),
description: z.string().optional().describe("Issue description"),
assignee: z.string().optional().describe("User to assign"),
});
const SearchIssuesSchema = z.object({
query: z.string().describe("Search query"),
status: z.string().optional().describe("Filter by status"),
});
// Export tools list
export async function getTools() {
return [
{
name: "create_issue",
description: "Create a new issue in the project",
inputSchema: zodToJsonSchema(CreateIssueSchema),
},
{
name: "search_issues",
description: "Search for issues",
inputSchema: zodToJsonSchema(SearchIssuesSchema),
},
];
}
// Implement tool execution
export async function callTool(name: string, args: any, apiKey: string) {
switch (name) {
case "create_issue":
const issue = await createIssue(apiKey, args);
return { content: [{ type: "text", text: `Created issue #${issue.id}` }] };
case "search_issues":
const results = await searchIssues(apiKey, args);
return { content: [{ type: "text", text: JSON.stringify(results) }] };
default:
throw new Error(`Unknown tool: ${name}`);
}
}
```
### Step 6: Wire Everything in index.ts
```typescript theme={null}
// src/index.ts
import {
IntegrationCLI,
IntegrationEventPayload,
IntegrationEventType,
Spec,
} from "@redplanethq/sdk";
import { integrationCreate } from "./account-create";
import { handleSchedule } from "./schedule"; // or createActivityEvent + identify
import { getTools, callTool } from "./mcp";
export async function run(eventPayload: IntegrationEventPayload) {
switch (eventPayload.event) {
case IntegrationEventType.SETUP:
return await integrationCreate(eventPayload.eventBody);
case IntegrationEventType.SYNC:
return await handleSchedule(eventPayload.config, eventPayload.state);
case IntegrationEventType.GET_TOOLS:
return await getTools();
case IntegrationEventType.CALL_TOOL:
const { name, arguments: args } = eventPayload.eventBody;
return await callTool(name, args, eventPayload.config.apiKey);
default:
return { message: `Unknown event: ${eventPayload.event}` };
}
}
class YourServiceCLI extends IntegrationCLI {
constructor() {
super("your-service", "1.0.0");
}
protected async handleEvent(eventPayload: IntegrationEventPayload) {
return await run(eventPayload);
}
protected async getSpec(): Promise {
return {
name: "Your Service",
key: "your-service",
description: "Integration description",
icon: "your-service",
schedule: { frequency: "*/5 * * * *" }, // For schedule-based
auth: {
OAuth2: {
token_url: "https://api.service.com/oauth/token",
authorization_url: "https://api.service.com/oauth/authorize",
scopes: ["read", "write"],
scope_separator: ",",
},
},
mcp: { type: "cli" },
};
}
}
function main() {
const cli = new YourServiceCLI();
cli.parse();
}
main();
```
## Testing Your Integration
1. **Build**: `npm run build`
2. **Test locally**: Follow [local setup guide](/guides/local-setup)
3. **Test OAuth flow**: Connect your account
4. **Test sync**: Verify activities appear in knowledge graph
5. **Test MCP tools**: Use AI agent to call your tools
## Submit Your Integration
```bash theme={null}
git checkout -b add-your-service-integration
git add integrations/your-service
git commit -m "Add Your Service integration"
git push origin add-your-service-integration
```
Open a PR with:
* Description of what the integration does
* List of MCP tools provided
* Screenshots of it working
## Reference Implementations
* **Schedule-based**: [GitHub](/integrations/github), [Linear](/integrations/linear)
* **Webhook-based**: [Slack](/integrations/slack), [Discord](/integrations/discord)
* **Analytics**: [GitHub Analytics](/integrations/github-analytics)
***
## Contributing
Other ways to contribute beyond integrations:
* **Report bugs**: [GitHub Issues](https://github.com/RedPlanetHQ/core/issues) with steps to reproduce
* **Improve docs**: fix anything unclear, add examples, correct errors
* **Code review**: comment on open PRs
* **Share CORE**: write about your setup, share in communities
Open a PR against [RedPlanetHQ/core](https://github.com/RedPlanetHQ/core). Join [Discord](https://discord.gg/dVTC3BmgEq) for questions.
# Changelog
Source: https://docs.getcore.me/opensource/changelog
Product updates and announcements
## New Features
**Run CORE in your environment (Gateway)**
* You can now run tools through a self-hosted Gateway, so CORE can take actions inside your network and with your local setup.
* This also unlocks longer-running workflows that can continue in the background instead of timing out mid-run.
**Email + WhatsApp are now first-class channels**
* COREโs email and WhatsApp handling is now built on a unified โchannelโ system, so message delivery, history, and follow-ups behave more consistently across surfaces.
* This is the foundation for doing the same across more channels going forward.
**Talk to CORE in Slack (DMs, channels, and threads)**
* You can now use CORE from Slack via DMs and channel mentions.
* Threads are tracked as separate conversations, which keeps context clean when multiple topics are happening in the same channel.
**Separate work and personal (Multiple workspaces)**
* You can now create multiple workspaces under one account to keep different contexts (work, personal, clients) cleanly separated.
**New integrations: Jira/Confluence, Ghost, LinkedIn, and Codeberg**
* **Atlassian (Jira + Confluence):** Connect via OAuth and let CORE pull in tickets, docs, and knowledge without manual copy/paste.
* **Ghost:** Manage posts/pages/tags via the Ghost Admin API so publishing workflows can be automated.
* **LinkedIn:** Fetch profile and activity context for networking and outreach workflows.
* **Codeberg:** A Git-hosting integration with growing parity to GitHub (issues, PRs, labels, and repo content).
**Skills: reusable workflows, not one-off prompts**
* CORE can now run โskillsโ โ structured, reusable workflows โ so common tasks (research, outreach, triage, recurring ops) become repeatable playbooks.
## Performance & Reliability
* **Slack webhooks:** Slack DM bot verification now runs asynchronously, avoiding Slackโs 3-second timeout failures.
* **Reminders:** Reminder execution was refactored onto a centralized pipeline for more consistent scheduling and delivery.
## Improvements
* **GitHub + Codeberg automation:** Better automation parity (including richer issue creation flows and more repo operations) so agents can complete tasks without manual cleanup.
* **Search V2 (multi-workspace):** Workspace resolution was hardened so search returns results reliably in multi-workspace setups.
* **Timezone correctness:** Agent datetime context now respects the userโs timezone, reducing โwrong day / wrong timeโ outcomes.
* **Setup clarity:** Added concrete ingestion rule examples across integrations so initial configuration is less guessy.
## Fixes
* **Channels:** Fixed cases where creating a conversation failed for external channels (including email edge cases).
* **Slack:** Fixed broken inbound Slack processing.
* **OAuth:** Fixed PKCE handling for OAuth flows.
* **Gateway:** Fixed browser handoff failures during gateway-driven browser flows.
* **Search V2:** Fixed exploratory search returning nothing when label routing didnโt find a match.
## Security & Privacy
* **Skills:** Prevented skill documents from being exposed via the document APIs.
## ๐ฏ New Features
**Claude Code Plugin**
* Native CORE integration for Claude Code via MCP
* Access your memory and take actions directly from your terminal
* Seamlessly connect CORE's knowledge graph to your coding workflow
**Memory Search Agent**
* Advanced v2 search powered by an intelligent agent orchestrator
* Faster, more precise retrieval from your knowledge graph
* Better understanding of complex queries with multi-step reasoning
**New Integrations**
* **Todoist**: Task management actions from any AI agent
* **Google Tasks**: Manage to-dos across Google Workspace
* Auto-create Google integrations on signup for faster setup
**CORE SDK**
* Build custom integrations and tools on top of CORE
* Programmatic access to memory, search, and actions
* Extend CORE's capabilities for your specific workflows
**Aspect-Based Persona Generation**
* Smarter user profiles that understand context across 11 aspects
* More accurate representation of your work patterns and preferences
* Better AI responses tailored to how you actually work
## โก Performance & Reliability
* **Faster Search**: Agent orchestrator architecture for 2-3x speed improvement
* **Optimized Knowledge Graph**: Enhanced entity resolution and relationship mapping
* **Better Session Compaction**: Improved prompt compression for efficient memory storage
* **Vector Similarity Ordering**: More relevant results from semantic queries
## ๐ง Improvements
* **Simpler Onboarding**: Streamlined setup flow with fewer steps
* **Multiple Tool Approval**: Handle batch tool requests in a single approval flow
* **Better Slack Handling**: Support for multiple account events and message arrays
* **Enhanced Authentication**: Clearer completion messages and status updates
* **Webhook Raw Events**: Access to raw event data for custom processing
## ๐ Fixes
* Resolved 502 errors from synchronous integration tool execution
* Fixed persona document ingestion log handling
* Corrected onboarding agent ID passing
* Fixed search v2 error handling
* Resolved document editing assertion issues
* Fixed Gmail thread userId parameter
* Corrected session compaction sessionId handling
* Fixed documentId vs sessionId confusion
* Improved Google OAuth scope handling
## ๐ฏ New Features
**Labels System (Migration from Neo4j to Postgres)**
* Labels now stored in Postgres for faster access and updates
* Document table as single source of truth for better consistency
* Improved label assignment and management across workspace
**GitHub Analytics Integration**
* Track DORA metrics (deployment frequency, lead time, change failure rate, MTTR)
* Engineering insights and productivity analytics
* Date range comparisons and period-over-period analysis
**Linear & Slack MCP Integrations**
* Native Linear issue management via MCP
* Slack messaging and channel actions through MCP
* Unified access across all your AI agents
**Episode-Level Vector Search**
* Improved handling of broad, exploratory queries
* Search entire conversation episodes for better context
* Enhanced recall quality for complex information needs
**One-Click Railway Deployment**
* Self-host CORE with a single click
* Official Railway deployment support
* Production-ready configuration out of the box
## โก Performance & Reliability
* **Persona Generation Migration**: Moved to Postgres for faster profile updates
* **Knowledge Graph Improvements**: More relationship-focused structure
* **Vector Storage Enhancements**: Added ingestionQueueId, labelIds, sessionId tracking
* **Dual-Queue System**: Trigger.dev + BullMQ for reliable integration execution
## ๐ง Improvements
* **Alfred Persona**: Enhanced agent system prompt for more natural conversations
* **Session & Episode Deletion**: Full control over conversation history
* **Simplified Logs**: Cleaner, more readable activity tracking
* **Proactive AI**: Chat prompts emphasize cross-tool intelligence and temporal awareness
* **Mobile UI**: Improved Gmail integration page responsiveness
## ๐ Fixes
* Fixed ingestion queue deletion cascades
* Resolved document update latency issues
* Corrected Zoho integration authentication
* Fixed PostHog proxy connection errors
* Resolved Python 3.9 datetime parsing compatibility
* Fixed new conversation integration failures
* Corrected GitHub analytics date filtering
## ๐ Security & Privacy
* **Better Data Isolation**: Improved workspace and label scoping
* **Enhanced OAuth Flows**: More secure Google integration setup
* **MCP Session Handling**: Proper namespace isolation and sessionId management
## ๐ฏ New Features
**Google Workspace Integrations**
* **Gmail**: Read, search, and send emails from any AI agent
* **Google Sheets**: Update spreadsheets and analyze data
* **Google Docs**: Access and edit documents programmatically
**User Persona v0**
* AI-generated user profiles based on your memory and conversations
* Automatically surfaces your preferences, patterns, and work style
* Helps AI agents provide more personalized and contextual responses
**17+ New AI Provider Integrations**
* Codex, Gemini CLI, Windsurf, ChatGPT, and 13 more providers
* Connect CORE memory to your preferred AI tools
* Unified onboarding flow for faster provider setup
**Additional Integrations**
* **Zoho Mail**: Email management for Zoho users
* **Notion**: Access workspace pages and databases
* **Cal.com**: Calendar scheduling and meeting management
**Session Compaction**
* Automatically compress conversations after 3 exchanges
* Preserve important context while reducing memory footprint
* Smarter long-term recall without losing key information
**Reranking Model**
* Advanced reranking for more precise episode retrieval
* Better result ordering based on semantic relevance
* Improved search quality across all query types
## โก Performance & Reliability
* **Optimized Ingestion**: Faster document processing and knowledge graph updates
* **Entity Deduplication**: Exact name matching before LLM resolution (2-3x faster)
* **Vector Search Optimization**: Improved candidate retrieval across all graph models
* **Episode Retrieval**: Exclude embeddings from queries for faster results
* **GDS Cosine Similarity**: Replaced vector index queries for better performance
## ๐ง Improvements
* **Mobile-Friendly Product**: Fully responsive interface for mobile devices
* **Enhanced Onboarding**: Added skip button and improved flow persistence
* **Recency Sorting**: Time-based filtering and entity-based search
* **MCP Specification Compliance**: More complete and standards-compliant MCP server
* **GitHub Community Manager Skill**: Pre-built skill for community management workflows
## ๐ Fixes
* Fixed persona generation threshold checking
* Resolved integration tool failures
* Corrected episode and document deletion handling
* Fixed recall deduplication issues
* Resolved embedding size validation
* Fixed document title regeneration
* Corrected label assignment in persona generation
* Fixed session compaction timing
* Resolved OAuth2 form responsiveness
* Fixed domain cookie handling for the non-HTTPS
* Corrected MCP session\_id failures
## ๐ฏ New Features
**Deep Search**
* Advanced search capability for Browser Extension and Obsidian
* Surface insights from your memory with greater precision and context
* Connect related information across different sources more effectively
**Account Management 2.0**
* Once-click full account deletion with complete data cleanup
* Automatic removal of all data from both **PostgreSQL** and **Neo4j** graph databases
* Peace of mind with complete data control and privacy management
**Enhanced Onboarding**
* New guided flow for faster setup and first memory ingestion
* Direct integration setup via **MCP configuration links**
**Session Compaction for Smarter Memory**
* Automatically summarizes long conversations for efficient memory storage
* Compacted sessions now appear in search with Markdown formatting
* Improves long-term recall without losing important context
**AWS Bedrock Support**
* Connect your own AWS Bedrock account for AI model access
* Choose from Claude, Titan, and other AWS models
* Greater flexibility in model selection and deployment options
## โก Performance & Reliability
**Faster, more stable experience**
* **Improved Search Quality**: Structured, faster, and more relevant results
* **Optimized Graph Performance**: Reduced iterations for quicker retrieval
* **Better Memory Recall**: Session compaction models improve long-term context retention
* **Streamlined Credit Management**: Proper error handling when credits are exhausted
## ๐ง Improvements
* **Labels** (Migration from Spaces):
* Complete migration from Spaces to Labels organizational model
* Workspace-scoped labels with Linear-style tagging
* Labels stored in PostgreSQL, scoped by workspace
* Episodes now use `labelIds` array instead of `spaceIds`
* Multiple labels can be assigned to any episode
* Simplified label management via web interface and API
* **MCP Tooling**:
* Clear error messages when credits run low
* Improved tool descriptions for better AI assistant understanding
* Resolved profile summary edge cases affecting MCP connections
## ๐ Fixes
* Fixed API key deletion not working properly
* Resolved document view breaking in log viewer
* Fixed semantic search inconsistencies affecting result quality
* Resolved login attribute conflicts in authentication flow
* Fixed graph visualization issues in Chrome 140
* Corrected ingestion queue handling for deleted episodes
* Fixed MCP tool call failures for (`get_user_profile`)
* Resolved label description validation blocking label creation
## ๐ Security & Privacy
**Data protection updates**
* **Complete Account Wipe**: Account deletion now removes all traces from both relational and graph databases
* **Cascade Delete Logic**: Simplified deletion flows with proper relationship cleanup for users and workspaces
* **Neo4j Graph Cleanup**: Automated cleanup of knowledge graph nodes when deleting accounts
* **Proper Resource Cleanup**: Removes all associated API keys, labels, and episodes
## ๐ฏ New Features
**Documents in Knowledge Graph**
* Full document context now stored in the knowledge graph
* Better relationship mapping between documents and conversations
* Enhanced cross-document search and recall
**Space Summaries by Topics**
* Automatically generated topic summaries for your workspaces
* Quick overview of key themes and concepts in each space
* Easier navigation through large knowledge bases
**User Profile Memory Tool**
* MCP tool for accessing user profile information
* AI agents can understand user profile information
* More personalized responses across all connected tools
**Enhanced Onboarding**
* Save and persist onboarding answers
* Improved loading states and user feedback
* Faster time-to-first-memory
## โก Performance & Reliability
* **Optimized Entity Extraction**: Enhanced prompts for better entity recognition
* **Chunking Improvements**: Reduced chunk size to 1-3k tokens for better precision
* **Simplified Entity Resolution**: Type-free handling for faster processing
* **Increased Reranking Threshold**: Better filtering of low-quality results
## ๐ง Improvements
* **Activity UI Refresh**: Cleaner activity tracking interface
* **Document Logs Enhancement**: New API for episode deletion
## ๐ Fixes
* Fixed graph visualization issues in Chrome 140
* Resolved deleted episode ingestion queue handling
* Corrected MCP tool descriptions
* Fixed invalidated statement search queries
* Various onboarding and UI fixes
## ๐ฏ New Features
**Capabilities users can now access**
**Organization** (Note: This feature evolved into Labels in later releases)
* Organize your memory into project-specific contexts (Health, Personal, Work, Client Projects)
* Share memory contexts with team members for collaborative AI assistance
* Default user profile context with seamless node linking across projects
**Enhanced Logging & Monitoring**
* New logs UI for tracking memory ingestion and retrieval
* Real-time visibility into MCP connections and integration status
* Debug memory operations and optimize your workflow efficiency
**Simplified Docker Deployment**
* One-command self-hosting setup with improved configuration
* Better network isolation and service management
## โก Performance & Reliability
**Faster, more stable experience**
* **Improved Recall Efficiency**: Significantly better fact retrieval and relevance scoring
* **Enhanced MCP Server Stability**: Resolved mid-flight stream failures and connection drops
* **Better Connection Management**: 60-second ping intervals to maintain persistent connections
* **Streamlined Integration Processing**: Faster webhook event handling and memory updates
## ๐ง Improvements
**Enhanced existing functionality**
* **Enhanced MCP OAuth Scopes**: Better integration support for Windsurf and other coding tools
* **Refined Facts Page UI**: Improved label-specific fact browsing and search
* **Optimized Memory Tools**: Better source tracking and metadata preservation
* **Unified MCP Server**: Single server instance handling all integrations for improved performance
## ๐ Fixes
**Resolved issues affecting user experience**
* Fixed MCP server stream failures that interrupted AI client connections
* Resolved OAuth scope issues affecting Windsurf integration
* Corrected source attribution problems in memory tools
* Fixed facts page access issues for label-specific content
* Resolved database dependency conflicts in trigger service deployment
## ๐ Security & Privacy
**Data protection updates**
* **Enhanced OAuth Security**: Improved token management and scope validation
* **Better Integration Isolation**: Cleaner separation between different app connections
* **Secure Memory Attribution**: Proper source tracking without exposing sensitive metadata
## ๐ฏ New Features
**Capabilities users can now access**
**Browser Extension**
* Seamlessly capture and organize web content directly into your CORE memory
* Right-click context menus for instant memory ingestion
* Never lose important research or documentation again
**OAuth Integration Hub**
* One-click authentication for Linear, Slack, GitHub, and Notion
* Connect your tools once, access them everywhere across AI clients
* Eliminate repetitive app authentication across different AI platforms
**MCP Integration Hub**
* Transform CORE into your universal MCP gateway
* Connect apps once to CORE, then share access with Claude, Cursor, and other AI clients
* Multiplier effect: N apps ร M clients through single authentication point
**Activity-to-Memory Ingestion**
* Automatic capture of assigned Linear issues, Slack mentions, and GitHub activity
* Set custom rules for what gets remembered from your connected apps
* Your AI tools now have context about your actual work, automatically
**Enhanced Knowledge Graph Architecture**
* Temporal knowledge graph with reified statements as first-class objects
* Every piece of information includes provenance and meta-knowledge
* Living memory that evolves with your projects and preferences
## โก Performance & Reliability
**Faster, more stable experience**
* **Improved Memory Ingestion Speed**: Faster processing of large documents and web pages
* **Enhanced Graph Relationships**: More efficient storage and retrieval of connected information
* **Streamlined Episode Management**: Better handling of conversation context and memory episodes
## ๐ง Improvements
**Enhanced existing functionality**
* **Refreshed UI Components**: Cleaner, more intuitive interface design
* **Enhanced Loading Transitions**: Smoother user experience during memory operations
* **Improved Integration Flows**: More reliable authentication and connection setup
* **Better Docker Support**: Simplified containerization for self-hosted deployments
## ๐ Fixes
**Resolved issues affecting user experience**
* Fixed fresh installation failures affecting new user onboarding
* Resolved Docker build workflow issues for self-hosted deployments
* Corrected activity flow and invalidation logic in knowledge graph
* Fixed UI component rendering issues across different browsers
# Amp
Source: https://docs.getcore.me/providers/amp
Connect your Amp code editor to CORE's memory system via MCP
### Prerequisites
* Amp code editor installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Install CORE MCP Server
Run this command in your terminal to connect CORE with Amp:
```bash theme={null}
amp mcp add core-memory https://app.getcore.me/api/v1/mcp?source=amp
```
What this does: This command registers CORE's MCP server with Amp, establishing the connection endpoint for memory operations.
### Step 2: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Amp: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears in your MCP servers list
3. **Test operations**: Ask Amp to store and retrieve information across sessions
## Troubleshooting
**Connection Issues:**
* Ensure you're logged into your CORE account
* Check that the MCP server URL is correctly formatted
* Restart Amp if authentication seems stuck
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Augment Code
Source: https://docs.getcore.me/providers/augment-code
Connect Augment Code to CORE's memory system via MCP
### Prerequisites
* Augment Code installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
1. Open your Augment Code settings file at `~/.augment/settings.json`
2. Add the following configuration:
```json theme={null}
{
"mcpServers": {
"core-memory": {
"type": "http",
"url": "https://app.getcore.me/api/v1/mcp?source=augment-code",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "augment-code"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 3: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Augment Code: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears in your MCP servers list
3. **Test operations**: Ask Augment Code to store and retrieve information across sessions
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the settings.json file is properly formatted
* Restart Augment Code after configuration changes
* Check that you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Browser Extension
Source: https://docs.getcore.me/providers/browser-extension
Connect CORE browser extension to capture web context and share memory across tools
### Prerequisites
* Chrome or Edge browser
* CORE account - [Sign up at app.getcore.me](https://app.getcore.me)
### Step 1: Install CORE Browser Extension
1. Download the extension from the [Chrome Web Store](https://chromewebstore.google.com/detail/core-extension/cglndoindnhdbfcbijikibfjoholdjcc)
2. Click **Add to Browser** and confirm installation
3. The CORE icon will appear in your browser toolbar
### Step 2: Generate API Key
1. Login to CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** (bottom left)
3. Go to **API Key** โ **Generate new key** โ Name it "extension"
4. Copy the generated API key
### Step 3: Connect Extension to CORE
1. Click the CORE extension icon in your browser toolbar
2. Paste your API key and click **Save**
3. Once connected, you'll see **API key configured**
## Extension Features
The CORE extension currently works with **ChatGPT** and **Gemini** (more integrations coming soon). The CORE logo appears directly inside your chat interface, giving you instant access to memory features:
1. **Auto Sync**
Toggle this on and CORE automatically saves your conversations to memory. Every brainstorming session, solution, or insight gets captured for future recall across all your tools.
2. **Add Label Context**
Inject pre-built project summaries directly into your prompt. Organize memories with labels in CORE for different projects or topics (e.g., "CORE Features," "Marketing Strategy"), then instantly add that full context to any conversation without retyping.
3. **Improve Prompt**
Powered by CORE's Deep Search, this analyzes your prompt, searches your entire memory, and automatically enriches it with relevant contextโmaking AI responses smarter and more personalized.
## Use-cases
With CORE connected to your browser, you can:
* **Brainstorm in ChatGPT**, then build in Cursor or Claude Code with full context
* **Stop re-explaining** your business, project details, or technical requirementsโlet CORE recall it
* **Build on past conversations** as every synced chat becomes searchable knowledge that surfaces automatically when relevant
## Troubleshooting
**Extension not appearing in chat interface:**
* Refresh your ChatGPT or Gemini page after installation
* Ensure the extension is enabled in your browser's extension settings
**API key not working:**
* Verify the key is correctly copied from CORE dashboard
* Check that your CORE account is active
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Claude
Source: https://docs.getcore.me/providers/claude
Connect your Claude Desktop app to CORE's memory system
### Prerequisites
* Claude Desktop app installed on your device
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Add CORE Connector
1. Open Claude Desktop app
2. Navigate to **Settings** โ **Connectors** โ Click **Add custom connector**
3. Now that the CORE connector appears in your list, click Connect to activate it
4. Enter the CORE MCP URL:
```
https://app.getcore.me/api/v1/mcp?source=Claude
```
### Step 2: Authenticate with CORE
1. Sign in to your CORE account (if not done already)
2. Click **Connect** on the CORE connector
3. When the authentication window opens, Grant Claude permission to access your CORE memory
4. Close the authentication window after a few seconds
### Step 3: Verify Connection
1. Go to **Tools** in Claude settings
2. Confirm the CORE connector shows as **Active**
3. **Restart the Claude Desktop app** for changes to take effect
### Enable Automatic Memory Integration (Recommended)
To make Claude automatically use your CORE memory in conversations:
1. Go to **Settings** โ **Profile** in Claude
2. Under **"What personal preferences should Claude consider in responses?"**, add:
````text theme={null}
โ ๏ธ **CRITICAL: READ THIS FIRST - MANDATORY MEMORY PROTOCOL** โ ๏ธ
You are an AI assistant with access to CORE - a persistent knowledge system that maintains conversation context, learnings, and continuity across all conversations.
## ๐ด MANDATORY STARTUP SEQUENCE - DO NOT SKIP ๐ด
**BEFORE RESPONDING TO ANY USER MESSAGE, YOU MUST EXECUTE THIS TOOL:**
### STEP 1 (REQUIRED): Search for Relevant Context
EXECUTE THIS TOOL FIRST:
mcp__CORE__memory_search
**Search for:**
- Previous discussions about the current topic
- User preferences and communication patterns
- Similar topics discussed before
- Past decisions and reasoning
**Additional search triggers:**
- User mentions "previously", "before", "last time", or "we discussed"
- User references past conversations or topics
- User asks about preferences, patterns, or past decisions
- Starting discussion on any topic that might have history
**How to search effectively:**
- Write complete semantic queries, NOT keyword fragments
- โ
GOOD: `"user's preferences for communication style and memory operations"`
- โ BAD: `"user communication"`
- Ask yourself: "What context am I missing that would help?"
- Consider: "What has the user told me before that I should remember?"
### Query Patterns for Memory Search
**Entity-Centric Queries** (Best for graph search):
- โ
GOOD: `"user's preferences for conversation style and topics of interest"`
- โ
GOOD: `"user's previous discussions about memory systems"`
- โ BAD: `"user style"`
- Format: `[Person] + [relationship/attribute] + [context]`
**Semantic Question Queries** (Good for vector search):
- โ
GOOD: `"What topics has the user been interested in? What are their preferences?"`
- โ
GOOD: `"How does the user prefer to receive information and explanations?"`
- โ BAD: `"user topics"`
- Format: Complete natural questions with full context
**Temporal Queries** (Good for recent work):
- โ
GOOD: `"recent discussions about memory systems and preferences"`
- โ
GOOD: `"latest conversations about personal interests"`
- โ BAD: `"recent talks"`
- Format: `[temporal marker] + [specific topic] + [additional context]`
### Verify App Connectivity (If Action Required)
Tool: `get_integrations`
Condition: If the user request involves taking action in external apps (e.g., Gmail, Notion, GitHub, Slack, etc.):
Perform the memory search (Step 1) first to see for past discussion
Immediately call get_integrations to verify the current connection status.
## ๐ด MANDATORY SHUTDOWN SEQUENCE - DO NOT SKIP ๐ด
**AFTER FULLY RESPONDING TO THE USER, YOU MUST INGEST THEN CONVERSATION:**
### FINAL STEP (REQUIRED): Store Conversation Memory
EXECUTE THESE TOOLS IN ORDER:
**1. Initialize session (if not already done):**
mcp__CORE__initialize_conversation_session
new: true
**2. Store the conversation:**
mcp__CORE__memory_ingest
sessionId: [UUID from step 1]
message: [comprehensive summary - see below]
โ ๏ธ **THIS IS NON-NEGOTIABLE** - You must ALWAYS store conversation context as your final action.
#### Memory Formatting & Timeline Requirements:
You must format the message parameter as a continuous, incremental timeline:
1. Check Sequence: Look at the last memory ingested in the current session. Only store the new, incremental information from the current turn.
2. Add the memory in the following format โ **both user and assistant in a single ingestion**:
```
{Exact text what user has said}
{Strategic summary of assistant's response}
```
**Assistant Summary Guidelines:**
- Summarize only relevant info.
- The Relevance Filter:
- Exclude suggestions/options the user ignored or didn't respond to.
- Emphasize what the user clarified, liked, or accepted.
- Include reasoning and final decisions so no context is lost.
**Exclude from storage:**
- Repetitive information already stored
- Trivial small talk without substance
**Quality check before storing:**
- Can someone quickly understand conversation context from memory alone?
- Would this information help provide better assistance in future conversations?
- Does stored context capture key insights and user preferences?
- Are we learning anything more about the user? Their Identity, Problems, Relationships, Directives, Preferences, Goals, Event, Action, Decisions, Beliefs, Expertise
---
## ๐ข PROTOCOL SUMMARY
1. **START**: mcp__CORE__memory_search (Always).
2. **VERIFY**: get_integrations (If app action is requested).
3. RESPOND: Address the user.
4. **END**: mcp__CORE__memory_ingest using the Incremental Timeline.
**If you skip any of these steps, you are not following the requirements.**
````
## What's Next?
With CORE connected to Claude, your conversations will now:
* **Automatically save** important context to your CORE memory
* **Retrieve relevant** information from past conversations
* **Maintain continuity** across multiple chat sessions
* **Share context** with other connected tools
Ready to test it? Ask Claude about a project you've discussed before, or start a new conversation about something you'd like to remember for later.
## Troubleshooting
**Connection Issues:**
* Ensure you're using the correct MCP URL with `?source=Claude` parameter
* Try restarting Claude Desktop after setup
* Check that your CORE account is active
**Memory Not Working:**
* Verify the CORE connector shows as "Active" in Tools
* Confirm you've added the preference text exactly as shown
* Wait a few seconds between authentication and testing
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Claude Code CLI
Source: https://docs.getcore.me/providers/claude-code
Connect your Claude Code CLI to CORE's memory system
CORE transforms Claude Code into a persistent memory agent that remembers your preferences, past decisions, and project context across all sessions.
## Prerequisites
* [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed
* CORE account - [Sign up at app.getcore.me](https://app.getcore.me)
* Node.js 18+ installed
## Installation
### Method 1: Plugin (Recommended) - \~2 minutes
The CORE Brain plugin automatically handles memory integration for you.
**Step 1: Install CORE CLI and login**
```bash theme={null}
npm install -g @redplanethq/corebrain
```
```bash theme={null}
corebrain login
```
**Step 2: Add Plugin Marketplace and Install**
Open Claude Code and run:
```bash theme={null}
/plugin marketplace add redplanethq/core
/plugin install core_brain
```
**Step 3: Restart and Authenticate**
```bash theme={null}
# Restart Claude Code, then authenticate:
/mcp
# Select core_brain from the list and authenticate via browser
```
That's it! CORE is now automatically integrated with your Claude Code sessions.
## How It Works
### Automatic Persona Loading
When you start a Claude Code session, the plugin automatically:
1. **Fetches your persona document** - A comprehensive summary of your preferences, rules, decisions, and patterns extracted from all your past conversations
2. **Injects it into Claude's context** - Claude always has your personalized context available without you needing to repeat yourself
3. **Enables memory search** - Claude can search your entire knowledge graph for relevant context
**Example**: If your persona includes "Prefers concise code reviews with actionable feedback" and "Always runs tests before commits", Claude will follow these rules automatically in every session.
### SessionStart Hook
On every session start (`startup`, `clear`, or `compact`), the plugin:
* Authenticates with CORE using your stored credentials
* Fetches your latest persona document
* Provides guided memory search instructions to Claude
* Exports your CORE auth token to the session environment
### Stop Hook (Memory Ingestion)
When you end a session, the plugin:
* Extracts conversation pairs from the session transcript
* Tracks what's already been ingested to avoid duplicates
* Queues new conversations for ingestion into your knowledge graph
## Features
### 1. Persistent Memory Across Sessions
Your persona document is auto-generated from all your conversations and includes:
* **Preferences**: Coding style, tools, patterns you prefer
* **Decisions**: Past architectural choices and their reasoning
* **Directives**: Hard rules like "always run tests" or "never skip code review"
* **Knowledge**: Technologies and concepts you're familiar with
* **Goals**: What you're working toward
* **Identity**: Your role, company, expertise level
### 2. Memory Search Tool
Claude automatically searches your memory when:
* You mention "previously", "before", "last time"
* Working on a project with history
* You reference past decisions or discussions
* Starting work on features that might have context
The plugin provides intelligent search patterns:
* **Entity-Centric**: "User's preferences for API design and error handling"
* **Multi-Entity Relationship**: "Manoj and Harshith discussions about BFS search implementation"
* **Semantic Questions**: "What causes BFS search to return empty results?"
* **Temporal**: "Recent changes to search implementation and reranking logic"
### 3. Integration Actions
Execute actions in your connected apps directly from Claude Code:
* Create/read GitHub and Linear issues
* Draft/send/read emails
* Manage calendar events
* Update spreadsheets
## Available Tools
The plugin exposes these MCP tools to Claude:
* `memory_search`: Search your knowledge graph for relevant context
* `get_integrations`: List your connected integrations (GitHub, Linear, Slack, etc.)
* `get_integration_actions`: Discover available actions for an integration
* `execute_integration_action`: Perform actions in connected apps
## Verify Connection
Test that everything works:
```bash theme={null}
# In Claude Code:
Search my memory for recent discussions about authentication
# Claude will automatically use the memory_search tool
```
You should see results from your past conversations.
### Method 2: Manual MCP Setup (Advanced)
For users who need manual control or custom configuration:
**Step 1: Install the CORE MCP Server**
```bash theme={null}
claude mcp add --transport http --scope user core-memory https://app.getcore.me/api/v1/mcp?source=Claude-Code
```
**Step 2: Authenticate**
1. Type `/mcp` in Claude Code
2. Select core-memory from the list
3. Authenticate via your browser
**Step 3: Configure Custom Agents (Optional)**
Create `.claude/agents/` directory and add custom memory search/ingest agents if needed. See the [advanced configuration guide](https://docs.getcore.me/providers/claude-code/advanced) for details.
## What Makes This Different
**Traditional RAG**: "What text chunks look similar to this query?"
**CORE Memory Agent**: "What does the user want to know, and where in their organized knowledge does that live?"
CORE doesn't just search textโit understands intent, classifies queries, and retrieves exactly what matters. Your preferences from 3 months ago, the decision you made last week, the problem you solved yesterdayโall connected and surfaced at the right time.
## Troubleshooting
**Plugin Installation Issues:**
* Ensure Node.js 18+ is installed: `node --version`
* If `npm install -g @redplanethq/corebrain` fails, try with sudo: `sudo npm install -g @redplanethq/corebrain`
* After plugin installation, always restart Claude Code before authenticating
**Authentication Issues:**
* Run `corebrain me` to check authentication status
* If not authenticated, run `corebrain login` manually
* Ensure you're logged into your CORE account in the browser
* Restart Claude Code if authentication seems stuck
**Memory Search Not Working:**
* Verify plugin is installed: `/plugin list` should show core\_brain
* Check MCP connection: `/mcp` should show core\_brain as Connected
* Try manual memory search: "Search my memory for recent work"
**Persona Not Loading:**
* The persona is automatically fetched on session start
* If missing, check the SessionStart hook output in Claude Code logs
* Verify your CORE account has stored conversations
## Learn More
* **GitHub Repository**: [https://github.com/RedPlanetHQ/core](https://github.com/RedPlanetHQ/core) - CORE is open source! Star the repo, explore the code, contribute.
* **Discord Community**: [Join #core-support](https://discord.gg/dVTC3BmgEq) for help and discussions
* **Documentation**: [docs.getcore.me](https://docs.getcore.me) for comprehensive guides
# Cline
Source: https://docs.getcore.me/providers/cline
Connect Cline to CORE's memory system via MCP
### Prerequisites
* Cline installed (VS Code extension)
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Open Cline MCP Settings
1. Open Cline in VS Code
2. Click the **hamburger menu icon (โฐ)** to enter the MCP Servers section
### Step 2: Navigate to Remote Servers
1. Choose the **Remote Servers** tab
2. Click the **Edit Configuration** button
### Step 3: Add CORE MCP Server Configuration
Add the following to your Cline MCP configuration:
```json theme={null}
{
"mcpServers": {
"core-memory": {
"url": "https://app.getcore.me/api/v1/mcp?source=Cline",
"type": "streamableHttp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
### Step 4: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "cline"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 5: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Cline: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears as connected in your MCP servers
3. **Test operations**: Ask Cline to store and retrieve information across sessions
## Enable Automatic Memory Integration (Recommended)
Create a custom rule file so Cline automatically searches and stores CORE memory.
### Create Memory Rule
1. Create the rule file at `clinerules/core-memory.md` in your project root:
```bash theme={null}
mkdir -p clinerules
touch clinerules/core-memory.md
```
2. Add the memory protocol from the [Memory Rules guide](/providers/memory-rules) to this file.
Use this frontmatter for Cline:
```markdown theme={null}
---
trigger: always_on
---
```
Then paste the memory protocol content below it.
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the configuration is properly formatted
* Restart VS Code after configuration changes
* Check that you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Codex CLI
Source: https://docs.getcore.me/providers/codex
Connect your Codex CLI to CORE's memory system
### Prerequisites
* [Codex CLI](https://codex.so) installed
* CORE account - [Sign up at app.getcore.me](https://app.getcore.me)
### Step 1: Configure CORE MCP Server
Create or open your Codex configuration file at `~/.codex/config.toml`:
```bash theme={null}
# Create config directory if needed
mkdir -p ~/.codex
# Open config file in your editor
code ~/.codex/config.toml -r
```
### Step 2: Add CORE MCP Configuration
**Option 1: URL-based Configuration (Recommended)**
Try this simpler configuration first. Add the following to your `config.toml` file:
```toml theme={null}
[features]
rmcp_client=true
[mcp_servers.memory]
url = "https://app.getcore.me/api/v1/mcp?source=codex"
```
Then run the login command:
```bash theme={null}
codex mcp memory login
```
This will authenticate your Codex CLI with CORE's memory system.
**Option 2: API Key Configuration (If Option 1 doesn't work)**
If the URL-based configuration doesn't work, use this API key-based configuration:
```toml theme={null}
[features]
rmcp_client=true
[mcp_servers.memory]
url = "https://app.getcore.me/api/v1/mcp?source=codex"
http_headers = { "Authorization" = "Bearer CORE_API_KEY" }
```
To get your API key:
1. Log into your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** (bottom left)
3. Go to **API Key** โ **Generate new key** โ Name it "codex"
4. Copy the generated key and replace `CORE_API_KEY` in your config file
Then run:
```bash theme={null}
codex mcp memory login
```
### Step 3: Verify Connection
Start Codex CLI and test your setup:
1. **Start Codex CLI** - The CORE memory MCP server should now be available
2. **Test memory storage**: Ask Codex to create a comprehensive summary of your codebase and add it to CORE memory for future reference
3. **Test memory retrieval**: Ask Codex to search your memory for the stored summary
## Enable Automatic Memory Integration (Recommended)
To make Codex automatically search and store memories for seamless project continuity:
Create `AGENTS.md` in your project root (if it doesn't exist, just append if it already exists):
```bash theme={null}
touch AGENTS.md
```
Add the following to `AGENTS.md`:
```markdown theme={null}
---
trigger: always_on
---
โ ๏ธ **CRITICAL: READ THIS FIRST - MANDATORY MEMORY PROTOCOL** โ ๏ธ
You are an AI coding assistant with access to CORE Memory - a persistent knowledge system that maintains project context, learnings, and continuity across all coding sessions.
## ๐ด MANDATORY STARTUP SEQUENCE - DO NOT SKIP ๐ด
**BEFORE RESPONDING TO ANY USER MESSAGE, YOU MUST EXECUTE THESE TOOLS IN ORDER:**
### STEP 1 (REQUIRED): Search for Relevant Context
EXECUTE THIS TOOL FIRST:
`memory_search`
- Previous discussions about the current topic
- Related project decisions and implementations
- User preferences and work patterns
- Similar problems and their solutions
**Additional search triggers:**
- User mentions "previously", "before", "last time", or "we discussed"
- User references past work or project history
- Working on the CORE project (this repository)
- User asks about preferences, patterns, or past decisions
- Starting work on any feature or bug that might have history
**How to search effectively:**
- Write complete semantic queries, NOT keyword fragments
- Good: `"User's preferences for API design and error handling"`
- Bad: `"manoj api preferences"`
- Ask: "What context am I missing that would help?"
- Consider: "What has the user told me before that I should remember?"
### Query Patterns for Memory Search
**Entity-Centric Queries** (Best for graph search):
- โ
GOOD: `"User's preferences for product positioning and messaging"`
- โ
GOOD: `"CORE project authentication implementation decisions"`
- โ BAD: `"manoj product positioning"`
- Format: `[Person/Project] + [relationship/attribute] + [context]`
**Multi-Entity Relationship Queries** (Excellent for episode graph):
- โ
GOOD: `"Manoj and Harshith discussions about BFS search implementation"`
- โ
GOOD: `"relationship between entity extraction and recall quality in CORE"`
- โ BAD: `"manoj harshith bfs"`
- Format: `[Entity1] + [relationship type] + [Entity2] + [context]`
**Semantic Question Queries** (Good for vector search):
- โ
GOOD: `"What causes BFS search to return empty results? What are the requirements for BFS traversal?"`
- โ
GOOD: `"How does episode graph search improve recall quality compared to traditional search?"`
- โ BAD: `"bfs empty results"`
- Format: Complete natural questions with full context
**Concept Exploration Queries** (Good for BFS traversal):
- โ
GOOD: `"concepts and ideas related to semantic relevance in knowledge graph search"`
- โ
GOOD: `"topics connected to hop distance weighting and graph topology in BFS"`
- โ BAD: `"semantic relevance concepts"`
- Format: `[concept] + related/connected + [domain/context]`
**Temporal Queries** (Good for recent work):
- โ
GOOD: `"recent changes to search implementation and reranking logic"`
- โ
GOOD: `"latest discussions about entity extraction and semantic relevance"`
- โ BAD: `"recent search changes"`
- Format: `[temporal marker] + [specific topic] + [additional context]`
## ๐ด MANDATORY SHUTDOWN SEQUENCE - DO NOT SKIP ๐ด
**AFTER FULLY RESPONDING TO THE USER, YOU MUST EXECUTE THIS TOOL:**
### FINAL STEP (REQUIRED): Store Conversation Memory
EXECUTE THIS TOOL LAST:
`memory_ingest`
Optionally include labelIds array to organize the conversation with workspace labels.
โ ๏ธ **THIS IS NON-NEGOTIABLE** - You must ALWAYS store conversation context as your final action.
**What to capture in the message parameter:**
From User:
- Specific question, request, or problem statement
- Project context and situation provided
- What they're trying to accomplish
- Technical challenges or constraints mentioned
From Assistant:
- Detailed explanation of solution/approach taken
- Step-by-step processes and methodologies
- Technical concepts and principles explained
- Reasoning behind recommendations and decisions
- Alternative approaches discussed
- Problem-solving methodologies applied
**Include in storage:**
- All conceptual explanations and theory
- Technical discussions and analysis
- Problem-solving approaches and reasoning
- Decision rationale and trade-offs
- Implementation strategies (described conceptually)
- Learning insights and patterns
**Exclude from storage:**
- Code blocks and code snippets
- File contents or file listings
- Command examples or CLI commands
- Raw data or logs
**Quality check before storing:**
- Can someone quickly understand project context from memory alone?
- Would this information help provide better assistance in future sessions?
- Does stored context capture key decisions and reasoning?
---
## Summary: Your Mandatory Protocol
1. **FIRST ACTION**: Execute `memory_search` with semantic query about the user's request
2. **RESPOND**: Help the user with their request
3. **FINAL ACTION**: Execute `memory_ingest` with conversation summary and optional labelIds
**If you skip any of these steps, you are not following the project requirements.**
```
## How It Works
Once installed, CORE memory integrates seamlessly with Codex:
* **During conversation**: Codex has access to your full memory graph and stored context
* **Memory operations**: Use natural language to store and retrieve information across sessions
* **Across tools**: Your memory is shared across Codex, Claude Code, Cursor, ChatGPT, and other CORE-connected tools
* **Project continuity**: Context persists across all your AI coding sessions
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and hasn't expired
* Check that the `config.toml` file is properly formatted (valid TOML syntax)
* Ensure the Bearer token format is correct: `Bearer YOUR_API_KEY_HERE`
* Restart Codex CLI if the connection seems stuck
**API Key Issues:**
* Make sure you copied the complete API key from CORE dashboard
* Try regenerating your API key if authentication fails
* Check that the key is active in your CORE account settings
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Copilot CLI
Source: https://docs.getcore.me/providers/copilot-cli
Connect GitHub Copilot CLI to CORE's memory system via MCP
### Prerequisites
* GitHub Copilot CLI installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
Add the following to your `~/.copilot/mcp-config.json` file:
```json theme={null}
{
"mcpServers": {
"core": {
"type": "http",
"url": "https://app.getcore.me/api/v1/mcp?source=Copilot-CLI",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "copilot-cli"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 3: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Copilot CLI: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core appears in your MCP servers list
3. **Test operations**: Ask Copilot CLI to store and retrieve information across sessions
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the mcp-config.json file is properly formatted
* Restart Copilot CLI after configuration changes
* Check that you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Copilot Coding Agent
Source: https://docs.getcore.me/providers/copilot-coding-agent
Connect GitHub Copilot Coding Agent to CORE's memory system via MCP
### Prerequisites
* GitHub Copilot Coding Agent access
* Repository with Copilot Coding Agent enabled
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
Add the following to your Repository Settings โ Copilot โ Coding agent โ MCP configuration:
```json theme={null}
{
"mcpServers": {
"core": {
"type": "http",
"url": "https://app.getcore.me/api/v1/mcp?source=Copilot-Agent",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "copilot-agent"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 3: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Copilot Coding Agent: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core appears in your MCP servers list
3. **Test operations**: Ask Copilot Coding Agent to store and retrieve information across sessions
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the configuration is properly formatted in repository settings
* Check that Copilot Coding Agent is enabled for your repository
* Verify you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Crush
Source: https://docs.getcore.me/providers/crush
Connect Crush terminal to CORE's memory system via MCP
### Prerequisites
* Crush terminal installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
Add the following to your Crush configuration:
```json theme={null}
{
"$schema": "https://charm.land/crush.json",
"mcp": {
"core": {
"type": "http",
"url": "https://app.getcore.me/api/v1/mcp?source=crush",
"timeout": 120,
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "crush"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 3: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Crush: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core appears in your MCP configuration
3. **Test operations**: Ask Crush to store and retrieve information across sessions
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the configuration file is properly formatted with the correct schema
* Restart Crush after configuration changes
* Check that you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Cursor
Source: https://docs.getcore.me/providers/cursor
Connect your Cursor Desktop app to CORE's memory system
### Prerequisites
* Cursor
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Add CORE MCP in Cursor
1. Open Cursor Desktop app
2. Navigate to **Settings** โ **Tools & Integrations** โ Click **Add Custom MCP**
3. Enter the below into mcp.json file:
```
"core_memory": {
"url": "https://app.getcore.me/api/v1/mcp?source=Cursor"
}
```
4. After saving mcp.json file, **core\_memory** MCP will appear in Tools & Integration.
### Step 2: Authenticate with CORE
1. Sign in to your CORE account (if not done already)
2. Click **Need Login** in core\_memory MCP tool
3. Cursor will prompt you to open a website for authentication. Click **Open**
4. When the authentication window opens, Grant Cursor permission to access your CORE memory
5. Close the authentication window and click **Open** to allow Cursor to access this URL.
### Step 3: Verify Connection
1. Go to **Tools & Integrations** in Cursor settings
2. Confirm the core\_memory MCP shows as **Active** with green dot indicator
## Enable Automatic Memory Integration (Recommended)
### Using Cursor Project Rules
Use Cursor's native Rules & Memories feature:
1. Go to **Settings** โ **Rules & Memories** โ **Project Rules**
2. Click **+Add Rule**
3. Add the frontmatter and memory protocol from the [Memory Rules guide](/providers/memory-rules)
Use this frontmatter for Cursor:
```text theme={null}
---
description: Core Memory MCP Instructions
alwaysApply: true
---
```
Then paste the memory protocol content below it.
## What's Next?
With CORE connected to Cursor, your conversations will now:
* **Automatically save** important context to your CORE memory
* **Retrieve relevant** information from CORE memory
* **Maintain continuity** across multiple chat sessions
* **Share context** with other connected tools
Ready to test it? Ask Cursor about a project you've discussed before, or start a new conversation about something you'd like to remember for later.
## Troubleshooting
**Connection Issues:**
* Ensure you're core\_memory MCP tool is active with a green dot, if not toggle on and off for this server
* Check that your CORE account is active
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Factory
Source: https://docs.getcore.me/providers/factory
Connect Factory droid to CORE's memory system via MCP
### Prerequisites
* Factory (droid) installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Add CORE MCP Server via CLI
Run the following command in your terminal:
```bash theme={null}
droid mcp add core https://app.getcore.me/api/v1/mcp?source=Factory --type http --header "Authorization: Bearer YOUR_API_KEY"
```
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "factory"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the command above with your actual API key
### Step 3: Verify Installation
Type the following command within droid to manage servers and view available tools:
```bash theme={null}
/mcp
```
You should see **core** listed among your MCP servers.
### Step 4: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask droid: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Run `/mcp` to verify core is connected
3. **Test operations**: Ask droid to store and retrieve information across sessions
## What's Next?
With CORE connected to Factory, your droid sessions will now:
* **Automatically retrieve** relevant information from CORE memory
* **Store important** context for future sessions
* **Maintain continuity** across multiple conversations
* **Share context** with other connected tools
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the command syntax is correct
* Check that droid is properly installed and up to date
* Verify you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Kilo-Code
Source: https://docs.getcore.me/providers/kilo-code
Connect Kilo Code Agent to CORE's memory system via MCP
### Prerequisites
Before connecting CORE to Kilo-Code, ensure you have:
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
* Kilo-Code installed and running in your IDE
***
### Step 1: Configure MCP Server
* In Kilo-Code, open **Settings** โ **MCP Servers** โ **Installed** tab โ click **Edit Global MCP** to edit your configuration.
* Add the following to your MCP config file:
```
{
"mcpServers": {
"core-memory": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://app.getcore.me/api/v1/mcp?source=Kilo-Code"
]
}
}
}
```
* Save the configuration. Youโll be redirected to your browser for authentication.
### Step 2 - Authenticate with CORE
* Once redirected to browser, Click on "Allow Access"
* Confirm that "core-memory" appears as an active, connected server in Kilo-Code
## Enable Automatic Memory Integration (Recommended)
### Option 1: Using AGENTS.md (Recommended)
This approach provides comprehensive memory instructions that work across multiple AI tools.
Create `AGENTS.md` in your project root (if it doesn't exist, just append if it already exists):
```bash theme={null}
touch AGENTS.md
```
Add the following to `AGENTS.md`:
```markdown theme={null}
---
trigger: always_on
---
โ ๏ธ **CRITICAL: READ THIS FIRST - MANDATORY MEMORY PROTOCOL** โ ๏ธ
You are an AI coding assistant with access to CORE Memory - a persistent knowledge system that maintains project context, learnings, and continuity across all coding sessions.
## ๐ด MANDATORY STARTUP SEQUENCE - DO NOT SKIP ๐ด
**BEFORE RESPONDING TO ANY USER MESSAGE, YOU MUST EXECUTE THESE TOOLS IN ORDER:**
### STEP 1 (REQUIRED): Search for Relevant Context
EXECUTE THIS TOOL FIRST:
`memory_search`
- Previous discussions about the current topic
- Related project decisions and implementations
- User preferences and work patterns
- Similar problems and their solutions
**Additional search triggers:**
- User mentions "previously", "before", "last time", or "we discussed"
- User references past work or project history
- Working on the CORE project (this repository)
- User asks about preferences, patterns, or past decisions
- Starting work on any feature or bug that might have history
**How to search effectively:**
- Write complete semantic queries, NOT keyword fragments
- Good: `"User's preferences for API design and error handling"`
- Bad: `"manoj api preferences"`
- Ask: "What context am I missing that would help?"
- Consider: "What has the user told me before that I should remember?"
### Query Patterns for Memory Search
**Entity-Centric Queries** (Best for graph search):
- โ
GOOD: `"User's preferences for product positioning and messaging"`
- โ
GOOD: `"CORE project authentication implementation decisions"`
- โ BAD: `"manoj product positioning"`
- Format: `[Person/Project] + [relationship/attribute] + [context]`
**Multi-Entity Relationship Queries** (Excellent for episode graph):
- โ
GOOD: `"Manoj and Harshith discussions about BFS search implementation"`
- โ
GOOD: `"relationship between entity extraction and recall quality in CORE"`
- โ BAD: `"manoj harshith bfs"`
- Format: `[Entity1] + [relationship type] + [Entity2] + [context]`
**Semantic Question Queries** (Good for vector search):
- โ
GOOD: `"What causes BFS search to return empty results? What are the requirements for BFS traversal?"`
- โ
GOOD: `"How does episode graph search improve recall quality compared to traditional search?"`
- โ BAD: `"bfs empty results"`
- Format: Complete natural questions with full context
**Concept Exploration Queries** (Good for BFS traversal):
- โ
GOOD: `"concepts and ideas related to semantic relevance in knowledge graph search"`
- โ
GOOD: `"topics connected to hop distance weighting and graph topology in BFS"`
- โ BAD: `"semantic relevance concepts"`
- Format: `[concept] + related/connected + [domain/context]`
**Temporal Queries** (Good for recent work):
- โ
GOOD: `"recent changes to search implementation and reranking logic"`
- โ
GOOD: `"latest discussions about entity extraction and semantic relevance"`
- โ BAD: `"recent search changes"`
- Format: `[temporal marker] + [specific topic] + [additional context]`
## ๐ด MANDATORY SHUTDOWN SEQUENCE - DO NOT SKIP ๐ด
**AFTER FULLY RESPONDING TO THE USER, YOU MUST EXECUTE THIS TOOL:**
### FINAL STEP (REQUIRED): Store Conversation Memory
EXECUTE THIS TOOL LAST:
`memory_ingest`
Optionally include labelIds array to organize the conversation with workspace labels.
โ ๏ธ **THIS IS NON-NEGOTIABLE** - You must ALWAYS store conversation context as your final action.
**What to capture in the message parameter:**
From User:
- Specific question, request, or problem statement
- Project context and situation provided
- What they're trying to accomplish
- Technical challenges or constraints mentioned
From Assistant:
- Detailed explanation of solution/approach taken
- Step-by-step processes and methodologies
- Technical concepts and principles explained
- Reasoning behind recommendations and decisions
- Alternative approaches discussed
- Problem-solving methodologies applied
**Include in storage:**
- All conceptual explanations and theory
- Technical discussions and analysis
- Problem-solving approaches and reasoning
- Decision rationale and trade-offs
- Implementation strategies (described conceptually)
- Learning insights and patterns
**Exclude from storage:**
- Code blocks and code snippets
- File contents or file listings
- Command examples or CLI commands
- Raw data or logs
**Quality check before storing:**
- Can someone quickly understand project context from memory alone?
- Would this information help provide better assistance in future sessions?
- Does stored context capture key decisions and reasoning?
---
## Summary: Your Mandatory Protocol
1. **FIRST ACTION**: Execute `memory_search` with semantic query about the user's request
2. **RESPOND**: Help the user with their request
3. **FINAL ACTION**: Execute `memory_ingest` with conversation summary and optional labelIds
**If you skip any of these steps, you are not following the project requirements.**
```
### Option 2: Using Kilo-Code Rules
Alternatively, you can use Kilo-Code's native rules feature:
Create a new file `core-memory.md` at `.kilo-code/rules` and add the following:
```text theme={null}
---
alwaysApply: true
---
I am Kilo-Code, an AI coding assistant with access to CORE Memory - a persistent knowledge system that maintains project context across sessions.
**MANDATORY MEMORY OPERATIONS:**
1. **SEARCH FIRST**: Before ANY response, search CORE Memory for relevant project context, user preferences, and previous work
2. **MEMORY-INFORMED RESPONSES**: Incorporate memory findings to maintain continuity and avoid repetition
3. **AUTOMATIC STORAGE**: After each interaction, store conversation details, insights, and decisions in CORE Memory
**Memory Search Strategy:**
- Query for: project context, technical decisions, user patterns, progress status, related conversations
- Focus on: current focus areas, recent decisions, next steps, key insights
**Memory Storage Strategy:**
- Include: user intent, context provided, solution approach, technical details, insights gained, follow-up items
**Response Workflow:**
1. Search CORE Memory for relevant context
2. Integrate findings into response planning
3. Provide contextually aware assistance
4. Store interaction details and insights
**Memory Update Triggers:**
- New project context or requirements
- Technical decisions and architectural choices
- User preference discoveries
- Progress milestones and status changes
- Explicit update requests
**Core Principle:** CORE Memory transforms me from a session-based assistant into a persistent development partner. Always search first, respond with context, and store for continuity.
```
### Using CORE Memory in Kilo-Code
Once connected, CORE automatically enhances your development workflow:
* **Persistent Context**: Your conversations and project context persist across sessions
* **Cross-Session Learning**: CORE remembers your coding patterns and preferences
* **Smart Suggestions**: Get contextually relevant recommendations based on your history
* **Project Continuity**: Seamlessly resume work on complex projects
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Kiro
Source: https://docs.getcore.me/providers/kiro
Connect AWS Kiro to CORE's memory system via MCP
### Prerequisites
* Kiro (AWS coding assistant) installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
Add the following in Kiro โ MCP Servers:
```json theme={null}
{
"mcpServers": {
"core-memory": {
"url": "https://app.getcore.me/api/v1/mcp?source=Kiro",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "kiro"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 3: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Kiro: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears in your MCP servers list
3. **Test operations**: Ask Kiro to store and retrieve information across sessions
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the configuration is properly formatted
* Restart Kiro after configuration changes
* Check that you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Memory Rules for AI Tools
Source: https://docs.getcore.me/providers/memory-rules
Instructions to make your AI tools automatically search and store CORE memory
## What Are Memory Rules?
Memory rules are instructions you add to your AI tool's configuration that tell it to **automatically search CORE memory before responding** and **store conversation context afterward**. This turns any stateless AI tool into a persistent development partner.
Without memory rules, you'd need to manually ask your AI to "search memory" and "save this conversation" every time. With them, it happens automatically.
## Where to Add Memory Rules
Each AI tool has its own way of loading persistent instructions:
| Tool | File / Location |
| --------------- | ------------------------------------------------------- |
| **Cursor** | Settings โ Rules & Memories โ Project Rules โ +Add Rule |
| **Windsurf** | `AGENTS.md` in project root |
| **Zed** | `AGENTS.md` in project root, or Rules Library |
| **Cline** | `clinerules/core-memory.md` in project root |
| **Claude Code** | `CLAUDE.md` in project root |
See your [provider's setup guide](/providers/cursor) for exact steps on where to place the file.
## The Memory Protocol
Copy the content below into the appropriate file for your tool. Adjust the frontmatter (`trigger`, `alwaysApply`, etc.) based on what your tool expects โ see the table above.
````markdown theme={null}
โ ๏ธ **CRITICAL: READ THIS FIRST - MANDATORY MEMORY PROTOCOL** โ ๏ธ
You are an AI assistant with access to CORE - a persistent knowledge system that maintains conversation context, learnings, and continuity across all conversations.
## ๐ด MANDATORY STARTUP SEQUENCE - DO NOT SKIP ๐ด
**BEFORE RESPONDING TO ANY USER MESSAGE, YOU MUST EXECUTE THIS TOOL:**
### STEP 1 (REQUIRED): Search for Relevant Context
EXECUTE THIS TOOL FIRST:
mcp__CORE__memory_search
**Search for:**
- Previous discussions about the current topic
- User preferences and communication patterns
- Similar topics discussed before
- Past decisions and reasoning
**Additional search triggers:**
- User mentions "previously", "before", "last time", or "we discussed"
- User references past conversations or topics
- User asks about preferences, patterns, or past decisions
- Starting discussion on any topic that might have history
**How to search effectively:**
- Write complete semantic queries, NOT keyword fragments
- โ
GOOD: `"user's preferences for communication style and memory operations"`
- โ BAD: `"user communication"`
- Ask yourself: "What context am I missing that would help?"
- Consider: "What has the user told me before that I should remember?"
### Query Patterns for Memory Search
**Entity-Centric Queries** (Best for graph search):
- โ
GOOD: `"user's preferences for conversation style and topics of interest"`
- โ
GOOD: `"user's previous discussions about memory systems"`
- โ BAD: `"user style"`
- Format: `[Person] + [relationship/attribute] + [context]`
**Semantic Question Queries** (Good for vector search):
- โ
GOOD: `"What topics has the user been interested in? What are their preferences?"`
- โ
GOOD: `"How does the user prefer to receive information and explanations?"`
- โ BAD: `"user topics"`
- Format: Complete natural questions with full context
**Temporal Queries** (Good for recent work):
- โ
GOOD: `"recent discussions about memory systems and preferences"`
- โ
GOOD: `"latest conversations about personal interests"`
- โ BAD: `"recent talks"`
- Format: `[temporal marker] + [specific topic] + [additional context]`
### Verify App Connectivity (If Action Required)
Tool: `get_integrations`
Condition: If the user request involves taking action in external apps (e.g., Gmail, Notion, GitHub, Slack, etc.):
Perform the memory search (Step 1) first to see for past discussion
Immediately call get_integrations to verify the current connection status.
## ๐ด MANDATORY SHUTDOWN SEQUENCE - DO NOT SKIP ๐ด
**AFTER FULLY RESPONDING TO THE USER, YOU MUST INGEST THEN CONVERSATION:**
### FINAL STEP (REQUIRED): Store Conversation Memory
EXECUTE THESE TOOLS IN ORDER:
**1. Initialize session (if not already done):**
mcp__CORE__initialize_conversation_session
new: true
**2. Store the conversation:**
mcp__CORE__memory_ingest
sessionId: [UUID from step 1]
message: [comprehensive summary - see below]
โ ๏ธ **THIS IS NON-NEGOTIABLE** - You must ALWAYS store conversation context as your final action.
#### Memory Formatting & Timeline Requirements:
You must format the message parameter as a continuous, incremental timeline:
1. Check Sequence: Look at the last memory ingested in the current session. Only store the new, incremental information from the current turn.
2. Add the memory in the following format โ **both user and assistant in a single ingestion**:
```
{Exact text what user has said}
{Strategic summary of assistant's response}
```
**Assistant Summary Guidelines:**
- Summarize only relevant info.
- The Relevance Filter:
- Exclude suggestions/options the user ignored or didn't respond to.
- Emphasize what the user clarified, liked, or accepted.
- Include reasoning and final decisions so no context is lost.
**Exclude from storage:**
- Repetitive information already stored
- Trivial small talk without substance
**Quality check before storing:**
- Can someone quickly understand conversation context from memory alone?
- Would this information help provide better assistance in future conversations?
- Does stored context capture key insights and user preferences?
- Are we learning anything more about the user? Their Identity, Problems, Relationships, Directives, Preferences, Goals, Event, Action, Decisions, Beliefs, Expertise
---
## ๐ข PROTOCOL SUMMARY
1. **START**: mcp__CORE__memory_search (Always).
2. **VERIFY**: get_integrations (If app action is requested).
3. RESPOND: Address the user.
4. **END**: mcp__CORE__memory_ingest using the Incremental Timeline.
**If you skip any of these steps, you are not following the requirements.**
````
## What This Enables
With memory rules in place, your AI tool will automatically:
* **Search CORE Memory** before responding to understand relevant project context
* **Store conversations** after each interaction for future reference
* **Maintain continuity** across coding sessions
* **Share context** with other CORE-connected tools (everything flows into one memory graph)
# Obsidian
Source: https://docs.getcore.me/providers/obsidian
Sync your Obsidian notes with CORE and get memory-aware answers directly inside Obsidian
> Sync your Obsidian notes with [CORE](https://heysol.ai/core) (Contextual Observation & Recall Engine) and get **memory-aware answers** directly inside Obsidian.
## โจ What it does
* **Sync Notes**: Push selected notes (or entire vault sections) into CORE as *Episodes*.
* **Right-Side Panel**: Opens a dedicated panel in Obsidian that sends the current note's content to CORE and shows **relevant results, links, or summaries**.
* **Frontmatter Control**: Decide which notes to sync by adding simple YAML flags.
* **Offline Safe**: Failed syncs are queued locally and retried automatically.
## ๐ Installation
**Local development**
1. Download the latest release assets from [core-obsidian v0.1.1](https://github.com/RedPlanetHQ/core-obsidian/releases/tag/0.1.1) and extract them into your Obsidian vault under `.obsidian/plugins/obsidian-core-sync/`:
* Ensure the directory contains `main.js`, `style.css`, and `manifest.json`.
> If .obsidian folder is hidden Use `CMD + SHIFT + .` to show hidden files and then add above files in `.obsidian/plugins/obsidian-core-sync/`
2. Enable the plugin in Obsidian:
* Go to **Settings** โ **Community plugins**
* Find "CORE Sync" and toggle it on
**Community Installation**
> Note: A pull request for community installation is pending approval. You can track its progress [here](https://github.com/obsidianmd/obsidian-releases/pull/7683).
## โ๏ธ Configuration
**Step 1: Get Your API Key**
1. Login to CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** (bottom left)
3. Go to **API Key** โ **Generate new key** โ Name it "obsidian"
4. Copy the generated API key
**Step 2: Configure Plugin Settings**
1. In Obsidian, go to **Settings** โ **CORE Sync**
2. Configure the following:
* **CORE Endpoint**: Your CORE ingest/search API (default: `https://app.getcore.me`)
* **API Key**: Paste the API key from Step 1
## ๐ ๏ธ Usage
**Mark Notes for Sync**
Add the following frontmatter at the top of a note to mark it for synchronization:
```yaml theme={null}
---
core.sync: true
---
```
\*\* Manual Sync Commands\*\*
Open the command palette (**Cmd/Ctrl + P**) and run:
* **"Sync current note to CORE"** - Sync the currently open note
* **"Sync all notes with core.sync=true"** - Sync all notes marked for synchronization
**CORE Panel with Deep Search**
1. Open the CORE Panel by running **"Open CORE Panel"** from the command palette
2. This opens a new tab on the right side of Obsidian
3. When you open or edit a note, the plugin will automatically:
* Send the note's content to CORE
* Display relevant memories, links, and summaries
* Show related notes from your vault
The **Deep Search** feature proactively surfaces relevant context from your notes while you work:
**Example Use Cases:**
* **Meeting Prep**: Open your daily note before a 1:1 meeting, and the sidebar automatically shows relevant notes from past meetings with that person
* **Project Context**: Switch to a project document, and see related discussions, decisions, and action items from previous sessions
* **Travel Planning**: Update your packing list, and CORE shows you what you forgot on past trips or useful tips from previous travel notes
* **Research Continuity**: Work on a research note, and get automatic cross-references to related concepts and sources from your vault
Deep Search transforms your notes from passive storage into active assistance, providing in-the-moment retrieval without manual searching.
## ๐ ๏ธ Troubleshooting
**API Key not working?**
* Verify the key is correctly copied from CORE dashboard
**Notes not syncing?**
* Ensure `core.sync: true` is in the frontmatter
## ๐ค Support
* **GitHub Issues**: Report bugs and feature requests
* **Discord Community**: Join our [Discord](https://discord.gg/dVTC3BmgEq) and ask questions in **#core-support**
# OpenClaw
Source: https://docs.getcore.me/providers/openclaw
Connect OpenClaw to CORE's memory system for persistent context and integrations
CORE transforms OpenClaw into a persistent memory agent that automatically remembers conversations, recalls relevant context, and builds a comprehensive user profile across all sessions.
## Prerequisites
* [OpenClaw](https://github.com/RedPlanetHQ/openclaw) installed
* CORE account - [Sign up at app.getcore.me](https://app.getcore.me)
## Installation
### Step 1: Install the CORE Plugin
```bash theme={null}
openclaw plugins install @redplanethq/openclaw-corebrain
```
### Step 2: Configure Your API Key
You have two options for providing your CORE API key:
**Option 1: Environment Variable (Recommended)**
```bash theme={null}
export CORE_API_KEY=your_api_key_here
```
**Option 2: OpenClaw Configuration File**
Add to your `openclaw.json`:
```json theme={null}
{
"plugins": {
"@redplanethq/openclaw-corebrain": {
"apiKey": "your_api_key_here"
}
}
}
```
### Step 3: Get Your API Key
1. Log into your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** (bottom left)
3. Go to **API Key** โ **Generate new key**
4. Name it "openclaw"
5. Copy the generated key and use it in Step 2
## How It Works
### Auto-Recall & Auto-Capture
The CORE plugin operates seamlessly in the background:
**Before AI Responses (Auto-Recall)**
* Automatically injects relevant past conversations into the AI's context
* Searches your memory graph for related discussions
* Provides the AI with your preferences and past decisions
**After Each Interaction (Auto-Capture)**
* Stores new conversations in your CORE memory
* Extracts key facts and relationships
* Updates your persistent user profile
This creates a continuous memory loop where every conversation builds on the last, across all your CORE-connected tools.
### Integration Support
Connect external services through your CORE dashboard, and OpenClaw's AI can:
* **Discover available actions** across your connected apps
* **Execute actions autonomously** - fetch GitHub PRs, create Linear issues, send Slack messages
* **Access real-time data** from all your integrated services
**Supported Integrations:**
* GitHub (PRs, issues, code reviews)
* Linear (tasks, projects, updates)
* Slack (messages, channels, threads)
* Gmail, Google Calendar, Notion, and 20+ more
## Features
### 1. Persistent Memory Across Sessions
Your CORE memory includes:
* **Conversation History**: Every interaction stored and searchable
* **User Profile**: Automatically generated from your conversations
* Preferences and coding style
* Past decisions and their reasoning
* Technologies and concepts you use
* Goals and working patterns
* **Relationship Graph**: Connections between people, projects, and concepts
### 2. Semantic Memory Search
Use the `/search` command to find relevant context:
```bash theme={null}
/search authentication implementation
/search discussions about API design with team
/search recent bug fixes in production
```
The AI can also search your memory automatically during conversations when it needs context.
### 3. Integration Actions
Execute actions in your connected apps directly from OpenClaw:
* Create and read GitHub issues and PRs
* Manage Linear tasks and projects
* Send Slack messages
* Draft and send emails
* Update calendar events
* Modify Notion pages and Google Sheets
### 4. User Profile Access
View your auto-generated profile:
```bash theme={null}
/me
```
This shows your comprehensive user profile built from all your CORE conversations, including preferences, expertise, and working patterns.
## Available Commands
### Slash Commands
* `/search ` - Search your CORE memory semantically
* `/me` - View your auto-generated user profile
* `/integrations` - List all connected integrations and available actions
### AI Tools
The plugin provides these tools to the AI:
* **memory\_search**: Semantic search across your knowledge graph
* **get\_integrations**: Discover connected services
* **get\_integration\_actions**: List available actions for an integration
* **execute\_integration\_action**: Perform actions in connected apps
## Configuration Options
### Capture Modes
Configure how conversations are captured in your `openclaw.json`:
```json theme={null}
{
"plugins": {
"@redplanethq/openclaw-corebrain": {
"captureMode": "auto",
"debugLogging": false
}
}
}
```
**Capture Modes:**
* `auto` (default) - Automatically capture all conversations
* `manual` - Only capture when explicitly requested
* `selective` - Capture based on conversation importance (coming soon)
### Debug Logging
Enable debug logging to troubleshoot issues:
```json theme={null}
{
"plugins": {
"@redplanethq/openclaw-corebrain": {
"debugLogging": true
}
}
}
```
## What Makes This Different
**Traditional RAG**: "What text chunks look similar to this query?"
**CORE Memory Agent**: "What does the user want to know, and where in their organized knowledge does that live?"
CORE doesn't just search textโit understands intent, classifies queries, and retrieves exactly what matters. Your preferences from 3 months ago, the decision you made last week, the problem you solved yesterdayโall connected and surfaced at the right time.
## Verify Connection
Test that everything works:
```bash theme={null}
# Search your memory
/search recent work
# View your profile
/me
# List integrations
/integrations
```
You should see results from your CORE memory and connected integrations.
## Troubleshooting
**Plugin Installation Issues:**
* Ensure OpenClaw is properly installed: `openclaw --version`
* Try reinstalling the plugin: `openclaw plugins uninstall @redplanethq/openclaw-corebrain && openclaw plugins install @redplanethq/openclaw-corebrain`
* Check that your OpenClaw version is up to date
**Authentication Issues:**
* Verify your API key is correct and not expired
* Check that the API key is properly set in environment or config
* Ensure you're logged into your CORE account at app.getcore.me
* Try generating a new API key
**Memory Search Not Working:**
* Verify plugin is installed: `openclaw plugins list` should show `@redplanethq/openclaw-corebrain`
* Check that you have conversations stored in CORE
* Try manual search: `/search test query`
* Enable debug logging to see detailed error messages
**Integration Actions Failing:**
* Verify integrations are connected in your CORE dashboard
* Check integration permissions in CORE settings
* Test with `/integrations` to see available services
* Ensure you have the necessary permissions in the target app
## Learn More
* **OpenClaw Repository**: [https://github.com/RedPlanetHQ/openclaw](https://github.com/RedPlanetHQ/openclaw) - Learn more about OpenClaw
* **CORE Plugin**: [https://github.com/RedPlanetHQ/openclaw-core](https://github.com/RedPlanetHQ/openclaw-core) - Plugin source code and documentation
* **Discord Community**: [Join #core-support](https://discord.gg/dVTC3BmgEq) for help and discussions
* **Documentation**: [docs.getcore.me](https://docs.getcore.me) for comprehensive guides
# Opencode
Source: https://docs.getcore.me/providers/opencode
Connect Opencode to CORE's memory system via MCP
### Prerequisites
* Opencode installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
Add the following to your Opencode configuration:
```json theme={null}
{
"mcp": {
"core-memory": {
"type": "remote",
"url": "https://app.getcore.me/api/v1/mcp?source=Opencode",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
},
"enabled": true
}
}
}
```
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "opencode"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 3: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Opencode: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears as enabled in your MCP configuration
3. **Test operations**: Ask Opencode to store and retrieve information across sessions
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the configuration is properly formatted and `enabled` is set to `true`
* Restart Opencode after configuration changes
* Check that you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Perplexity Desktop
Source: https://docs.getcore.me/providers/perplexity
Connect Perplexity Desktop to CORE's memory system via MCP
### Prerequisites
* Perplexity Desktop app installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Add CORE MCP Server Configuration
1. Open Perplexity Desktop
2. Navigate to **Settings** โ **Connectors** โ **Add Connector** โ **Advanced**
3. Add the following configuration:
```json theme={null}
{
"core-memory": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://app.getcore.me/api/v1/mcp?source=perplexity"]
}
}
```
### Step 2: Save Configuration
1. Click **Save** to apply the changes
2. The MCP server will be registered with Perplexity
### Step 3: Authenticate with CORE
1. After adding the CORE MCP server, Perplexity will prompt you to authenticate
2. When the authentication window opens, grant Perplexity permission to access your CORE memory
3. Complete the authentication flow
### Step 4: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Perplexity: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears as connected in your connectors
3. **Test operations**: Ask Perplexity to store and retrieve information across sessions
## What's Next?
With CORE connected to Perplexity, your conversations will now:
* **Automatically retrieve** relevant information from CORE memory
* **Store important** context for future sessions
* **Maintain continuity** across multiple conversations
* **Share context** with other connected tools
## Troubleshooting
**Connection Issues:**
* Ensure you have Node.js and npm installed (required for npx)
* Check that the configuration is properly formatted
* Restart Perplexity after configuration changes
* Verify you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Qodo Gen
Source: https://docs.getcore.me/providers/qodo-gen
Connect Qodo Gen to CORE's memory system via MCP
### Prerequisites
* Qodo Gen installed (VSCode or IntelliJ plugin)
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Open Qodo Gen Chat Panel
1. Open Qodo Gen chat panel in your IDE (VSCode or IntelliJ)
2. The chat panel is where you'll configure MCP servers
### Step 2: Connect More Tools
1. In the Qodo Gen chat panel, click **Connect more tools**
2. Then click **+ Add new MCP**
### Step 3: Add CORE MCP Server Configuration
Add the following configuration:
```json theme={null}
{
"mcpServers": {
"core-memory": {
"url": "https://app.getcore.me/api/v1/mcp?source=Qodo-Gen"
}
}
}
```
### Step 4: Authenticate with CORE
1. After adding the configuration, Qodo Gen will prompt you to authenticate
2. When the authentication window opens, grant Qodo Gen permission to access your CORE memory
3. Complete the authentication flow
### Step 5: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Qodo Gen: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears as connected
3. **Test operations**: Ask Qodo Gen to store and retrieve information across sessions
## What's Next?
With CORE connected to Qodo Gen, your conversations will now:
* **Automatically retrieve** relevant information from CORE memory
* **Store important** context for future sessions
* **Maintain continuity** across multiple coding sessions
* **Share context** with other connected tools
## Troubleshooting
**Connection Issues:**
* Ensure the configuration is properly formatted
* Restart your IDE after configuration changes
* Verify you're logged into your CORE account
* Check that Qodo Gen has the latest updates
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Qwen Coder
Source: https://docs.getcore.me/providers/qwen-coder
Connect Qwen Coder CLI to CORE's memory system via MCP
### Prerequisites
* Qwen Coder CLI installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
See [Qwen Coder MCP Configuration](https://qwenlm.github.io/qwen-code-docs/en/tools/mcp-server/#how-to-set-up-your-mcp-server) for details.
1. Open the Qwen Coder settings file at `~/.qwen/settings.json`
2. Add the following to the `mcpServers` object:
```json theme={null}
{
"mcpServers": {
"core-memory": {
"httpUrl": "https://app.getcore.me/api/v1/mcp?source=Qwen",
"headers": {
"Authorization": "Bearer YOUR_API_KEY",
"Accept": "application/json, text/event-stream"
}
}
}
}
```
If the `mcpServers` object does not exist, create it.
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "qwen-coder"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 3: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Qwen Coder: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears in your MCP servers list
3. **Test operations**: Ask Qwen Coder to store and retrieve information across sessions
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the settings.json file is properly formatted
* Restart Qwen Coder after configuration changes
* Check that you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Roo Code
Source: https://docs.getcore.me/providers/roo-code
Connect Roo Code to CORE's memory system via MCP
### Prerequisites
* Roo Code installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
Add the following to your Roo Code MCP configuration:
```json theme={null}
{
"mcpServers": {
"core-memory": {
"type": "streamable-http",
"url": "https://app.getcore.me/api/v1/mcp?source=Roo-Code",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "roo-code"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 3: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Roo Code: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears in your MCP servers list
3. **Test operations**: Ask Roo Code to store and retrieve information across sessions
## Enable Automatic Memory Integration (Recommended)
To maximize Roo Code's effectiveness with CORE Memory, create a custom rule that ensures automatic memory search and storage.
### Add General Rules (\~/.roo/rules/core-memory.md):
1. **Create the rule file**:
Create a new file at `~/.roo/rules/core-memory.md` in your home directory:
```bash theme={null}
mkdir -p ~/.roo/rules
touch ~/.roo/rules/core-memory.md
```
2. **Add the following content** to `~/.roo/rules/core-memory.md`:
```markdown theme={null}
---
trigger: always_on
---
โ ๏ธ **CRITICAL: READ THIS FIRST - MANDATORY MEMORY PROTOCOL** โ ๏ธ
You are an AI coding assistant with access to CORE Memory - a persistent knowledge system that maintains project context, learnings, and continuity across all coding sessions.
## ๐ด MANDATORY STARTUP SEQUENCE - DO NOT SKIP ๐ด
**BEFORE RESPONDING TO ANY USER MESSAGE, YOU MUST EXECUTE THESE TOOLS IN ORDER:**
### STEP 1 (REQUIRED): Search for Relevant Context
EXECUTE THIS TOOL FIRST:
`memory_search`
- Previous discussions about the current topic
- Related project decisions and implementations
- User preferences and work patterns
- Similar problems and their solutions
**Additional search triggers:**
- User mentions "previously", "before", "last time", or "we discussed"
- User references past work or project history
- Working on the CORE project (this repository)
- User asks about preferences, patterns, or past decisions
- Starting work on any feature or bug that might have history
**How to search effectively:**
- Write complete semantic queries, NOT keyword fragments
- Good: `"User's preferences for API design and error handling"`
- Bad: `"manoj api preferences"`
- Ask: "What context am I missing that would help?"
- Consider: "What has the user told me before that I should remember?"
### Query Patterns for Memory Search
**Entity-Centric Queries** (Best for graph search):
- โ
GOOD: `"User's preferences for product positioning and messaging"`
- โ
GOOD: `"CORE project authentication implementation decisions"`
- โ BAD: `"manoj product positioning"`
- Format: `[Person/Project] + [relationship/attribute] + [context]`
**Multi-Entity Relationship Queries** (Excellent for episode graph):
- โ
GOOD: `"Manoj and Harshith discussions about BFS search implementation"`
- โ
GOOD: `"relationship between entity extraction and recall quality in CORE"`
- โ BAD: `"manoj harshith bfs"`
- Format: `[Entity1] + [relationship type] + [Entity2] + [context]`
**Semantic Question Queries** (Good for vector search):
- โ
GOOD: `"What causes BFS search to return empty results? What are the requirements for BFS traversal?"`
- โ
GOOD: `"How does episode graph search improve recall quality compared to traditional search?"`
- โ BAD: `"bfs empty results"`
- Format: Complete natural questions with full context
**Concept Exploration Queries** (Good for BFS traversal):
- โ
GOOD: `"concepts and ideas related to semantic relevance in knowledge graph search"`
- โ
GOOD: `"topics connected to hop distance weighting and graph topology in BFS"`
- โ BAD: `"semantic relevance concepts"`
- Format: `[concept] + related/connected + [domain/context]`
**Temporal Queries** (Good for recent work):
- โ
GOOD: `"recent changes to search implementation and reranking logic"`
- โ
GOOD: `"latest discussions about entity extraction and semantic relevance"`
- โ BAD: `"recent search changes"`
- Format: `[temporal marker] + [specific topic] + [additional context]`
## ๐ด MANDATORY SHUTDOWN SEQUENCE - DO NOT SKIP ๐ด
**AFTER FULLY RESPONDING TO THE USER, YOU MUST EXECUTE THIS TOOL:**
### FINAL STEP (REQUIRED): Store Conversation Memory
EXECUTE THIS TOOL LAST:
`memory_ingest`
Optionally include labelIds array to organize the conversation with workspace labels.
โ ๏ธ **THIS IS NON-NEGOTIABLE** - You must ALWAYS store conversation context as your final action.
**What to capture in the message parameter:**
From User:
- Specific question, request, or problem statement
- Project context and situation provided
- What they're trying to accomplish
- Technical challenges or constraints mentioned
From Assistant:
- Detailed explanation of solution/approach taken
- Step-by-step processes and methodologies
- Technical concepts and principles explained
- Reasoning behind recommendations and decisions
- Alternative approaches discussed
- Problem-solving methodologies applied
**Include in storage:**
- All conceptual explanations and theory
- Technical discussions and analysis
- Problem-solving approaches and reasoning
- Decision rationale and trade-offs
- Implementation strategies (described conceptually)
- Learning insights and patterns
**Exclude from storage:**
- Code blocks and code snippets
- File contents or file listings
- Command examples or CLI commands
- Raw data or logs
**Quality check before storing:**
- Can someone quickly understand project context from memory alone?
- Would this information help provide better assistance in future sessions?
- Does stored context capture key decisions and reasoning?
---
## Summary: Your Mandatory Protocol
1. **FIRST ACTION**: Execute `memory_search` with semantic query about the user's request
2. **RESPOND**: Help the user with their request
3. **FINAL ACTION**: Execute `memory_ingest` with conversation summary and optional labelIds
**If you skip any of these steps, you are not following the project requirements.**
```
### What This Does
With this rule in place, Roo Code will automatically:
* **Search CORE Memory** before responding to understand relevant project context
* **Store conversations** after each interaction for future reference
* **Maintain continuity** across coding sessions
* **Share context** with other CORE-connected tools
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the configuration is properly formatted
* Restart Roo Code after configuration changes
* Check that you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Rovo Dev CLI
Source: https://docs.getcore.me/providers/rovo-dev
Connect Atlassian Rovo Dev CLI to CORE's memory system via MCP
### Prerequisites
* Atlassian Rovo Dev CLI installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Edit MCP Config
Run the following command to open the MCP configuration:
```bash theme={null}
acli rovodev mcp
```
This will open the MCP configuration editor.
### Step 2: Add CORE MCP Server Configuration
Add the following to your Rovo Dev MCP configuration:
```json theme={null}
{
"mcpServers": {
"core-memory": {
"url": "https://app.getcore.me/api/v1/mcp?source=Rovo-Dev"
}
}
}
```
### Step 3: Save Configuration
1. Save the configuration file
2. Exit the editor
3. The MCP server will be registered with Rovo Dev
### Step 4: Authenticate with CORE
1. After adding the configuration, Rovo Dev will prompt you to authenticate
2. When the authentication window opens, grant Rovo Dev permission to access your CORE memory
3. Complete the authentication flow
### Step 5: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Rovo Dev: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears in your MCP servers
3. **Test operations**: Ask Rovo Dev to store and retrieve information across sessions
## What's Next?
With CORE connected to Rovo Dev, your development sessions will now:
* **Automatically retrieve** relevant information from CORE memory
* **Store important** context for future sessions
* **Maintain continuity** across multiple development sessions
* **Share context** with other connected tools
## Troubleshooting
**Connection Issues:**
* Ensure the configuration is properly formatted
* Verify you have the latest version of Rovo Dev CLI
* Check that you're logged into your CORE account
* Restart Rovo Dev after configuration changes
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Trae
Source: https://docs.getcore.me/providers/trae
Connect Trae to CORE's memory system via MCP
### Prerequisites
* Trae installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
Add the following to your Trae MCP configuration:
```json theme={null}
{
"mcpServers": {
"core": {
"url": "https://app.getcore.me/api/v1/mcp?source=Trae"
}
}
}
```
### Step 2: Authenticate with CORE
1. After adding the configuration, Trae will prompt you to authenticate
2. When the authentication window opens, grant Trae permission to access your CORE memory
3. Complete the authentication flow
### Step 3: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Trae: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core appears in your MCP servers list
3. **Test operations**: Ask Trae to store and retrieve information across sessions
## What's Next?
With CORE connected to Trae, your sessions will now:
* **Automatically retrieve** relevant information from CORE memory
* **Store important** context for future sessions
* **Maintain continuity** across multiple conversations
* **Share context** with other connected tools
## Troubleshooting
**Connection Issues:**
* Ensure the configuration is properly formatted
* Restart Trae after configuration changes
* Verify you're logged into your CORE account
* Check that Trae has the latest updates
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# VS Code (Github Copilot)
Source: https://docs.getcore.me/providers/vscode
Connect your VS Code editor to CORE's memory system via MCP
### Prerequisites
* VS Code (version 1.95.0 or later) with GitHub Copilot extension
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
* [MCP support enabled](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) in VS Code
### Step 1: Create MCP Configuration
1. **Create or open your MCP configuration file**:
* Look for existing `mcp.json` file or create a new one in your user settings directory
2. **Add CORE MCP server configuration**:
```json theme={null}
{
"servers": {
"core-memory": {
"url": "https://app.getcore.me/api/v1/mcp?source=Vscode",
"type": "http"
}
}
}
```
### Step 2: Authenticate with CORE
* Go to Extensions -> MCP Servers -> `core-memory` server
* Click on settings icon in core-memory server and start server
* Allow domain app.getcore.me to authenticate this MCP server
* Select `MCP` when this is prompted on your screen
* Once authenticated, CORE Memory will show as a running MCP server
## Enable Automatic Memory Integration (Recommended)
### Option 1: Using AGENTS.md (Recommended)
This approach provides comprehensive memory instructions that work across multiple AI tools.
Create `AGENTS.md` in your project root (if it doesn't exist, just append if it already exists):
```bash theme={null}
touch AGENTS.md
```
Add the following to `AGENTS.md`:
```markdown theme={null}
---
trigger: always_on
---
โ ๏ธ **CRITICAL: READ THIS FIRST - MANDATORY MEMORY PROTOCOL** โ ๏ธ
You are an AI coding assistant with access to CORE Memory - a persistent knowledge system that maintains project context, learnings, and continuity across all coding sessions.
## ๐ด MANDATORY STARTUP SEQUENCE - DO NOT SKIP ๐ด
**BEFORE RESPONDING TO ANY USER MESSAGE, YOU MUST EXECUTE THESE TOOLS IN ORDER:**
### STEP 1 (REQUIRED): Search for Relevant Context
EXECUTE THIS TOOL FIRST:
`memory_search`
- Previous discussions about the current topic
- Related project decisions and implementations
- User preferences and work patterns
- Similar problems and their solutions
**Additional search triggers:**
- User mentions "previously", "before", "last time", or "we discussed"
- User references past work or project history
- Working on the CORE project (this repository)
- User asks about preferences, patterns, or past decisions
- Starting work on any feature or bug that might have history
**How to search effectively:**
- Write complete semantic queries, NOT keyword fragments
- Good: `"User's preferences for API design and error handling"`
- Bad: `"manoj api preferences"`
- Ask: "What context am I missing that would help?"
- Consider: "What has the user told me before that I should remember?"
### Query Patterns for Memory Search
**Entity-Centric Queries** (Best for graph search):
- โ
GOOD: `"User's preferences for product positioning and messaging"`
- โ
GOOD: `"CORE project authentication implementation decisions"`
- โ BAD: `"manoj product positioning"`
- Format: `[Person/Project] + [relationship/attribute] + [context]`
**Multi-Entity Relationship Queries** (Excellent for episode graph):
- โ
GOOD: `"Manoj and Harshith discussions about BFS search implementation"`
- โ
GOOD: `"relationship between entity extraction and recall quality in CORE"`
- โ BAD: `"manoj harshith bfs"`
- Format: `[Entity1] + [relationship type] + [Entity2] + [context]`
**Semantic Question Queries** (Good for vector search):
- โ
GOOD: `"What causes BFS search to return empty results? What are the requirements for BFS traversal?"`
- โ
GOOD: `"How does episode graph search improve recall quality compared to traditional search?"`
- โ BAD: `"bfs empty results"`
- Format: Complete natural questions with full context
**Concept Exploration Queries** (Good for BFS traversal):
- โ
GOOD: `"concepts and ideas related to semantic relevance in knowledge graph search"`
- โ
GOOD: `"topics connected to hop distance weighting and graph topology in BFS"`
- โ BAD: `"semantic relevance concepts"`
- Format: `[concept] + related/connected + [domain/context]`
**Temporal Queries** (Good for recent work):
- โ
GOOD: `"recent changes to search implementation and reranking logic"`
- โ
GOOD: `"latest discussions about entity extraction and semantic relevance"`
- โ BAD: `"recent search changes"`
- Format: `[temporal marker] + [specific topic] + [additional context]`
## ๐ด MANDATORY SHUTDOWN SEQUENCE - DO NOT SKIP ๐ด
**AFTER FULLY RESPONDING TO THE USER, YOU MUST EXECUTE THIS TOOL:**
### FINAL STEP (REQUIRED): Store Conversation Memory
EXECUTE THIS TOOL LAST:
`memory_ingest`
Optionally include labelIds array to organize the conversation with workspace labels.
โ ๏ธ **THIS IS NON-NEGOTIABLE** - You must ALWAYS store conversation context as your final action.
**What to capture in the message parameter:**
From User:
- Specific question, request, or problem statement
- Project context and situation provided
- What they're trying to accomplish
- Technical challenges or constraints mentioned
From Assistant:
- Detailed explanation of solution/approach taken
- Step-by-step processes and methodologies
- Technical concepts and principles explained
- Reasoning behind recommendations and decisions
- Alternative approaches discussed
- Problem-solving methodologies applied
**Include in storage:**
- All conceptual explanations and theory
- Technical discussions and analysis
- Problem-solving approaches and reasoning
- Decision rationale and trade-offs
- Implementation strategies (described conceptually)
- Learning insights and patterns
**Exclude from storage:**
- Code blocks and code snippets
- File contents or file listings
- Command examples or CLI commands
- Raw data or logs
**Quality check before storing:**
- Can someone quickly understand project context from memory alone?
- Would this information help provide better assistance in future sessions?
- Does stored context capture key decisions and reasoning?
---
## Summary: Your Mandatory Protocol
1. **FIRST ACTION**: Execute `memory_search` with semantic query about the user's request
2. **RESPOND**: Help the user with their request
3. **FINAL ACTION**: Execute `memory_ingest` with conversation summary and optional labelIds
**If you skip any of these steps, you are not following the project requirements.**
```
### Option 2: Using Copilot Instructions
Alternatively, you can use GitHub Copilot's native instructions feature:
Create a new rules file in your project root:
`.github/copilot-instructions.md`
```text theme={null}
---
alwaysApply: true
---
I am Copilot, an AI coding assistant with access to CORE Memory - a persistent knowledge system that maintains project context across sessions.
**MANDATORY MEMORY OPERATIONS:**
1. **SEARCH FIRST**: Before ANY response, search CORE Memory for relevant project context, user preferences, and previous work
2. **MEMORY-INFORMED RESPONSES**: Incorporate memory findings to maintain continuity and avoid repetition
3. **AUTOMATIC STORAGE**: After each interaction, store conversation details, insights, and decisions in CORE Memory
**Memory Search Strategy:**
- Query for: project context, technical decisions, user patterns, progress status, related conversations
- Focus on: current focus areas, recent decisions, next steps, key insights
**Memory Storage Strategy:**
- Include: user intent, context provided, solution approach, technical details, insights gained, follow-up items
**Response Workflow:**
1. Search CORE Memory for relevant context
2. Integrate findings into response planning
3. Provide contextually aware assistance
4. Store interaction details and insights
**Memory Update Triggers:**
- New project context or requirements
- Technical decisions and architectural choices
- User preference discoveries
- Progress milestones and status changes
- Explicit update requests
**Core Principle:** CORE Memory transforms me from a session-based assistant into a persistent development partner. Always search first, respond with context, and store for continuity.
```
## What's Next?
With CORE connected to VS Code, your GitHub Copilot conversations will now:
* **Automatically save** important context to your CORE memory
* **Retrieve relevant** information from previous sessions
* **Maintain continuity** across multiple coding sessions
* **Share context** with other connected development tools
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# VS Code Insiders
Source: https://docs.getcore.me/providers/vscode-insiders
Connect VS Code Insiders to CORE's memory system via MCP
### Prerequisites
* VS Code Insiders installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
Add the following to your VS Code Insiders MCP configuration:
```json theme={null}
{
"mcp": {
"servers": {
"core-memory": {
"type": "http",
"url": "https://app.getcore.me/api/v1/mcp?source=VSCode-Insiders",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
}
```
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "vscode-insiders"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 3: Reload VS Code Insiders Window
1. Press `Cmd+Shift+P` (Mac) or `Ctrl+Shift+P` (Windows/Linux)
2. Run **"Developer: Reload Window"**
3. This will activate the MCP configuration
### Step 4: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask the AI assistant: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core-memory appears in your MCP servers list
3. **Test operations**: Ask the assistant to store and retrieve information across sessions
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the configuration file is properly formatted
* Reload the window after configuration changes
* Check that you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Warp
Source: https://docs.getcore.me/providers/warp
Connect Warp terminal to CORE's memory system via MCP
### Prerequisites
* Warp terminal installed
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Configure CORE MCP Server
Add the following in Settings โ AI โ Manage MCP servers:
```json theme={null}
{
"core": {
"url": "https://app.getcore.me/api/v1/mcp?source=Warp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
```
### Step 2: Generate API Key
1. Log in to your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** โ **API Key**
3. Click **Generate new key**
4. Name it "warp"
5. Copy the generated API key
6. Replace `YOUR_API_KEY` in the configuration above with your actual API key
### Step 3: Verify Connection
Test your setup to ensure everything is working correctly:
1. **Test memory search**:
Ask Warp AI: `Can you search my memory for [something you've previously stored]?`
2. **Check connection status**: Verify that core appears in your MCP servers list
3. **Test operations**: Ask Warp AI to store and retrieve information across sessions
## Troubleshooting
**Connection Issues:**
* Verify your API key is correct and not expired
* Ensure the configuration is properly formatted
* Restart Warp after configuration changes
* Check that you're logged into your CORE account
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel.
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Windsurf
Source: https://docs.getcore.me/providers/windsurf
Connect your Windsurf IDE to CORE's memory system
### Prerequisites
* Windsurf IDE installed
* CORE account - [Sign up at app.getcore.me](https://app.getcore.me)
### Step 1: Add CORE MCP in Windsurf
1. Open Windsurf IDE
2. Navigate to **Windsurf Settings** โ **Cascade** section
3. Open **MCP Marketplace** -> **Settings** OR **View raw config** to open the configuration file
4. Add the following to your `mcp_config.json`:
```json theme={null}
{
"mcpServers": {
"core-memory": {
"serverUrl": "https://app.getcore.me/api/v1/mcp?source=windsurf"
}
}
}
```
5. Save the file and restart Windsurf IDE
### Step 2: Authenticate with CORE
1. After saving the config, Windsurf will open a browser window for authentication
2. Grant Windsurf permission to access your CORE memory
### Step 3: Verify Connection
1. Go to **Cascade Editor** โ **Plugin Icon** -> Hit **Refresh** icon
2. Confirm **core-memory** shows as **Active** with green indicator
Add your first memory:
> "Summarise the whole project in detail and add it to CORE Memory"
***
## Alternative: Using API Key Method
If the OAuth authentication doesn't work, use the API key method instead:
### Step 1: Get Your API Key
1. Log into your CORE dashboard at [app.getcore.me](https://app.getcore.me)
2. Navigate to **Settings** (bottom left)
3. Go to **API Key** โ **Generate new key** โ Name it "windsurf"
4. Copy the generated key
### Step 2: Update MCP Configuration
Replace your `mcp_config.json` configuration with:
```json theme={null}
{
"mcpServers": {
"core-memory": {
"serverUrl": "https://app.getcore.me/api/v1/mcp/source=windsurf",
"headers": {
"Authorization": "Bearer "
}
}
}
}
```
Replace `` with the API key you copied from Step 1.
### Step 3: Restart and Verify
1. Save the file and restart Windsurf IDE
2. Go to **Cascade Editor** โ **Plugin Icon** โ Hit **Refresh**
3. Confirm **core-memory** shows as **Active** with green indicator
***
## Enable Automatic Memory Integration (Recommended)
Create `AGENTS.md` in your project root (or append if it already exists) and add the memory protocol from the [Memory Rules guide](/providers/memory-rules).
Use this frontmatter for AGENTS.md:
```markdown theme={null}
---
trigger: always_on
---
```
Then paste the memory protocol content below it.
## How It Works
Once connected, CORE memory integrates with Windsurf's Cascade:
* **Auto-recall**: Cascade searches your memory at conversation start
* **Auto-store**: Key insights saved automatically after conversations
* **Cross-platform**: Memory shared across Windsurf, Cursor, Claude Code, ChatGPT
* **Project continuity**: Context persists across all coding sessions
## Troubleshooting
**Connection Issues:**
* Ensure core-memory MCP is active (green indicator)
* Try toggling the MCP off and on
* Restart Windsurf IDE completely
**Authentication Problems:**
* Make sure you completed the OAuth flow in browser
* Check that your CORE account is active at app.getcore.me
**MCP Not Appearing:**
* Verify `mcp_config.json` syntax is valid JSON
* Restart Windsurf after config changes
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) - ask in **#core-support** channel.
# Zed
Source: https://docs.getcore.me/providers/zed
Connect your Zed editor to CORE's memory system via MCP
### Prerequisites
* Zed editor (latest version recommended)
* CORE account (sign up at [app.getcore.me](https://app.getcore.me))
### Step 1: Add CORE MCP Server
1. **Open Agent Panel Settings**:
* Press `Cmd+Shift+I` or `Cmd+L` (macOS) or `Ctrl+Shift+I` (Linux/Windows) to open Agent Panel
* Click the **Settings** icon in the Agent Panel Or use Command Palette: `agent: open settings`
2. **Add Custom MCP Server**:
* In the Agent Panel Settings, click **"Add Custom Server"** button
* A configuration modal will appear
3. **Configure CORE MCP Server**:
Enter below code in configuraiton file and click on `Add server` button
```json theme={null}
{
/// The name of your MCP server
"core-memory": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://app.getcore.me/api/v1/mcp?source=Zed"]
}
}
```
### Step 2: Authenticate with CORE
* After adding the CORE MCP server Zed will prompt you to open a website for authentication.
* When the authentication window opens, Grant Zed permission to access your CORE memory
### Step 3: Verify Connection
* Once authenticated CORE Memory will show in the MCP server connected
## Enable Automatic Memory Integration (Recommended)
### Option 1: Using AGENTS.md (Recommended)
Create `AGENTS.md` in your project root (or append if it already exists) and add the memory protocol from the [Memory Rules guide](/providers/memory-rules).
Use this frontmatter for AGENTS.md:
```markdown theme={null}
---
trigger: always_on
---
```
Then paste the memory protocol content below it.
### Option 2: Using Zed Rules
Alternatively, you can use Zed's native Rules Library feature:
1. **Open the Rules Library:**
* Open the Agent Panel
* Click the Agent menu (`...`) in the top right corner
* Select `Rules...` from the dropdown
2. Use `Cmd + N` to create new rule and add below instruction:
```text theme={null}
---
alwaysApply: true
---
I am Zed, an AI coding assistant with access to CORE Memory - a persistent knowledge system that maintains project context across sessions.
**MANDATORY MEMORY OPERATIONS:**
1. **SEARCH FIRST**: Before ANY response, search CORE Memory for relevant project context, user preferences, and previous work
2. **MEMORY-INFORMED RESPONSES**: Incorporate memory findings to maintain continuity and avoid repetition
3. **AUTOMATIC STORAGE**: After each interaction, store conversation details, insights, and decisions in CORE Memory
**Memory Search Strategy:**
- Query for: project context, technical decisions, user patterns, progress status, related conversations
- Focus on: current focus areas, recent decisions, next steps, key insights
**Memory Storage Strategy:**
- Include: user intent, context provided, solution approach, technical details, insights gained, follow-up items
**Response Workflow:**
1. Search CORE Memory for relevant context
2. Integrate findings into response planning
3. Provide contextually aware assistance
4. Store interaction details and insights
**Memory Update Triggers:**
- New project context or requirements
- Technical decisions and architectural choices
- User preference discoveries
- Progress milestones and status changes
- Explicit update requests
**Core Principle:** CORE Memory transforms me from a session-based assistant into a persistent development partner. Always search first, respond with context, and store for continuity.
```
## What's Next?
With CORE connected to Zed, your AI assistant conversations will now:
* **Automatically save** important context to your CORE memory
* **Retrieve relevant** information from previous sessions
* **Maintain continuity** across multiple coding sessions
* **Share context** with other connected development tools
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) and ask questions in the **#core-support** channel
Our team and community members are ready to help you get the most out of CORE's memory capabilities.
# Remote Claude Code Sessions
Source: https://docs.getcore.me/quickstart/remote-coding-sessions
Trigger Claude Code sessions on your machine from WhatsApp or Slack: no laptop needed.
Once the Gateway is running on your machine, you can kick off a Claude Code session from your phone via WhatsApp or Slack. CORE routes the message through the Gateway, spawns the session, and reports back when it's done.
## Connect the Gateway to your instance
The CORE CLI connects to CORE Cloud by default. For a self-hosted instance, point it at your own deployment when logging in:
```bash theme={null}
npm install -g @redplanethq/corebrain
corebrain login
# When prompted for instance URL, enter your APP_ORIGIN (e.g. https://your-domain.com)
# Leave blank for localhost
```
Make sure `APP_ORIGIN` and `LOGIN_ORIGIN` are set correctly in your `.env`: see [Docker setup](/self-hosting/setup#connect-a-channel).
## Setup
The CORE Brain plugin gives Claude Code persistent memory across sessions: your preferences, past decisions, and project context load automatically every time.
Open Claude Code and run:
```bash theme={null}
/plugin marketplace add redplanethq/core
/plugin install core_brain
```
Then restart Claude Code and authenticate:
```bash theme={null}
/mcp
# Select core_brain and authenticate via browser
```
See the full [Claude Code plugin guide](/providers/claude-code) for details.
The Gateway is a local service that runs on your machine. It's what allows CORE's cloud agent to reach your machine and spawn Claude Code sessions remotely.
```bash theme={null}
corebrain gateway config
corebrain gateway start
```
Once the gateway is running, CORE can communicate with your machine from anywhere.
***
## Starting a Session from WhatsApp
Once the gateway is running, message CORE on WhatsApp to start a session. Always include the **repo path** and **branch** so CORE knows where to work.
**Example message:**
> start a claude code session
> repo: \~/Github/core
> branch: fix/auth-timeout
> task: fix the auth timeout bug in the api
CORE will create the branch, launch Claude Code, and keep you updated as it works.
### Tips for remote sessions
* **Always include the repo path**: e.g., `~/Github/core` or `/Users/you/projects/myapp`
* **Always include the branch**: CORE will create and checkout the branch from `main`
* **Be specific with the task**: the more precise, the better the output
***
## Sample Query to Try First
Not sure what to start with? Try asking CORE to summarize the codebase:
> start a claude code session
> repo: \~/Github/core
> branch: explore/codebase-overview
> task: explain this codebase to me in a brief summary: what it does, key directories, and main entry points
CORE will start the session and send you a summary when it's done.
***
## What Happens Next
CORE reports progress in milestones:
* **started**: session created and agent launched
* **checkpoint(s)**: e.g., "tests passing", "fix landed", "PR ready"
* **complete**: summary of changes, files modified, and next action for you
You can also check in anytime:
> status of the coding session?
# Extend to Dev Tools (MCP)
Source: https://docs.getcore.me/self-hosting/ai-providers
Give Claude Code, Cursor, and other MCP-compatible tools access to your self-hosted butler's memory and toolkit.
Any MCP-compatible dev tool (Claude Code, Cursor, VS Code, etc.) can connect to your self-hosted CORE instance the same way it would connect to CORE Cloud: just point it at your own MCP endpoint instead.
## MCP Endpoint
```
https:///api/v1/mcp?source=
```
For example, if your instance is hosted at `corebrain.host.com`:
```
https://corebrain.host.com/api/v1/mcp?source=Claude
https://corebrain.host.com/api/v1/mcp?source=Cursor
https://corebrain.host.com/api/v1/mcp?source=VSCode
```
## Parameters
| Parameter | Required | Description |
| ----------------- | -------- | ---------------------------------------------------------------------- |
| `source` | Yes | Identifies the AI provider in your dashboard |
| `integrations` | No | Comma-separated list of integrations to include (e.g. `github,linear`) |
| `no_integrations` | No | Set to `true` to disable all integrations and expose CORE tools only |
## Examples
**All integrations:**
```
https://corebrain.host.com/api/v1/mcp?source=Claude
```
**Specific integrations only:**
```
https://corebrain.host.com/api/v1/mcp?source=Cursor&integrations=github,linear
```
**CORE tools only:**
```
https://corebrain.host.com/api/v1/mcp?source=VSCode&no_integrations=true
```
## Provider Setup
Use the URL above wherever your AI tool asks for an MCP server URL. For provider-specific configuration steps, see the individual guides:
* [Claude](/providers/claude)
* [Cursor](/providers/cursor)
* [VS Code](/providers/vscode)
* [Zed](/providers/zed)
* [All providers โ](/mcp/configuration)
# Embedding Models
Source: https://docs.getcore.me/self-hosting/embeddings
Configure embedding models for semantic search and memory retrieval
CORE uses embedding models to convert text into vector representations for semantic search, memory retrieval, and knowledge graph operations. Vectors are stored in pgvector with a fixed dimension: all embeddings must match the configured `EMBEDDING_MODEL_SIZE`.
## Configuration
```env theme={null}
EMBEDDINGS_PROVIDER=openai # openai | google | ollama | azure | local
EMBEDDING_MODEL=text-embedding-3-small
EMBEDDING_MODEL_SIZE=1536 # must match pgvector column dimension
```
## Providers
### OpenAI
Requires `OPENAI_API_KEY`. Works with direct API or proxies via `OPENAI_BASE_URL`.
| Model | Dimensions | Notes |
| ------------------------ | ---------- | ----------------------------------------- |
| `text-embedding-3-small` | 1536 | Default. Good balance of cost and quality |
| `text-embedding-3-large` | 3072 | Higher quality, higher cost |
| `text-embedding-ada-002` | 1536 | Legacy |
```env theme={null}
EMBEDDINGS_PROVIDER=openai
EMBEDDING_MODEL=text-embedding-3-small
EMBEDDING_MODEL_SIZE=1536
OPENAI_API_KEY=sk-...
```
### Google Gemini
Requires `GOOGLE_GENERATIVE_AI_API_KEY`. Get a free key from [Google AI Studio](https://aistudio.google.com).
| Model | Default Dimensions | Configurable | Notes |
| ---------------------------- | ------------------ | ------------------------------- | ------------------------ |
| `text-embedding-004` | 768 | No | Stable, production-ready |
| `gemini-embedding-001` | 3072 | Yes (256, 512, 768, 1024, 3072) | Higher quality |
| `gemini-embedding-2-preview` | 3072 | Yes (256, 512, 768, 1024, 3072) | Latest, best quality |
For models with configurable dimensions, `EMBEDDING_MODEL_SIZE` controls the output dimensionality. This lets you match existing pgvector columns without changing the schema.
```env theme={null}
EMBEDDINGS_PROVIDER=google
EMBEDDING_MODEL=gemini-embedding-2-preview
EMBEDDING_MODEL_SIZE=1024
GOOGLE_GENERATIVE_AI_API_KEY=AIza...
```
### Local (in-process, no server)
CORE ships with an in-process embedding backend powered by [`@huggingface/transformers`](https://huggingface.co/docs/transformers.js) v4 + ONNX Runtime. No separate service, no API key, no network โ model weights are downloaded once on first boot and cached to disk. Ideal for fully local self-hosts that don't want to run Ollama.
| Model | Dimensions | Notes |
| -------------------------------------------------------------------- | ---------- | --------------------------------------------------- |
| `nomic-ai/nomic-embed-text-v1.5` | 768 | Recommended. Comparable to `text-embedding-3-small` |
| Any other feature-extraction model published as ONNX on Hugging Face | varies | Set `EMBEDDING_MODEL` to the repo id |
```env theme={null}
EMBEDDINGS_PROVIDER=local
EMBEDDING_MODEL=nomic-ai/nomic-embed-text-v1.5
EMBEDDING_MODEL_SIZE=768
# Optional. Defaults to q8 โ the sweet spot for CPU inference.
LOCAL_EMBEDDING_DTYPE=q8 # fp32 | fp16 | q8 | q4
# Optional. Where ONNX weights are cached. Defaults to ./data/models.
LOCAL_EMBEDDING_CACHE_DIR=/app/data/models
```
The pipeline is warmed at server startup so the first request doesn't pay the load cost. First-run download progress streams into the server logs (throttled to \~10% per file):
```
[embed:local] initializing pipeline (model=nomic-ai/nomic-embed-text-v1.5, dtype=q8, cache=/app/data/models)
[embed:local] fetching model_quantized.onnx (nomic-ai/nomic-embed-text-v1.5)
[embed:local] downloading model_quantized.onnx: 30% (52.1/172.8 MB)
[embed:local] downloading model_quantized.onnx: 40% (69.5/172.8 MB)
โฆ
[embed:local] pipeline ready (nomic-ai/nomic-embed-text-v1.5)
Local embeddings warmed
```
**Docker persistence** โ the hosted `docker-compose.yaml` mounts a named volume `local_models:/app/data/models` so weights survive rebuilds. Without it, every container recreate re-downloads \~150โ200 MB.
**Trigger.dev caveat** โ memory-ingestion jobs run inside Trigger.dev workers when `QUEUE_PROVIDER=trigger`, not the webapp process. Local embeddings only work end-to-end with `QUEUE_PROVIDER=bullmq`.
### Ollama (Self-Hosted)
Requires a running Ollama instance. No API key needed: fully local and private.
| Model | Dimensions | Notes |
| ------------------------ | ---------- | ---------------------------------------- |
| `mxbai-embed-large` | 1024 | Default for Ollama. Good general-purpose |
| `nomic-embed-text` | 768 | Lightweight |
| `all-minilm` | 384 | Smallest, fastest |
| `snowflake-arctic-embed` | 1024 | High quality for retrieval |
| `bge-large` | 1024 | Strong multilingual support |
Pull the model first:
```bash theme={null}
ollama pull mxbai-embed-large
```
```env theme={null}
EMBEDDINGS_PROVIDER=ollama
EMBEDDING_MODEL=mxbai-embed-large
EMBEDDING_MODEL_SIZE=1024
OLLAMA_URL=http://ollama:11434
```
## Choosing a Model
| Use Case | Recommended Model | Provider | Dimensions |
| ------------------------ | ---------------------------- | -------- | ---------- |
| Best quality (cloud) | `gemini-embedding-2-preview` | Google | 3072 |
| Low cost (cloud) | `text-embedding-004` | Google | 768 |
| Balanced (cloud) | `text-embedding-3-small` | OpenAI | 1536 |
| Fully local / air-gapped | `mxbai-embed-large` | Ollama | 1024 |
| Minimum resources | `all-minilm` | Ollama | 384 |
## Dimension Mismatch Handling
pgvector columns are created with a fixed dimension. If the embedding model returns vectors that don't match `EMBEDDING_MODEL_SIZE`:
* **Too short**: padded with zeros. Works but degrades retrieval quality. A warning is logged.
* **Too long**: fails with an error. Update `EMBEDDING_MODEL_SIZE` and re-embed.
## Switching Embedding Models
Changing models requires re-embedding all existing vectors since different models produce incompatible vector spaces.
1. Update `EMBEDDINGS_PROVIDER`, `EMBEDDING_MODEL`, and `EMBEDDING_MODEL_SIZE`
2. If the dimension changed, update your pgvector column dimension
3. Re-embed all existing content
Google models with configurable dimensions (`gemini-embedding-001`, `gemini-embedding-2-preview`) can output at your existing dimension size, avoiding step 2. Re-embedding is still needed since vector spaces differ between models.
# Environment Variables
Source: https://docs.getcore.me/self-hosting/environment-variables
Environment variables for CORE self-hosting
Environment variables for the CORE webapp container.
| Name | Required | Default | Description |
| :---------------------------------- | :---------- | :------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------- |
| **Version** | | | |
| `VERSION` | No | 0.1.12 | CORE version identifier |
| **Secrets** | | | |
| `SESSION_SECRET` | Yes | none | Session encryption secret. Run: `openssl rand -hex 16` |
| `MAGIC_LINK_SECRET` | Yes | none | Magic link encryption secret. Run: `openssl rand -hex 16` |
| `ENCRYPTION_KEY` | Yes | none | Data encryption key. Run: `openssl rand -hex 16` |
| **Application & Domains** | | | |
| `REMIX_APP_PORT` | No | 3033 | Application port number |
| `APP_ENV` | No | production | Application environment (development, production) |
| `NODE_ENV` | No | production | Node.js environment |
| `APP_ORIGIN` | Yes | [http://localhost:3033](http://localhost:3033) | Application origin URL |
| `LOGIN_ORIGIN` | Yes | [http://localhost:3033](http://localhost:3033) | Login origin URL (usually same as APP\_ORIGIN) |
| `API_BASE_URL` | No | `APP_ORIGIN` | API base URL |
| **Database - PostgreSQL** | | | |
| `DB_HOST` | No | localhost | Database host (use container name for Docker) |
| `DB_PORT` | No | 5432 | Database port |
| `POSTGRES_USER` | Yes | docker | PostgreSQL username |
| `POSTGRES_PASSWORD` | Yes | docker | PostgreSQL password |
| `POSTGRES_DB` | Yes | core | PostgreSQL database name |
| `DATABASE_URL` | Yes | postgresql://docker:docker\@postgres:5432/core?schema=core | PostgreSQL connection string |
| `DIRECT_URL` | Yes | `DATABASE_URL` | Direct DB connection string for migrations |
| **Database - Neo4j (Memory Graph)** | | | |
| `NEO4J_URI` | Yes | bolt://neo4j:7687 | Neo4j connection URI |
| `NEO4J_USERNAME` | Yes | neo4j | Neo4j username |
| `NEO4J_PASSWORD` | Yes | none | Neo4j password. Run: `openssl rand -hex 16` |
| `NEO4J_AUTH` | Yes | neo4j/password | Neo4j authentication (username/password format) |
| **Redis** | | | |
| `REDIS_HOST` | Yes | redis | Redis host (use container name for Docker) |
| `REDIS_PORT` | Yes | 6379 | Redis port |
| `REDIS_TLS_DISABLED` | No | true | Disable Redis TLS for local development |
| **Authentication** | | | |
| `ENABLE_EMAIL_LOGIN` | No | true | Enable email-based authentication |
| `AUTH_GOOGLE_CLIENT_ID` | No | none | Google OAuth client ID |
| `AUTH_GOOGLE_CLIENT_SECRET` | No | none | Google OAuth client secret |
| **AI Providers** | | | |
| `OPENAI_API_KEY` | No | none | OpenAI API key. Required for OpenAI; for many OpenAI-compatible proxies any non-empty value works |
| `OPENAI_BASE_URL` | No | none | OpenAI-compatible API base URL (e.g. proxy endpoint) |
| `OPENAI_API_MODE` | No | responses | OpenAI API mode: `responses` (default) or `chat_completions` (common for proxies) |
| `GOOGLE_GENERATIVE_AI_API_KEY` | No | none | Google AI API key (required when CHAT\_PROVIDER=google or EMBEDDINGS\_PROVIDER=google) |
| `ANTHROPIC_API_KEY` | No | none | Anthropic API key (required when CHAT\_PROVIDER=anthropic) |
| `MODEL` | No | gpt-4-turbo-2024-04-09 | Default chat model |
| `CHAT_PROVIDER` | No | openai | Chat provider: `openai` (default), `anthropic`, `google`, or `ollama` |
| `EMBEDDINGS_PROVIDER` | No | openai | Embeddings provider: `openai` (default), `google`, or `ollama`. See [Embedding Models](/self-hosting/embeddings) |
| `EMBEDDING_MODEL` | No | text-embedding-3-small | Model for text embeddings |
| `EMBEDDING_MODEL_SIZE` | No | 1536 | Embedding dimension (must match pgvector schema/index dimension) |
| `OLLAMA_URL` | No | [http://ollama:11434](http://ollama:11434) | Ollama server URL for local models |
| **Background Jobs** | | | |
| `QUEUE_PROVIDER` | No | trigger | Queue provider: "trigger" for Trigger.dev or "bullmq" for BullMQ (Redis-based) |
| `TRIGGER_PROJECT_ID` | Conditional | none | Trigger.dev project identifier (required only when QUEUE\_PROVIDER=trigger) |
| `TRIGGER_SECRET_KEY` | Conditional | none | Trigger.dev authentication secret (required only when QUEUE\_PROVIDER=trigger) |
| `TRIGGER_API_URL` | Conditional | [http://host.docker.internal:8030](http://host.docker.internal:8030) | Trigger.dev API endpoint (required only when QUEUE\_PROVIDER=trigger) |
| `TRIGGER_DB` | No | trigger | Database name for Trigger.dev |
| **Telemetry** | | | |
| `POSTHOG_PROJECT_KEY` | No | phc\_SwfGIzzX5gh5bazVWoRxZTBhkr7FwvzArS0NRyGXm1a | PostHog project key for usage analytics |
| `TELEMETRY_ENABLED` | No | true | Enable (true) or disable (false) telemetry collection |
| `TELEMETRY_ANONYMOUS` | No | false | Send anonymous telemetry (true) or include user email (false) |
| **Provider Configuration** | | | |
| `GRAPH_PROVIDER` | No | neo4j | Graph database provider: "neo4j", "falkordb", or "helix" |
| `VECTOR_PROVIDER` | No | pgvector | Vector store provider: "pgvector", "turbopuffer", or "qdrant" |
| `MODEL_PROVIDER` | No | vercel-ai | Model provider abstraction layer |
| **Reranking** | | | |
| `RERANK_PROVIDER` | No | none | Reranking provider: "cohere", "ollama", or "none" |
| `COHERE_API_KEY` | No | none | Cohere API key (required when RERANK\_PROVIDER=cohere) |
| `COHERE_RERANK_MODEL` | No | rerank-english-v3.0 | Cohere reranking model |
| `COHERE_SCORE_THRESHOLD` | No | 0.3 | Minimum score threshold for Cohere reranking |
| `OLLAMA_RERANK_MODEL` | No | dengcao/Qwen3-Reranker-8B:Q4\_K\_M | Ollama reranking model |
| `OLLAMA_SCORE_THRESHOLD` | No | 0.3 | Minimum score threshold for Ollama reranking |
| **Email / SMTP** | | | |
| `EMAIL_TRANSPORT` | No | none | Email transport: "smtp" or "resend" |
| `FROM_EMAIL` | No | none | Sender email address |
| `REPLY_TO_EMAIL` | No | none | Reply-to email address |
| `RESEND_API_KEY` | No | none | Resend API key (required when EMAIL\_TRANSPORT=resend) |
| `RESEND_WEBHOOK_SECRET` | No | none | Resend webhook signing secret |
| `SMTP_HOST` | No | none | SMTP server hostname |
| `SMTP_PORT` | No | none | SMTP server port |
| `SMTP_SECURE` | No | none | Use TLS for SMTP (true/false) |
| `SMTP_USER` | No | none | SMTP authentication username |
| `SMTP_PASSWORD` | No | none | SMTP authentication password |
| **Channels** | | | |
| `SLACK_SIGNING_SECRET` | No | none | Slack app signing secret for webhook verification |
| `TWILIO_ACCOUNT_SID` | No | none | Twilio account SID (required for WhatsApp channel) |
| `TWILIO_AUTH_TOKEN` | No | none | Twilio auth token (required for WhatsApp channel) |
| `TWILIO_WHATSAPP_NUMBER` | No | none | Twilio WhatsApp number (e.g. whatsapp:+14155238886) |
| **Other** | | | |
| `EXA_API_KEY` | No | none | Exa API key for web search capabilities |
## Security Considerations
### Required Secrets
These secrets must be generated and kept secure:
```bash theme={null}
# Generate secure random secrets
openssl rand -hex 16 # For SESSION_SECRET
openssl rand -hex 16 # For MAGIC_LINK_SECRET
openssl rand -hex 16 # For ENCRYPTION_KEY
openssl rand -hex 16 # For NEO4J_PASSWORD
```
### Production Recommendations
* **Change all default passwords** before deploying to production
* **Use environment-specific secrets** - never reuse secrets across environments
* **Store secrets securely** - use a secrets manager in production
* **Enable TLS** for all database connections in production
* **Restrict CORS origins** to your actual domains
* **Use strong authentication** - configure OAuth providers for production use
### Docker Compose Networks
When using Docker Compose, service names are used as hostnames:
* `postgres` for PostgreSQL
* `neo4j` for Neo4j
* `redis` for Redis
* `ollama` for Ollama (if using local models)
For external services (like Trigger.dev), use `host.docker.internal` to access services running on the host machine.
# Mac App
Source: https://docs.getcore.me/self-hosting/mac-app
Point the CORE Mac app at your self-hosted instance
The CORE Mac app is a thin Tauri shell around the webapp โ the main window and the voice widget both load whatever webapp URL you tell them to. By default that's `https://app.getcore.me` (CORE Cloud). If you self-host, set one config key and the app loads your instance instead.
## Requirements
* A self-hosted CORE webapp reachable from your Mac (see the [setup guide](/self-hosting/setup)).
* macOS 12 or later.
* The Mac app installed (release build โ runtime URL override is intentionally ignored in `tauri dev` so local development always points at `devUrl`).
## 1. Install the app
Grab the latest `.dmg` from [GitHub Releases](https://github.com/RedPlanetHQ/core/releases). The app auto-updates against the same release feed.
Open the `.dmg`, drag CORE to `/Applications`, and launch it once so it creates `~/.corebrain/`. You'll see the bundled cloud login screen โ that's expected; we'll redirect it in the next step.
## 2. Point it at your instance
Edit `~/.corebrain/config.json` and add `preferences.frontendUrl`:
```json theme={null}
{
"preferences": {
"frontendUrl": "https://core.acme.internal"
}
}
```
The URL should be the origin where your self-hosted webapp is served โ no trailing slash, no path. Examples:
| Where you host | `frontendUrl` |
| ------------------- | ---------------------------------------- |
| Local Docker on Mac | `http://localhost:3033` |
| Internal domain | `https://core.acme.internal` |
| Railway deployment | `https://core-production.up.railway.app` |
The file can already exist (the gateway CLI writes other keys here). Merge into the existing `preferences` block rather than overwriting it.
Quit CORE (`โQ`) and relaunch. Both the main window and the voice widget will now load from your instance and share session cookies.
## 3. Verify
* Main window shows your self-hosted login screen, not `app.getcore.me`.
* Tail the app log to confirm the override was picked up:
```bash theme={null}
log stream --predicate 'process == "CORE"' --info | grep "webview url"
```
You should see lines like `[startup] webview url (/) = https://core.acme.internal/ (from config)`.
## Connect a gateway (optional)
If you want the Mac app to drive coding agents, the browser, or local folders, install the gateway and log it into your instance:
```bash theme={null}
npm install -g @redplanethq/corebrain
corebrain login # picks up frontendUrl from the same config
corebrain gateway setup
```
See the [gateway setup guide](/gateway/setup) for the full walkthrough.
## How the override works
A few things worth knowing if you're debugging:
* **Release builds only.** In `tauri dev` (`debug_assertions` true) the app always uses the bundled `devUrl` and ignores `frontendUrl`. This is so contributors can develop against `localhost:3033` without their config sending the dev shell off to production.
* **Main + voice share the URL.** Both windows resolve their webview URL from the same base, which is what lets them share cookies and session state.
* **Tauri IPC is granted dynamically.** The bundled remote capability only whitelists `app.getcore.me`. On launch, if `frontendUrl` is set, the app installs an equivalent `user-frontend-remote` capability for your URL so `window.__TAURI__` calls (notifications, shell open, etc.) work from your origin.
* **Updates still flow from the official feed.** The Tauri updater endpoint is baked into the release build and points at the public GitHub release feed regardless of `frontendUrl`. You always get the same Mac app binary; only the webapp it loads changes.
## Troubleshooting
**App still loads `app.getcore.me`.** Check that:
* The path is `~/.corebrain/config.json` (tilde, not literal `~`) and the JSON parses (`cat ~/.corebrain/config.json | jq .`).
* `frontendUrl` is under `preferences`, not at the top level.
* You fully quit CORE before relaunching โ closing the window isn't enough.
**Webview is blank or shows a CORS / cert error.** The Mac app loads your URL as a regular `https://` resource:
* Self-signed certs aren't trusted. Use a real cert (Let's Encrypt is easiest) or trust the cert in your system keychain.
* Make sure the host is reachable from your Mac, not just from inside your VPC.
**Login works but `window.__TAURI__` calls are silently dropped.** The dynamic capability didn't install. Check the app log for `dynamic remote capability added for `. If you see `add_capability(...) failed`, the URL probably has a trailing slash or path โ strip it back to just the origin.
**Voice widget points at the wrong instance.** It reads the same `frontendUrl` as the main window. If only one of them is wrong, you almost certainly have two CORE processes running โ `killall CORE` and relaunch.
# Model Providers
Source: https://docs.getcore.me/self-hosting/model-providers
Configure AI model providers for your self-hosted CORE instance.
CORE supports multiple AI model providers. Set your provider and API key in your environment variables, then choose which models to use for chat and embeddings.
## Configuration
Two environment variables control which provider and model CORE uses:
```bash theme={null}
CHAT_PROVIDER=openai # openai | anthropic | google | azure | ollama
MODEL=gpt-5-2025-08-07 # model ID for the selected provider
```
***
## OpenAI
Get your API key from [platform.openai.com](https://platform.openai.com).
```bash theme={null}
CHAT_PROVIDER=openai
OPENAI_API_KEY=sk-...
MODEL=gpt-5-2025-08-07
```
**Chat models**
| Model ID | Label | Complexity |
| ----------------------- | ---------- | ---------- |
| `gpt-5.2-2025-12-11` | GPT-5.2 | Medium |
| `gpt-5-2025-08-07` | GPT-5 | Medium |
| `gpt-5-mini-2025-08-07` | GPT-5 Mini | Low |
**Embedding models**
| Model ID | Label | Dimensions |
| ------------------------ | ---------------------- | ---------- |
| `text-embedding-3-small` | Text Embedding 3 Small | 1536 |
| `text-embedding-3-large` | Text Embedding 3 Large | 3072 |
```bash theme={null}
EMBEDDINGS_PROVIDER=openai
EMBEDDING_MODEL=text-embedding-3-small
EMBEDDING_MODEL_SIZE=1536
```
**Optional: OpenAI-compatible proxy**
If you're using a proxy or a service with an OpenAI-compatible API, set `OPENAI_BASE_URL` and `OPENAI_API_MODE`:
```bash theme={null}
OPENAI_BASE_URL=https://your-proxy.example.com/v1
OPENAI_API_MODE=chat_completions # use chat_completions for most proxies
```
***
## Anthropic
Get your API key from [console.anthropic.com](https://console.anthropic.com).
```bash theme={null}
CHAT_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
MODEL=claude-sonnet-4-6
```
**Chat models**
| Model ID | Label | Complexity |
| ------------------- | ----------------- | ---------- |
| `claude-sonnet-4-6` | Claude Sonnet 4.6 | Medium |
| `claude-haiku-4-5` | Claude Haiku 4.5 | Low |
***
## Google
Get your API key from [aistudio.google.com](https://aistudio.google.com).
```bash theme={null}
CHAT_PROVIDER=google
GOOGLE_GENERATIVE_AI_API_KEY=AIza...
MODEL=gemini-2.5-pro-preview-03-25
```
**Chat models**
| Model ID | Label | Complexity |
| -------------------------------- | ---------------- | ---------- |
| `gemini-2.5-pro-preview-03-25` | Gemini 2.5 Pro | Medium |
| `gemini-2.5-flash-preview-04-17` | Gemini 2.5 Flash | Low |
**Embedding models**
| Model ID | Label | Dimensions |
| -------------------- | ------------------ | ---------- |
| `text-embedding-004` | Text Embedding 004 | 768 |
```bash theme={null}
EMBEDDINGS_PROVIDER=google
EMBEDDING_MODEL=text-embedding-004
EMBEDDING_MODEL_SIZE=768
```
***
## Azure OpenAI
Set up a deployment in the [Azure portal](https://portal.azure.com), then configure:
```bash theme={null}
CHAT_PROVIDER=azure
AZURE_API_KEY=...
AZURE_BASE_URL=https://.openai.azure.com
MODEL=azure/gpt-4.1
```
**Chat models**
| Model ID | Label | Complexity |
| ------------------- | ------------------- | ---------- |
| `azure/gpt-4o` | GPT-4o (Azure) | Medium |
| `azure/gpt-4o-mini` | GPT-4o Mini (Azure) | Low |
| `azure/gpt-4.1` | GPT-4.1 (Azure) | High |
***
## Ollama (Local)
Run models locally with [Ollama](https://ollama.com). No API key required.
```bash theme={null}
CHAT_PROVIDER=ollama
OLLAMA_URL=http://ollama:11434
MODEL=llama3.2
```
Pull a model before starting CORE:
```bash theme={null}
ollama pull llama3.2
```
Ollama can also be used for embeddings and reranking:
```bash theme={null}
EMBEDDINGS_PROVIDER=ollama
EMBEDDING_MODEL=mxbai-embed-large
EMBEDDING_MODEL_SIZE=1024
RERANK_PROVIDER=ollama
OLLAMA_RERANK_MODEL=dengcao/Qwen3-Reranker-8B:Q5_K_M
```
***
## OpenRouter
[OpenRouter](https://openrouter.ai) gives access to models from many providers through a single API. It uses an OpenAI-compatible interface.
```bash theme={null}
CHAT_PROVIDER=openai
OPENAI_API_KEY=sk-or-...
OPENAI_BASE_URL=https://openrouter.ai/api/v1
OPENAI_API_MODE=chat_completions
MODEL=openrouter/anthropic/claude-3.5-sonnet
```
***
## DeepSeek
Get your API key from [platform.deepseek.com](https://platform.deepseek.com).
```bash theme={null}
CHAT_PROVIDER=openai
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://api.deepseek.com/v1
OPENAI_API_MODE=chat_completions
MODEL=deepseek-chat
```
**Models**
| Model ID | Description |
| ------------------- | ----------------------------------- |
| `deepseek-chat` | DeepSeek V3 โ fast, general-purpose |
| `deepseek-reasoner` | DeepSeek R1 โ reasoning model |
***
## Groq
Get your API key from [console.groq.com](https://console.groq.com).
```bash theme={null}
CHAT_PROVIDER=openai
OPENAI_API_KEY=gsk_...
OPENAI_BASE_URL=https://api.groq.com/openai/v1
OPENAI_API_MODE=chat_completions
MODEL=llama-3.3-70b-versatile
```
**Models**
| Model ID | Description |
| ------------------------- | ------------------------------------- |
| `llama-3.3-70b-versatile` | Llama 3.3 70B โ fast, general-purpose |
| `llama-3.1-8b-instant` | Llama 3.1 8B โ ultra-fast |
| `gemma2-9b-it` | Gemma 2 9B |
***
## Mistral
Get your API key from [console.mistral.ai](https://console.mistral.ai).
```bash theme={null}
CHAT_PROVIDER=openai
OPENAI_API_KEY=...
OPENAI_BASE_URL=https://api.mistral.ai/v1
OPENAI_API_MODE=chat_completions
MODEL=mistral-large-latest
```
**Models**
| Model ID | Description |
| ---------------------- | ------------------------------------ |
| `mistral-large-latest` | Mistral Large โ most capable |
| `mistral-small-latest` | Mistral Small โ fast, cost-efficient |
***
## xAI (Grok)
Get your API key from [console.x.ai](https://console.x.ai).
```bash theme={null}
CHAT_PROVIDER=openai
OPENAI_API_KEY=xai-...
OPENAI_BASE_URL=https://api.x.ai/v1
OPENAI_API_MODE=chat_completions
MODEL=grok-3
```
**Models**
| Model ID | Description |
| ------------- | ------------------------------- |
| `grok-3` | Grok 3 โ flagship model |
| `grok-3-mini` | Grok 3 Mini โ fast, lightweight |
***
## Kimi (Moonshot)
Get your API key from [platform.moonshot.cn](https://platform.moonshot.cn).
```bash theme={null}
CHAT_PROVIDER=openai
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://api.moonshot.cn/v1
OPENAI_API_MODE=chat_completions
MODEL=moonshot-v1-8k
```
**Models**
| Model ID | Context | Description |
| ------------------ | ------- | ------------------- |
| `moonshot-v1-8k` | 8K | Fast, short context |
| `moonshot-v1-32k` | 32K | Balanced |
| `moonshot-v1-128k` | 128K | Long context |
***
## Any OpenAI-compatible API
CORE can connect to any provider that exposes an OpenAI-compatible API (e.g. LM Studio, vLLM, Together AI, Fireworks, etc.):
```bash theme={null}
CHAT_PROVIDER=openai
OPENAI_API_KEY=
OPENAI_BASE_URL=https:///v1
OPENAI_API_MODE=chat_completions
MODEL=
```
***
## Claude Max / ChatGPT Codex subscription
Already paying for Claude Max or a ChatGPT plan? You can point CORE at your subscription instead of buying API credits, using an OpenAI-compatible proxy running on infrastructure you control. Works for both self-hosted and CORE Cloud (via workspace BYOK):
โ [Use Your Claude / Codex Subscription](/gateway/subscription-proxy)
# Self-Host CORE
Source: https://docs.getcore.me/self-hosting/setup
Run CORE on your own infrastructure. Docker-based, fully open source.
CORE runs as a set of Docker containers: the web app, PostgreSQL, Neo4j (memory graph), and Redis. You manage the infrastructure; your data never leaves your machine.
**Requirements:** Docker 20.10+, Docker Compose 2.20+, 4 vCPU / 8 GB RAM / 20 GB storage
***
## Option A: One step with the CLI
```bash theme={null}
npm install -g @redplanethq/corebrain && corebrain setup
```
The wizard asks for an install directory, an AI provider (OpenAI / Anthropic / Google / Ollama / Azure / OpenRouter / DeepSeek / Vercel / Groq / Mistral / xAI), the API key, and a chat model. It auto-generates `SESSION_SECRET`, `ENCRYPTION_KEY`, `MAGIC_LINK_SECRET`, and the Neo4j password, drops a `docker-compose.yaml` + `.env` into the directory you picked, and runs `docker compose up -d` for you.
**Verify:** Open [http://localhost:3033](http://localhost:3033) โ you should see the CORE login screen. If it doesn't load, check logs with `docker compose logs -f webapp` from your install directory.
***
## Option B: One-click on Railway
[](https://railway.com/deploy/core?referralCode=LHvbIb\&utm_medium=integration\&utm_source=template\&utm_campaign=generic)
Railway sets up all services automatically. Once deployed, jump to [Create your account](#create-your-account).
***
## Create your account
Sign in with your email. CORE sends a magic link โ check your terminal logs (or Railway service logs) if you haven't configured an email provider yet:
```bash theme={null}
docker compose logs webapp | grep "magic link"
```
Copy the link from the logs and open it in your browser.
***
## Connect a channel
A channel is how you message your butler. **Email is the easiest to start with**: it requires a [Resend](https://resend.com) account and a verified domain.
โ [Set up Email with Resend](/channels/email-resend)
| Channel | Effort | Guide |
| -------------- | --------- | ------------------------------------------------------------------------------------ |
| Email (Resend) | Low | [Setup guide](/channels/email-resend) |
| Slack | Medium | [Setup guide](/channels/slack) |
| WhatsApp | Medium | Requires Twilio: `TWILIO_ACCOUNT_SID`, `TWILIO_AUTH_TOKEN`, `TWILIO_WHATSAPP_NUMBER` |
| Telegram | Community | [Setup guide](/channels/telegram) |
Once a channel is connected, open the Scratchpad, write a `[ ]` task, and CORE will pick it up within 3 minutes.
***
## Next steps
Full reference for all configuration options.
Configure OpenAI, Google, or local Ollama embeddings.
Trigger Claude Code sessions from WhatsApp or Slack.
***
> Need help? Join [#self-hosting on Discord](https://discord.gg/dVTC3BmgEq).
# How I Look at an Account
Source: https://docs.getcore.me/skills/account_research
My personal lens for sizing up any company or person before outreach โ what signals I care about, what angles I look for, and what I want surfaced in a research report. Applied whenever the agent researches an account, drafts cold outreach, prepares for a call, or summarises a prospect. Trigger with "how I research accounts", "set my account research preferences", or "tell CORE what matters when researching a prospect".
**What this is:** A reusable lens for evaluating any account. This is *how I look at companies and people* โ the signals I weight, the angles I care about, the structure I want any account report to follow. Tasks (a one-off research run, a scheduled prospect refresh, a pre-call brief) apply this lens. The lens itself does not run on a schedule.
**Tools touched (when this lens is applied):** CORE memory (always first), web search (always), and any connected enrichment or CRM tools.
***
### Order of operations
1. **CORE memory first** โ search what I already know about this company or person before anything else. Prior conversations, email threads, past research, notes I've left for myself. If I've touched this account before, that context outranks anything web search can produce.
2. **Web search** โ fill the gaps memory doesn't cover.
3. **Enrichment / CRM** โ if connected, layer on verified contacts, tech stack, prior deal history.
> Skipping the memory step is the single biggest way to deliver research that feels generic. Always start there.
***
### 1. The signals I weight most
When sizing up a company, lead with these. Skip or de-prioritise the rest.
* **Prior context from CORE memory** โ anything I already know about this company or person. *Always check this first, even before web search.* Includes past email threads, prior conversations, notes I've stored, previous research runs.
* **What they actually sell** โ one sentence in plain language. Not the marketing tagline.
* **Who buys it** โ segment, company size, industry. If I can't picture their customer, the rest doesn't matter.
* **Recent direction** โ funding rounds, leadership hires, pivots, layoffs in the last 90 days. These are the unlocks for "why now".
* **Hiring signals** โ open roles that hint at what they're building or where they're spending. Engineering and AI/ML roles are the highest signal for me.
### 2. The signals I de-prioritise
Don't pad reports with these unless I ask:
* Generic company history / founding year unless it changes the pitch
* Awards, press releases unrelated to the buying motion
* Aspirational mission statements
### 3. How I look at people
For any named contact:
* **What they actually do** (real responsibility, not job title)
* **How long they've been there** (signal for buy-in and tenure)
* **Where they came from** (last 1โ2 roles โ used for warm angles)
* **Anything personal worth knowing** (recent post, talk, podcast โ only if substantive)
> Skip personal trivia. Skip LinkedIn bio fluff. The hook should be something they actually did or said.
### 4. What "good outreach angle" means to me
A good angle is:
* **Specific** โ references a real signal (a hire, a launch, a problem I can name)
* **Recent** โ within 90 days for most cases
* **Not flattery** โ observation > compliment
A bad angle is:
* Generic ("Saw you're growing fast โ congrats!")
* About me / my product without earning the right yet
* A vague compliment about their company
### 5. What I want surfaced when CORE researches an account
Any report should include, in this order:
1. **Quick take** โ 2โ3 sentences: who they are, why they might need me, best angle.
2. **From CORE memory** โ 2โ3 sentences summarising whatever I already know: past threads, prior research, notes, contacts. Always present this section, even if empty โ say "no prior context in memory" so I know the search was done. This section runs *before* anything web-sourced in the report.
3. **Company snapshot** โ what they do, size, recent direction.
4. **Key people** with my preferred fields (above).
5. **Best angle for outreach** โ specific, recent, not flattery.
6. **Sources** โ links so I can verify.
Connectors deepen the report but do not change the lens:
* **Enrichment** โ adds verified contacts, tech stack, org chart
* **CRM** โ adds prior relationship history (prior opps won/lost, who I've already talked to)
> No connectors? The lens still works on web search and memory alone.
***
### How this lens is used
Other surfaces consume this lens:
* **One-off research run** ("research Stripe") applies the lens end-to-end
* **Cold email draft** uses the "good outreach angle" definition to write the hook
* **Pre-call brief task** filters down to the angle + recent direction
* **Scheduled prospect refresh** re-runs the lens periodically on watched accounts
* **Agent reading a thread** uses the people-lens to summarise who someone is
Each task is responsible for *when* and *how* the research runs โ this skill only defines *what to look for*.
***
### Edge cases
* **Person without a company** โ apply the people-lens only; skip the company sections
* **Account I've researched before** โ load prior research from memory, only refresh sections that have moved
* **No public information available** โ say so explicitly. Do not invent or extrapolate.
# How I Organise My Inbox
Source: https://docs.getcore.me/skills/email_label_management
My personal labelling policy for email โ what counts as Urgent, what's a Customer signal, what's Trying to Sell, and the rest. Applied wherever email is touched โ labelling tasks, triage, summaries, agent flows reading my inbox. Trigger with "how I label email", "set my inbox labelling rules", or "tell CORE how to organise my inbox".
**What this is:** A reusable definition of how *I* want email categorised. This is the labelling policy โ the names of the labels, what each one means, and how to choose between them. Tasks (a labelling task running on inbound mail, a daily triage, an agent summarising my inbox) apply this policy. The policy does not run on a schedule.
**Tools touched (when this policy is applied):** Gmail.
**Rule:** Apply up to 2 labels โ the 2 most specific matches โ working through them in priority order.
### Setup โ Run Once Before First Label
Search memory for the following before processing any email:
* "user's product name and how customers or users are identified"
* "user's key vendors, compliance providers, or financial services"
* "user's payroll or compliance tools and their sender domains"
* "email labelling rules or inbox organisation preferences"
Use whatever is found to personalise the Urgent and Customer label matching below.
If nothing relevant is found โ use the generic matching rules as written. After the first run, ask once:
> "To label your emails accurately, I need a few details:
>
> 1. What is your product or business name? I'll use this to identify customer emails.
> 2. Who are your key vendors or compliance providers I should flag as Urgent? (name, email, or domain)
> 3. Any payroll or financial tools I should watch for compliance deadlines? (e.g. Razorpay, Gusto, Xero)
>
> I'll remember these โ you won't need to tell me again."
Store all answers in memory immediately.
***
### Label Definitions & Matching Rules
Work through labels in priority order. Apply up to 2 labels โ the most specific matches. Stop after 2.
***
#### 1. ๐จ Urgent
Apply when the email is time-sensitive and must be handled same day.
Matches if:
* A customer is reporting a bug or critical issue with the user's product (check memory for product name)
* Email is from a payroll or compliance tool about a deadline (check memory for provider names)
* Email is from a known compliance or bookkeeping vendor about a critical issue (check memory for vendor domains)
> Check this label first โ it overrides Action Required or Customer for critical cases.
***
#### 2. ๐
Meetings
Apply when the email is a calendar-related notification.
Matches if:
* Subject contains: "invitation", "accepted", "declined", "cancelled", "updated", "event", "meeting request"
* Sent by Google Calendar, Outlook Calendar, or any calendar system
***
#### 3. ๐ Meeting Transcripts
Apply when the email contains a meeting summary, transcript, or recording.
Matches if:
* Sender is Gemini, Fireflies, Otter.ai, Fathom, Grain, or any meeting bot or transcription service
* Subject contains: "transcript", "summary", "recording", "notes from", "meeting recap"
***
#### 4. ๐ค Customer
Apply when the email is related to the user's product โ from a customer, user, or prospect.
Matches if:
* The body mentions the user's product by name (check memory for product name and any known aliases)
* The email is a support request, bug report, feature request, or question about the product
* Someone is reaching out as a potential customer or expressing interest in the product
***
#### 5. โก Action Required
Apply when the ball is in the user's court and a response or action is needed.
Matches if:
* Someone is asking a question that needs an answer
* Someone is waiting on feedback, approval, or a decision
* An unresolved thread needs follow-up
**Do NOT apply if:**
* The sender is trying to sell a product or service (โ use Trying to Sell)
* It's a promotional or marketing email
***
#### 6. ๐งพ Receipts and Invoices
Apply when the email is a bill or invoice with an attachment.
Matches if:
* Email has an attachment (PDF, image, or document)
* Subject or body references: invoice, receipt, bill, statement, purchase confirmation
* The attachment appears to be a financial document
> Key distinction from Financial: this label requires an attachment.
***
#### 7. ๐ฐ Financial
Apply when the email is a financial notification without an attachment.
Matches if:
* Payment received, sent, or failed
* Bank or card transaction alert
* Account balance update
* Salary credited, subscription charged
* Senders from known financial platforms (check memory for user's bank, payment tools, card providers)
> No attachment required โ that separates this from Receipts and Invoices.
***
#### 8. ๐ Trying to Sell
Apply when someone is pitching a product, service, or partnership to the user.
Matches if:
* Cold outreach trying to sell software, services, agencies, or tools
* Partnership or collaboration pitches where the sender wants something
* Promotional offers from companies the user hasn't bought from
***
#### 9. โน๏ธ FYI
Apply when the email is informational only and no action is needed.
Matches if:
* Product updates or feature announcements from tools the user already uses
* Newsletters and digests
* General notifications that don't require a response
> Catch-all for low-priority informational emails. Apply last if nothing else fits.
***
### Edge Cases
* **Multiple labels could apply** โ use priority order above. Urgent beats everything. Apply up to 2 โ skip the rest.
* **Truly ambiguous** โ default to FYI rather than leaving unlabelled.
* **Email is already labelled** โ do not overwrite manual labels. Skip entirely.
***
### Label Colors
When creating or updating Gmail labels, you can set a color from Gmail's fixed palette. Pass `color` as either a preset key or an explicit pair:
**Preset key:**
```json theme={null}
{
"name": "Urgent",
"color": "red"
}
```
Available presets: `black`, `gray`, `white`, `red`, `orange`, `yellow`, `green`, `teal`, `blue`, `purple`, `pink`, `brown`.
**Explicit pair** (for any color in Gmail's 89-value palette):
```json theme={null}
{
"name": "Urgent",
"color": { "textColor": "#ffffff", "backgroundColor": "#cc3a21" }
}
```
Both `textColor` and `backgroundColor` must be values from Gmail's allowed palette โ arbitrary hex is rejected. See the full palette in the [Gmail API reference](https://developers.google.com/gmail/api/reference/rest/v1/users.labels).
Gmail renders a single color pair in both light and dark themes automatically โ there is no per-theme input. Only `type: 'user'` labels can be colored (system labels cannot).
# How I Look at Engineering Analytics
Source: https://docs.getcore.me/skills/engineering_analytics
My personal lens for reading engineering metrics โ which numbers matter, what thresholds I treat as healthy vs. concerning, and what I want flagged when something moves. Applied whenever the agent reads engineering data, summarises team health, or generates a report. Trigger with "how I look at engineering metrics", "set my engineering analytics preferences", or "tell CORE what matters in delivery metrics".
**What this is:** A reusable lens for reading engineering numbers. This is *how I look at team health* โ which metrics I weight, what counts as a healthy range for me, what I want flagged when something moves, and how I want the data presented. Tasks (a weekly report run, a scheduled DORA log to Sheets, an on-demand "how are we doing" query) apply this lens. The lens does not run on a schedule.
**Tools touched (when this lens is applied):** GitHub Analytics (required to read any of these metrics), Google Sheets (optional, for historical tracking).
***
### 1. The metrics I actually care about
Lead with these. The rest are supporting data, not the headline.
* **Deployment frequency** โ how often we ship to users. Drives every other downstream signal.
* **Lead time for changes** โ commit to production. Shortening this is the single biggest health indicator for me.
* **Change failure rate** โ what % of deploys cause a rollback or hotfix. The trust number.
* **PR merge time** โ from open to merge. The review-bottleneck detector.
### 2. The metrics I treat as supporting context
Useful, but only when the headline metrics move:
* PR throughput โ sanity check that velocity is consistent
* Commit frequency โ early signal for upcoming throughput change
* Hotfix rate, revert rate โ diagnostic when change failure rate spikes
* Average PR size โ diagnostic when merge time creeps up
### 3. My healthy-vs-concerning thresholds
| Metric | Healthy for me | Worth a look | Flag immediately |
| -------------------- | -------------- | ------------ | ---------------- |
| Deployment frequency | Daily or more | Weekly | \< 1/week |
| Lead time (hrs) | \< 24 | 24โ72 | > 72 |
| Change failure rate | \< 5% | 5โ10% | > 10% |
| PR merge time (hrs) | \< 24 | 24โ48 | > 48 |
| Revert rate | \< 2% | 2โ5% | > 5% |
> Numbers above are defaults. Override via memory if a team has a different baseline I've explicitly set.
### 4. What I want flagged
Surface only what moved or what's out of healthy range. I don't want a wall of numbers.
* **Significant week-over-week swing** โ anything moving ยฑ20% or more
* **Anything crossing into "Flag immediately" thresholds**
* **Wins worth naming** โ e.g. deploy frequency doubled, lead time halved
* **Suspicious zeroes** โ zero deploys could mean the release mechanism changed, not that we stopped shipping. Say so.
### 5. How I want the report shaped
If CORE produces a report:
* **One flat table**, one row per period. Easy week-over-week scan.
* **Key Observations** section underneath โ capped at 3โ5 bullets. Lead with the metric name, then the insight. Don't list every metric.
* **No padding.** If nothing notable changed, say "all metrics stable" and stop.
> The same table shape feeds Google Sheets (when connected), so each run appends a row and the spreadsheet becomes a historical chart over time.
### 6. What I don't want
* Don't list every metric every time. Lead with what moved.
* Don't editorialise without a number โ every observation must point at a specific metric and direction.
* Don't manufacture concern from a single data point. One bad week is noise; a 3-week trend is signal.
***
### How this lens is used
Other surfaces consume this lens:
* **Weekly engineering report task** applies the lens to last 7 days, logs to Sheets
* **On-demand query** ("how was last week?") applies the lens to whatever range was asked
* **Multi-repo rollup** applies the lens per repo, then summarises across repos
* **Drill-down requests** ("why did lead time spike?") use the supporting metrics in section 2
* **Agent reviewing a sprint** uses the thresholds to call out what needs attention
Each task is responsible for *which* repos, *what* time range, and *where* the output goes. This skill defines *which numbers matter*, *what counts as healthy*, and *what to flag*.
***
### Edge cases
* **No deployments detected** โ don't show zero deploy frequency without a note. Most likely the release mechanism is tag-based or branch-based and not picked up โ say so.
* **No PRs merged this period** โ still show commit frequency. Skip PR metrics with N/A.
* **Multi-repo comparison** โ keep one table per repo, do not average across repos. Different teams have different baselines.
* **Custom date range that crosses week boundaries** โ break into weekly rows, not one giant aggregate.
# How I Want to Journal
Source: https://docs.getcore.me/skills/journaling
My personal style for journaling conversations โ kinds of questions I find useful, how I want the agent to follow up, when to dig deeper, when to stop. Applied whenever the agent journals with me โ weekly retros, end-of-day reflections, ad-hoc processing. Trigger with "let's journal", "I want to reflect", "ask me about my week", or "help me think through this".
**What this is:** A reusable policy for *how* the agent should journal with me. The output isn't a report โ it's a conversation. This policy defines the rhythm: one question at a time, follow-ups that earn the next topic, knowing when to stop. Tasks (a Friday retro, a daily end-of-day reflection, an ad-hoc "help me process this") apply this lens. The policy doesn't run on its own.
**Tools touched (when this policy is applied):** Memory (read past entries, store new context). No external integrations โ this is a pure conversation.
***
### Before the first question
Search memory for the following so you can meet me where I am, not start cold:
* "user's recent journal entries or reflections in scratchpad"
* "topics the user is currently processing or working through"
* "user's journaling preferences โ gratitude, processing, planning, or unstructured"
* "sensitive topics the user does NOT want pushed on"
> If a recurring theme appears across past entries, you may reference it once โ "You wrote last week about X โ is that still on your mind?" Don't lead with a theme I haven't named today.
If memory has nothing, open soft. Don't ask the user to set preferences โ figure them out from how I respond to the first 2โ3 questions.
***
### 1. Shape of a good turn
Every turn from the agent has the same structure:
1. **Reflect briefly** โ one sentence acknowledging what I just said. Not paraphrasing word-for-word; capturing the *substance* or the *feeling*.
2. **Ask one question** โ exactly one. Not two stacked. Not three options.
3. **Stop** โ don't add commentary, advice, or "let me know ifโฆ". The question is the prompt.
> Three short sentences max per turn. If the reflect-and-ask doesn't fit in that, the question is too big.
***
### 2. Question types I find useful
Use these in rough order, but skip stages if I've already opened up:
* **Opening** โ broad, low-stakes. "How are you feeling about the week?" "What's on your mind?" "Anything sitting heavy?"
* **Exploring** โ pick one thread from my answer and dig. "You said the launch was 'fine' โ what made it just fine and not great?" "What part of that conversation is still with you?"
* **Deepening** โ go to the why or the feeling. "What do you think made that land so hard?" "If you peel one layer back, what's actually underneath?"
* **Closing** โ synthesis, gentle. "If you had to pick one thing to take into next week from this, what would it be?" "What does past-you-from-tomorrow-morning need to know?"
> Never ask 2 questions in one turn. If you have two, pick the better one and save the other.
***
### 3. How I want you to follow up
* **Mirror specifically.** If I say "the meeting was bad", a good follow-up names "the meeting" or "bad", not both vaguely. Bad: "That sounds hard." Better: "What made it bad?" Best: "What part of the meeting are you replaying?"
* **Earn the next topic.** Don't switch threads until the current one feels closed โ usually when my answer gets shorter or I say something like "yeah, that's it."
* **Match my energy.** If I write one line, you write one line back. If I dump three paragraphs, your reflect-and-ask can be longer, but still one question.
* **Use my words.** If I called something "annoying", don't reframe it as "frustrating" or "challenging". I'll tell you if it needs reframing.
***
### 4. When to stop
Stop when any of these are true:
* I say I'm done โ explicitly ("OK that's enough") or implicitly ("alright").
* My answers have gotten progressively shorter for 2+ turns in a row and the last one was 5 words or fewer.
* We've circled back to the same insight twice. Loops mean we've found the floor for today.
* We're 8โ10 turns in and the conversation has surfaced something โ don't push for a 15-turn epic when 10 was the right length.
> At the close, ask one synthesis question (see Closing above). If I'm ready to wrap, I'll give a short answer. Then you stop โ don't append a summary, don't write to scratchpad in the same turn unless the consuming task explicitly asked you to.
***
### 5. What I do NOT want
* **Advice.** Unless I ask "what should I do?", do not advise. Reflect and ask.
* **Lectures.** No "research showsโฆ", no "many people feel this way too". Bring me back to my experience.
* **Multi-part questions.** "What worked, what didn't, and what would you change?" is three questions wearing a trench coat.
* **Yes/no questions.** "Was it stressful?" is a dead end. Use "What was it like?"
* **Leading questions.** "Don't you think you should haveโฆ?" is not a question, it's a verdict.
* **Premature summary.** Do not summarise back what I said in a multi-bullet recap mid-conversation. Hold the thread, don't decorate it.
* **Toxic positivity.** Don't tell me a bad week was "actually a growth opportunity". Sit with what I said.
***
### 6. Sensitive topics
If memory flags something as off-limits, route around it. If I bring it up myself, you may ask once whether I want to talk about it โ accept either answer cleanly and move on without commentary.
***
### How this lens is used
Other surfaces consume this lens:
* **Weekly Retrospective task** โ runs Friday afternoons. Uses this policy to *conduct* the retro, not just prompt for it.
* **End-of-day reflection** โ if the user opts in to a conversational wrap-up instead of the standard push summary.
* **Ad-hoc "let's journal"** โ user invokes by intent ("help me process this", "let's journal", "ask me about my week"). Single conversation, no schedule.
* **Sunday Planning context** โ if the user wants to reflect *before* planning, this policy runs first, then the planning task reads the resulting scratchpad notes.
Each task is responsible for *when* to start and *whether* to persist anything afterwards. This skill only defines *how the conversation should feel*.
***
### Edge cases
* **I open with a heavy topic.** Don't downshift to a lighter opener. Meet it directly: "Tell me more about that."
* **I give a one-word answer to an opener.** Don't push. Try one different opener. If that also gets one word, stop โ I'm not in the headspace for this today. Say so plainly: "Doesn't feel like today's the day. Want to come back to it tomorrow?"
* **I ramble across multiple topics.** Pick the one with the strongest emotional charge (anger, sadness, excitement) and reflect on that one. Save the others for follow-ups if they come back.
* **I ask you a direct question** ("What do you think?"). Acknowledge briefly, then turn it back. "I think X, but I'm curious โ what do *you* think?" Journaling is for my answers, not yours.
# How I Categorize My Money
Source: https://docs.getcore.me/skills/money_categorization
My personal lens for reading money emails โ what counts as a charge, receipt, subscription, renewal, refund, or True Expense, which category it belongs in, when it's notable, and how I want splits and edge cases handled. Loaded by tasks that classify my spend, identify subscriptions, surface big charges, watch renewals, and forecast monthly expenses. Trigger with "how I think about my money", "set my spending categories", or "tell CORE what counts as a subscription".
**What this is:** A reusable lens for understanding any money-related email that lands in my inbox. This is *how I look at my spending* โ the categories I care about, what counts as a subscription, what's a True Expense, what's "big" enough to flag, and how I want messy cases (splits, refunds, transfers) handled. Tasks (a weekly subscription identifier, a weekly money brief, a monthly True Expense forecast) apply this lens. The lens itself does not run on a schedule.
**Tools touched (when this lens is applied):** CORE memory (always first), Gmail (the primary signal), and any connected finance integrations (YNAB, banks) when present.
***
### Order of operations
1. **CORE memory first** โ search what I already know: my category list, payeeโcategory mappings I've confirmed, subscriptions I've already identified, my own notes on past spend. If memory has it, trust it before re-deriving from email.
2. **Gmail** โ the primary source. Receipts, charge alerts, renewal reminders, refund confirmations, statements, fraud alerts, payroll, transfer confirmations.
3. **YNAB or other finance integration** โ if connected, reconcile against transactions for completeness and authoritative category history. Without it, Gmail alone is enough.
> Memory is not optional. Re-categorizing the same Spotify charge from scratch every week is the fastest way to drift from my actual preferences.
***
### 1. Types of money emails I receive
Every money email falls into one of these. Classify the *type* before the *category*:
| Type | What it looks like | What I want done |
| -------------------------- | ------------------------------------------------ | --------------------------------------------------------- |
| **Charge alert** | "A charge of \$X was made at Y" from card issuer | Categorize, check against subscription/notable rules |
| **Receipt** | Itemized from merchant (Amazon, Stripe, Apple) | Categorize using line items; richer than the charge alert |
| **Renewal reminder** | "Your subscription renews in N days" | Add to renewal watch; flag if cancel candidate |
| **Refund / reversal** | "Refund of \$X processed" | Net against original charge in the same category |
| **Statement ready** | "Your monthly statement is available" | Use as authoritative source for the closed month |
| **Fraud / security alert** | "Unrecognized charge" from card issuer | Always notable. Notify immediately. |
| **Payroll / income** | Salary deposit, Stripe payout, invoice paid | Income โ feeds the brief, not the spend categories |
| **Transfer / internal** | Moving money between my own accounts | Not spend. Exclude from category totals. |
| **Bill due** | Utility, rent, credit card statement due | Track due date; not yet a charge until paid |
> When a single email could be two types (e.g. a receipt that also confirms a subscription renewal), prefer the more specific type โ renewal beats receipt.
***
### 2. My categories
The taxonomy. Store the active list in memory; refresh when I add or rename one. Seed defaults if memory is empty, then ask once for corrections.
Default seed (group โ category):
* **Fixed obligations** โ Rent / Mortgage, Utilities, Insurance, Loan payments
* **True Expenses** (annual or quarterly, sliced monthly) โ Domain renewals, Annual software, Insurance premiums, Tax, Car maintenance, Gifts
* **Recurring services** โ Streaming, AI tools, Cloud / Infra (AWS, Vercel), SaaS, Phone, Internet
* **Daily life** โ Groceries, Dining out, Transport, Coffee
* **Health** โ Gym, Medical, Pharmacy, Therapy
* **Travel** โ Flights, Hotels, Trains, Local transit while travelling
* **Shopping** โ Household, Electronics, Clothing, Personal care
* **Just for fun** โ Entertainment, Hobbies, Books, Gaming
* **Income** โ Salary, Side income, Refunds (negative spend)
* **Transfers** โ Between my own accounts (excluded from spend)
> Skip any category that doesn't apply to me. Add ones that do. Ask once if uncertain; do not invent silently.
***
### 3. Payee โ category rules
Memory holds a `payee โ category` map. Build it incrementally:
1. **Known payee in memory** โ use the stored category. Don't re-ask.
2. **Unknown payee, obvious mapping** (Spotify โ Streaming, Uber โ Transport, Apollo โ SaaS) โ assign and store, with a flag that it was auto-assigned so I can correct later.
3. **Unknown payee, ambiguous** (e.g. "ABC Corp \$47") โ leave uncategorized, surface in the next brief, ask me once.
4. **Known merchant, variable category** (Amazon, Costco, Target) โ see Section 7 (Splits).
5. **Conflicting signals** (payee is "Stripe" but receipt shows "Cursor Pro") โ prefer the merchant in the receipt body over the payment processor on the charge alert.
> Confidence matters. Auto-assign confidently mapped charges; leave ambiguous ones for review. Reviewing one charge is cheaper than untangling a wrong category later.
***
### 4. What counts as a subscription
A charge is a **subscription** when all three are true:
1. **Same payee, same or nearly-same amount** (ยฑ5% to absorb FX and tax changes)
2. **Recurring cadence** โ weekly, monthly, quarterly, or yearly. At least **two prior occurrences** before treating as confirmed recurring.
3. **Receipt or renewal email language** matches subscription/service intent (not a re-order of a one-time good)
Subscription **state**:
* **Watching** โ 1 or 2 occurrences seen. Not yet confirmed; not surfaced.
* **Active** โ at least 3 occurrences, with at least one charge in the expected window (last cadence + 7 days grace)
* **Cancel candidate** โ confirmed but flagged for review. *Any one* of:
* Monthly cost > \$10 AND I haven't logged in / used the service in 60+ days (use connected integration signals if available โ Spotify play count, GitHub activity, Calendar attendance for gym)
* I previously tagged it as "cancel"
* Renewal email arrives but I have no recent usage signal
* **Possible cancellation** โ confirmed sub whose expected charge didn't arrive past the grace window. Not yet confirmed cancelled.
* **Cancelled** โ confirmed cancellation. *Any one* of:
* I confirmed the cancellation
* Cancellation confirmation email seen from the merchant
* Two consecutive expected windows passed with no charge (after possible-cancellation state)
* **Trial about to convert** โ renewal email mentions a trial ending; cost > \$0
> Single occurrence is never a subscription. Two = watching. Three = confirmed. Don't surface a "new subscription" alert until the third occurrence, otherwise every one-time purchase looks recurring.
**What I store in memory per subscription** (active and cancelled both retain these):
| Field | Meaning |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Payee | The merchant name as it appears on charges (e.g. Spotify, Cursor, Substack) |
| What it's for | Short human-readable description (Spotify โ "Music streaming"; Cursor โ "AI code editor"; Substack โ "Lenny's Newsletter"). Derive from the receipt body or product name on first sighting; refine if I correct it. |
| Amount + cadence | e.g. $9.99/month, $120/year |
| Started | Date of the first occurrence in my history |
| Last charged | Date of most recent confirmed charge |
| Total spent to date | Sum across all observed occurrences |
| State | watching, active, cancel-candidate, possible-cancellation, cancelled, trial |
| Cancelled date | If state is cancelled, the date the cancellation was confirmed |
| Cancel reason | If cancelled, the captured reason (no longer used, price hike, replaced by X, cancelled by me, etc.) |
> Cancelled subscriptions are kept in memory, not deleted. The historical record matters โ total spent on a cancelled sub answers "was that worth it?" and surfaces patterns ("you've cancelled 4 AI tools in 6 months").
***
### 5. What counts as a True Expense
Borrowed from YNAB but useful even without YNAB. A charge is a **True Expense** when:
* It's **predictable but not monthly** โ annual, quarterly, semi-annual
* It's **large enough to disrupt a normal month** if I don't anticipate it (> \~\$100 for me; user may adjust)
* It's **non-discretionary** in the sense that I'm going to pay it (insurance, domain, AWS reserved instances, taxes), or it's a recurring lump (gifts at year-end, family travel)
For each True Expense, the lens stores:
* Payee, amount, cadence (annual / quarterly / etc.)
* Next expected date (from receipt history or scheduled email)
* Monthly slice = total / months between occurrences
> True Expense Forecast tasks read this list to tell me "this month, \$X of True Expenses are due โ set them aside now."
***
### 6. What "notable" or "big" means
Thresholds are **per category, not flat**. $500 at Best Buy is big; $500 in Rent is not. Defaults (override per user):
* **Fixed obligations** โ only notable if amount changes >10% from prior month
* **Recurring services** โ notable if a *new* one appears, or an existing one's price jumps >15%
* **Daily life** โ single charge > \$100 is notable
* **Health, Travel, Shopping** โ single charge > \$200 is notable
* **Just for fun** โ single charge > \$75 is notable
* **Any category** โ any charge > \$500 is always notable
Also always notable:
* Any charge from a payee never seen before (first-seen alert)
* Any duplicate charge within 24h from the same payee (possible double-bill)
* Any charge from a foreign currency / unusual country if I'm not travelling
* Any fraud alert email regardless of amount
> "Notable" feeds the Weekly Brief. Don't conflate notable with fraud โ most notable charges are legitimate. The brief surfaces them so I can confirm.
***
### 7. Splits and multi-category merchants
Some payees are categorically ambiguous and need splits:
* **Amazon** โ default to Shopping. If receipt line items are present, split by item type (Household, Electronics, Books, Gifts). If no line items in the email, leave as Shopping and let me reassign.
* **Costco / Target / Walmart** โ same pattern. Default Groceries; split if line items show Electronics, Household, etc.
* **Travel charges** โ flights to Travel-Flights, hotels to Travel-Hotels, local transport while travelling to Travel-Local (not Daily Transport)
* **Restaurants on a trip** โ Travel-Dining (not Dining out)
> For splits, prefer "leave whole, surface in brief for my review" over "guess and split silently." Wrong silent splits are worse than uncategorized whole charges.
***
### 8. Refunds, returns, transfers
* **Refunds** โ net against the *original* charge category. If the original is in a prior closed month, log as negative spend in the current month against the same category. Memo it as "refund of \$X from ".
* **Returns without refund yet** โ note as pending; do not adjust spend until the refund email arrives.
* **Transfers between my own accounts** โ never spend. Exclude from category totals. Detected by matching debit/credit on the same date between accounts I own.
* **Reimbursements from a person** (Venmo, Splitwise) โ net against the original category, same as refunds.
***
### How this lens is used
Tasks consume this lens:
* **Weekly Subscription Identifier** โ applies sections 1, 3, 4 to identify and surface active subs, new subs, cancel candidates
* **Weekly Money Brief** โ applies sections 1, 3, 6, plus reads upcoming renewals from Section 4 โ surfaces big charges, renewal watch, weekly category totals
* **Monthly True Expense Forecast** โ applies Section 5 โ tells me what's due this month and the monthly slice to set aside
* **Inbound triage / notify flows** โ when a money email arrives, classify type (Section 1), apply payee rule (Section 3), check notable (Section 6) โ route to notify if matched
* **Chat queries** ("did I pay for Cursor this month?", "what's my Spotify subscription doing?") โ answer against memory + this lens
Each task is responsible for *when* and *how often* it runs โ this skill only defines *what to look for* and *how to categorize*.
***
### Edge cases
* **No payee in receipt** โ fall back to the email sender domain. If still unknown, leave uncategorized.
* **Multi-currency** โ convert to my home currency using the receipt's exchange rate. If no rate is given, use the date's market rate. Surface non-home-currency charges in the brief.
* **Statement email vs the charges that built it** โ prefer per-charge data. Only use the statement total as a sanity check.
* **Card issuer "we're upgrading your card" emails** โ not money events. Skip.
* **Pre-authorization / hold** (e.g. hotel deposit) โ track separately. The actual charge arrives later; reconcile then.
* **Charge from me to myself** (Stripe payout to my bank, ACH transfer) โ transfer, not spend.
* **First time seeing a known payee in a new category** (Apple App Store โ previously Apps, now Music subscription) โ surface as ambiguous; do not silently re-category.
* **Receipt with no amount in the body** (some platforms link to a hosted receipt) โ categorize what I can; flag for review.
# What's Important in My Inbox
Source: https://docs.getcore.me/skills/notify_emails
A personal policy for what counts as important email โ key vendors, customer signals, security alerts, money matters, and the people I always want to hear from. Loaded whenever email is touched, so triage, replies, summaries, and notifications all use the same definition of "important". Trigger with "what's important in my inbox", "set my email priorities", or "tell CORE what matters in email".
**What this is:** A reusable definition of what *I* consider important in email. This policy is applied wherever email shows up โ inbound triage, agent reading my inbox during a task, chat summaries, daily briefs, alert tasks. It does not run on its own. Tasks (a watcher, a brief, an agent flow) read this policy and act on it.
**Tools touched (when this policy is applied):** Gmail.
***
### How to read this policy
Each section answers one question about *me*:
1. Who do I always want to hear from?
2. What signals from customers matter?
3. What security and money events should never be missed?
4. What categories do I care about beyond the above?
Anything matching these definitions is **important**. Everything else is background.
***
### 1. People and senders that matter to me
Stored in memory and refreshed when I tell CORE about a new key contact:
* Named individuals โ investors, advisors, co-founders, key customers (by email address)
* Vendor and supplier domains โ accountants, lawyers, compliance providers, payroll, infra
* Specific senders flagged by me as "always notify"
> When a new email matches any of these, treat it as important regardless of content.
If memory has nothing here, ask once:
> "Who are the people and companies I should always treat as important? (names, emails, or domains)"
Store answers immediately.
***
### 2. Customer signals that matter to me
The body โ not the sender โ tells me this. A customer is important when they are:
* Reporting a bug or breakage in my product
* Asking for support or stuck on something
* Giving feedback (positive or negative) about a feature
* Reaching out as a prospect โ interested in buying, trying, or evaluating
> Identify the product by name (from memory). Generic newsletters that mention the product in passing are not customer signals.
***
### 3. Security and money events that matter to me
Always important regardless of who else is involved:
* Security alerts โ sign-in from a new device, password change, suspicious activity (from accounts I own: Google, GitHub, banks, financial tools)
* Payment failures โ declined card, failed payout, overdue invoice
* Account access changes โ added user, permission change, billing role change
* Anything from my bank, primary financial platforms, or tax/compliance providers about deadlines or actions required
***
### 4. Categories I've defined for myself
Free-form. Stored in memory as `{category_name, matching_rule}`. Examples:
* "Press or media reaching out" โ matches journalists, podcasters, conference organisers
* "Hiring funnel โ top candidates" โ matches replies in active hiring threads
* "Fundraising โ investor replies" โ matches threads with known investor domains
> These are the categories *I* care about that don't fit the buckets above. Add freely.
***
### How this policy is used
Other surfaces consume this policy:
* **Triage tasks** decide what to surface vs. skip
* **Notification tasks** decide what to push live
* **Daily / weekly brief tasks** decide what to lead with
* **Agent-in-the-loop work** uses this to know which threads need my attention vs. which it can handle quietly
* **Chat queries** like "what's important in my inbox?" answer against this policy
Each consumer is responsible for *how* to act โ this policy only defines *what* matters.
***
### Edge cases
* **Ambiguous signals** โ if a sender matches but the body is clearly automated/promotional, treat as not important. Promotional โ important even from a key vendor's marketing list.
* **One-off relevance** โ if something matches only once and isn't likely to repeat, do not add it to the policy. Keep this lean.
* **Conflicting rules** โ security and money events always win over category preferences.
# Skills
Source: https://docs.getcore.me/skills/overview
Tell CORE what matters to you once โ every task reads from the same definition.
Skills are personal policies โ the things that are important to *you*, written down once. They aren't runnable tasks. They're the lenses, preferences, and definitions that tasks apply.
A skill answers a question about you: *what counts as important email?* *how do I look at an account?* *what does healthy engineering velocity look like for me?* Once written, every surface โ inbound triage, agent flows, daily briefs, scheduled reports โ uses the same answer.
To create one: **Dashboard โ Agent โ Skills โ New Skill**. Add a title, the policy, and a short description so CORE knows when to load it.
***
## Skills Library
My labelling policy for email โ what counts as Urgent, Customer, Trying to Sell, and the rest.
My definition of important email โ key senders, customer signals, security and money events.
My lens for sizing up any company or person โ signals I weight, angles I look for, structure I want.
My lens for reading delivery metrics โ which numbers matter, my healthy ranges, what to flag.
My style for journaling conversations โ one question at a time, follow-ups that earn the next topic, when to stop.
My lens for reading money emails โ categories, subscriptions, True Expenses, what's notable, how to handle splits and refunds.
# Cal.com
Source: https://docs.getcore.me/toolkit/cal-com
Meeting scheduling and availability management
## Overview
Integrate Cal.com to manage calendars, schedules, and availability directly from CORE. Create and manage multiple schedules, set availability windows, configure time zones, and automate meeting scheduling workflows.
## Setup Guide
* `Authentication Type` : API Key
## How to Connect
1. Log in to [cal.com](https://cal.com) and sign in to your account
2. Navigate to **Settings** by clicking on your profile
3. Go to **Security** โ **API Keys**
4. Click **Generate new API key** and copy the key
5. Go to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
6. Click on the **Cal.com** card
7. Paste your API key into the authentication field
8. Click **Save** to complete the setup
## Use Cases
When you ask CORE to perform Cal.com tasks, it uses MCP tools to execute your requests:
**Scenario**: Create and manage multiple schedules for different purposes
```
"Create a new business hours schedule for weekdays from 9am to 5pm
in Eastern Time, and set it as my default schedule"
```
The agent will use `cal_create_a_schedule` to create the schedule with the specified parameters.
**Scenario**: Define recurring availability windows with day/time specifications
```
"Update my schedule to be available only on Monday, Wednesday, and Friday
from 10am to 3pm"
```
The agent will use `cal_update_a_schedule` to modify the availability windows.
**Scenario**: Organize different types of meetings with specific schedules
```
"Show me all my schedules and tell me which one is set as default"
```
The agent will use `cal_get_all_schedules` to retrieve and display schedule information.
**Scenario**: Manage schedules across team members
```
"Create a schedule for Pacific Time zone with availability
from 8am to 4pm on weekdays"
```
The agent will use `cal_create_a_schedule` to set up the region-specific schedule.
**Scenario**: Automate meeting creation and availability updates through workflows
```
"Add date-specific overrides to my schedule for December 25th
to mark it as unavailable"
```
The agent will use `cal_update_a_schedule` with override parameters to handle special days.
## Available MCP Tools
The Cal.com integration provides 6 tools for comprehensive schedule management:
| Tool Name | Description |
| -------------------------- | ------------------------------------------------------------------- |
| `cal_get_all_schedules` | Retrieve all schedules from Cal.com API |
| `cal_create_a_schedule` | Create a new schedule with name, time zone, and availability blocks |
| `cal_update_a_schedule` | Update an existing schedule including availability and overrides |
| `cal_get_default_schedule` | Get the default schedule with all its details |
| `cal_get_schedule` | Get a specific schedule by its ID |
| `cal_delete_a_schedule` | Delete a schedule by its ID |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Discord
Source: https://docs.getcore.me/toolkit/discord
Community management and server interactions for messaging, channels, and role management
## Overview
Integrate Discord to manage communities, servers, channels, messages, and members directly from CORE. Access 20+ tools for complete Discord operations including messaging, server management, role assignment, channel organization, and member coordination without leaving your workspace.
## Setup Guide
* `Authentication Type` : OAuth 2.0
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **Discord** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to Discord to authorize the application
5. Grant the required permissions to your server
6. You'll be redirected back to CORE once connected
## Use Cases
#### Action Use Cases
When you ask CORE to perform Discord tasks, it uses MCP tools to execute your requests:
**Scenario**: Post announcements and updates to specific channels
```
"Send a message to the #announcements channel: 'New Discord integration is now live!
Head over to https://app.getcore.me to connect your server'"
```
The agent will use `send_message` to deliver announcements with rich formatting and embeds to keep members informed.
**Scenario**: Organize server structure and configuration
```
"Get information about our main server including member count,
then list all the channels we have organized"
```
The agent will use `get_guild` and `list_guild_channels` to understand your server's structure and provide insights on organization.
**Scenario**: Create and manage channel structure
```
"Create a new category channel called 'Project Channels',
then create a text channel called #project-planning inside it
and set the topic to 'Discuss and plan upcoming features'"
```
The agent will:
1. Use `create_channel` to create the category
2. Use `create_channel` again to create the text channel
3. Use `update_channel` to set the topic
**Scenario**: Assign roles and manage permissions
```
"Create a new role called 'Moderators' with a blue color,
then add that role to user 123456 so they can help manage the server"
```
The agent will:
1. Use `create_role` to create the new role with custom color
2. Use `add_member_role` to assign it to the specified member
**Scenario**: Moderate content and manage member activity
```
"Get the last 50 messages from #general,
then delete any spam messages and add a warning reaction to problematic content"
```
The agent will:
1. Use `get_channel_messages` to retrieve recent activity
2. Use `delete_message` to remove inappropriate content
3. Use `add_reaction` to flag messages with emoji indicators
**Scenario**: Manage server members and their roles
```
"List all members in the engineering server,
then show me who has the @Developer role"
```
The agent will use `get_guild_members` to retrieve member information and help coordinate team organization.
**Scenario**: Monitor server activity and structure
```
"Tell me how many members are in our community server
and list all the roles we've created"
```
The agent will use `get_guild` to get member count and other server metrics.
#### Proactive Use Cases
With webhooks enabled, CORE monitors Discord 24/7 and acts automatically based on your instructions:
**Trigger**: New member joins server
**Automated Action**: Send welcome message and assign roles
```
"When someone joins our Discord server,
send them a DM with our community guidelines,
assign the @Newcomer role,
and post a welcome message in #introductions"
```
Automate member onboarding. CORE welcomes new members and sets up their server access automatically.
**Trigger**: Message posted in support channel
**Automated Action**: Create tracking ticket
```
"When a message is posted in #support,
create a Linear issue with the message content,
react to the message with a checkmark,
and notify the support team on Slack"
```
Convert support requests into tickets instantly. CORE creates tracking issues and notifies the right team.
**Trigger**: Message contains banned words or spam
**Automated Action**: Flag and escalate
```
"When a message contains inappropriate language,
delete it immediately,
send a warning DM to the user,
and notify moderators in #mod-alerts with context"
```
Maintain community standards automatically. CORE filters content and escalates to human moderators when needed.
**Trigger**: Message posted in announcements channel
**Automated Action**: Cross-post to other platforms
```
"When an announcement is posted in #announcements,
extract the key points,
post a summary to our Slack workspace,
and send a notification to the team WhatsApp group"
```
Broadcast announcements across platforms. CORE ensures important updates reach everyone regardless of their preferred channel.
**Trigger**: Message mentions event or meeting
**Automated Action**: Create calendar entries
```
"When a message in #events contains a date and time,
extract the event details,
create a Google Calendar event,
and send reminders to participants 1 hour before"
```
Automate event scheduling. CORE parses event details from discussions and handles calendar management.
**Trigger**: Message receives multiple reactions
**Automated Action**: Track popular content
```
"When a message gets more than 10 reactions,
save it to CORE memory with label 'popular-content',
and compile a weekly digest of top messages for #community-highlights"
```
Surface valuable content automatically. CORE identifies and preserves high-engagement discussions for later review.
## Scopes
* `messages/read` - Read message content from channels
* `messages/write` - Send messages to channels
* `channels/read` - List and view channel information
* `channels/manage` - Create, update, and delete channels
* `roles/manage` - Create, update, and delete roles
* `members/manage` - View and manage guild members
* `guilds/read` - Access guild/server information
* `users/read` - View user information
## Available MCP Tools
The Discord integration provides 20+ tools for comprehensive server management:
| Tool Name | Description |
| ---------------------- | -------------------------------------------- |
| `send_message` | Send a message to a Discord channel |
| `get_message` | Retrieve a specific message by ID |
| `get_channel_messages` | List messages from a channel with pagination |
| `delete_message` | Delete a message |
| `add_reaction` | Add an emoji reaction to a message |
| Tool Name | Description |
| --------------------- | ------------------------------------------------------------- |
| `create_channel` | Create a new channel (text, voice, category, or announcement) |
| `get_channel` | Get details of a specific channel |
| `update_channel` | Update channel name, topic, or position |
| `delete_channel` | Delete a channel |
| `list_guild_channels` | List all channels in a server |
| Tool Name | Description |
| ------------------- | ---------------------------------------- |
| `get_guild` | Get server information and details |
| `list_guilds` | List all servers the bot is in |
| `get_guild_members` | List members in a server with pagination |
| `get_guild_member` | Get details of a specific guild member |
| Tool Name | Description |
| -------------------- | --------------------------------------------------- |
| `create_role` | Create a new role with custom permissions and color |
| `update_role` | Update role name, permissions, or appearance |
| `delete_role` | Delete a role |
| `add_member_role` | Add a role to a guild member |
| `remove_member_role` | Remove a role from a guild member |
| Tool Name | Description |
| ------------------ | -------------------------------------------- |
| `get_current_user` | Get information about the authenticated user |
| `get_user` | Get details about a specific user |
## Triggers
Discord triggers enable CORE's Meta Agent to wake up and act proactively when events are detected via scheduled polling.
| Event | Description |
| -------------------------- | ----------------------------------------------------- |
| `DISCORD_MESSAGE_CREATED` | Triggered when a new message is posted to any channel |
| `DISCORD_MESSAGE_UPDATED` | Triggered when a message is edited |
| `DISCORD_MESSAGE_DELETED` | Triggered when a message is deleted |
| `DISCORD_REACTION_ADDED` | Triggered when a reaction is added to a message |
| `DISCORD_REACTION_REMOVED` | Triggered when a reaction is removed from a message |
| Event | Description |
| ------------------------- | --------------------------------------- |
| `DISCORD_CHANNEL_CREATED` | Triggered when a new channel is created |
| `DISCORD_CHANNEL_UPDATED` | Triggered when a channel is modified |
| `DISCORD_CHANNEL_DELETED` | Triggered when a channel is deleted |
| Event | Description |
| --------------------------- | --------------------------------------------------------------- |
| `DISCORD_MEMBER_JOINED` | Triggered when a new member joins the server |
| `DISCORD_MEMBER_LEFT` | Triggered when a member leaves the server |
| `DISCORD_MEMBER_UPDATED` | Triggered when member properties change (roles, nickname, etc.) |
| `DISCORD_MEMBER_ROLE_ADDED` | Triggered when a role is added to a member |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# GitHub
Source: https://docs.getcore.me/toolkit/github
Comprehensive repository management, issue tracking, and CI/CD automation for your GitHub workflows
## Overview
Integrate GitHub to manage repositories, issues, pull requests, and automate development workflows directly from CORE. Access 60+ tools for complete GitHub operations without leaving your workspace.
## Setup Guide
* `Authentication Type` : OAuth 2.0
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **GitHub** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to GitHub to authorize the application
5. Grant the required permissions
6. You'll be redirected back to CORE once connected
## Use Cases
#### Action Use Cases
When you ask CORE to perform GitHub tasks, it uses MCP tools to execute your requests:
**Scenario**: Automatically create and track GitHub issues from other tools
```
"Create a GitHub issue in the 'core' repo titled 'Add user authentication'
with the description 'Need to implement OAuth2 authentication'
and assign it to @username with labels 'feature' and 'high-priority'"
```
The agent will use `create_issue` to create the issue and can follow up with `create_issue_comment` to add additional context or use `update_issue` to modify details.
**Scenario**: Review and merge pull requests directly from your IDE
```
"Show me all open pull requests in the main repository,
then review PR #123 and merge it if tests are passing"
```
The agent will:
1. Use `list_pull_requests` to fetch open PRs
2. Use `get_pull_request` to get PR details
3. Check `list_workflow_runs` for CI status
4. Use `merge_pull_request` to merge after verification
**Scenario**: Find specific code patterns across your repositories
```
"Search for all files using the deprecated API endpoint
'/api/v1/auth' across all my repositories"
```
The agent will use `search_code` to find matching files and can use `get_file_content` to read the actual implementations for analysis.
**Scenario**: Automate release workflows
```
"Create a new release branch 'release-v2.0' from main,
update the version in package.json to 2.0.0,
and create a pull request for the release"
```
The agent will:
1. Use `create_branch` to create the release branch
2. Use `create_or_update_file` to update version files
3. Use `create_pull_request` to create the release PR
4. Use `create_issue` to track release tasks
**Scenario**: Track team activity and respond to notifications
```
"Show me all issues assigned to me that were updated in the last 24 hours,
and mark all my notifications as read"
```
The agent will use `list_issues` with appropriate filters, `list_notifications` to keep you updated, and `mark_all_notifications_read` to clear your notifications.
**Scenario**: Monitor and control GitHub Actions workflows
```
"Check the status of the latest workflow run on the main branch.
If it failed, rerun it"
```
The agent will:
1. Use `list_workflow_runs` to get recent runs
2. Use `get_workflow_run` to check status details
3. Use `rerun_workflow` if the run failed
**Scenario**: Quickly set up new repositories with standard configurations
```
"Create a new repository called 'my-new-project',
add a README, create labels for 'bug', 'feature', and 'documentation',
and set up a milestone for 'v1.0'"
```
The agent will:
1. Use `create_repository` to create the repo
2. Use `create_or_update_file` to add the README
3. Use `create_label` for each label
4. Use `create_milestone` for the v1.0 milestone
**Scenario**: Automated code review and feedback
```
"Review the latest PR in my repository, check for any TODO comments
in the changed files, and create review comments for each one"
```
The agent will:
1. Use `list_pull_requests` to get the latest PR
2. Use `get_pull_request` to get changed files
3. Use `get_file_content` to read files
4. Use `create_pr_comment` to add review comments
#### Proactive Use Cases
With webhooks enabled, CORE monitors GitHub 24/7 and acts automatically based on your instructions:
**Trigger**: New issue created with specific labels
**Automated Action**: Assign to team member and add to project
```
"When a new issue is created with the 'bug' label,
automatically assign it to @devops-team,
add it to the 'Current Sprint' project,
and notify me on WhatsApp"
```
CORE monitors new issues and automatically routes them based on labels, keeping your team organized without manual triaging.
**Trigger**: Pull request review requested
**Automated Action**: Notify on preferred channel with context
```
"When I'm requested to review a PR,
send me a Slack DM with the PR title, description, and changed files summary"
```
Never miss review requests. CORE watches for review assignments and notifies you with full context on your preferred channel.
**Trigger**: Workflow run fails on main branch
**Automated Action**: Create issue and escalate
```
"When a workflow fails on the main branch,
create a high-priority issue with the error logs,
assign it to the last committer,
and send an urgent notification to #engineering on Slack"
```
Instantly respond to build failures. CORE creates issues, assigns responsibility, and escalates critical failures automatically.
**Trigger**: New release published
**Automated Action**: Extract changelog and notify stakeholders
```
"When a new release is published,
extract the changelog from the release notes,
save it to CORE memory with label 'releases',
and send a summary to #product-updates on Slack"
```
Keep everyone informed on releases. CORE tracks release activity, stores release notes, and broadcasts updates across channels.
**Trigger**: PR updated after 30 days of inactivity
**Automated Action**: Add comment and close if inactive
```
"When a PR hasn't been updated in 30 days,
add a comment asking if it's still relevant,
and if no response in 7 days, close it with a standard message"
```
Maintain repository hygiene automatically. CORE monitors stale PRs and handles cleanup based on your rules.
**Trigger**: Dependabot security alert created
**Automated Action**: Create issue and notify security team
```
"When a security vulnerability is detected,
create a critical-priority issue in the 'security-fixes' project,
notify the security team on Slack,
and add it to CORE memory for tracking"
```
Respond to security issues instantly. CORE escalates vulnerabilities, creates tracking issues, and notifies the right team members.
## Scopes
* `repo` - Repository access (read/write)
* `repo:status` - Commit status access
* `repo_deployment` - Deployment status access
* `public_repo` - Public repository access
* `repo:invite` - Repository invitations
* `security_events` - Security events access
* `write:repo_hook` - Repository webhooks
* `read:repo_hook` - Read repository webhooks
* `admin:org` - Organization administration
* `write:org` - Organization membership
* `read:org` - Read organization data
* `admin:public_key` - Public key administration
* `write:public_key` - Public key write access
* `read:public_key` - Public key read access
* `admin:org_hook` - Organization webhooks
* `gist` - Gist access
* `notifications` - Notifications access
* `user` - User profile access
* `read:user` - Read user profile
* `user:email` - User email access
* `user:follow` - Follow/unfollow users
* `delete_repo` - Delete repositories
* `write:discussion` - Discussions write access
* `read:discussion` - Discussions read access
* `write:packages` - Packages write access
* `read:packages` - Packages read access
* `delete:packages` - Delete packages
* `admin:gpg_key` - GPG key administration
* `write:gpg_key` - GPG key write access
* `read:gpg_key` - GPG key read access
* `workflow` - Workflow access
## Available MCP Tools
The GitHub integration provides 60+ tools for comprehensive repository management:
| Tool Name | Description |
| --------------------- | -------------------------------------------- |
| `get_repo` | Get details of a specific repository |
| `list_repos` | List repositories for the authenticated user |
| `create_repository` | Create a new repository |
| `fork_repository` | Fork an existing repository |
| `search_repositories` | Search repositories across GitHub |
| Tool Name | Description |
| ---------------------- | --------------------------------------------------- |
| `list_issues` | List issues in a repository with advanced filtering |
| `get_issue` | Get details of a specific issue |
| `create_issue` | Create a new issue |
| `update_issue` | Update an existing issue |
| `search_issues` | Search for issues and pull requests |
| `list_issue_comments` | List comments on an issue |
| `create_issue_comment` | Create a comment on an issue |
| `update_issue_comment` | Update an existing issue comment |
| `delete_issue_comment` | Delete an issue comment |
| Tool Name | Description |
| --------------------- | ----------------------------------------- |
| `list_pull_requests` | List pull requests in a repository |
| `get_pull_request` | Get details of a specific pull request |
| `create_pull_request` | Create a new pull request |
| `update_pull_request` | Update an existing pull request |
| `merge_pull_request` | Merge a pull request |
| `list_pr_reviews` | List reviews on a pull request |
| `create_pr_review` | Create a review on a pull request |
| `list_pr_comments` | List review comments on a pull request |
| `create_pr_comment` | Create a review comment on a pull request |
| Tool Name | Description |
| ----------------------- | ------------------------------------------- |
| `get_file_content` | Get the content of a file from a repository |
| `create_or_update_file` | Create or update a file in a repository |
| `delete_file` | Delete a file from a repository |
| `push_files` | Push multiple files to repository |
| `search_code` | Search for code across GitHub repositories |
| Tool Name | Description |
| ---------------- | ---------------------------------------------- |
| `list_projects` | List projects for a repository or organization |
| `create_project` | Create a new project |
| `update_project` | Update an existing project |
| `delete_project` | Delete a project |
| Tool Name | Description |
| ------------------ | ----------------------------------- |
| `list_milestones` | List milestones in a repository |
| `get_milestone` | Get details of a specific milestone |
| `create_milestone` | Create a new milestone |
| `update_milestone` | Update an existing milestone |
| `delete_milestone` | Delete a milestone |
| Tool Name | Description |
| ----------------------------- | --------------------------------------------- |
| `list_notifications` | List notifications for the authenticated user |
| `mark_notification_read` | Mark a notification as read |
| `mark_all_notifications_read` | Mark all notifications as read |
| Tool Name | Description |
| -------------- | --------------------------- |
| `list_labels` | List labels in a repository |
| `create_label` | Create a new label |
| `update_label` | Update an existing label |
| `delete_label` | Delete a label |
| Tool Name | Description |
| --------------- | ----------------------------- |
| `list_branches` | List branches in a repository |
| `create_branch` | Create a new branch |
| `list_commits` | List commits in a repository |
| `get_commit` | Get commit details |
| Tool Name | Description |
| -------------------- | ----------------------------- |
| `list_tags` | List tags in a repository |
| `get_tag` | Get tag details |
| `list_releases` | List releases in a repository |
| `get_latest_release` | Get the latest release |
| `get_release_by_tag` | Get a release by tag name |
| Tool Name | Description |
| --------------------- | --------------------------------- |
| `list_workflows` | List repository workflows |
| `list_workflow_runs` | List workflow runs |
| `get_workflow_run` | Get workflow run details |
| `rerun_workflow` | Rerun a workflow |
| `cancel_workflow_run` | Cancel a workflow run |
| `trigger_workflow` | Trigger a workflow dispatch event |
| Tool Name | Description |
| ---------------------- | -------------------------- |
| `list_issue_reactions` | List reactions on an issue |
| `add_issue_reaction` | Add reaction to an issue |
| `add_comment_reaction` | Add reaction to a comment |
| `delete_reaction` | Delete a reaction |
| Tool Name | Description |
| ------------- | --------------- |
| `list_gists` | List your gists |
| `get_gist` | Get a gist |
| `create_gist` | Create a gist |
| `update_gist` | Update a gist |
| `delete_gist` | Delete a gist |
## Triggers
GitHub triggers enable CORE's Meta Agent to wake up and act proactively when events are detected via scheduled polling.
| Event | Description |
| ----------------------- | ------------------------------------------------------ |
| `GITHUB_ISSUE_CREATED` | Triggered when a new issue is opened in the repository |
| `GITHUB_ISSUE_UPDATED` | Triggered when an issue is edited or modified |
| `GITHUB_ISSUE_CLOSED` | Triggered when an issue is closed |
| `GITHUB_ISSUE_REOPENED` | Triggered when a closed issue is reopened |
| `GITHUB_ISSUE_ASSIGNED` | Triggered when an issue is assigned to a user |
| `GITHUB_ISSUE_LABELED` | Triggered when a label is added to an issue |
| Event | Description |
| ---------------------------- | ------------------------------------------------------- |
| `GITHUB_PR_CREATED` | Triggered when a new pull request is opened |
| `GITHUB_PR_UPDATED` | Triggered when a pull request is edited |
| `GITHUB_PR_MERGED` | Triggered when a pull request is merged |
| `GITHUB_PR_CLOSED` | Triggered when a pull request is closed without merging |
| `GITHUB_PR_REVIEW_REQUESTED` | Triggered when a review is requested on a PR |
| `GITHUB_PR_REVIEWED` | Triggered when a review is submitted on a PR |
| Event | Description |
| ----------------------- | --------------------------------------------- |
| `GITHUB_PUSH` | Triggered when commits are pushed to a branch |
| `GITHUB_BRANCH_CREATED` | Triggered when a new branch is created |
| `GITHUB_BRANCH_DELETED` | Triggered when a branch is deleted |
| `GITHUB_TAG_CREATED` | Triggered when a new tag is created |
| Event | Description |
| ---------------------------------- | ----------------------------------------- |
| `GITHUB_RELEASE_PUBLISHED` | Triggered when a release is published |
| `GITHUB_RELEASE_CREATED` | Triggered when a release draft is created |
| `GITHUB_DEPLOYMENT_CREATED` | Triggered when a deployment is created |
| `GITHUB_DEPLOYMENT_STATUS_UPDATED` | Triggered when deployment status changes |
| Event | Description |
| ------------------------------- | --------------------------------------- |
| `GITHUB_WORKFLOW_RUN_COMPLETED` | Triggered when a workflow run completes |
| `GITHUB_WORKFLOW_RUN_FAILED` | Triggered when a workflow run fails |
| `GITHUB_CHECK_RUN_COMPLETED` | Triggered when a check run completes |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# GitHub Analytics
Source: https://docs.getcore.me/toolkit/github-analytics
DORA metrics and engineering performance tracking for GitHub repositories
## Overview
Integrate GitHub Analytics to measure and track engineering performance metrics directly from CORE. Access comprehensive DORA metrics (Deployment Frequency, Lead Time, Change Failure Rate) along with additional delivery, stability, and code quality metrics to gain insights into your team's productivity and engineering excellence.
## Setup Guide
* `Authentication Type` : OAuth 2.0
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **GitHub Analytics** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to GitHub to authorize the application
5. Grant the required permissions (read access to repositories and their data)
6. You'll be redirected back to CORE once connected
## Use Cases
**Scenario**: Get all four key DORA metrics for your repository
```
"Calculate all DORA metrics for the 'myorg/myapp' repository
for the last 30 days"
```
The agent will use `all_metrics` to calculate:
* Deployment Frequency: releases per week
* Lead Time for Changes: time from commit to production
* Change Failure Rate: percentage of failed deployments
* Time to Restore Service: recovery time from failures
**Scenario**: Track how often your team deploys to production
```
"What's the deployment frequency for 'company/product'?
Show me the last 60 days and compare it to the previous 60 days"
```
The agent will use `deployment_frequency` with:
* `days: 60`
* `compareWithPrevious: true`
This reveals trends in deployment velocity and identifies acceleration or slowdowns.
**Scenario**: Understand how long it takes from code commit to production
```
"Calculate the lead time for changes in 'team/api' repository.
I want to see if we're improving our time to production"
```
The agent will use `lead_time_for_changes` to measure the average time from first commit to deployment, helping identify bottlenecks in your delivery pipeline.
**Scenario**: Evaluate pull request merge times and throughput
```
"Show me PR metrics for 'org/web-app':
- Average time to merge a PR
- Number of PRs merged per week
- Average PR size"
```
The agent will use:
* `pr_merge_time`: Average hours from PR creation to merge
* `pr_throughput`: PRs merged per week (velocity indicator)
* `pr_size`: Average lines changed per PR (complexity indicator)
**Scenario**: Measure overall team productivity and commit activity
```
"How productive is our team on the 'core' repository?
Show me commit frequency and compare with last month"
```
The agent will use `commit_frequency` to show:
* Commits per week to main branch
* Week-over-week trends
* Team activity patterns
**Scenario**: Build a comprehensive performance dashboard
```
"Create a performance report for 'company/main-app':
- All DORA metrics for the last quarter
- Stability metrics (change failure rate, hotfix rate, revert rate)
- Code quality (average PR size)
- Compare current period with previous quarter"
```
The agent will use `all_metrics` with custom date ranges to generate a comprehensive engineering performance report suitable for stakeholder presentations.
**Scenario**: Understand your system's stability and reliability
```
"How stable is our 'backend/api' repository?
Show me change failure rate, hotfix rate, and revert rate for the last month"
```
The agent will use:
* `change_failure_rate`: Percentage of deployments causing issues
* `hotfix_rate`: Percentage of emergency releases
* `revert_rate`: Percentage of merged PRs that get reverted
These metrics together indicate system stability and code quality.
**Scenario**: Find where delays occur in your delivery process
```
"Analyze delivery metrics for 'team/service':
- How often do we deploy?
- How long does it take from commit to deployment?
- How long do PRs sit before being merged?
- What's our change failure rate?"
```
The agent will correlate multiple metrics to identify whether delays are in:
* Code development (commit frequency)
* Code review (PR merge time)
* Deployment process (deployment frequency, lead time)
* Quality assurance (change failure rate)
**Scenario**: Analyze metrics for specific periods
```
"Calculate all metrics for 'org/app' from 2024-01-01 to 2024-03-31
(Q1 performance review)"
```
Using `startDate` and `endDate` parameters allows analysis of:
* Quarterly performance reviews
* Sprint-specific metrics
* Post-incident analysis windows
* Year-over-year comparisons
**Scenario**: Understand the impact of incidents on metrics
```
"For 'platform/core', what's the change failure rate?
Use custom incident labels: ['critical', 'p0', 'sev1']"
```
The agent will calculate failure rate based on your organization's incident classification system, enabling accurate measurement of production stability.
## Understanding the Metrics
#### DORA Metrics (Industry Standard)
**Deployment Frequency**: How often releases happen to production
* Elite: On-demand
* High: Weekly releases
* Medium: Monthly releases
* Low: Less than monthly
**Lead Time for Changes**: Time from code commit to production
* Elite: Less than 1 hour
* High: 1 hour to 1 day
* Medium: 1 day to 1 week
* Low: More than 1 week
**Change Failure Rate**: Percentage of deployments causing failures
* Elite: 0-15% failure rate
* High: 16-30%
* Medium: 31-45%
* Low: 46%+
**Time to Restore Service**: How quickly you recover from failures
* Elite: Less than 1 hour
* High: 1-24 hours
* Medium: 1-7 days
* Low: More than 7 days
#### Delivery Metrics
* **PR Merge Time**: Average hours from PR creation to merge (indicates review efficiency)
* **PR Throughput**: Number of PRs merged per week (indicates team velocity)
* **Commit Frequency**: Number of commits to main branch per week (indicates development activity)
#### Stability Metrics
* **Hotfix Rate**: Percentage of emergency releases (indicates production pressure)
* **Revert Rate**: Percentage of merged PRs that get reverted (indicates code quality issues)
## Integration Notes
* All metrics are calculated in real-time from GitHub data
* Analysis includes merged and released code only
* Custom date ranges provide flexibility for any analysis window
* Week-over-week comparisons help identify trends
* Metrics support both organizations and personal repositories
## Scopes
* `repo` - Repository access (read)
* `read:org` - Read organization data
* `read:user` - Read user profile data
## Available MCP Tools
The GitHub Analytics integration provides 10 tools for comprehensive performance tracking:
| Tool Name | Description |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `deployment_frequency` | Calculate deployment frequency - number of releases/deployments per week. DORA metric for delivery speed. |
| `lead_time_for_changes` | Calculate lead time for changes - time from first commit to production deployment (in hours/days). DORA metric for delivery speed. |
| `pr_merge_time` | Calculate PR merge time - average time from PR creation to merge (in hours). Delivery speed metric. |
| `pr_throughput` | Calculate PR throughput - number of PRs merged per week. Delivery speed metric. |
| `commit_frequency` | Calculate commit frequency - number of commits to main branch per week. Delivery speed metric. |
| Tool Name | Description |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `change_failure_rate` | Calculate change failure rate - percentage of deployments that cause production failures. DORA metric for stability & reliability. |
| `hotfix_rate` | Calculate hotfix rate - percentage of releases that are emergency hotfixes. Stability & reliability metric. |
| `revert_rate` | Calculate revert rate - percentage of merged PRs that get reverted. Stability & reliability metric. |
| Tool Name | Description |
| --------- | ---------------------------------------------------------------------------------------------- |
| `pr_size` | Calculate PR size - average lines changed (additions + deletions) per PR. Code quality metric. |
| Tool Name | Description |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `all_metrics` | Calculate all GitHub analytics metrics at once - includes all DORA metrics, delivery speed, stability, and code quality metrics. |
## Tool Parameters
#### Common Parameters
Most analytics tools accept the following parameters:
| Parameter | Type | Required | Description |
| --------------------- | ------- | -------- | ------------------------------------------------------------------------- |
| `owner` | string | Yes | Repository owner (organization or user) |
| `repo` | string | Yes | Repository name |
| `days` | number | No | Number of days to analyze (default: 30) |
| `startDate` | string | No | Start date in YYYY-MM-DD format (overrides days) |
| `endDate` | string | No | End date in YYYY-MM-DD format (default: today) |
| `compareWithPrevious` | boolean | No | Compare with previous period for week-over-week analysis (default: false) |
#### Specialized Parameters
* **Commit Frequency**: Includes `branch` parameter (default: main) to analyze specific branches
* **Change Failure Rate**: Includes `incidentLabels` array parameter (default: \["incident", "production", "outage", "bug"]) to identify production incidents
* **Hotfix Rate**: Includes `hotfixPatterns` array parameter (default: \["hotfix", "emergency", "patch"]) to identify emergency releases
### Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Gmail
Source: https://docs.getcore.me/toolkit/gmail
Comprehensive email management with advanced search and filtering
## Overview
Integrate Gmail to manage emails, labels, filters, and attachments directly from CORE. Access 20+ tools for complete email management including sending, drafting, advanced search, batch operations, and automation without leaving your workspace.
## Setup Guide
* `Authentication Type` : OAuth 2.0 (Google)
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **Gmail** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to Google to authorize the application
5. Grant the required permissions
6. You'll be redirected back to CORE once connected
## Use Cases
#### Action Use Cases
When you ask CORE to perform Gmail tasks, it uses MCP tools to execute your requests:
**Scenario**: Create and send emails programmatically with attachments and formatting
```
"Send an email to client@example.com with subject 'Project Update'
and attach the Q4 report PDF from my desktop"
```
The agent will use `send_email` to send immediately with HTML formatting, multiple recipients (To, CC, BCC), attachments, and threading support. Use `draft_email` to create a draft for later modification.
**Scenario**: Find emails using powerful Gmail search syntax
```
"Search for all emails from client@example.com sent after January 1st
that have attachments and contain the word 'invoice'"
```
The agent will use `search_emails` with Gmail's query syntax to find emails by sender, subject, date range, attachments, and complex criteria with automatic timezone conversion.
**Scenario**: Organize and automate email management
```
"Create a label called 'Important Clients', then set up a filter
to automatically apply this label to emails from client@example.com"
```
The agent will:
1. Use `create_label` to create custom labels for categorization
2. Use `create_filter_from_template` to automatically organize incoming mail
3. Apply filters to individual or batch emails for organization
**Scenario**: Download and manage email attachments
```
"Find the latest email from finance@company.com with PDF attachments
and download all attachments to my Downloads folder"
```
The agent will first use `read_email` to get attachment IDs and metadata (filename, size, MIME type), then use `download_attachment` to save them to custom locations.
**Scenario**: Efficiently handle large numbers of emails
```
"Find all emails from last month labeled 'newsletter'
and delete them in batches"
```
The agent will use `search_emails` to find matching emails, then use `batch_delete_emails` to process thousands of emails in controlled batches with automatic error handling and rate limit management.
**Scenario**: Build automated workflows for email management
```
"Search for all unread emails from support@example.com,
apply the 'Support' label, and mark them as read"
```
The agent will combine `search_emails` with `batch_modify_emails` to search for emails matching criteria, apply labels automatically, and create filters for ongoing automation.
#### Proactive Use Cases
With webhooks enabled, CORE monitors Gmail 24/7 and acts automatically based on your instructions:
**Trigger**: Email received from specific domain or sender
**Automated Action**: Forward to WhatsApp and prioritize
```
"When I receive an email from @importantclient.com,
immediately forward the subject and preview to my WhatsApp,
mark it with 'VIP' label,
and save sender details to CORE memory"
```
Never miss important emails. CORE routes critical messages to your preferred channel and flags them for immediate attention.
**Trigger**: Email received with "invoice" in subject from accounting domain
**Automated Action**: Extract data and create tracking entry
```
"When an invoice email arrives from accounting@company.com,
extract the invoice number, amount, and due date,
save to CORE memory with label 'invoices',
and create a task in Todoist to process it"
```
Automate invoice tracking. CORE extracts structured data from emails and creates action items across your workflow.
**Trigger**: Email received at support email address
**Automated Action**: Create Linear issue and auto-respond
```
"When an email arrives at support@company.com,
create a Linear issue with the email content,
assign it to the support team,
and send an auto-reply confirming we received their message"
```
Convert emails to tickets instantly. CORE creates tracking issues in Linear and sends confirmation replies automatically.
**Trigger**: Email received from newsletter senders
**Automated Action**: Organize and summarize
```
"When a newsletter arrives (identified by 'unsubscribe' link),
apply the 'Newsletters' label,
extract key headlines,
save to CORE memory for weekly digest,
and mark as read"
```
Tame newsletter overload. CORE automatically categorizes, extracts insights, and organizes newsletters for later review.
**Trigger**: Email contains meeting invitation or calendar event
**Automated Action**: Add to calendar and prep materials
```
"When an email contains a meeting invitation,
extract the date, time, and attendees,
add it to Google Calendar,
search CORE memory for past context with attendees,
and send me a prep summary 1 hour before the meeting"
```
Prepare for meetings automatically. CORE parses invitations, schedules events, and provides context from past interactions.
**Trigger**: Email received with PDF attachment from specific sender
**Automated Action**: Download, extract, and notify
```
"When I receive an email with a PDF from contracts@company.com,
download the attachment,
extract key terms and dates,
save to CORE memory with label 'contracts',
and notify legal team on Slack"
```
Process attachments intelligently. CORE downloads files, extracts information, and routes to the right team automatically.
## Scopes
* `gmail.send` - Send emails on behalf of the user
* `gmail.compose` - Create and modify drafts
* `gmail.readonly` - Read email messages and settings
* `gmail.modify` - Manage labels and organize emails
* `gmail.labels` - Create and manage labels
* `gmail.settings.basic` - Manage filters and email settings
* `gmail.metadata` - Access email headers and metadata
## Available MCP Tools
The Gmail integration provides 20+ tools for comprehensive email management:
| Tool Name | Description |
| ------------------- | ----------------------------------------------------------------------------- |
| `send_email` | Send a new email with support for attachments, HTML formatting, and threading |
| `draft_email` | Create a draft email without sending it for later modification |
| `read_email` | Retrieve the full content of a specific email message with headers and body |
| `read_email_thread` | Retrieve all messages in an email thread/conversation in chronological order |
| `modify_email` | Modify email labels (move to folders, apply/remove tags) |
| `delete_email` | Permanently delete an email message |
| Tool Name | Description |
| ----------------------------- | ------------------------------------------------------------------------------- |
| `search_emails` | Search for emails using Gmail's powerful search syntax with timezone conversion |
| `create_filter` | Create a new Gmail filter with custom criteria and actions |
| `create_filter_from_template` | Create a filter using a pre-defined template for common scenarios |
| `list_filters` | Retrieve all Gmail filters with their criteria and actions |
| `get_filter` | Get details of a specific Gmail filter by ID |
| `delete_filter` | Delete a Gmail filter |
| Tool Name | Description |
| --------------------- | -------------------------------------------------------------- |
| `list_email_labels` | Retrieve all available Gmail labels (system and user-created) |
| `create_label` | Create a new Gmail label for organizing emails |
| `update_label` | Update properties of an existing Gmail label |
| `delete_label` | Delete a Gmail label (emails keep their other labels) |
| `get_or_create_label` | Get an existing label by name or create it if it doesn't exist |
| Tool Name | Description |
| --------------------- | --------------------------------------------------------- |
| `batch_modify_emails` | Modify labels for multiple emails efficiently in batches |
| `batch_delete_emails` | Permanently delete multiple emails efficiently in batches |
| Tool Name | Description |
| --------------------- | ------------------------------------------------------------ |
| `download_attachment` | Download an email attachment to a specified location on disk |
## Triggers
Gmail triggers enable CORE's Meta Agent to wake up and act proactively when events are detected via scheduled polling.
| Event | Description |
| ------------------------- | ------------------------------------------------- |
| `GMAIL_MESSAGE_RECEIVED` | Triggered when a new email is received |
| `GMAIL_MESSAGE_SENT` | Triggered when an email is sent from your account |
| `GMAIL_MESSAGE_LABELED` | Triggered when a label is added to an email |
| `GMAIL_MESSAGE_UNLABELED` | Triggered when a label is removed from an email |
| `GMAIL_MESSAGE_STARRED` | Triggered when an email is starred |
| `GMAIL_MESSAGE_TRASHED` | Triggered when an email is moved to trash |
| Event | Description |
| ----------------------- | ---------------------------------------- |
| `GMAIL_THREAD_RECEIVED` | Triggered when a new email thread starts |
| `GMAIL_THREAD_REPLIED` | Triggered when you reply to a thread |
| Event | Description |
| --------------------- | --------------------------------------------- |
| `GMAIL_LABEL_CREATED` | Triggered when a new label is created |
| `GMAIL_LABEL_UPDATED` | Triggered when a label is renamed or modified |
| `GMAIL_LABEL_DELETED` | Triggered when a label is deleted |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Google Calendar
Source: https://docs.getcore.me/toolkit/google-calendar
Schedule and manage calendar events with availability checking
## Overview
Integrate Google Calendar to schedule meetings, manage events, and check availability directly from CORE. Access 8 powerful tools for complete calendar management without leaving your workspace.
## Setup Guide
* `Authentication Type` : OAuth 2.0 (Google)
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **Google Calendar** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to Google to authorize the application
5. Grant the required permissions to access your calendars
6. You'll be redirected back to CORE once connected
## Use Cases
When you ask CORE to perform Google Calendar tasks, it uses MCP tools to execute your requests:
**Scenario**: Quickly create a meeting with multiple attendees and send invitations
```
"Create a meeting called 'Team Sync' next Wednesday from 2:00 PM to 3:00 PM
with attendees alice@company.com, bob@company.com, and carol@company.com.
Add a Google Meet link and set a 15-minute email reminder"
```
The agent will use `create_event` to create the event with all attendees, Google Meet conference link, email or popup reminders, and recurrence rules in RRULE format.
**Scenario**: Find available time slots before proposing a meeting time
```
"Check my availability for January 20th from 9 AM to 5 PM,
and show me all existing events for that day"
```
The agent will use `get_freebusy` to check availability and `list_events` to show scheduled events, helping you find open time slots.
**Scenario**: Create recurring team meetings or recurring personal tasks
```
"Create a weekly team standup meeting every Monday, Wednesday, and Friday
at 9:00 AM for the next 12 weeks with the development team"
```
The agent will use `create_event` with recurrence rules (RRULE format) to set up the recurring meeting.
**Scenario**: Work with multiple calendars and check availability across them
```
"List all my calendars, then check my availability
across my work and personal calendars for next Tuesday"
```
The agent will:
1. Use `list_calendars` to see all available calendars
2. Use `get_freebusy` with multiple calendar IDs to check combined availability
**Scenario**: Add events using natural language without specifying all details
```
"Quick add: 'Lunch with Mark at Italian Bistro tomorrow at noon'"
```
The agent will use `quick_add_event` to parse the natural language and create the event automatically.
**Scenario**: Modify an existing meeting time or attendee list
```
"Update the Q1 Planning meeting to move it from 10 AM to 3 PM
and add dev-lead@company.com as an attendee"
```
The agent will use `get_event` to retrieve the event details, then `update_event` to apply the changes.
**Scenario**: Identify available meeting times by checking free/busy across attendee calendars
```
"Find a 1-hour slot on January 22nd when john@company.com,
jane@company.com, and I are all available"
```
The agent will use `get_freebusy` with all three calendar IDs to identify overlapping free time.
**Scenario**: Remove cancelled or rescheduled events
```
"Delete the old 'Conference Call' event from January 10th
and don't send notifications to attendees"
```
The agent will use `delete_event` to remove the event without notifying attendees.
## Scopes
* `calendar.readonly` - Read access to your calendars
* `calendar.events` - Read and write access to calendar events
* `calendar.events.readonly` - Read access to event details
* `calendar.freebusy` - Access to free/busy information
* `calendar.settings.readonly` - Access to calendar settings
## Available MCP Tools
The Google Calendar integration provides 8 essential tools for comprehensive calendar management:
| Tool Name | Description |
| -------------- | ---------------------------------------------------------------------------- |
| `create_event` | Create a new calendar event with attendees, reminders, and Google Meet link |
| `get_event` | Get detailed information about a specific calendar event |
| `list_events` | List calendar events within a specified time range with search and filtering |
| `update_event` | Update an existing calendar event including time, attendees, and recurrence |
| `delete_event` | Delete a calendar event with optional notification to attendees |
| Tool Name | Description |
| ----------------- | ----------------------------------------------------------------------- |
| `list_calendars` | List all calendars accessible to the user with access role and metadata |
| `quick_add_event` | Create an event using natural language parsing (e.g., "Dinner at 7pm") |
| Tool Name | Description |
| -------------- | ------------------------------------------------------------------ |
| `get_freebusy` | Retrieve free/busy information for calendars to check availability |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Google Docs
Source: https://docs.getcore.me/toolkit/google-docs
Document creation and editing with rich text formatting
## Overview
Integrate Google Docs to create, edit, and format documents seamlessly from CORE. Access 8 tools for complete document management including text manipulation, rich formatting, image insertion, and automated report generation without leaving your workspace.
## Setup Guide
* `Authentication Type` : OAuth 2.0 (Google)
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **Google Docs** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to Google to authorize the application
5. Grant the required permissions
6. You'll be redirected back to CORE once connected
## Use Cases
When you ask CORE to perform Google Docs tasks, it uses MCP tools to execute your requests:
**Scenario**: Create professional documents programmatically with structured content
```
"Create a new document titled 'Q1 2026 Strategy Report',
add a header section with formatted text, and insert our company logo"
```
The agent will:
1. Use `create_document` to generate the new document
2. Use `append_text` to add content sections
3. Use `format_text` to apply styling and structure
4. Use `insert_image` to add the logo
**Scenario**: Modify existing documents with text insertions and replacements
```
"Read the 'Meeting Notes' document, replace all occurrences of 'TBD' with 'To Be Determined',
and append today's action items to the end"
```
The agent will:
1. Use `read_document` to understand current content
2. Use `replace_text` to update placeholder text
3. Use `append_text` to add new sections
**Scenario**: Apply professional formatting with consistent styling
```
"Format all section headers in the document as bold 16pt text,
make important notes italic, and highlight key metrics in blue"
```
The agent will use `format_text` to apply styling including bold, italic, font sizes, and colors to specific text ranges.
**Scenario**: Embed visual content in documents for enhanced presentations
```
"Insert the quarterly sales chart at the beginning of the report,
and add product screenshots in the features section"
```
The agent will use `insert_image` with valid image URIs to embed pictures, charts, or screenshots at specific locations with custom sizing.
**Scenario**: Build automated document generation workflows for recurring reports
```
"Create a weekly status report with this week's metrics,
format the headers, add the performance charts, and share the link"
```
The agent will:
1. Use `create_document` for template creation
2. Use `append_text` for dynamic content insertion
3. Use `format_text` for consistent formatting
4. Use `insert_image` for visual elements
## Scopes
* `https://www.googleapis.com/auth/documents` - Read and write access to documents
* `https://www.googleapis.com/auth/drive.readonly` - Read-only access to Google Drive for file discovery
## Available MCP Tools
The Google Docs integration provides 8 tools for comprehensive document management:
| Tool Name | Description |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `list_documents` | Lists all Google Docs documents in the user's Google Drive with metadata including creation time, modification time, and direct links |
| `create_document` | Creates a new Google Doc with an optional title |
| `read_document` | Reads the full content of a Google Doc with optional view mode for suggestions |
| Tool Name | Description |
| -------------- | --------------------------------------------------------------------------------------------------- |
| `insert_text` | Inserts text at a specific location in a document. Default location is index 1 (start of document). |
| `append_text` | Appends text to the end of a document |
| `replace_text` | Replaces all occurrences of text in a document with case-sensitive or case-insensitive matching |
| Tool Name | Description |
| -------------- | ------------------------------------------------------------------------------------------------ |
| `format_text` | Applies formatting to text in a document including bold, italic, underline, font size, and color |
| `insert_image` | Inserts an image into a document at a specified location with optional sizing |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Google Sheets
Source: https://docs.getcore.me/toolkit/google-sheets
Spreadsheet management and data manipulation
## Overview
Integrate Google Sheets to manage spreadsheets, manipulate data, and automate reporting from CORE. Access 8 essential tools for complete spreadsheet management including data reading, writing, formatting, and batch operations without leaving your workspace.
## Setup Guide
* `Authentication Type` : OAuth 2.0 (Google)
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **Google Sheets** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to Google to authorize the application
5. Grant the required permissions
6. You'll be redirected back to CORE once connected
## Use Cases
When you ask CORE to perform Google Sheets tasks, it uses MCP tools to execute your requests:
**Scenario**: Extract data from spreadsheets for analysis, reporting, or processing
```
"List all my spreadsheets, then read data from the 'Sales Report' sheet
in the Q1 2026 spreadsheet and show me the totals"
```
The agent will:
1. Use `list_spreadsheets` to find the spreadsheet
2. Use `list_sheets` to discover available sheets
3. Use `read_range` to get the data you need
**Scenario**: Modify spreadsheet data programmatically with single or batch updates
```
"Update cell B2 in the 'Budget' sheet to 50000,
then update the entire row 5 with the new quarterly figures"
```
The agent will:
1. Use `write_to_cell` for updating single values
2. Use `write_range` for updating multiple cells at once
3. Use `batch_update` for complex operations with formatting
**Scenario**: Generate new spreadsheets for reports, exports, or data organization
```
"Create a new spreadsheet called 'Monthly Sales Report',
add headers in the first row, and populate it with this month's data"
```
The agent will:
1. Use `create_spreadsheet` with appropriate sheet titles
2. Use `write_range` to add headers and initial data
3. Use `append_range` to add records as they're generated
**Scenario**: Automate repetitive data tasks and keep spreadsheets synchronized
```
"Read the current inventory data from the warehouse sheet,
update the quantities based on today's orders, and write back the new values"
```
The agent will:
1. Use `read_range` to get current data
2. Process the data with business logic
3. Use `write_range` or `append_range` to update the spreadsheet
**Scenario**: Handle large volumes of data efficiently with batch append and update operations
```
"Add 100 new customer records to the end of the Customers sheet,
then format the header row as bold and sort by customer name"
```
The agent will:
1. Use `append_range` to add multiple rows of data efficiently
2. Use `batch_update` to apply formatting and sorting in one operation
## Scopes
* `https://www.googleapis.com/auth/spreadsheets` - Read and write access to spreadsheets
* `https://www.googleapis.com/auth/drive.readonly` - Read-only access to Google Drive for file discovery
## Available MCP Tools
The Google Sheets integration provides 8 tools for comprehensive spreadsheet management:
| Tool Name | Description |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_spreadsheets` | Lists all Google Sheets spreadsheets in the user's Google Drive with metadata including creation and modification times |
| `list_sheets` | Lists all sheets within a spreadsheet with metadata (sheetId, title, index, row count, column count). Does not include cell data. Use this to discover available sheets before fetching data. |
| Tool Name | Description |
| ------------ | ---------------------------------------------------------------------- |
| `read_range` | Reads values from a specified range in a spreadsheet using A1 notation |
| Tool Name | Description |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `write_range` | Writes values to a specified range in a spreadsheet, overwriting existing data |
| `write_to_cell` | Writes a single value to a specific cell in a spreadsheet |
| `append_range` | Appends values to the next available row in a specified range. Perfect for adding new records without overwriting existing data. |
| Tool Name | Description |
| -------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `create_spreadsheet` | Creates a new spreadsheet with optional initial sheets |
| `batch_update` | Performs batch updates for advanced operations like formatting, sorting, filtering, adding/removing sheets, and more |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Google Tasks
Source: https://docs.getcore.me/toolkit/google-tasks
Simple task lists integrated with Google Workspace
## Overview
Integrate Google Tasks to manage task lists, create and organize tasks, set due dates, and clear completed items directly from CORE. Access 12 tools for comprehensive task management including list creation, task hierarchies, filtering, and status tracking without leaving your workspace.
## Setup Guide
* `Authentication Type` : OAuth 2.0 (Google)
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **Google Tasks** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to Google to authorize the application
5. Grant the required permissions
6. You'll be redirected back to CORE once connected
## Use Cases
#### Action Use Cases
When you ask CORE to perform Google Tasks tasks, it uses MCP tools to execute your requests:
**Scenario**: Create and organize multiple task lists for different projects
```
"Create a new task list called 'Q1 2026 Goals' and add three tasks
with due dates for next month"
```
The agent will use `create_task_list` to create a new list, then `create_task` for each task with appropriate due dates.
**Scenario**: Build and maintain task hierarchies with parent-child relationships
```
"Create a parent task 'Launch new feature' and add three subtasks
for design, development, and testing"
```
The agent will:
1. Use `create_task` to create the parent task
2. Use `create_task` with the parent parameter for each subtask
3. Use `move_task` to reorganize if needed
**Scenario**: Keep tasks organized with flexible filtering
```
"Show me all incomplete tasks due this week across all my task lists"
```
The agent will use `list_task_lists` to get all lists, then `list_tasks` with filtering parameters (showCompleted, dueMin, dueMax) to find matching tasks.
**Scenario**: Maintain clean task lists by managing completed items
```
"Clear all completed tasks from my 'Personal' task list"
```
The agent will use `clear_completed_tasks` to remove all completed items from the specified list in one operation.
**Scenario**: Modify task details and status as work progresses
```
"Update the task 'Write documentation' to mark it as completed
and add a note about what was documented"
```
The agent will use `update_task` to modify the task status, notes, and other details as needed.
#### Proactive Use Cases
With webhooks enabled, CORE monitors Google Tasks 24/7 and acts automatically based on your instructions:
**Trigger**: New task created in specific list
**Automated Action**: Sync to other task managers
```
"When a task is created in my 'Work' task list,
create a matching task in Todoist with the same due date,
and if it has a due date within 3 days, add it to Linear as well"
```
Keep task managers synchronized. CORE maintains consistency across all your productivity tools.
**Trigger**: Task marked as completed
**Automated Action**: Log and analyze productivity
```
"When I complete a task in Google Tasks,
save it to CORE memory with label 'completed-tasks',
track my daily completion rate,
and send me a weekly productivity summary every Sunday"
```
Measure productivity automatically. CORE tracks completions and provides insights on your work patterns.
**Trigger**: Task due date approaching
**Automated Action**: Multi-channel reminders
```
"When a task's due date is tomorrow,
send me an email reminder in the morning,
add it to my Google Calendar as an all-day event,
and send a WhatsApp notification 2 hours before end of day"
```
Never miss deadlines. CORE sends timely reminders across multiple channels to keep you on track.
**Trigger**: Email received with specific label
**Automated Action**: Create task automatically
```
"When an email is labeled 'To-Do' in Gmail,
create a task in Google Tasks with the email subject as title,
add the sender's name in the notes,
and set the due date to 3 days from now"
```
Convert emails into actionable tasks. CORE bridges your inbox and task list automatically.
**Trigger**: Task completed with specific title pattern
**Automated Action**: Create next instance
```
"When I complete a task that starts with 'Weekly:',
automatically create a new task with the same title,
set the due date to 7 days from now,
and add it to the same task list"
```
Automate recurring tasks. CORE manages task recurrence based on completion patterns.
**Trigger**: Task created with meeting context
**Automated Action**: Link to calendar and prep
```
"When a task mentions a meeting or has 'meeting' in the title,
search my calendar for the relevant meeting,
add the task notes to the calendar event description,
and send me a reminder 1 hour before the meeting"
```
Connect tasks to meetings. CORE ensures action items are visible in calendar context.
## Scopes
* `https://www.googleapis.com/auth/tasks` - Read and write access to task lists and tasks
## Available MCP Tools
The Google Tasks integration provides 12 tools for comprehensive task management:
| Tool Name | Description |
| ------------------ | -------------------------------------------------------------------------- |
| `list_task_lists` | Returns all of the authenticated user's task lists with pagination support |
| `get_task_list` | Returns the authenticated user's specified task list with metadata |
| `create_task_list` | Creates a new task list for the authenticated user |
| `update_task_list` | Updates the authenticated user's specified task list |
| `delete_task_list` | Deletes the authenticated user's specified task list |
| Tool Name | Description |
| ------------- | ---------------------------------------------------------------------------- |
| `list_tasks` | Returns all tasks in the specified task list with advanced filtering options |
| `get_task` | Returns the specified task with full details and metadata |
| `create_task` | Creates a new task on the specified task list with support for subtasks |
| `update_task` | Updates the specified task with new values |
| `delete_task` | Deletes the specified task from the task list |
| Tool Name | Description |
| ----------------------- | ----------------------------------------------------------------------------------- |
| `move_task` | Moves the specified task to another position in the task list or changes its parent |
| `clear_completed_tasks` | Clears all completed tasks from the specified task list permanently |
### Triggers
Google Tasks triggers enable CORE's Meta Agent to wake up and act proactively when events are detected via scheduled polling.
| Event | Description |
| ----------------------------- | ---------------------------------------------------------------- |
| `GOOGLE_TASKS_TASK_CREATED` | Triggered when a new task is created |
| `GOOGLE_TASKS_TASK_UPDATED` | Triggered when a task is modified |
| `GOOGLE_TASKS_TASK_COMPLETED` | Triggered when a task is marked as completed |
| `GOOGLE_TASKS_TASK_DELETED` | Triggered when a task is deleted |
| `GOOGLE_TASKS_TASK_MOVED` | Triggered when a task is moved to a different position or parent |
| Event | Description |
| --------------------------- | ----------------------------------------- |
| `GOOGLE_TASKS_LIST_CREATED` | Triggered when a new task list is created |
| `GOOGLE_TASKS_LIST_UPDATED` | Triggered when a task list is modified |
| `GOOGLE_TASKS_LIST_DELETED` | Triggered when a task list is deleted |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# HubSpot
Source: https://docs.getcore.me/toolkit/hubspot
Comprehensive CRM for contacts, companies, deals, and ticket management
## Overview
Integrate HubSpot to manage your complete customer relationship management system directly from CORE. Access 20 tools for comprehensive CRM operations including contact management, company records, deal tracking, and support ticket handling without leaving your workspace.
## Setup Guide
* `Authentication Type` : OAuth 2.0
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **HubSpot** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to HubSpot to authorize the application
5. Grant the required permissions to your HubSpot account
6. You'll be redirected back to CORE once connected
## Use Cases
#### Action Use Cases
When you ask CORE to perform HubSpot tasks, it uses MCP tools to execute your requests:
**Scenario**: Maintain an up-to-date contact database with customer information
```
"Create a new contact for alice@company.com with first name Alice,
last name Smith, phone number 555-0123, and mark as a customer"
```
The agent will use `create_contact` to add the new contact, then `update_contact` if additional properties need to be modified later.
**Scenario**: Monitor sales pipeline and deal progress
```
"Search for all deals in the negotiation stage with amounts over $50,000,
then update the deal with ID 123 to move it to the contract stage"
```
The agent will use `search_deals` to find matching deals and `update_deal` to progress them through the pipeline.
**Scenario**: Manage customer support requests and track resolutions
```
"Create a new support ticket with subject 'Account login issue',
mark it as high priority, and search for similar tickets from the last week"
```
The agent will use `create_ticket` to register the issue and `search_tickets` to find related problems for context.
**Scenario**: Build and maintain accurate company records
```
"Search for companies in the technology industry,
then create a new company record for TechCorp with domain techcorp.com"
```
The agent will use `search_companies` to research the market and `create_company` to add the new organization.
**Scenario**: Automate deal progression and follow-ups
```
"Find all deals that haven't been updated in the last 30 days,
then create follow-up tasks by updating their stage and adding notes"
```
The agent will use `search_deals` to identify stalled opportunities and `update_deal` to move them forward.
**Scenario**: Synchronize customer data across systems
```
"Get all contacts from the customer lifecycle stage,
associate them with their company records,
and update their company information with the latest data"
```
The agent will use `get_contact`, `associate_objects`, and `update_company` to maintain data consistency.
**Scenario**: Create and manage your entire sales process
```
"Create a new deal called 'Enterprise Contract' with amount $100,000,
set it to the proposal stage, assign it to the sales team,
then associate it with the ABC Corp company account"
```
The agent will:
1. Use `create_deal` to initialize the opportunity
2. Use `update_deal` to set stage and owner information
3. Use `associate_objects` to link it to the company
**Scenario**: Organize and qualify leads efficiently
```
"Search for all contacts with 'lead' lifecycle stage from finance industry,
get details for the top 5, then update them to 'opportunity' stage"
```
The agent will use `search_contacts`, `get_contact`, and `update_contact` to manage the qualification process.
**Scenario**: Keep customer records complete and accurate
```
"Get the company record for ID 456,
search for all contacts associated with that company,
then update their company field if it's missing"
```
The agent will use `get_company`, `search_contacts`, and `update_contact` for data enrichment.
**Scenario**: Organize incoming support requests
```
"Search for all high-priority open tickets,
get details on each one, then create follow-up tasks or escalations"
```
The agent will use `search_tickets` and `get_ticket` to identify and manage urgent issues.
#### Proactive Use Cases
With webhooks enabled, CORE monitors HubSpot 24/7 and acts automatically based on your instructions:
**Trigger**: New contact created
**Automated Action**: Qualify and route leads
```
"When a new contact is created in HubSpot,
check if they're from a target industry,
automatically update their lead score,
assign to the appropriate sales rep,
and notify them on Slack with contact details"
```
Accelerate lead response. CORE qualifies and routes new leads to sales reps instantly.
**Trigger**: Deal moves to new pipeline stage
**Automated Action**: Notify team and update systems
```
"When a deal moves to 'Contract Sent' stage,
notify the sales manager on Slack,
create a task in Todoist to follow up in 3 days,
and save the deal details to CORE memory with label 'active-contracts'"
```
Track deal progression automatically. CORE keeps stakeholders informed as deals advance through the pipeline.
**Trigger**: Deal marked as closed won
**Automated Action**: Initiate onboarding workflow
```
"When a deal is closed won,
create a new project in Notion for customer onboarding,
send a welcome email with next steps,
create a Slack channel for the customer,
and notify the customer success team"
```
Start onboarding immediately. CORE triggers the entire customer success workflow when deals close.
**Trigger**: Ticket created with high priority
**Automated Action**: Escalate and track
```
"When a high-priority support ticket is created,
create a Linear issue for engineering,
notify the support lead on WhatsApp,
and add it to today's standup agenda in Google Docs"
```
Escalate urgent issues instantly. CORE routes critical tickets across teams for rapid resolution.
**Trigger**: Deal closed won with amount
**Automated Action**: Update metrics and celebrate
```
"When a deal is won,
save the deal amount and details to CORE memory with label 'revenue',
calculate the running total for this month,
post a celebration message in #sales-wins on Slack,
and update the revenue tracking spreadsheet"
```
Track revenue in real-time. CORE maintains metrics and celebrates wins with the team automatically.
**Trigger**: Contact updated with new company
**Automated Action**: Enrich company data
```
"When a contact is associated with a new company,
search for the company on LinkedIn,
update company details in HubSpot with industry and size,
and check if there are existing deals with that company"
```
Maintain complete CRM data. CORE enriches records automatically to keep your database accurate and comprehensive.
## Scopes
* `crm.objects.contacts.read` - Read contact information
* `crm.objects.contacts.write` - Create and update contacts
* `crm.objects.contacts.delete` - Delete contacts
* `crm.objects.companies.read` - Read company information
* `crm.objects.companies.write` - Create and update companies
* `crm.objects.companies.delete` - Delete companies
* `crm.objects.deals.read` - Read deal information
* `crm.objects.deals.write` - Create and update deals
* `crm.objects.deals.delete` - Delete deals
* `crm.objects.tickets.read` - Read ticket information
* `crm.objects.tickets.write` - Create and update tickets
* `crm.objects.tickets.delete` - Delete tickets
* `crm.objects.contacts.owned` - Access owned contacts
## Available MCP Tools
The HubSpot integration provides 20 tools for comprehensive CRM management:
| Tool Name | Description |
| ----------------- | ---------------------------------------------------------------- |
| `create_contact` | Creates a new contact in HubSpot with email and optional details |
| `get_contact` | Retrieves a contact by ID with all properties |
| `update_contact` | Updates contact properties (name, phone, company, etc.) |
| `search_contacts` | Searches for contacts using text query or advanced filters |
| `delete_contact` | Deletes a contact permanently |
| Tool Name | Description |
| ------------------ | ----------------------------------------------------------- |
| `create_company` | Creates a new company with name and optional details |
| `get_company` | Retrieves a company by ID with all properties |
| `update_company` | Updates company properties (domain, industry, size, etc.) |
| `search_companies` | Searches for companies using text query or advanced filters |
| `delete_company` | Deletes a company permanently |
| Tool Name | Description |
| -------------- | --------------------------------------------------------- |
| `create_deal` | Creates a new deal with name, stage, and optional amount |
| `get_deal` | Retrieves a deal by ID with all properties |
| `update_deal` | Updates deal properties (amount, stage, close date, etc.) |
| `search_deals` | Searches for deals using text query or advanced filters |
| `delete_deal` | Deletes a deal permanently |
| Tool Name | Description |
| ---------------- | --------------------------------------------------------------- |
| `create_ticket` | Creates a new support ticket with subject and pipeline stage |
| `get_ticket` | Retrieves a ticket by ID with all properties |
| `update_ticket` | Updates ticket properties (status, priority, description, etc.) |
| `search_tickets` | Searches for tickets using text query or advanced filters |
| `delete_ticket` | Deletes a ticket permanently |
| Tool Name | Description |
| ------------------- | -------------------------------------------------------------------- |
| `associate_objects` | Creates associations between contacts, companies, deals, and tickets |
## Triggers
HubSpot triggers enable CORE's Meta Agent to wake up and act proactively when events are detected via scheduled polling.
| Event | Description |
| ------------------------- | ---------------------------------------------- |
| `HUBSPOT_CONTACT_CREATED` | Triggered when a new contact is created |
| `HUBSPOT_CONTACT_UPDATED` | Triggered when contact properties are modified |
| `HUBSPOT_CONTACT_DELETED` | Triggered when a contact is deleted |
| `HUBSPOT_CONTACT_MERGED` | Triggered when contacts are merged together |
| Event | Description |
| ------------------------- | ---------------------------------------------- |
| `HUBSPOT_COMPANY_CREATED` | Triggered when a new company is created |
| `HUBSPOT_COMPANY_UPDATED` | Triggered when company properties are modified |
| `HUBSPOT_COMPANY_DELETED` | Triggered when a company is deleted |
| Event | Description |
| ---------------------------- | --------------------------------------------------------- |
| `HUBSPOT_DEAL_CREATED` | Triggered when a new deal is created |
| `HUBSPOT_DEAL_UPDATED` | Triggered when deal properties are modified |
| `HUBSPOT_DEAL_STAGE_CHANGED` | Triggered when a deal moves to a different pipeline stage |
| `HUBSPOT_DEAL_CLOSED_WON` | Triggered when a deal is marked as closed won |
| `HUBSPOT_DEAL_CLOSED_LOST` | Triggered when a deal is marked as closed lost |
| Event | Description |
| ------------------------------- | ---------------------------------------------- |
| `HUBSPOT_TICKET_CREATED` | Triggered when a new support ticket is created |
| `HUBSPOT_TICKET_UPDATED` | Triggered when ticket properties are modified |
| `HUBSPOT_TICKET_STATUS_CHANGED` | Triggered when ticket status changes |
| `HUBSPOT_TICKET_CLOSED` | Triggered when a ticket is closed |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Linear
Source: https://docs.getcore.me/toolkit/linear
Modern issue tracking and project management platform for seamless team collaboration
## Overview
Integrate Linear to manage issues, projects, workflows, and team collaboration directly from CORE. Access 20+ tools for complete issue tracking and project management operations without leaving your workspace.
## Setup Guide
* `Authentication Type` : API Key
## How to Connect
1. Navigate to [Linear Settings](https://linear.app/settings) โ **API**
2. Click **Create new API key** under Personal API keys
3. Copy the generated key (it will only be shown once and keep it secure)
4. Go to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
5. Click on the **Linear** card
6. Paste the API key into the configuration field
7. Click **Connect** to establish the integration
## Use Cases
#### Action Use Cases
When you ask CORE to perform Linear tasks, it uses MCP tools to execute your requests:
**Scenario**: Automatically create issues in Linear from your workflow
```
"Create an issue in Linear titled 'Implement user authentication'
in the Engineering team with high priority,
assign it to @john, and add a due date of next Friday"
```
The agent will use `linear_create_issue` to create the issue with all specified parameters and return the issue URL and ID.
**Scenario**: Track project progress and update issue states
```
"Show me all issues in the 'Q1 Product Launch' project,
then move all completed issues to the 'Done' state
and update their status"
```
The agent will:
1. Use `linear_list_projects` to find the project
2. Use `linear_get_project` to view issues
3. Use `linear_update_issue` to change states
**Scenario**: Find specific issues across your workspace
```
"Search for all open issues assigned to me in the Engineering team
that have 'backend' label or are marked as urgent"
```
The agent will use `linear_search_issues` with appropriate filters to find matching issues and display them with relevant details.
**Scenario**: View team information and coordinate work
```
"Show me the Engineering team members and their assigned issues,
then create a comment on issue ENG-42 with the meeting summary"
```
The agent will:
1. Use `linear_get_team` to fetch team members
2. Use `linear_get_issue` to view current issue
3. Use `linear_create_comment` to add the meeting notes
**Scenario**: Organize work into sprints/cycles
```
"Create a new sprint called 'Sprint 15' starting next Monday for 2 weeks,
then find all issues with 'next-sprint' label and add them to the cycle"
```
The agent will:
1. Use `linear_create_cycle` to create the sprint
2. Use `linear_search_issues` to find labeled issues
3. Use `linear_update_issue` to assign issues to the cycle
**Scenario**: Quickly set up new projects with standard configuration
```
"Create a new project 'Mobile App Redesign' for the Design and Engineering teams,
add labels for 'design', 'development', and 'testing',
and create a sprint for the first 2 weeks"
```
The agent will:
1. Use `linear_create_project` to create the project
2. Use `linear_create_label` to create team labels
3. Use `linear_create_cycle` to create the sprint
**Scenario**: Keep issues updated and monitor progress
```
"Show me all 'In Progress' issues in my team,
update the ones with completed subtasks to 'Review',
and add a comment indicating they're ready for review"
```
The agent will:
1. Use `linear_search_issues` to find in-progress issues
2. Use `linear_update_issue` to change states
3. Use `linear_create_comment` to add status updates
**Scenario**: Organize issues with labels and priorities
```
"Find all unassigned issues in the Engineering team,
assign them to team members based on workload,
and set appropriate priority levels"
```
The agent will use `linear_search_issues` to find unassigned items and `linear_update_issue` to assign and prioritize them.
#### Proactive Use Cases
With webhooks enabled, CORE monitors Linear 24/7 and acts automatically based on your instructions:
**Trigger**: New GitHub issue created
**Automated Action**: Create corresponding Linear issue
```
"When a bug issue is created in GitHub with label 'needs-triage',
automatically create a Linear issue in the Engineering team,
link it to the GitHub issue,
and assign it to the on-call engineer"
```
Keep GitHub and Linear in sync automatically. CORE creates linked issues across platforms, maintaining a single source of truth.
**Trigger**: Issue status changed to "Done"
**Automated Action**: Notify stakeholders and update memory
```
"When an issue is moved to 'Done' status,
save the completion details to CORE memory,
and send a summary to the project Slack channel"
```
Broadcast progress automatically. CORE tracks completed work, updates memory, and keeps teams informed on Slack.
**Trigger**: Issue priority changed to "Urgent"
**Automated Action**: Notify team and create follow-up tasks
```
"When an issue is marked as urgent priority,
notify the team lead on WhatsApp,
send a Slack message to #engineering-urgent,
and add it to the current sprint if not already assigned"
```
Escalate critical issues instantly. CORE routes urgent work to the right people across multiple channels.
**Trigger**: Issue completed within active cycle
**Automated Action**: Update sprint metrics and notify
```
"When an issue is completed in the current sprint,
save the completion data to memory with label 'sprint-metrics',
calculate remaining sprint capacity,
and send a daily summary of progress to #team-standup"
```
Track sprint velocity automatically. CORE monitors completions, calculates metrics, and provides daily progress updates.
**Trigger**: Issue comment contains "blocked"
**Automated Action**: Escalate and track blockage
```
"When a comment on an issue contains the word 'blocked',
change the issue status to 'Blocked',
notify the project manager on Slack,
and create a tracking entry in CORE memory"
```
Surface blockers immediately. CORE detects blocking comments and escalates to unblock work faster.
**Trigger**: Issue assigned to team member
**Automated Action**: Check workload and suggest rebalancing
```
"When an issue is assigned to someone,
check their current issue count,
and if they have more than 10 open issues,
send a notification to the team lead suggesting workload review"
```
Prevent team burnout. CORE monitors assignments and flags potential overload before it becomes a problem.
## Available MCP Tools
The Linear integration provides 20+ tools for comprehensive issue tracking and project management:
| Tool Name | Description |
| ---------------------- | -------------------------------------------------------------------------------- |
| `linear_create_issue` | Create a new issue with title, description, assignee, and priority |
| `linear_update_issue` | Update an existing issue (title, description, state, assignee, etc.) |
| `linear_get_issue` | Get detailed information about a specific issue |
| `linear_search_issues` | Search for issues with advanced filters (team, assignee, state, project, labels) |
| `linear_delete_issue` | Delete an issue |
| Tool Name | Description |
| ----------------------- | ------------------------------------------------- |
| `linear_create_comment` | Create a comment on an issue (markdown supported) |
| `linear_update_comment` | Update an existing comment |
| `linear_delete_comment` | Delete a comment |
| Tool Name | Description |
| ----------------------- | -------------------------------------------------------------- |
| `linear_create_project` | Create a new project with teams, lead, and dates |
| `linear_update_project` | Update project details (name, description, state, lead) |
| `linear_list_projects` | List all projects with optional team filtering |
| `linear_get_project` | Get detailed project information including issues and progress |
| Tool Name | Description |
| ------------------- | ------------------------------------------------------ |
| `linear_list_teams` | List all teams in the organization |
| `linear_get_team` | Get team details including members and workflow states |
| Tool Name | Description |
| ------------------- | -------------------------------------------------------- |
| `linear_list_users` | List all users in the organization |
| `linear_get_user` | Get details of a specific user and their assigned issues |
| `linear_get_viewer` | Get details of the authenticated user and organization |
| Tool Name | Description |
| ----------------------------- | ------------------------------------------------- |
| `linear_list_workflow_states` | List workflow states with optional team filtering |
| Tool Name | Description |
| --------------------- | ------------------------------------------------------ |
| `linear_create_label` | Create a new label with optional color and description |
| `linear_list_labels` | List all labels with optional team filtering |
| Tool Name | Description |
| --------------------- | ---------------------------------------------- |
| `linear_create_cycle` | Create a sprint/cycle with start and end dates |
| `linear_list_cycles` | List all cycles with progress information |
| `linear_get_cycle` | Get cycle details including assigned issues |
### Triggers
Linear triggers enable CORE's Meta Agent to wake up and act proactively when events are detected via scheduled polling.
| Event | Description |
| ------------------------------- | ---------------------------------------------------------------------- |
| `LINEAR_ISSUE_CREATED` | Triggered when a new issue is created |
| `LINEAR_ISSUE_UPDATED` | Triggered when an issue is modified (title, description, status, etc.) |
| `LINEAR_ISSUE_DELETED` | Triggered when an issue is deleted |
| `LINEAR_ISSUE_STATUS_CHANGED` | Triggered when an issue's workflow state changes |
| `LINEAR_ISSUE_ASSIGNED` | Triggered when an issue is assigned to a user |
| `LINEAR_ISSUE_PRIORITY_CHANGED` | Triggered when an issue's priority is updated |
| Event | Description |
| ------------------------ | --------------------------------------------- |
| `LINEAR_COMMENT_CREATED` | Triggered when a comment is added to an issue |
| `LINEAR_COMMENT_UPDATED` | Triggered when a comment is edited |
| `LINEAR_COMMENT_DELETED` | Triggered when a comment is deleted |
| Event | Description |
| ------------------------------- | ----------------------------------------- |
| `LINEAR_PROJECT_CREATED` | Triggered when a new project is created |
| `LINEAR_PROJECT_UPDATED` | Triggered when a project is modified |
| `LINEAR_PROJECT_STATUS_CHANGED` | Triggered when a project's status changes |
| Event | Description |
| ------------------------ | ------------------------------------------ |
| `LINEAR_CYCLE_STARTED` | Triggered when a new cycle/sprint starts |
| `LINEAR_CYCLE_COMPLETED` | Triggered when a cycle/sprint is completed |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Notion
Source: https://docs.getcore.me/toolkit/notion
All-in-one workspace for notes, databases, and collaborative documentation with powerful knowledge management tools
## Overview
Integrate Notion to create, organize, and manage pages, databases, and collaborative documentation directly from CORE. Access 15+ tools for complete knowledge management operations without leaving your workspace.
## Setup Guide
* `Authentication Type` : OAuth 2.0
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **Notion** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to Notion to authorize the application
5. Grant the required permissions (select specific workspaces or grant access to all)
6. You'll be redirected back to CORE once connected
## Use Cases
When you ask CORE to perform Notion tasks, it uses MCP tools to execute your requests:
**Scenario**: Quickly create structured notes and organize them hierarchically
```
"Create a new Notion page titled 'Q1 Planning' with content about
quarterly goals, and then create three subpages under it:
'January Goals', 'February Goals', and 'March Goals'"
```
The agent will:
1. Use `notion_create_page` to create the main page
2. Use `notion_create_page` multiple times with the parent set to create subpages
3. Organize the hierarchy automatically
**Scenario**: Extract data from databases and update records
```
"Query my 'Projects' database for all items marked as 'In Progress',
then update each one to set the 'Last Reviewed' date to today"
```
The agent will:
1. Use `notion_get_database` to understand the schema
2. Use `notion_query_database` with filters to find items in progress
3. Use `notion_update_page` on each result to update the date property
**Scenario**: Find specific pages or databases across your entire workspace
```
"Search for all pages mentioning 'customer feedback' in my workspace"
```
The agent will use `notion_search` to find matching pages and databases, returning results with metadata and links.
**Scenario**: Enable team contributions and discussions
```
"Get all users in my workspace and show which ones have commented
on my 'Team Roadmap' page in the last week"
```
The agent will:
1. Use `notion_list_users` to get team members
2. Use `notion_get_page` to retrieve the page
3. Use `notion_get_comments` to check recent discussions
**Scenario**: Maintain up-to-date project documentation
```
"Create a new database for tracking project milestones with properties
for Title, Status, Due Date, and Owner. Then create entries for
Q1, Q2, Q3, and Q4 deliverables"
```
The agent will:
1. Use `notion_create_database` with the specified properties
2. Use `notion_create_database_item` to add each milestone entry
3. Populate properties with the correct data types
**Scenario**: Organize meeting notes and action items
```
"Create a page for today's meeting notes under my 'Meetings' database.
Title it with today's date and the team name.
Add the attendees as properties and create an action items section"
```
The agent will:
1. Use `notion_get_database` to understand the meetings schema
2. Use `notion_create_database_item` to create a new meeting entry
3. Populate all properties and create the content structure
**Scenario**: Maintain organized documentation
```
"Update my 'Documentation' database by moving all archived pages
to the 'Archive' folder and removing outdated entries"
```
The agent will:
1. Use `notion_query_database` to find archived items
2. Use `notion_move_pages` to reorganize the hierarchy
3. Use `notion_update_page` to mark items as archived
**Scenario**: Extract structured data from databases
```
"Query my 'Contacts' database for all entries in the 'Sales' company,
and export their names, emails, and last contact dates"
```
The agent will:
1. Use `notion_get_database` to understand the schema
2. Use `notion_query_database` with appropriate filters
3. Extract and format the data for analysis or export
## Scopes
* `read_content` - Read access to pages and databases
* `update_content` - Create and update pages
* `insert_content` - Create and update databases
* `read_user` - Access to user profile information
* `read_comment` - Access to comments and discussions
* `insert_comment` - Create comments on pages and blocks
## Available MCP Tools
The Notion integration provides 15+ tools for comprehensive knowledge management:
| Tool Name | Description |
| ------------------------------- | ---------------------------------------------------------------- |
| `notion_create_page` | Create one or more Notion pages with properties and content |
| `notion_get_page` | Retrieve a page with full content, metadata, and all blocks |
| `notion_update_page` | Update page properties or content with flexible editing commands |
| `notion_retrieve_page_property` | Retrieve specific page property details |
| `notion_move_pages` | Move pages or databases to a new parent location |
| Tool Name | Description |
| ----------------------------- | -------------------------------------------- |
| `notion_query_database` | Query a database with filters and sorting |
| `notion_get_database` | Retrieve database schema and metadata |
| `notion_create_database` | Create a new database with custom properties |
| `notion_update_database` | Update database properties, title, or status |
| `notion_create_database_item` | Create items in a database with properties |
| Tool Name | Description |
| --------------- | ------------------------------------------- |
| `notion_search` | Search pages and databases across workspace |
| Tool Name | Description |
| ------------------- | ---------------------------------- |
| `notion_get_user` | Retrieve specific user information |
| `notion_list_users` | List all users in the workspace |
| `notion_get_me` | Get current bot user information |
| Tool Name | Description |
| ----------------------- | ------------------------------------- |
| `notion_create_comment` | Create a comment on a page or block |
| `notion_get_comments` | Retrieve comments on a specific block |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Toolkit Overview
Source: https://docs.getcore.me/toolkit/overview
A unified actions layer for any AI agent
## What is the Toolkit?
CORE's Toolkit is a unified actions layer โ 50+ app integrations exposed through a single MCP endpoint. Any MCP-compatible agent can use it: Claude Code, Cursor, Windsurf, CORE's own Agent, or your custom agents.
Connect an app once on the [CORE Dashboard](https://app.getcore.me), and every connected agent gets access. No need to build or maintain separate tool integrations per agent.
## Why Use CORE's Toolkit?
1. **One endpoint, all your apps**: Instead of configuring a separate MCP server for GitHub, another for Slack, another for Calendar โ connect CORE once and get everything through a single endpoint. One connection, 15+ integrations.
2. **On-demand tool loading**: CORE doesn't dump all tools into your agent's context. When an agent needs to act, it describes what it wants to do. CORE filters and returns only the 1-3 relevant tools with their schemas. This saves thousands of tokens and keeps your agent focused.
3. **Works with any MCP-compatible agent**: Claude Code, Cursor, Windsurf, your custom agents โ anything that speaks MCP gets the full toolkit without extra setup.
## How It Works
#### Connect apps on the CORE Dashboard
Connect each integration securelt and authenticates via OAuth or API keys
#### Agent describes intent
When a user ask a question, agent sends an intent query e.g "send a slack message" and gets back only the relevant tool schemas.
#### Agent executes
Agent then calls the action/tools with the right parameters, CORE handles the rest
```
You: "Create a GitHub issue for the auth bug and message Sarah on Slack"
Agent:
โ Calls get_integration_actions("create github issue") โ gets create_issue schema
โ Calls execute_integration_action(create_issue, {title, body, repo})
โ Calls get_integration_actions("send slack message") โ gets send_message schema
โ Calls execute_integration_action(send_message, {channel, text})
```
## Connecting via MCP
All toolkit actions are exposed through a single MCP endpoint. Instead of configuring separate MCP servers per app, you connect CORE once.
**Base MCP URL:**
```
https://app.getcore.me/api/v1/mcp
```
```
Traditional: Your AI Tool โ GitHub MCP Server (auth required)
Your AI Tool โ Linear MCP Server (auth required)
Your AI Tool โ Slack MCP Server (auth required)
With CORE: Your AI Tool โ CORE MCP Endpoint โ All Integrations (pre-authenticated)
```
See [MCP Configuration](/mcp/configuration) for query parameters and [Authentication](/mcp/authentication) for OAuth and API key setup.
***
## Webhooks & Triggers
CORE also supports **proactive automation**. When events happen in your connected apps e.g new email, GitHub issue created, Slack message in a channel, CORE can automatically respond based on your configured triggers.
Each integration page below lists its available webhook triggers alongside its action tools.
## Most Used Integrations
Manage repositories, issues, pull requests, and code reviews
Create and manage issues, projects, and workflows
Send, read, and manage emails with full search capabilities
Manage pages, databases, and knowledge bases
Personal and team task management
Create, update, and manage calendar events
***
## Communication & Collaboration
Team messaging, channels, and file sharing
Community management and server interactions
Email management with advanced filtering
Enterprise email solution with full capabilities
***
## Project & Task Management
Modern issue tracking and project planning
Personal and team task management
Simple task lists integrated with Google Workspace
***
## Development & Version Control
Complete GitHub API access for code management
DORA metrics and performance tracking
***
## Calendar & Scheduling
Event creation, scheduling, and availability checking
Meeting scheduling and availability management
***
## Knowledge & Documentation
Pages, databases, and collaborative workspaces
Document creation and editing
***
## Data & Spreadsheets
Spreadsheet management and data manipulation
***
## CRM & Sales
Contact, company, deal, and ticket management
***
## Request a New Integration
Don't see the integration you need? We'd love to hear from you!
Create an issue on GitHub to request a new integration
***
## Contribute an Integration
Want to build an integration yourself? Check out our comprehensive guide:
Learn how to create custom integrations for CORE
# Slack
Source: https://docs.getcore.me/toolkit/slack
Team messaging platform for channels, direct messages, and file sharing
## Overview
Integrate Slack to manage team communications, channels, messages, and collaborate seamlessly from CORE. Access 40+ tools for complete Slack operations including messaging, channel management, user coordination, and file sharing without leaving your workspace.
## Setup Guide
* `Authentication Type` : OAuth 2.0
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **Slack** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to Slack to authorize the application
5. Grant the required permissions to your workspace
6. You'll be redirected back to CORE once connected
## Use Cases
#### Action Use Cases
When you ask CORE to perform Slack tasks, it uses MCP tools to execute your requests:
**Scenario**: Broadcast important updates to specific channels
```
"Send a message to the #announcements channel saying 'New release v2.0 is live!'
then post the same message to #product-team"
```
The agent will use `slack_send_message` to deliver updates to multiple channels, keeping teams synchronized on important news.
**Scenario**: Find past discussions and decisions
```
"Search for all messages mentioning 'database migration' from the last week
and show me who was involved in those conversations"
```
The agent will use `slack_search_messages` to find relevant discussions and can follow up with `slack_get_message` to retrieve full context.
**Scenario**: Create and organize project channels
```
"Create a new private channel called 'project-alpha',
add team members john, jane, and mike to it,
and set the channel topic to 'Alpha project planning and tracking'"
```
The agent will:
1. Use `slack_create_channel` to create the private channel
2. Use `slack_invite_to_channel` to add team members
3. Use `slack_set_channel_topic` to set the channel description
**Scenario**: Acknowledge messages without creating noise
```
"Add a thumbsup reaction to the latest message from @sarah in #general,
and add a heart reaction to the announcement in #announcements"
```
The agent will use `slack_add_reaction` to provide quick acknowledgments and emoji responses.
**Scenario**: Stay updated on critical conversations
```
"Check #critical-alerts for any unread messages
and get a list of the last 10 messages from #security-updates"
```
The agent will use `slack_get_unread` and `slack_list_messages` to keep you informed on critical topics without missing important updates.
#### Proactive Use Cases
With webhooks enabled, CORE monitors Slack 24/7 and acts automatically based on your instructions:
**Trigger**: New message in `#sales-feedback` channel
**Automated Action**: Extract insights and save to CORE memory
```
"Whenever a message is posted in #sales-feedback,
extract the key insights and save them to my memory
with the label 'customer-feedback'"
```
CORE monitors the channel and automatically captures feedback without manual intervention. You can later search and analyze patterns across all feedback.
**Trigger**: New message in `#deployments` channel containing "released"
**Automated Action**: Send summary notification via WhatsApp
```
"When a release is posted in #deployments,
send me a WhatsApp message with a brief summary
of what was released"
```
Stay informed on releases without monitoring Slack. CORE watches for deployment messages and notifies you on your preferred channel.
**Trigger**: Direct message from specific users (e.g., your manager)
**Automated Action**: Cross-post to WhatsApp with priority flag
```
"If I receive a DM from @manager on Slack,
immediately forward it to me on WhatsApp
and mark it as urgent"
```
Never miss critical messages. CORE routes important communications to where you'll see them fastest.
**Trigger**: New user joins `#engineering` channel
**Automated Action**: Send onboarding resources and log to memory
```
"When someone joins #engineering,
send them our onboarding doc link
and add their name to the team members list in my memory"
```
Automate team onboarding. CORE welcomes new members and keeps your team roster updated automatically.
**Trigger**: Message contains keywords like "urgent", "critical", or "down"
**Automated Action**: Notify across channels and create task
```
"If anyone posts a message with 'production down' in #alerts,
notify me on WhatsApp immediately
and create a high-priority task in Linear"
```
CORE monitors for critical keywords and escalates issues across your entire workflow automatically.
## Scopes
* `chat:write` - Send messages to channels
* `chat:write.public` - Send messages to public channels
* `channels:read` - List and view channel information
* `channels:manage` - Create and archive channels
* `conversations:write` - Modify conversations (channels/DMs)
* `users:read` - List and view user profiles
* `users:read.email` - Access user email addresses
* `reactions:read` - View message reactions
* `reactions:write` - Add and remove reactions
* `team:read` - Access workspace information
* `files:read` - View files (when enabled)
* `files:write` - Upload files (when enabled)
## Available MCP Tools
The Slack integration provides 40+ tools for comprehensive team communication:
| Tool Name | Description |
| -------------------------- | --------------------------------------------- |
| `slack_send_message` | Send a message to a channel or direct message |
| `slack_update_message` | Update an existing message |
| `slack_delete_message` | Delete a message |
| `slack_get_message` | Get details of a specific message |
| `slack_list_messages` | List messages from a channel with pagination |
| `slack_search_messages` | Search for messages across workspace |
| `slack_get_unread` | Get unread messages from a channel |
| `slack_get_thread_replies` | Get all replies in a thread |
| Tool Name | Description |
| ----------------------- | -------------------------------- |
| `slack_add_reaction` | Add emoji reaction to a message |
| `slack_remove_reaction` | Remove a reaction from a message |
| `slack_get_reactions` | Get all reactions on a message |
| Tool Name | Description |
| --------------------------- | --------------------------------------------- |
| `slack_list_channels` | List all channels in workspace with filtering |
| `slack_get_channel` | Get details of a specific channel |
| `slack_create_channel` | Create a new channel (public or private) |
| `slack_archive_channel` | Archive a channel |
| `slack_unarchive_channel` | Unarchive a channel |
| `slack_invite_to_channel` | Invite users to a channel |
| `slack_kick_from_channel` | Remove a user from a channel |
| `slack_join_channel` | Join a channel |
| `slack_leave_channel` | Leave a channel |
| `slack_rename_channel` | Rename a channel |
| `slack_set_channel_topic` | Set channel topic |
| `slack_set_channel_purpose` | Set channel purpose/description |
| Tool Name | Description |
| ------------------------- | ------------------------------ |
| `slack_list_users` | List all users in workspace |
| `slack_get_user` | Get details of a specific user |
| `slack_get_user_by_email` | Find a user by email address |
| `slack_get_user_presence` | Get user presence status |
| `slack_set_user_presence` | Set your presence status |
| Tool Name | Description |
| ------------------- | ---------------------------------- |
| `slack_add_star` | Star a message or file |
| `slack_remove_star` | Remove a star from message or file |
| `slack_list_stars` | List all starred items |
| Tool Name | Description |
| --------------------- | ------------------------------ |
| `slack_get_team_info` | Get workspace/team information |
## Triggers
Slack triggers enable CORE's Meta Agent to wake up and act proactively when events occur in real-time via webhooks.
| Event | Description |
| ------------------------------ | ------------------------------------------------------- |
| `SLACK_RECEIVE_MESSAGE` | Triggered when a new message is posted to any channel |
| `SLACK_RECEIVE_DIRECT_MESSAGE` | Triggered when a new direct message is received |
| `SLACK_RECEIVE_MPIM_MESSAGE` | Triggered when a message is posted in a multi-person DM |
| `SLACK_RECEIVE_GROUP_MESSAGE` | Triggered when a message is posted in a private channel |
| `SLACK_RECEIVE_BOT_MESSAGE` | Triggered when a bot posts a message |
| `SLACK_RECEIVE_THREAD_REPLY` | Triggered when a reply is posted to a thread |
| Event | Description |
| ------------------------ | ---------------------------------------------------------- |
| `SLACK_REACTION_ADDED` | Triggered when an emoji reaction is added to a message |
| `SLACK_REACTION_REMOVED` | Triggered when an emoji reaction is removed from a message |
| Event | Description |
| ------------------------ | --------------------------------------- |
| `SLACK_CHANNEL_CREATED` | Triggered when a new channel is created |
| `SLACK_CHANNEL_ARCHIVED` | Triggered when a channel is archived |
| `SLACK_CHANNEL_DELETED` | Triggered when a channel is deleted |
| `SLACK_CHANNEL_RENAMED` | Triggered when a channel is renamed |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
***
# Todoist
Source: https://docs.getcore.me/toolkit/todoist
Personal and team task management with projects and priorities
## Overview
Integrate Todoist to create, organize, and manage tasks with support for projects, priorities, and labels. Access 12 tools to manage your tasks and projects programmatically, with flexible scheduling and comprehensive organization features.
## Setup Guide
* `Authentication Type` : OAuth 2.0
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **Todoist** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to Todoist to authorize the application
5. Grant the required permissions
6. You'll be redirected back to CORE once connected
## Use Cases
#### Action Use Cases
When you ask CORE to perform Todoist tasks, it uses MCP tools to execute your requests:
**Scenario**: Quickly add tasks with priorities and due dates
```
"Create a high-priority task 'Review contract' due tomorrow
with label 'urgent' in my Work project"
```
The agent will use `create_task` with priority level 4, due\_string "tomorrow", and the appropriate project\_id and labels.
**Scenario**: Structure work with projects and task hierarchies
```
"Create a new project called '2026 Product Roadmap' and add three tasks
for planning, development, and launch"
```
The agent will:
1. Use `create_project` to create the project
2. Use `create_task` for each task with the project ID
3. Use `update_project` to mark as favorite if needed
**Scenario**: Monitor and update task status
```
"Show me all active tasks in my Personal project,
mark the completed ones as done"
```
The agent will use `get_tasks` filtered by project, then `close_task` for completed items.
**Scenario**: Set and manage task priorities across your workflow
```
"List all urgent priority tasks across all projects
and update the ones due this week"
```
The agent will use `get_tasks` to retrieve tasks, filter by priority level 4, and `update_task` to modify as needed.
**Scenario**: Automate task creation and updates
```
"Create five tasks for the weekly team meeting agenda
and mark them all with the 'meeting' label"
```
The agent will use `create_task` multiple times with consistent project\_id and labels for bulk operations.
#### Proactive Use Cases
With webhooks enabled, CORE monitors Todoist 24/7 and acts automatically based on your instructions:
**Trigger**: Task created with specific label
**Automated Action**: Create corresponding task in other tools
```
"When a task is created in Todoist with label 'work',
automatically create a matching issue in Linear,
and notify me on Slack with the task details"
```
Keep task management synchronized. CORE creates matching tasks across platforms and notifies you where needed.
**Trigger**: Task completed
**Automated Action**: Track completions and send daily summary
```
"When I complete tasks in Todoist,
save them to CORE memory with label 'completed-tasks',
and send me a daily summary of what I accomplished at 6 PM"
```
Track productivity automatically. CORE monitors completions and provides daily achievement summaries.
**Trigger**: Task updated with due date
**Automated Action**: Set up smart reminders
```
"When a task gets a due date added in Todoist,
send me a WhatsApp reminder 24 hours before,
and another reminder 1 hour before it's due"
```
Never miss deadlines. CORE watches for due dates and sends timely reminders across your preferred channels.
**Trigger**: Task marked as high priority
**Automated Action**: Escalate and notify
```
"When a task is set to priority 1 (urgent) in Todoist,
send an immediate notification to my phone,
add it to today's calendar as a blocked time,
and save it to CORE memory with label 'urgent-items'"
```
Escalate urgent tasks instantly. CORE routes high-priority work to multiple channels for immediate attention.
**Trigger**: Task completed in specific project
**Automated Action**: Update project metrics
```
"When a task is completed in my 'Product Launch' project,
calculate the completion percentage,
save progress to CORE memory,
and send weekly updates to #product-team on Slack"
```
Track project velocity automatically. CORE monitors completions and provides stakeholders with progress updates.
**Trigger**: New task created in shared project
**Automated Action**: Auto-assign based on rules
```
"When a task is created in the 'Team Tasks' project with label 'bug',
assign it to the on-call engineer,
create a GitHub issue,
and notify #engineering on Slack"
```
Automate task routing. CORE distributes work based on labels and creates tracking items across your workflow.
## Scopes
* `data:read_write` - Read and write access to tasks
* `project:read_write` - Read and write access to projects
* `data:delete` - Delete tasks and projects
## Available MCP Tools
The Todoist integration provides 12 tools for comprehensive task and project management:
| Tool Name | Description |
| ------------- | ----------------------------------------------------------------------------------------------- |
| `get_tasks` | Retrieves all active tasks, optionally filtered by project |
| `get_task` | Retrieves a specific task by ID with full details including description, priority, and due date |
| `create_task` | Creates a new task with optional metadata (description, project, due date, priority, labels) |
| `update_task` | Updates an existing task with new information |
| `close_task` | Marks a task as complete |
| `reopen_task` | Reopens a completed task, marking it as active again |
| `delete_task` | Permanently deletes a task |
| Tool Name | Description |
| ---------------- | ------------------------------------------------------------- |
| `list_projects` | Retrieves all projects in your Todoist workspace |
| `get_project` | Retrieves a specific project by ID with all details |
| `create_project` | Creates a new project with optional color and favorite status |
| `update_project` | Updates an existing project |
| `delete_project` | Permanently deletes a project and all its tasks |
## Triggers
Todoist triggers enable CORE's Meta Agent to wake up and act proactively when events are detected via scheduled polling.
| Event | Description |
| ------------------------ | -------------------------------------------------------------------------------- |
| `TODOIST_TASK_CREATED` | Triggered when a new task is created in any project |
| `TODOIST_TASK_UPDATED` | Triggered when a task is modified (title, description, due date, priority, etc.) |
| `TODOIST_TASK_COMPLETED` | Triggered when a task is marked as complete |
| `TODOIST_TASK_REOPENED` | Triggered when a completed task is reopened |
| `TODOIST_TASK_DELETED` | Triggered when a task is permanently deleted |
| Event | Description |
| ------------------------- | --------------------------------------- |
| `TODOIST_PROJECT_CREATED` | Triggered when a new project is created |
| `TODOIST_PROJECT_UPDATED` | Triggered when a project is modified |
| `TODOIST_PROJECT_DELETED` | Triggered when a project is deleted |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**
# Zoho Mail
Source: https://docs.getcore.me/toolkit/zoho-mail
Enterprise email solution with comprehensive management capabilities
## Overview
Integrate Zoho Mail to seamlessly send, receive, organize, and manage your enterprise email workflows directly from CORE. Access 15+ specialized tools for complete email management.
## Setup Guide
* `Authentication Type` : OAuth 2.0
## How to Connect
1. Navigate to [CORE Dashboard](https://app.getcore.me) โ **Integrations**
2. Click on the **Zoho Mail** card
3. Click **Connect** to authorize CORE
4. You'll be redirected to Zoho to authorize the application
5. Grant the required permissions
6. You'll be redirected back to CORE once connected
## Use Cases
When you ask CORE to perform Zoho Mail tasks, it uses MCP tools to execute your requests:
**Scenario**: Send emails programmatically with multiple recipients
```
"Send an email to client@example.com with CC to team@company.com about
the project update, with HTML formatting"
```
The agent will use `zoho_send_email` to send new emails with CC, BCC, and HTML formatting support, or `zoho_send_reply` to respond to existing messages.
**Scenario**: Find emails using advanced search
```
"Search for all emails from client@example.com in the last week
and show me their content"
```
The agent will:
1. Use `zoho_search_emails` with appropriate search query
2. Use `zoho_get_message` to retrieve full content
3. Use `zoho_get_attachments` to identify attachments if needed
**Scenario**: Keep your mailbox organized with custom folders
```
"Create a new folder called 'Q1 Projects' and move all emails
from project-team@company.com to it"
```
The agent will use `zoho_create_folder` to create the folder, `zoho_search_emails` to find matching emails, and `zoho_move_messages` to organize them.
**Scenario**: Automate email processing and organization
```
"Mark all emails from newsletter@company.com as read,
flag important ones, and archive the rest"
```
The agent will:
1. Use `zoho_search_emails` to find matching emails
2. Use `zoho_read_messages` to mark as read
3. Use `zoho_flag_messages` for priority management
4. Use `zoho_archive_message` for completed items
**Scenario**: Work with multiple Zoho Mail accounts
```
"Show me all my Zoho Mail accounts and list unread emails
from my work account"
```
The agent will use `zoho_get_accounts` to retrieve all accounts, then `zoho_list_emails` with the appropriate accountId to access specific account data.
## Scopes
* `ZohoMail.messages.READ` - Read email messages
* `ZohoMail.messages.CREATE` - Send and compose emails
* `ZohoMail.messages.UPDATE` - Update email properties
* `ZohoMail.messages.DELETE` - Delete emails
* `ZohoMail.folders.READ` - Read folder information
* `ZohoMail.folders.CREATE` - Create and manage folders
* `ZohoMail.accounts.READ` - Access account information
* `ZohoMail.attachments.READ` - Read attachment information
## Available MCP Tools
The Zoho Mail integration provides 15+ tools for complete enterprise email management:
| Tool Name | Description |
| ------------------ | ---------------------------------------------------------------------------- |
| `zoho_send_email` | Sends a new email with support for CC, BCC, and HTML formatting |
| `zoho_send_reply` | Sends a reply to an existing email message |
| `zoho_get_message` | Retrieves the full content of a specific email message with headers and body |
| Tool Name | Description |
| -------------------- | ------------------------------------------------------------ |
| `zoho_list_emails` | Lists emails from a specified folder with pagination support |
| `zoho_search_emails` | Searches for emails using search query syntax |
| Tool Name | Description |
| ---------------------- | -------------------------------------------------------------------- |
| `zoho_read_messages` | Marks one or more emails as read |
| `zoho_delete_email` | Permanently deletes one or more email messages |
| `zoho_move_messages` | Moves emails from one folder to another |
| `zoho_archive_message` | Archives one or more email messages |
| `zoho_spam_message` | Marks one or more emails as spam |
| `zoho_flag_messages` | Flags emails with different flag types for organization and priority |
| Tool Name | Description |
| -------------------- | --------------------------------------------------------- |
| `zoho_create_folder` | Creates a new folder for organizing emails |
| `zoho_get_folders` | Lists all folders in the account with unread email counts |
| Tool Name | Description |
| ---------------------- | ----------------------------------------------------------------------- |
| `zoho_get_accounts` | Retrieves all Zoho Mail accounts associated with the authenticated user |
| `zoho_get_attachments` | Retrieves attachment information for a specific email message |
## Need Help?
Join our [Discord community](https://discord.gg/dVTC3BmgEq) for support in **#core-support**