context MCP server
Commit Nov 5, 2026Provides an MCP layer to retrieve recent trends and events between conversations to give LLMs personalized, short-term context.
Also known as Runtime-Roost/context-server
- Stars
- 1
- Tools
- 46
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Nov 5, 2026
- License
- MIT
What is context MCP?
context provides an MCP layer to retrieve recent trends and events between conversations to give LLMs personalized, short-term context. It exposes 46 tools, such as ping, identify_actor, save_context.
Summary generated from the project's README
About context MCP server
Providing a personalized layer of short-term memory between conversations is what context-server enables for AI clients. While standard LLMs often maintain long-term preferences or immediate conversation history, this server acts as a bridge to retrieve recent trends and events that persist across different chat sessions. This allows an AI to remember that you recently migrated hardware or worked on a specific project without needing those details repeated in every new prompt.
Developers can set this up locally using a PostgreSQL database. The server is configured via a local mcp.json file, which can be generated using the npm run mcp:config command. It supports various environment variables for database management, such as PGHOST and PGDATABASE, and includes tools for managing the database schema through scripts. The system also features an inspection tool to view shared context records and supports actor attribution to track whether a human or a specific AI model synthesized a piece of information.
What you can do with it
- 1Retrieve recent project trendsAsk the AI to recall specific technical tasks or hardware changes you have been working on over the last few weeks.
- 2Maintain continuity between sessionsProvide the LLM with context that exists outside of the current conversation window to make interactions feel more personal.
- 3Audit and inspect shared memoriesUse a separate interface to view whiteboard records and attribution without giving the agent control over the tools.
- 4Track information sourcesEnsure every piece of saved context is linked to a specific actor like a human or a specific model version.
Written from the project's README. Every use case is checked against a quote from it.
context MCP tools 46
Detected from the READMEpingidentify_actorsave_contextsearch_contextget_user_profilelist_recent_contextget_contextacknowledge_contextrequest_actor_sessionget_actor_session_request_statusclaim_actor_sessionrenew_actor_session
| ping | — | |
| identify_actor | — | |
| save_context | — | |
| search_context | — | |
| get_user_profile | — | |
| list_recent_context | — | |
| get_context | — | |
| acknowledge_context | — | |
| request_actor_session | — | |
| get_actor_session_request_status | — | |
| claim_actor_session | — | |
| renew_actor_session | — |
Show all 46 toolsShow fewer tools
create_channeladd_channel_memberremove_channel_memberlist_channelssave_channel_contextsearch_channel_contextlist_channel_contextget_channel_contextupdate_channel_contextdelete_channel_contextcreate_access_groupadd_access_group_memberremove_access_group_memberlist_access_groupssave_group_contextsearch_group_contextlist_group_contextget_group_contextupdate_group_contextdelete_group_contextsave_personal_contextsearch_personal_contextlist_personal_contextget_personal_contextupdate_personal_contextdelete_personal_contextdatabase_metadatadelete_contextupdate_contextcontext_purge_previewcontext_purge_confirmactor_purge_previewactor_purge_confirmvacuum_database
| create_channel | — | |
| add_channel_member | — | |
| remove_channel_member | — | |
| list_channels | — | |
| save_channel_context | — | |
| search_channel_context | — | |
| list_channel_context | — | |
| get_channel_context | — | |
| update_channel_context | — | |
| delete_channel_context | — | |
| create_access_group | — | |
| add_access_group_member | — | |
| remove_access_group_member | — | |
| list_access_groups | — | |
| save_group_context | — | |
| search_group_context | — | |
| list_group_context | — | |
| get_group_context | — | |
| update_group_context | — | |
| delete_group_context | — | |
| save_personal_context | — | |
| search_personal_context | — | |
| list_personal_context | — | |
| get_personal_context | — | |
| update_personal_context | — | |
| delete_personal_context | — | |
| database_metadata | — | |
| delete_context | — | |
| update_context | — | |
| context_purge_preview | — | |
| context_purge_confirm | — | |
| actor_purge_preview | — | |
| actor_purge_confirm | — | |
| vacuum_database | — |
Configuration
EMBEDDINGS_AUTO_PULLEMBEDDINGS_ENABLEDEMBEDDINGS_MODELEMBEDDINGS_PROVIDEROLLAMA_HOST
| Name | Description | |
|---|---|---|
| EMBEDDINGS_AUTO_PULL | — | |
| EMBEDDINGS_ENABLED | — | |
| EMBEDDINGS_MODEL | — | |
| EMBEDDINGS_PROVIDER | — | |
| OLLAMA_HOST | — |
Automated checks
Ran Nov 14, 2026Full report →Not verified yet. A server needs a score of 80, no serious finding, and enough data for us to check. How checks work · What to fix for more points
- Source repository linked and reachableruntime-roost/context-server is public and reachablegithub.com/runtime-roost/context-server ↗Pass
- Package names this repository as its sourceNot checked
- Build provenance (Sigstore attestation)Not checked
- Open source license (OSI)MITspdx.org/licenses/MIT.html ↗Pass
- Commit or release in the last yearLast commit or release 2026-11-05github.com/runtime-roost/context-server ↗Pass
- OpenSSF ScorecardNot checked
- Package name not close to a popular packageNot checked
- No critical advisory in the package or its dependenciesNot checked
- No hidden instructions to the model46 tool descriptions and the README read; no override phrases, credential paths or hidden charactersPass
- Destructive tools are labelledNot checked
- Remote endpoint answers the MCP handshakeNot checked
README
View on GitHubcontext-server
A personalized context-driven MCP archive server.
ChatGPT, and many others have long-term memories for static facts and user preferences. Obviously, they also have context of the current conversation.
But what if we had a custom layer sit between the two, referencing the user's recent trends and events regardless of the conversation? It would feel more like talking to a friend, rather than a machine we brute forced into learning English and following directions.
This is that layer.
Example
Long-term memory might know:
- User prefers TypeScript
- User owns a homelab
- User enjoys automation projects
This MCP layer might retrieve:
- User has been building an MCP server this week
- User recently migrated to an RX 7800 XT
- User spent the last month building an Elite Dangerous database
Together, the LLM gains both long-term preferences and recent context between conversations.
The full LLM runtime situation should look something like this:
AI doesn't need to remember everything. It just needs to know where its memories are.
Note: Your mileage may vary significantly depending on the instructions given to the model. This MCP server can provide relevant context, but it is ultimately up to the LLM to decide when to retrieve it, how to interpret it, and how much weight to give it.
Configuring
The tracked mcp.example.json shows the portable MCP client
configuration. Generate the ignored, machine-specific mcp.json with an
absolute path to this checkout and the current OS username:
npm run mcp:config
The same command is available in VS Code under Tasks: Run Task as
MCP: Generate config.
The generated file is local machine configuration and is automatically added
to .gitignore. Standard PGHOST, PGDATABASE, PGUSER, AUTO_MANAGE_DB,
REQUIRE_ACTOR_IDENTIFICATION, TRUST_OPENAI_TUNNEL_IDENTITY, and
EMBEDDINGS_ENABLED, ATTACHMENT_STORAGE_DIR,
ATTACHMENT_PERSONAL_QUOTA_BYTES, and ATTACHMENT_GROUP_QUOTA_BYTES
environment variables
override the generated defaults.
Automatic database management is disabled by default.
The generated file uses this shape:
{
"mcpServers": {
"personal_context": {
"active": true,
"args": [
"/PATH/TO/personal-context-server/dist/index.js"
],
"command": "node",
"env": {
"PGHOST": "/var/run/postgresql",
"PGDATABASE": "personal_context",
"PGUSER": "USERNAME"
},
"type": "stdio"
}
}
}
Create a local .env from the example if you want to run the server directly:
cp .env.example .env
Create and manage the local PostgreSQL database with the included helper:
scripts/db.sh create
scripts/db.sh status
scripts/db.sh shell
The helper always manages a database named personal_context. It also supports
drop and reset (with confirmation), and honors the standard PostgreSQL
connection environment variables. The same commands are available from VS Code
under Tasks: Run Task as the Database: ... tasks.
Set AUTO_MANAGE_DB=true to have the server run the helper's status check
before connecting its MCP transport and run create when the database is
missing. Startup fails instead of creating anything when PostgreSQL is
unreachable or the required PostgreSQL command-line tools are unavailable.
Inspection tool
The repository includes a separate operator surface for inspecting shared context without exposing agent controls:
npm run inspection:start
It listens only on http://127.0.0.1:4180 by default. The browser receives
Whiteboard records, attribution, and actor acknowledgements. It may edit only
the body of an existing Whiteboard note, using optimistic concurrency. Source,
tags, visibility, and actor attribution remain server-owned. Notes carrying a
message-to-* inbox tag are read-only because changing or deleting them could
alter agent delivery. New notes are plain Whiteboard records attributed to
actor:human:blake, with no tags and the fixed source inspection-tool.
Deletion is version-checked and uses the same inbox guard. There are no wake,
submit, approve, or agent-control routes.
Ordinary notes may also be archived with a required reason. Archiving moves the
record out of every general Whiteboard read by changing its server-owned
visibility to archived; it does not merely hide a card. The archive preserves
the note's content, original author, source, and acknowledgements, and records
the reason, time, and actor:human:blake as the archiving actor. Restoring a
note returns it to the Whiteboard while retaining the archive/restore history.
Agent inbox notes cannot be archived.
Private channel and direct-message bodies are excluded in SQL, not merely
hidden by the UI. The Inspection API returns only an envelope: channel,
participants, sender, timestamps, acknowledgement count, and record ID. Its
response includes private_message_contents_exposed: false as an explicit
privacy contract.
The standalone native Android inspection companion is obsolete and retained temporarily for compatibility testing. Agent Companion is the active phone UI. The obsolete client uses a separate TLS gateway on one exact RFC1918 address:
npm run inspection:mobile
Set the INSPECTION_MOBILE_* values shown in .env.example. The TLS private
key and per-phone bearer token must be regular mode-0600 files outside the
repository. The gateway exposes only GET /api/inspection and the bounded
Whiteboard create/body-update/delete/archive/restore routes; it holds no MCP,
runtime, or agent credential.
The installed user service reads those non-secret paths and bind settings from
the mode-0600 %h/.config/personal-context/inspection-mobile.env; the token
itself remains in the separate file named by INSPECTION_MOBILE_TOKEN_PATH.
Actor attribution
Actor attribution records who synthesized a memory, while source continues to
describe where the information came from. Durable actor IDs represent
operational categories rather than conversations or model versions, for
example actor:openai:codex, actor:openai:chatgpt, and
actor:human:blake.
For clients with persistent MCP sessions, call identify_actor once before
saving. The resolved actor becomes active for that server instance, and
subsequent save_context calls automatically attach it. Calling
identify_actor again switches actors.
Clients that may reconnect or launch a fresh stdio process between calls, such as some LM Studio configurations, should include actor identity directly in every save:
{
"text": "Tested actor attribution successfully.",
"tags": ["tool_testing"],
"source": "LM Studio actor-attribution test, 2026-07-19",
"actor": {
"external_id": "actor:eden",
"name": "Eden",
"kind": "ai"
},
"subject": {
"external_id": "subject:project:context-server",
"name": "Context Server",
"kind": "project",
"aliases": ["personal context server"]
}
}
An explicit actor requires a stable external_id, takes precedence over the
session-active actor, and becomes active when the session does persist. Actor
resolution and context insertion share one database transaction. The standalone
identify_actor tool still permits intentionally anonymous actors, but display
names are never used to merge actors.
For compatibility, an unidentified save succeeds with actor: null and an
ACTOR_NOT_IDENTIFIED warning. Set REQUIRE_ACTOR_IDENTIFICATION=true for
clients such as LM Studio to reject the write before it happens. The structured
ACTOR_IDENTIFICATION_REQUIRED error tells the model to retry the same
save_context call with an actor object. Strict mode is disabled by default and
requires attribution without choosing the actor for the model.
Existing databases upgrade through the transactional schema_migrations
ledger. Existing contexts are not backfilled and remain actor: null.
Knowledge subjects
Contexts may optionally reference a canonical subject describing what the
knowledge is about. Subject IDs use a separate lowercase subject: namespace,
for example subject:project:context-server. A subject has a stable external
ID, canonical name, optional kind, and optional retrieval aliases.
Subjects are classification metadata, not principals: they never grant
ownership, authentication, visibility, or access. The actor remains who
created or owns a record under the applicable visibility contract. OpenAI
tunnel subject values are authentication-local metadata and must not be copied
into knowledge-subject IDs.
Migration 19 adds subjects and nullable contexts.subject_id. Existing rows
intentionally remain unclassified (subject: null); no subject is inferred
from actor, content, tags, or tunnel identity. New records can supply subject
when saved, and existing Whiteboard or personal records can be explicitly
backfilled through their existing update tools. Text retrieval matches the
subject ID, canonical name, kind, and aliases while preserving the original
visibility and actor-ownership predicates.
Immutable context payloads
Migration 20 creates versioned context_payloads rows for every context. Each
payload has a stable pointer, type (text), media type, byte size, version, and
immutable body. Existing text becomes payload version 1. Replacing context text
creates a new version; previous versions remain, direct payload updates are
rejected, and deleting the context cascades all payload versions.
Context envelopes return payload_ref metadata. Search and list responses carry
at most a 500-character preview so an agent can decide whether an exact read is
worthwhile; exact get_* operations hydrate the complete text behind the same
visibility and actor-authorization checks. contexts.content remains a
compatibility mirror in this migration slice. These payload records provide the
indirection point for later image, document, OCR, transcript, and embedding
storage without changing context-envelope identity.
Context connections
Migration 21 adds directed, typed connections between context envelopes. A
connection records a normalized relationship such as led_to, supports,
contradicts, or supersedes, an optional bounded rationale explaining why the
edge exists, and the authenticated actor that created it. Exact reads and
search/list envelopes expose connections from both directions with the other
context ID; they do not hydrate the other payload automatically.
Connections are semantic metadata, not capabilities. Both endpoints must be in
the same visibility scope: Whiteboard with Whiteboard, the same personal owner,
the same channel, or the same access group. The creator must have write access
to that scope. Direct, system, archived, cross-owner, and cross-scope edges are
rejected in this slice, and unauthorized callers receive the same not-found
boundary as missing contexts. The full administrative MCP surface exposes
connect_contexts and disconnect_contexts; the bounded conversation catalog
does not add new tool definitions in this slice.
Relevance and lifecycle metadata
Migration 22 gives every context an explicit lifecycle envelope: active,
warm, cold, or archive_candidate; bounded importance from 0–100; retrieval
count and last-retrieved time; optional completion time; and an optional
same-scope successor. Existing records start active at neutral importance 50.
These fields are signals rather than authority and do not themselves archive,
delete, pin, expose, or hydrate anything.
The authenticated full-surface update_context_lifecycle tool may change these
signals only when the actor has write access to the context. Supersession must
point to a context in the same visibility/ownership scope, so lifecycle metadata
cannot reveal or bridge into a hidden journal, channel, or group.
Reviewed auto-archive
Migration 23 adds durable, expiring archive previews and per-record evaluation
receipts. preview_auto_archive evaluates only cold/candidate Whiteboard notes;
it never archives by itself. Eligibility conservatively requires explicit
archive_candidate state, low importance, minimum age, completion or a
same-scope successor, no active inbound reference, no bridge position, no agent
inbox tag, and no protected tag. Protected tags default to archive:never,
reference, canonical, and active-project and are configurable through
AUTO_ARCHIVE_PROTECTED_TAGS.
confirm_auto_archive consumes one actor-bound 15-minute preview and archives
only an explicitly selected eligible subset. It rechecks candidate state inside
the transaction, writes ordinary reversible archive history, and never deletes
payloads or graph edges. A changed, expired, replayed, foreign, or expanded
selection fails closed.
Bounded retrieval assembly
assemble_context authenticates the active OpenAI tunnel actor, finds lexical
seed envelopes only inside that actor's readable Whiteboard, personal, channel,
and group scopes, and restores one hop of authorized graph topology. Archived
Whiteboard records are excluded from ordinary seed search and may surface only
as connected nodes. Direct and system records are never assembled.
Assembly ranks lifecycle importance, returns at most 20 envelopes, hydrates at
most five payload bodies, limits all remaining nodes to 500-character previews,
and enforces a total content-character budget. Results explain whether each node
was a seed or graph expansion and update retrieval counters/timestamps. To keep
the conversation catalog below 25,000 serialized characters, this tool replaces
ordinary Whiteboard acknowledgement on that surface; acknowledge_context
remains available on the full administrative surface.
Actor-only context boundary
Context-bearing MCP operations now require an authenticated actor by default,
including Whiteboard save/search/exact reads, recent/profile reads, database
metadata, acknowledgement, update/delete, and purge operations. Authentication
bootstrap (request_actor_session, status/claim/binding flows) remains separate
and does not read protected context. The trusted OpenAI path derives the author
from the bound local actor session; any caller-supplied actor object is ignored
for authority and cannot replace the authenticated principal.
REQUIRE_CONTEXT_AUTHENTICATION=false exists only for isolated legacy test
fixtures and should not be set in deployed services. Subjects, mentions,
connections, lifecycle fields, payload references, and tags remain inert
metadata: none can authenticate, grant membership, or widen visibility.
Whiteboard visibility
Every context now has a first-class visibility classification. Existing rows
are migrated to whiteboard, and new saves default to whiteboard. Whiteboard
records are shared context discoverable through search_context,
list_recent_context, get_context, and get_user_profile.
The general context tools intentionally accept only whiteboard.
Non-whiteboard rows fail closed: current whiteboard reads, updates, deletes,
and context purges do not expose or mutate them. This avoids presenting
self-asserted actor identity as real access control.
Private notebook
Authenticated actors can keep Tier 2 private notebook records with the
*_personal_context tools. A personal record is always attributed to and owned
by the authenticated actor. The server applies that ownership predicate before
text search, semantic ranking, limiting, serialization, exact-ID lookup,
updates, and deletion.
Personal records are invisible to Whiteboard tools, channel tools, and other
authenticated actors. Missing and unauthorized exact IDs both return null.
The same enrolled-key and operator-approved actor-session authentication
supported by channels is supported here. Personal records are never retrieved
automatically through the general search_context or list_recent_context
surfaces; clients must deliberately call the authenticated private-notebook
tools.
Access groups
Access groups provide Unix-like shared ownership for private archives. A
group-owned context keeps its authenticated actor as the author for provenance,
but the access group owns the authorization boundary. Current members with
can_read may list, search, and fetch group records. Current members with
can_write may save, update, and delete them.
Group owners and admins manage membership using owner/admin/member roles and
independent read/write capability flags. Removing a member revokes access
immediately without rewriting every group-owned record. Owners cannot be
removed. Membership is enforced before search, semantic ranking, limiting,
serialization, exact-ID lookup, update, and deletion. Missing and unauthorized
exact IDs both return null.
Group ownership is distinct from channels and actor-private notes: channels are conversation/history scopes, personal contexts belong to one actor, and group contexts belong to an access group shared by its current members.
Attachments
Attachments are immutable binary source artifacts stored outside context text.
PostgreSQL keeps ownership, integrity, provenance, and context-link metadata;
the bytes live in a content-addressed filesystem store under
ATTACHMENT_STORAGE_DIR (default: ./data/attachments). Never place that
directory inside a publicly served tree. Back it up together with PostgreSQL:
neither half is a complete archive by itself.
Personal actors and access groups each have a strict 100 MiB logical attachment
quota by default. Configure the independent byte limits with
ATTACHMENT_PERSONAL_QUOTA_BYTES and ATTACHMENT_GROUP_QUOTA_BYTES. Finalized
attachments and the full declared size of every active upload both count, so
parallel uploads cannot over-reserve a scope. Content deduplication saves
physical disk without bypassing logical quota accounting.
Uploads use an integrity-checked sequence:
begin_attachment_uploaddeclares personal or group ownership, filename, media type, exact byte length, and SHA-256.append_attachment_chunksends base64 chunks of at most 512 KiB at the exact next byte offset.finalize_attachment_uploadverifies length and SHA-256 before atomically publishing immutable bytes.
For new integrations, the payload-first aliases keep large artifact transfer separate from knowledge metadata:
begin_payload_uploadandappend_payload_chunkstage bytes without creating or modifying a context envelope.finalize_payload_uploadverifies the bytes and returns an immutablepayload:artifact:<uuid>:v1reference with server-derived media type, size, and SHA-256 metadata.attach_payload_to_contextapplies that finalized reference afterward with acanonical,source,derived, orreferencerole. Derived payloads must name a distinct, authorized payload in the same personal or group scope; lineage is committed atomically with the link and returned bylist_context_attachments.
These upload tools deliberately remain on the full administrative surface, not the bounded conversation catalog. The established attachment tools remain as compatibility APIs and resolve to the same immutable payload records.
Unfinished uploads expire after 24 hours and are pruned when a new upload
begins. cancel_attachment_upload removes one immediately.
get_attachment_quota reports finalized, reserved, available, and limit bytes.
Quota reservation is serialized per actor or group in PostgreSQL. Every upload
reservation, finalization, cancellation, deletion, and reconciliation result is
written to the append-only attachment_audit_events ledger.
Run npm run attachments:audit for a strict reconciliation of database rows,
stored object sizes and SHA-256 values, partial-upload sizes, and orphan files.
The command records its result and exits nonzero on any discrepancy. It reports
orphans for operator review and never deletes or repairs them automatically.
get_attachment, list_attachments, and read_attachment_chunk enforce the
current personal owner or group membership before returning metadata or bytes.
delete_attachment requires write access, cascades its context links, and
removes content-addressed bytes only when no other attachment metadata uses
them. Missing and unauthorized attachment IDs both return null.
link_attachment_to_context deliberately permits only exact scope matches:
personal attachment to the same actor's personal context, or group attachment
to a context owned by the same group. Links record canonical, source, derived, or
reference relationships, stable sort order, and optional inclusive page
ranges. list_context_attachments reads those links through the same attachment
authorization boundary. Original filenames are metadata only; generated UUIDs
and SHA-256 keys determine every filesystem path.
context MCP questions
What tools does context MCP provide?
It exposes 46 tools, including ping, identify_actor, save_context, search_context, get_user_profile.
How do I configure the server?
You can generate a machine-specific configuration file by running npm run mcp:config or using the MCP: Generate config task in VS Code.
Can I manage the database automatically?
Yes, by setting the AUTO_MANAGE_DB environment variable to true, the server will check for the database and create it if it is missing.
How does the server handle privacy for direct messages?
Private message bodies are excluded from SQL queries entirely, and the Inspection API returns an envelope that explicitly confirms contents are not exposed.
What happens if I don't identify an actor?
The save will still succeed but will be recorded with actor: null and trigger an ACTOR_NOT_IDENTIFIED warning.