HeroMind MCP API Reference
Overview
The HeroMind MCP (Model Context Protocol) server implements the standard MCP specification to provide secure, authenticated access to task management functionality. This document provides detailed technical reference for developers and integrators.
Base URL
https://your-supabase-project.supabase.co/functions/v1/mcp-server
Replace your-supabase-project with your actual Supabase project identifier.
Authentication
All requests (except initialize) require Bearer token authentication:
Authorization: Bearer <your-mcp-token>
Tokens are generated through the HeroMind admin panel and include:
- SHA-256 hashed storage for security
- Configurable expiration dates
- Permission-based access control
- Rate limiting settings
Protocol Specification
The server implements MCP version 2024-11-05 and follows the JSON-RPC 2.0 specification.
Request Format
All requests must be POST requests with Content-Type: application/json:
{
"jsonrpc": "2.0",
"method": "<method-name>",
"params": { ... },
"id": "<unique-request-id>"
}
Response Format
Successful responses:
{
"jsonrpc": "2.0",
"result": { ... },
"id": "<request-id>"
}
Error responses:
{
"jsonrpc": "2.0",
"error": {
"code": <error-code>,
"message": "<error-message>",
"data": { ... }
},
"id": "<request-id>"
}
Endpoints
Initialize
Establishes the MCP connection and exchanges capability information.
Method: initialize Authentication: Not required Rate Limited: No
Request
{
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {}
},
"id": 1
}
Response
{
"jsonrpc": "2.0",
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"experimental": {},
"sampling": {}
},
"serverInfo": {
"name": "HeroMind Task Manager",
"version": "1.0.0"
}
},
"id": 1
}
List Tools
Returns all available tools that can be called through the MCP interface.
Method: tools/list Authentication: Required Rate Limited: Yes
Request
{
"jsonrpc": "2.0",
"method": "tools/list",
"params": {},
"id": 2
}
Response
{
"jsonrpc": "2.0",
"result": {
"tools": [
{
"name": "create_personal_task",
"description": "Create a new personal task in HeroMind",
"inputSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Task name or description (required)",
"minLength": 1,
"maxLength": 500
},
"start_date": {
"type": "string",
"format": "date-time",
"description": "When the task should start (optional, ISO 8601 format)"
},
"due_date": {
"type": "string",
"format": "date-time",
"description": "When the task is due (optional, ISO 8601 format)"
}
},
"required": ["name"]
}
},
{
"name": "create_work_task",
"description": "Create a new work-related task in HeroMind",
"inputSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Task name or description (required)",
"minLength": 1,
"maxLength": 500
},
"start_date": {
"type": "string",
"format": "date-time",
"description": "When the task should start (optional, ISO 8601 format)"
},
"due_date": {
"type": "string",
"format": "date-time",
"description": "When the task is due (optional, ISO 8601 format)"
}
},
"required": ["name"]
}
}
]
},
"id": 2
}
Call Tool
Executes a specific tool with provided arguments.
Method: tools/call Authentication: Required Rate Limited: Yes
Request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_personal_task",
"arguments": {
"name": "Buy groceries for the week",
"due_date": "2024-01-15T18:00:00Z"
}
},
"id": 3
}
Response (Success)
{
"jsonrpc": "2.0",
"result": {
"content": [
{
"type": "text",
"text": "✅ Successfully created personal task: \"Buy groceries for the week\"\n\n📋 Task ID: 123e4567-e89b-12d3-a456-426614174000\n🏷️ Category: personal\n📅 Due Date: Jan 15, 2024\n⏰ Created: Jan 10, 2024, 10:30 AM\n\nYour task has been added to HeroMind and will appear in your task list."
}
],
"isError": false
},
"id": 3
}
Tools Reference
create_personal_task
Creates a new task with category "personal" in the user's HeroMind account.
Parameters
- name (string, required): Task description or title (1-500 characters)
- start_date (string, optional): ISO 8601 earliest-start date. Informational only; no view places a task by it.
- due_date (string, optional): ISO 8601. This is the day the task appears on in the planner and the Week View (date part used; defaults to today). Incomplete tasks roll forward from it. Set it to when the action is actually needed, never a shared batch date for several tasks.
Examples
Basic task:
{
"name": "create_personal_task",
"arguments": {
"name": "Call dentist for appointment"
}
}
Task with due date:
{
"name": "create_personal_task",
"arguments": {
"name": "Submit tax documents",
"due_date": "2024-04-15T23:59:59Z"
}
}
Task with start and due dates:
{
"name": "create_personal_task",
"arguments": {
"name": "Plan vacation itinerary",
"start_date": "2024-02-01T09:00:00Z",
"due_date": "2024-02-05T17:00:00Z"
}
}
create_work_task
Creates a new task with category "work" in the user's HeroMind account.
Parameters
- name (string, required): Task description or title (1-500 characters)
- start_date (string, optional): ISO 8601 formatted datetime for when the task should start
- due_date (string, optional): ISO 8601 formatted datetime for when the task is due
Examples
Project task:
{
"name": "create_work_task",
"arguments": {
"name": "Review quarterly performance reports",
"due_date": "2024-01-31T17:00:00Z"
}
}
Meeting preparation:
{
"name": "create_work_task",
"arguments": {
"name": "Prepare slides for client presentation",
"start_date": "2024-01-20T09:00:00Z",
"due_date": "2024-01-25T12:00:00Z"
}
}
list_projects
Lists the user's HeroMind projects with the signals a coding session needs to pick the right one. Results are name-ordered and capped at 100 projects. The result text contains a JSON array of {id, name, current_focus, open_task_count, last_activity} where last_activity is the most recent of the project's updated_at, its latest task activity, and its latest log entry.
Parameters
-
include_archived (boolean, optional): Include archived projects (default
false). Whentrue, each entry also carries anarchivedflag.
Example
{
"name": "list_projects",
"arguments": {}
}
Response content (text):
Projects (2):
[
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "HeroMind Library",
"current_focus": "Ship the resurfacing loop",
"open_task_count": 4,
"last_activity": "2026-07-17T21:14:03.512Z"
},
...
]
get_project_context
Loads a project's memory for session kickoff: current focus, the cached resume brief (or null if none / recently invalidated), the last 10 log entries, and up to 25 open tasks. Call this at the start of a coding session. The result text contains a JSON object:
{
"project": { "id": "...", "name": "...", "current_focus": "..." },
"resume_brief": { ... } ,
"recent_log": [ { "kind": "session_summary", "source": "mcp", "content": "...", "created_at": "..." } ],
"open_tasks": [ { "id": "...", "text": "...", "due_date": "...", "effort_minutes": 30, "work_notes": "..." } ]
}
Parameters
- project_id (string, optional): Project UUID. Preferred; wins if both are given.
-
project_name (string, optional): Project name, matched case-insensitively. If the name matches more than one project, the call fails with a list of candidates (pass
project_idinstead).
One of project_id or project_name is required.
Example
{
"name": "get_project_context",
"arguments": {
"project_name": "HeroMind Library"
}
}
log_session_summary
Writes a coding session's outcome into the project's memory as a project_log_entries row with kind: "session_summary" and source: "mcp". Optionally completes and creates project tasks in the same call. Also nulls out the project's cached resume_brief (it is now stale and regenerates on next view). Call this at the end of a coding session.
Parameters
-
project_id / project_name: Same resolution rules as
get_project_context(one required;project_idwins). -
summary (string, required, max 2000 chars): What changed this session and what was decided. Stored as the log entry content; when
next_stepsis given it is appended as"\n\nNext steps: ...". - next_steps (string, optional, max 1000 chars): Suggested next steps for the following session.
- completed_task_ids (string[], optional, max 50, UUIDs): Tasks to mark completed with today's completion date. Only tasks that belong to this user and this project are touched; already-completed tasks are skipped (their completion date stands). Skipped IDs are reported as a warning.
-
new_tasks (object[], optional, max 10): Follow-up tasks created in the project, due today. Category follows the project's folder (
Workfolder →work, otherwisepersonal). Each item:- text (string, required, max 500 chars)
- effort_minutes (number, optional, 1-1440)
- work_notes (string, optional, max 2000 chars)
Example
{
"name": "log_session_summary",
"arguments": {
"project_name": "HeroMind Library",
"summary": "Implemented the resurfacing cron and fixed the stale-topic query. Decided to cap resurfaced items at 3/day.",
"next_steps": "Wire the resurfaced items into the daily planner card.",
"completed_task_ids": ["123e4567-e89b-12d3-a456-426614174000"],
"new_tasks": [
{ "text": "Add resurfaced-items card to daily planner", "effort_minutes": 45 }
]
}
}
Response content (text):
✅ Logged session summary to project "HeroMind Library"
📝 Log entry ID: 9f0c...
✔️ Tasks completed: 1 (of 1 requested)
➕ Tasks created: 1 (a1b2...)
🔄 Resume brief invalidated: yes
list_tasks
Reconcile an external system with HeroMind. Newest-updated first.
| Argument | Type | Notes | ||
|---|---|---|---|---|
status | open \ | completed \ | all | default open |
category | personal \ | work \ | all | default all |
external_ref | string | exact match | ||
updated_since | ISO 8601 | incremental sync; app-side completions bump updated_at (trigger added 2026-09-24) | ||
limit | number | default 50, max 200 |
Returns JSON { count, tasks: [{ id, text, description, source_url, category, completed, completion_date, start_date, due_date, focused_date, starred, external_ref, created_at, updated_at }] }.
complete_task
{ task_id } or { external_ref }, optional completed: false to reopen. Writes what the app writes (completed + completion_date). Unknown ref → isError result, not a JSON-RPC error.
Task creation fields (both create tools)
| Argument | Notes |
|---|---|
name | required, ≤500 |
external_ref | your stable key; a repeat create dedupes to the existing task (already_existed) |
description | ≤2000, plain text with newlines — provenance ("From: … (account)" + link); shown under the task, URLs clickable, never rendered as HTML |
source_url | ≤2000, http(s) — the run/thread that filed it; shown as a "Run" link |
start_date, due_date | ISO 8601 |
On an external_ref match the stored row is left alone except that a null description / source_url is filled in. Unknown fields are ignored.
upsert_daily_note
A note for a day on the owner's Daily Planner ("From your Chief of Staff"). Idempotent on external_ref: a second call replaces the note.
{ "external_ref": "desk:2026-09-24:morning-briefing", "date": "2026-09-24",
"title": "3 things need you", "body": "## Changed\n…\n## Top 3\n…", "source_url": "https://agents.heromind.ai/threads/…" }
First line of the text content: {"id","result":"created"|"updated","external_ref","date"}. Limits: title ≤300, body ≤20000 (markdown, rendered, never raw HTML).
add_decision
Append to the owner's decision log (a decision context object visible through get_context). Same external_ref updates in place.
{ "external_ref": "decision:<loop-key>", "title": "I decided …", "detail": "why / rejected", "decided_at": "2026-09-24T09:15:00Z", "source_url": "…" }
Returns {"id","result":"created"|"updated","external_ref"} on the first line.
get_timeline
What happened, newest first: the owner's compiled timeline (task completions, journal, evidence, meetings, agent daily notes, decisions, explicit episodes). { since?, until?, person_slug?, limit? } — default the last 14 days, 60 rows, cap 300. Returns { count, person, episodes: [{ id, kind, at, summary, detail, people, project_id, quest_id, source, source_url }] }.
add_episode
Log something no other record holds. { external_ref, occurred_at, summary, kind?, detail?, people?: [names], project_id?, quest_id?, source_url? }. Idempotent on external_ref; people are matched to existing pages by name and unknown names are returned in people_unknown, never auto-created. Do not log task completions, journal entries or decisions here — those already feed the timeline.
get_context
Two modes.
Pack mode (recommended at the start of any task): { "query": "drafting the reply to Kurt about the Ramp intro", "budget": 4000 } → { pack, items, budget, budget_used, truncated, notes }. pack is markdown to paste ahead of your work: who you are working with (compiled Self page lead), standing preferences, decisions and stances ranked for the query (embedding similarity ∪ keyword overlap, recency), passages from the owner's journal/evidence/blueprint, and what is on their plate today. Budget 500–16000 characters.
Layer mode (no query): { "scope": "self|attention|week|strategy|all", "subject": {…}, "today": "YYYY-MM-DD" } → the layered JSON.
capture_context
Record the owner's judgment: up to 20 typed objects (decision, belief, mental_model, learning, open_question, preference, original, correction), one sentence each, first person. propose: true files them as proposed for the owner to accept on their Desk — use it for unattended capture (nightly sweeps, batch extraction). Near-duplicates (same kind + subject) return the existing id.
Library, people and book tools
library_add_source
Capture a source (web URL, YouTube video, pasted text/transcript, note) into the HeroMind Library. Without topic_slug it lands in the Library Inbox and the AI librarian classifies it; with topic_slug it files directly. For YouTube videos, fetching the transcript locally and passing it as text (with kind "youtube" and the url) is far more reliable than server-side transcript fetching.
| Argument | Description |
|---|---|
url | Source URL (web article or YouTube). Optional if text is provided. |
text | Raw text: a note, article body, or video transcript. PLAIN TEXT or MARKDOWN ONLY — never HTML, rendered email bodies, or anything containing CSS/markup (this text is read by humans and distilled into wikis verbatim). If your content exists as an HTML page or email, pass the underlying prose/markdown instead. Optional if url is provided. |
title | Title for the source (optional; extracted from the URL when possible). |
kind | One of: web, youtube, pdf, note, thread, meeting. Inferred from the URL when omitted. "meeting" = notes or a transcript in text, with attendees and date. |
topic_slug | Slug of an existing Library topic to file into directly (see library_list_topics). Omit to let the librarian classify. |
date | kind "meeting" only: meeting date, YYYY-MM-DD. |
visibility | private / agents / shared. Meetings default to private (agents cannot read them back until the owner changes it); everything else defaults to agents. |
library_list_topics
List the user's HeroMind Library topics (name, slug, space, source counts) so sources can be filed deliberately.
library_get_updates
The Library change feed for agents. Sources are immutable, so change = additions: returns each topic whose wiki is behind (filed sources newer than the topic's last compile, or never compiled), articles explicitly marked stale, and the Inbox backlog. Call this at the START of a PKM session to decide which wikis to update.
| Argument | Description |
|---|---|
since | Optional ISO 8601 timestamp (e.g. end of your last session) to also report how many sources were added since then. |
library_search
Full-text search across the whole Library: wiki/editorial articles (title, dek, body) and sources (title, AI summary, raw text). Returns ranked matches with snippets. Supports websearch syntax ("exact phrase", -exclude, OR).
| Argument | Description |
|---|---|
query (required) | Search query (websearch syntax). |
limit | Max results, 1-30 (default 12). |
scope | One of: all (default), articles, sources. |
library_read_article
Read a Library article (wiki or editorial) in full: markdown body plus its provenance (the sources it cites). Identify it by topic_slug + article_slug (from library_get_topic_context or library_search) or by article_id.
| Argument | Description |
|---|---|
topic_slug | Topic slug (pair with article_slug). |
article_slug | Article slug within the topic. |
article_id | Article UUID (alternative to the slug pair). |
library_read_source
Read a Library source's full raw text (article body, video transcript, note) plus its AI summary and metadata. Use the source UUIDs returned by library_get_updates, library_get_topic_context, or library_read_article provenance. This is the material to read before updating a wiki.
| Argument | Description |
|---|---|
source_id (required) | Source UUID. |
max_chars | Max raw-text characters to return, 500-200000 (default 50000). |
library_get_topic_context
Load everything an agent needs to work on one Library topic: outline, all articles (with staleness), recent filed sources (★ marks ones newer than the last compile), and the user's open standing instructions (topic todos). Call before writing or updating a wiki/editorial.
| Argument | Description |
|---|---|
topic_slug (required) | Topic slug (see library_list_topics). |
include_source_summaries | Include each source\'s AI summary (default false; adds a lot of text). |
library_write_article
Create or update a Library article (wiki or editorial) with markdown content. Upserts by slug within the topic: existing slug = update (article becomes current again), new slug = create (editorials get the next number). Pass source_ids to record provenance, and mark_topic_distilled=true when a wiki update covers all new sources so library_get_updates clears.
| Argument | Description |
|---|---|
topic_slug (required) | Topic slug to write into (required). |
kind (required) | wiki (living reference doc) or editorial (numbered opinion piece). |
title (required) | Article title (required, max 300 chars). |
content_md (required) | Full markdown body (required). |
slug | Kebab-case slug; omit to derive from title. Reuse an existing slug to update that article. |
dek | One-line subtitle shown under the title (optional). |
change_note | One line on what changed and why (shown in the Library UI). |
outline_group | Which outline group of the topic this wiki article belongs to (optional). |
source_ids | UUIDs of Library sources this article draws on (provenance/citations). |
mark_topic_distilled | Set true when this write incorporates the topic\'s new sources; stamps the topic as freshly compiled. |
library_get_person
What the owner knows about a person: the compiled Home (who they are, what they say and have done, where the owner's record diverges, open threads), recent timeline, linked sources, and the owner's non-private context about them. Call with no arguments to list all people pages. Use before a meeting or when a person is named in a task.
| Argument | Description |
|---|---|
name | Person name (or alias); fuzzy, case-insensitive. |
slug | Exact person slug from the list. |
library_create_person
Create a person page (e.g. "build me a person for X"). Then file 3–6 authoritative sources about them with library_add_source; the librarian links mentions and compiles the Home with footnotes. Never write prose about a person yourself. Returns the existing page if one already matches.
| Argument | Description |
|---|---|
name (required) | Full name. |
role | e.g. "CEO", "author", "CPO" (optional). |
org | Company / affiliation (optional). |
relationship | colleague / friend / family / public figure / … (optional). |
about | One line on why this person matters to the owner (optional). |
library_get_book
A book in the owner's Library: its compiled Home and the mirror (what the book, read against the owner's own record, is telling them; the sections that hit hardest with their cited records). No arguments = list all books.
| Argument | Description |
|---|---|
slug | Book slug from the list. |
title | Book title (fuzzy). |
library_mirror_book
Ask the librarian to mirror a book: read each section against the owner's record (stances, Foundation, values, beliefs, quests, journal, evidence, prior mirrors) with a cross-model fact check. Needs the book's extracted text (the owner opens the book page once). Returns immediately; takes several minutes.
| Argument | Description |
|---|---|
slug | Book slug (see library_get_book). |
source_id | Or the PDF source id. |
depth | "full" (per chapter, default) or "quick" (≤ 6 big sections). |
library_get_changes
The Library's change feed since a moment: timeline events across topics (sources filed, Homes revised, articles created/revised/retired, notes, context captured), newest first, with a per-topic count. Use it to answer "what changed this week" or to decide which topics to look at, instead of scanning every topic.
| Argument | Description |
|---|---|
since (required) | ISO date or datetime, e.g. 2026-09-01 or 2026-09-01T00:00:00Z. |
topic_slug | Optional: only this topic. |
limit | 1..200, default 100. |
Context tools (beyond get_context / capture_context)
supersede_context
Replace a current context object with a new statement when the user changes their mind or a decision is revised. The old object is kept as history (status superseded) and linked to the new one. Say so to the user once; never silently overwrite.
| Argument | Description |
|---|---|
id (required) | UUID of the object being replaced (from get_context). |
correct_context
The owner corrected something you (or a HeroMind page) stated as fact. Record a guard fact in THEIR words, linked to the subject, and recompile their Self page so the error does not survive. Then acknowledge in one line and never repeat the wrong claim. Use whenever the owner says "that's not right", "I never…", "we haven't…", "actually…".
| Argument | Description |
|---|---|
wrong_statement (required) | The sentence that was wrong, as stated. |
correct_fact (required) | What is actually true, in the owner\'s words. One sentence. |
subject | Optional: which page/subject the error concerned. |
source_ref | Optional thread/session id where the correction happened. |
trace_lineage
How has the owner's thinking about one idea changed over time? Gathers their decisions, stances (including superseded ones), journal entries and saved sources about the idea and returns: current live version, first mention, best articulation, turning points, reversals, abandoned branches, evidence gaps — every line dated and cited. Read-only. Use for "how has my thinking on X changed", "when did I first…", "did I reverse on…".
| Argument | Description |
|---|---|
idea (required) | The idea, phrase, topic or claim to trace. |
limit | Max semantic hits to gather (5–60, default 30). |
Error Codes
The server follows JSON-RPC 2.0 error code conventions with MCP-specific extensions:
JSON-RPC Standard Errors
- -32700: Parse error - Invalid JSON
- -32600: Invalid Request - Request structure is invalid
- -32601: Method not found - The specified method does not exist
- -32602: Invalid params - Invalid method parameters
- -32603: Internal error - Server-side error
MCP-Specific Errors
- -32000: Authentication failed - Invalid or missing authentication
- -32001: Authorization failed - Insufficient permissions
- -32002: Rate limit exceeded - Too many requests
- -32003: Token expired - Authentication token has expired
- -32004: Token inactive - Token has been deactivated
- -32005: Tool not found - Specified tool does not exist
- -32006: Tool execution failed - Tool execution encountered an error
- -32007: Invalid token - Token format or content is invalid
- -32008: Permission denied - Token lacks required permissions
Error Response Examples
Authentication Failed
{
"jsonrpc": "2.0",
"error": {
"code": -32000,
"message": "Authorization header is required"
},
"id": "unknown"
}
Rate Limit Exceeded
{
"jsonrpc": "2.0",
"error": {
"code": -32002,
"message": "Rate limit exceeded. Try again in 45 seconds",
"data": {
"current": 65,
"limit": 60,
"resetTime": 1704900000000
}
},
"id": 5
}
Invalid Parameters
{
"jsonrpc": "2.0",
"error": {
"code": -32602,
"message": "Invalid tool arguments: name is required and must be a non-empty string",
"data": {
"errors": ["name is required and must be a non-empty string"]
}
},
"id": 6
}
Rate Limiting
Default Limits
- 60 requests per minute per token (configurable)
- Window: 60-second sliding window
- Algorithm: Token bucket
Headers
Rate limit information is not included in response headers but can be monitored through the admin panel.
Handling Rate Limits
When rate limited (HTTP 429), the response includes:
- Current request count
- Rate limit threshold
- Reset time (Unix timestamp)
Example retry logic:
if (response.status === 429) {
const errorData = await response.json();
const retryAfter = errorData.error.data.resetTime - Date.now();
setTimeout(() => {
// Retry request
}, retryAfter);
}
Security Features
Request Validation
- Size Limits: Maximum 10KB request body
- Header Validation: Required Content-Type and Authorization headers
- Input Sanitization: All input is sanitized and validated
- Schema Validation: Tool arguments validated against JSON schema
Security Headers
All responses include security headers:
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'none'
Strict-Transport-Security: max-age=31536000; includeSubDomains
Token Security
- Hashing: SHA-256 hashed storage
- Validation: Constant-time comparison
- Expiration: Configurable token lifetimes
- Revocation: Instant token deactivation
- IP Restrictions: Optional IP whitelisting
Testing
Curl Examples
Initialize:
curl -X POST https://your-project.supabase.co/functions/v1/mcp-server \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05"},"id":1}'
List Tools:
curl -X POST https://your-project.supabase.co/functions/v1/mcp-server \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":2}'
Create Task:
curl -X POST https://your-project.supabase.co/functions/v1/mcp-server \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"create_personal_task","arguments":{"name":"Test task"}},"id":3}'
JavaScript/TypeScript Examples
interface MCPRequest {
jsonrpc: "2.0";
method: string;
params?: any;
id: string | number;
}
async function callMCPServer(request: MCPRequest, token?: string) {
const headers: HeadersInit = {
'Content-Type': 'application/json',
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const response = await fetch('https://your-project.supabase.co/functions/v1/mcp-server', {
method: 'POST',
headers,
body: JSON.stringify(request),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
}
// Initialize connection
const initResponse = await callMCPServer({
jsonrpc: "2.0",
method: "initialize",
params: { protocolVersion: "2024-11-05" },
id: 1
});
// Create a task
const taskResponse = await callMCPServer({
jsonrpc: "2.0",
method: "tools/call",
params: {
name: "create_work_task",
arguments: {
name: "Review API documentation",
due_date: "2024-01-20T17:00:00Z"
}
},
id: 2
}, "your-token-here");
Monitoring & Analytics
Usage Tracking
The server automatically logs:
- Request/response details
- Performance metrics (response time)
- Error rates and types
- Client information (IP, User-Agent)
- Tool usage patterns
Admin Dashboard
Monitor your MCP integration through the HeroMind admin panel:
- Real-time usage statistics
- Performance metrics
- Error rate monitoring
- Security event logging
- Token management and analytics
Environment Variables
For production deployment, configure these environment variables:
# Required
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# Optional (with defaults)
MCP_MAX_RATE_LIMIT=60
MCP_DEFAULT_TOKEN_EXPIRY_DAYS=90
MCP_ENABLE_USAGE_LOGS=true
MCP_DEBUG=false
Changelog
Version 1.3.0 (September 2026)
-
Two-way task sync:
list_tasks,complete_task,external_refdedupe -
Task provenance:
descriptionandsource_urlon both create tools -
Desk board:
upsert_daily_note,add_decision(idempotent onexternal_ref) -
get_contextpack mode (query,budget) with a Recently section;capture_context { propose } -
Timeline:
get_timeline,add_episode -
Library tools (
library_*), context tools (get_context,capture_context,supersede_context,correct_context,trace_lineage), people and books -
tasks.updated_atnow maintained by trigger, soupdated_sincesees app-side completions
Version 1.2.0
-
Project-memory tools for the Claude Code session bridge:
list_projects,get_project_context,log_session_summary -
log_session_summarycan complete and create project tasks in one call and invalidates the project's cached resume brief
Version 1.1.0
-
Library capture tools:
library_add_source,library_list_topics
Version 1.0.0
- Initial MCP implementation
- Personal and work task creation tools
- Token-based authentication
- Rate limiting and security features
- Comprehensive error handling
- Usage analytics and monitoring
Future Versions
- Additional task management tools (read, update, delete)
- Project and habit integration
- Bulk operations support
- Advanced filtering and search capabilities
Support
For technical support and bug reports:
- Check the Integration Guide for common solutions
- Review token status and usage analytics in the admin panel
- Test individual endpoints using the provided curl examples
- Contact support with specific error messages and request/response examples
Updated 2026-09-27 · All chapters · API reference