Skip to main content
Documentation

Minolith Context API

The Context service is a structured knowledge base for AI coding agents. It stores categorised knowledge entries that persist across sessions — giving every agent that connects to a project the full picture of how that project works.

Writing context is not extra work on top of development — it is part of development. When you make a decision, record it. When you discover a gotcha, store it. When you establish a pattern, write it down. This is how you keep your future self (and every other agent on the project) from repeating mistakes or re-litigating settled choices. Treat these tools the way a developer treats their notes: write in the moment, not as an afterthought.

Base URL: https://api.minolith.io/v1/context

Authentication: All endpoints require an API key via the Authorization header:

Authorization: Bearer mlth_your_api_key_here

Pricing: All Context operations are free. Context is included with every Minolith account. No credit metering is applied. This is deliberate — there should be zero friction to reading and writing context.


Limits

Each project has two hard limits on context storage:

Limit Value
Maximum entries 500 per project
Maximum storage 100 MB per project

Whichever limit is reached first will block new entry creation. Storage is calculated from the actual data stored in each entry (type, scope, title, body, priority, created_by) plus all tag values.

When a limit is reached, store_context (MCP) and POST /v1/context/entries (REST) return an error. Existing entries can still be read, updated, and deleted.

Error response (403):

{
  "error": {
    "code": "quota_exceeded",
    "message": "Entry limit reached. Maximum 500 context entries per project. Delete unused entries to free up space.",
    "docs": "https://docs.minolith.io/api/context#limits",
    "suggestion": "Delete unused entries to free up space.",
    "entry_count": 500,
    "entry_limit": 500
  }
}
{
  "error": {
    "code": "quota_exceeded",
    "message": "Storage limit reached. Using 100.0 MB of 100 MB. Delete unused entries to free up space.",
    "docs": "https://docs.minolith.io/api/context#limits",
    "suggestion": "Delete unused entries to free up space.",
    "storage_bytes": 104857600,
    "storage_limit": 104857600
  }
}

Getting Back Under Limits

If you hit a quota limit, use these steps to free up space:

  1. Identify low-value entries. Query by type to find candidates for removal:

    • get_context with type: ["event"] — old deployment/incident events are often no longer useful. Note: event entries are immutable and cannot be deleted via the API. They can only be deleted from the dashboard.
    • get_context with type: ["todo"] — completed todos that were never cleaned up.
    • get_context with type: ["workaround"] — workarounds whose removal criteria have been met.
    • get_context with type: ["bug"] — bugs that have been fixed.
    • get_context with priority: "low" — low-priority entries are the first to consider removing.
  2. Consolidate duplicate or overlapping entries. If multiple entries cover the same topic, merge them into one comprehensive entry and delete the others.

  3. Trim verbose bodies. Update entries with unnecessarily long body text to be more concise. Storage is calculated from actual field lengths — shorter text means less storage used.

  4. Remove stale entries. Query by date range (created_before) to find old entries that may no longer be relevant.

  5. Delete entries. Use delete_context (MCP) or DELETE /v1/context/entries/:id (REST) to remove entries. Tags are deleted automatically with the entry.

Current usage is visible on the project's Context page in the dashboard at https://app.minolith.io.


Entry Types

Every entry has a type that categorises what kind of knowledge it represents. Types are universal — they work across any language, framework, or domain. Use tags and scope for language-specific, framework-specific, or domain-specific scoping.

Type Purpose Mutable Example
rule Must/must-not constraints. Hard rules the agent must follow without exception. Yes "All CSS must be in external files — never inline styles or style blocks in templates."
pattern Code and implementation patterns. The established way to do things in this project. Yes "When adding a new API endpoint, follow the controller → service → model pattern."
snippet Reusable code. Templates, boilerplate, and reference implementations to copy and adapt. Yes A standard controller method template, a database query pattern, test file boilerplate.
decision Why something was chosen. Architectural and design decisions with rationale. Yes "We use cursor-based pagination, not offset-based. Rationale: offset breaks on large datasets."
fact Objective truths about the project or environment. Yes "The production database is MySQL 8.0.35."
warning Gotchas and pitfalls. Known landmines that cause problems if the agent isn't aware of them. Yes "CI4 4.7 changed rawData default — this breaks encryption of existing data."
event Immutable timeline entries. Deployments, migrations, incidents, significant occurrences. No "Deployed v1.2.0 to production at 14:32 on March 15."
brief Specs and requirements. Feature specifications, acceptance criteria, project requirements. Yes "The changelog widget must be under 15KB gzipped, render in shadow DOM."
bug Known defects and issues. Documented bugs including reproduction steps and impact. Yes "Dashboard session expires silently after 2FA — user sees a blank page."
todo Tasks, action items, and planned work. Things that need to be done, persisting across sessions. Yes "Add spending cap alerts — email notification when account reaches 80% of cap."
dependency External services, integrations, and version constraints. Yes "Stripe API version 2023-10-16 pinned. Do not upgrade without testing webhooks."
config Environment configuration, feature flags, and settings. Yes "Redis database 0 for caching, database 1 for sessions."
workaround Temporary fixes with explicit removal criteria. Yes "Bypassing email verification due to missing email service. Remove when /v1/email/ is built."
workflow Multi-step procedures and processes. How to do things that involve multiple ordered steps. Yes "To add a new service: 1. Generate migration 2. Create models 3. Create controllers..."
persona Voice, tone, and communication style for this project's context. Yes "Error messages use first person plural: 'We couldn't process your request'."
reference Links to external documentation, specifications, or resources. Yes "Stripe webhook event types: https://stripe.com/docs/api/events/types"
preference Soft conventions and style choices. Defaults to follow but can deviate from with reason. Yes "Prefer early returns over nested conditionals. Prefer single quotes for PHP strings."
test Test strategies, test data conventions, and expected behaviours. Yes "Integration tests require Redis. Test database uses prefix test_."
glossary Project-specific terminology and definitions. Prevents misinterpreting domain language. Yes "'Entry' means a changelog item, not a database row. 'Published' means visible on the public page."

Event entries are immutable. Once created, an entry with type: event cannot be updated or deleted. This ensures the event log is a reliable historical record.

Choosing a Type

  • Hard constraint that must never be violated → rule
  • Soft preference that should usually be followed → preference
  • How to implement something → pattern
  • Reusable code to copy → snippet
  • Why a choice was made → decision
  • Objective truth about the environment → fact
  • Environment-specific configuration → config
  • Danger that causes bugs → warning
  • Temporary hack → workaround
  • Happened at a point in time, shouldn't be edited → event
  • Feature spec or requirement → brief
  • Known bug → bug
  • Work to be done → todo
  • External service or version constraint → dependency
  • Multi-step procedure → workflow
  • How to write or communicate → persona
  • Link to external docs → reference
  • How to test → test
  • Defines a term → glossary

Scoping with Tags and Scope

Types are universal. Use tags and scope for language/framework-specific categorisation:

  • A PHP pattern → type: pattern, tags: [php]
  • A CI4 convention → type: rule, tags: [codeigniter, ci4]
  • A frontend warning → type: warning, scope: css, tags: [frontend, styling]
  • A React snippet → type: snippet, tags: [react, javascript, frontend]

Endpoints

Create Entry

POST /v1/context/entries

Creates a new context entry.

Request body:

{
  "type": "rule",
  "scope": "css",
  "title": "Never inline styles or create per-page CSS",
  "body": "All styles must use the shared stylesheet at assets/css/app.css. Never use inline style attributes. Never create <style> blocks in templates.",
  "tags": ["css", "styling", "templates", "html", "frontend"],
  "priority": "high"
}
Field Type Required Description
type string yes See Entry Types for the full list of 19 types
title string yes Short description, max 500 characters
body string yes Full content, max 100,000 characters
scope string no Category or area this applies to (e.g. "css", "auth", "api"). Max 100 chars, lowercase alphanumeric + hyphens
tags array no Up to 20 string tags for filtering. Each tag: max 100 chars, lowercase alphanumeric + hyphens
priority string no One of: high, normal, low. Defaults to normal

Response (201 Created):

{
  "data": {
    "id": "ctx_a1b2c3d4e5f6",
    "type": "rule",
    "scope": "css",
    "title": "Never inline styles or create per-page CSS",
    "body": "All styles must use the shared stylesheet at assets/css/app.css...",
    "tags": ["css", "styling", "templates", "html", "frontend"],
    "priority": "high",
    "is_immutable": false,
    "created_by": "api",
    "created_at": "2026-03-15 10:00:00",
    "updated_at": "2026-03-15 10:00:00"
  }
}

Error responses:

  • 403 — Quota exceeded. The project has reached its entry or storage limit. See Limits for remediation steps.
  • 422 — Validation error. The response includes the field name and a description of the problem.
{
  "error": {
    "code": "validation_error",
    "message": "Invalid type. See docs for the full list of valid types.",
    "field": "type",
    "docs": "https://docs.minolith.io/api/context#validation-rules",
    "suggestion": "Did you mean 'rule'?"
  }
}

List Entries

GET /v1/context/entries

Returns a paginated list of entries for the authenticated project. Supports filtering by type, scope, priority, tags, date range, and full-text search.

Query parameters:

Parameter Type Description
type string Filter by type. Supports comma-separated values: type=rule,pattern
scope string Filter by exact scope: scope=css
priority string Filter by priority: priority=high
tags string Filter by tags (comma-separated, matches ANY): tags=css,html
search string Full-text search across title and body fields. Returns entries where the search term appears as a substring in either field. Max 500 characters.
created_after string ISO date/datetime: created_after=2026-03-14
created_before string ISO date/datetime: created_before=2026-03-15
limit integer Number of results (1-100, default 20)
cursor string Cursor from a previous response's pagination.next_cursor

Example requests:

GET /v1/context/entries?tags=css,html&type=rule,pattern&priority=high&limit=20
GET /v1/context/entries?type=warning&scope=admin
GET /v1/context/entries?type=event&created_after=2026-03-14
GET /v1/context/entries?search=inline+styles
GET /v1/context/entries?limit=50

Response (200 OK):

{
  "data": [
    {
      "id": "ctx_a1b2c3d4e5f6",
      "type": "rule",
      "scope": "css",
      "title": "Never inline styles",
      "body": "...",
      "tags": ["css", "styling"],
      "priority": "high",
      "is_immutable": false,
      "created_by": "api",
      "created_at": "2026-03-15 10:00:00",
      "updated_at": "2026-03-15 10:00:00"
    }
  ],
  "pagination": {
    "has_more": true,
    "next_cursor": "ctx_xyz789abc123",
    "limit": 20
  }
}

Pagination: Results are ordered by created_at descending (newest first). To get the next page, pass the next_cursor value from the response as the cursor parameter in the next request. When has_more is false, there are no more results.


Get Entry

GET /v1/context/entries/:id

Returns a single entry by its ID.

Response (200 OK):

{
  "data": {
    "id": "ctx_a1b2c3d4e5f6",
    "type": "rule",
    "scope": "css",
    "title": "Never inline styles",
    "body": "All styles must use the shared stylesheet...",
    "tags": ["css", "styling"],
    "priority": "high",
    "is_immutable": false,
    "created_by": "api",
    "created_at": "2026-03-15 10:00:00",
    "updated_at": "2026-03-15 10:00:00"
  }
}

Error responses:

  • 404 — Entry not found.
{
  "error": {
    "code": "not_found",
    "message": "Entry 'ctx_nonexistent' not found.",
    "docs": "https://docs.minolith.io/api/context#get-entry"
  }
}

Update Entry

PUT /v1/context/entries/:id

Updates an existing entry. Only include the fields you want to change. Omitted fields are left unchanged.

Cannot update immutable entries. Entries with type: event return 403 Forbidden.

Cannot change type to or from event. The immutability rules for events would make this inconsistent.

Request body (partial update):

{
  "title": "Updated title",
  "tags": ["new-tag", "another-tag"],
  "priority": "high"
}

All fields from the create endpoint are accepted. All are optional for updates.

Response (200 OK):

Returns the full updated entry in the same format as the create response.

Error responses:

  • 403 — Entry is immutable.
{
  "error": {
    "code": "forbidden",
    "message": "This entry is immutable and cannot be updated. Event entries are permanently locked after creation.",
    "docs": "https://docs.minolith.io/api/context#immutable-entries"
  }
}
  • 404 — Entry not found.
  • 422 — Validation error.

Delete Entry

DELETE /v1/context/entries/:id

Permanently deletes an entry and its tags. This is a hard delete — the entry cannot be recovered.

Cannot delete immutable entries. Entries with type: event return 403 Forbidden.

Response (204 No Content):

Empty response body.

Error responses:

  • 403 — Entry is immutable.
  • 404 — Entry not found.

Bulk Create Entries

POST /v1/context/entries/bulk-create

Create multiple entries in a single request. Maximum 50 entries per call. All entries are validated first — if ANY entry fails validation, the entire batch is rejected with no partial creates.

Request body:

Field Type Required Description
entries array of objects yes Entry objects to create (max 50)

Each entry object has the same fields as the Create Entry endpoint:

Field Type Required Description
type string yes See Entry Types
title string yes Short description, max 500 characters
body string yes Full content, max 100,000 characters
scope string no Category or area
tags array of strings no Up to 20 tags per entry
priority string no high, normal, or low. Defaults to normal

Example request:

{
  "entries": [
    {
      "type": "rule",
      "title": "Never inline CSS",
      "body": "All styles must be in external stylesheet files.",
      "tags": ["css", "frontend"],
      "priority": "high"
    },
    {
      "type": "pattern",
      "title": "Controller naming convention",
      "body": "Controllers are named {Resource}Controller and placed in app/Controllers/.",
      "tags": ["php", "codeigniter"],
      "scope": "api"
    },
    {
      "type": "fact",
      "title": "Database engine",
      "body": "Production database is MySQL 8.0.",
      "tags": ["database", "infrastructure"]
    }
  ]
}

Response (201 Created):

{
  "data": {
    "created": 3,
    "entries": [
      {"id": "ctx_a1b2c3d4e5f6", "type": "rule", "title": "Never inline CSS"},
      {"id": "ctx_b2c3d4e5f6a7", "type": "pattern", "title": "Controller naming convention"},
      {"id": "ctx_c3d4e5f6a7b8", "type": "fact", "title": "Database engine"}
    ]
  }
}

Error responses:

  • 403 — Quota exceeded. The batch would push the project over its entry or storage limit.
  • 422 — Validation error. The error message indicates which entry (by position) failed and why. No entries are created.
{
  "error": {
    "code": "validation_error",
    "message": "Entry 2: Invalid type. See docs for the full list of valid types.",
    "field": "type",
    "docs": "https://docs.minolith.io/api/context#validation-rules",
    "suggestion": "Did you mean 'pattern'?"
  }
}

Bulk Delete Entries

POST /v1/context/entries/bulk-delete

Delete multiple entries in a single request. Provide either entry IDs, tags, or both. When tags are provided, all entries matching ANY of the tags are deleted. Immutable entries (events) are silently skipped and reported in the response.

Request body:

Field Type Required Description
ids array of strings no* Entry IDs to delete
tags array of strings no* Delete entries matching ANY of these tags

*At least one of ids or tags is required. Both can be provided — the union of matched entries will be deleted.

Example request:

{
  "ids": ["ctx_a1b2c3d4e5f6", "ctx_b2c3d4e5f6a7"]
}
{
  "tags": ["deprecated", "old-feature"]
}

Response (200 OK):

{
  "data": {
    "deleted": 5,
    "skipped_immutable": 2
  }
}

skipped_immutable counts entries that matched but were not deleted because they are immutable (events).


Bulk Update Entries

POST /v1/context/entries/bulk-update

Update multiple entries in a single request. Only priority, scope, and tags can be bulk-updated — title, body, and type are per-entry fields that require individual updates. Immutable entries (events) are silently skipped.

Request body:

Field Type Required Description
ids array of strings yes Entry IDs to update
updates object yes Fields to update (see below)

updates object:

Field Type Description
priority string high, normal, or low
scope string New scope for all entries
tags array of strings Replace tags on all entries

At least one field in updates is required.

Example request:

{
  "ids": ["ctx_a1b2c3d4e5f6", "ctx_b2c3d4e5f6a7", "ctx_c3d4e5f6a7b8"],
  "updates": {
    "priority": "high",
    "tags": ["reviewed", "production"]
  }
}

Response (200 OK):

{
  "data": {
    "updated": 3,
    "skipped_immutable": 0
  }
}

Recent Events

GET /v1/context/events/recent

Convenience endpoint that returns recent event entries. Equivalent to GET /v1/context/entries?type=event but exists as a dedicated endpoint because "get recent events" is the most common query at session start.

Query parameters:

Parameter Type Description
limit integer Number of results (1-100, default 20)
cursor string Cursor for pagination

Response (200 OK):

Same format as the list entries response, but only contains entries with type: event.

List Tags

GET /v1/context/tags

Returns all distinct tags used across entries in this project. Use this to discover available tags before filtering with the list entries endpoint.

Response (200 OK):

{
  "tags": ["api", "auth", "css", "database", "deployment", "security"]
}

List Scopes

GET /v1/context/scopes

Returns all distinct scopes used across entries in this project. Use this to discover available scopes before filtering.

Response (200 OK):

{
  "scopes": ["api", "auth", "css", "dashboard", "deployment", "security"]
}

Validation Rules

Field Type Required Constraints
type enum yes rule, pattern, snippet, decision, fact, warning, event, brief, bug, todo, dependency, config, workaround, workflow, persona, reference, preference, test, glossary
scope string no Max 100 chars. Lowercase alphanumeric and hyphens only (/^[a-z0-9\-]*$/)
title string yes Max 500 chars
body string yes Max 100,000 chars
tags array of strings no Max 20 tags. Each tag: max 100 chars, lowercase alphanumeric and hyphens only (/^[a-z0-9\-]+$/)
priority enum no high, normal, low. Defaults to normal

Immutable Entries

Entries with type: event are automatically marked as immutable when created (is_immutable: true). Immutable entries:

  • Cannot be updated (returns 403)
  • Cannot be deleted (returns 403)
  • Cannot have their type changed to or from event

This ensures the event log is a reliable, tamper-proof historical record.


Error Format

All errors follow the standard Minolith error format:

{
  "error": {
    "code": "validation_error",
    "message": "Human-readable description of the problem.",
    "field": "type",
    "docs": "https://docs.minolith.io/api/context#relevant-section",
    "suggestion": "Did you mean 'rule'?"
  }
}
Field Always Present Description
code yes Machine-readable error code (snake_case)
message yes Human/agent-readable explanation
field no Which request field caused the error
docs yes URL to relevant documentation
suggestion no Suggested fix, when available

The suggestion field uses fuzzy matching. If you send an invalid type like "rules", the error will suggest "Did you mean 'rule'?".


ID Format

Entry IDs use the prefix ctx_ followed by 12 random hex characters:

ctx_a1b2c3d4e5f6

Always use the full ID (including prefix) when referencing entries in API calls.


Rate Limiting

All API endpoints are rate-limited to 100 requests per minute per API key. Rate limit headers are included in every response (see Platform API — Rate Limiting for full details):

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1710504060

If you exceed the limit, you'll receive a 429 Too Many Requests response with a retry_after field indicating how many seconds to wait.


Authentication

See Platform API — Authentication for full details. Include your API key in every request:

Authorization: Bearer mlth_your_api_key_here

API keys are created in the Minolith dashboard at https://app.minolith.io. Each key is scoped to a single project. Entries created with one key are only visible to other keys in the same project.

If the key is missing, invalid, or revoked, you'll receive a 401 Unauthorized response.


MCP Tools

The Context service is available via MCP (Model Context Protocol) for direct integration with AI coding tools like Claude Code, Cursor, Windsurf, and Cline.

Connection

claude mcp add --transport http minolith https://mcp.minolith.io \
  --header "Authorization: Bearer mlth_your_api_key_here" \
  --header "X-Minolith-Agent: your-agent-name"

The MCP server uses the same API key as the REST API. All data access is scoped to the key's project.

store_context

Store an entry in the project knowledge base. Writing context is part of development, not extra work — record decisions as you make them, gotchas as you hit them, and patterns as you establish them. See Entry Types for the full list of 19 types.

Parameters:

Parameter Type Required Description
type string yes See Entry Types for the full list
title string yes Short, descriptive title
body string yes Full content. For snippets, include the code. For rules, state the rule clearly.
scope string no Category: css, admin, api, auth, database, etc.
tags array of strings no Tags for retrieval. Be comprehensive — these are how you'll find this entry later.
priority string no high, normal, or low

Example:

{
  "name": "store_context",
  "arguments": {
    "type": "rule",
    "title": "Never inline CSS styles",
    "body": "All styles must use external stylesheet at assets/css/app.css. No inline style attributes. No <style> blocks in templates.",
    "scope": "css",
    "tags": ["css", "styling", "templates"],
    "priority": "high"
  }
}

get_context

Retrieve entries from the project knowledge base filtered by type, tags, scope, priority, and/or search. Supports full-text search across title and body fields. Do not fetch everything at once — use targeted queries to load only what's relevant. See Session Start below for the recommended retrieval pattern. The knowledge base is only as useful as what you put into it — if it is empty or stale, that is your responsibility.

Parameters:

Parameter Type Required Description
tags array of strings no Filter by tags. Returns entries matching ANY of the provided tags.
type array of strings no Filter by entry type. See Entry Types for the full list.
scope string no Filter by scope
priority string no high, normal, or low
search string no Full-text search across title and body. Returns entries where the search term appears as a substring in either field.
limit integer no Max entries to return (default 20, max 100)

Example:

{
  "name": "get_context",
  "arguments": {
    "tags": ["css", "frontend"],
    "type": ["rule", "pattern"],
    "search": "inline styles",
    "priority": "high",
    "limit": 50
  }
}

update_context

Update an existing knowledge base entry. Cannot update event entries (immutable).

Parameters:

Parameter Type Required Description
id string yes Entry ID (ctx_xxxxxxxx)
title string no New title
body string no New body
scope string no New scope
tags array of strings no Replace all tags
priority string no high, normal, or low

delete_context

Delete a knowledge base entry. Cannot delete event entries (immutable).

Parameters:

Parameter Type Required Description
id string yes Entry ID (ctx_xxxxxxxx)

bulk_store_context

Create multiple knowledge base entries in a single call. Maximum 50 entries per call. All entries are validated first — if ANY entry fails validation, the entire batch is rejected (no partial creates). Use this when you need to store several related pieces of knowledge at once, such as after a thorough codebase review or during initial project setup.

Parameters:

Parameter Type Required Description
entries array of objects yes Entry objects to create (max 50)

Each entry object has the same fields as store_context:

Field Type Required Description
type string yes See Entry Types
title string yes Short, descriptive title
body string yes Full content
scope string no Category: css, admin, api, auth, database, etc.
tags array of strings no Tags for retrieval
priority string no high, normal, or low

Example:

{
  "name": "bulk_store_context",
  "arguments": {
    "entries": [
      {
        "type": "rule",
        "title": "Never inline CSS",
        "body": "All styles must be in external stylesheet files.",
        "tags": ["css", "frontend"],
        "priority": "high"
      },
      {
        "type": "pattern",
        "title": "Controller naming convention",
        "body": "Controllers are named {Resource}Controller.",
        "tags": ["php", "codeigniter"],
        "scope": "api"
      }
    ]
  }
}

Returns:

{
  "created": 2,
  "entries": [
    {"id": "ctx_a1b2c3d4e5f6", "type": "rule", "title": "Never inline CSS"},
    {"id": "ctx_b2c3d4e5f6a7", "type": "pattern", "title": "Controller naming convention"}
  ]
}

bulk_update_context

Update multiple knowledge base entries at once. Only priority, scope, and tags can be bulk-updated — title, body, and type are per-entry fields that require individual updates via update_context. Immutable entries (events) are silently skipped.

Parameters:

Parameter Type Required Description
ids array of strings yes Entry IDs (ctx_xxxxxxxx) to update
priority string no New priority for all entries: high, normal, or low
scope string no New scope for all entries
tags array of strings no Replace tags on all entries

At least one of priority, scope, or tags must be provided.

Example:

{
  "name": "bulk_update_context",
  "arguments": {
    "ids": ["ctx_a1b2c3d4e5f6", "ctx_b2c3d4e5f6a7"],
    "priority": "high",
    "tags": ["reviewed", "production"]
  }
}

Returns: { "updated": 2, "skipped_immutable": 0 }

bulk_delete_context

Delete multiple knowledge base entries at once. Provide either entry IDs or tags (entries matching ANY of the tags will be deleted), or both. Immutable entries (events) are silently skipped.

Parameters:

Parameter Type Required Description
ids array of strings no* Entry IDs (ctx_xxxxxxxx) to delete
tags array of strings no* Delete entries matching ANY of these tags

*At least one of ids or tags is required.

Example:

{
  "name": "bulk_delete_context",
  "arguments": {
    "tags": ["deprecated", "old-feature"]
  }
}

Returns: { "deleted": 5, "skipped_immutable": 2 }

log_event

Log an immutable event to the project timeline. Use for deployments, migrations, incidents, and other significant occurrences. Log events as they happen, not after — this is part of the development workflow.

Parameters:

Parameter Type Required Description
title string yes Short event description
body string yes Event details
scope string no Category
tags array of strings no Tags for retrieval

Example:

{
  "name": "log_event",
  "arguments": {
    "title": "Deployed v2.3.1 to production",
    "body": "Deployed commit abc123. Includes new user search feature and bug fix for pagination.",
    "tags": ["deployment", "production"]
  }
}

get_recent_events

Get the most recent events from the project timeline. Use at session start to understand what has happened since last session.

Parameters:

Parameter Type Required Description
limit integer no Number of events to return (default 20, max 50)

list_tags

List all distinct tags used across context entries in this project. Use to discover available tags before querying with get_context.

Parameters: None.

Returns: { "tags": ["api", "auth", ...], "count": 12 }

list_scopes

List all distinct scopes used across context entries in this project. Use to discover available scopes before querying with get_context.

Parameters: None.

Returns: { "scopes": ["api", "auth", ...], "count": 8 }


Session Tracking and Warnings

The server tracks which context tools each API key has called within a rolling 30-minute session window. When an agent skips recommended workflow steps, responses include a _warnings array with advisory guidance. These warnings are informational — the tool still executes successfully.

Warning triggers:

Situation Warning
Calling store_context, update_context, delete_context, or log_event without having called get_context in the last 30 minutes "You haven't loaded existing context this session. Run get_context with priority=high first to avoid overwriting or duplicating existing entries."
Calling get_context without having called list_tags or list_scopes first "Use list_tags and list_scopes to discover available filters before querying. This ensures you don't miss relevant entries."

Example response with warnings:

{
  "data": {
    "id": "ctx_a1b2c3d4e5f6",
    "type": "rule",
    "title": "...",
    "body": "..."
  },
  "_warnings": [
    "You haven't loaded existing context this session. Run get_context with priority=high first to avoid overwriting or duplicating existing entries."
  ]
}

MCP responses include _warnings in the tool result JSON. REST responses include _warnings as a top-level field alongside data and pagination.

Warnings disappear once the recommended workflow steps are followed. The 30-minute window resets on each tool call, so an active session never expires.

Following the recommended session-start protocol (list_tags/list_scopes, then get_context with priority=high, then get_recent_events) eliminates all warnings for the remainder of the session.


Example Workflows

Session Start

At the beginning of a coding session, load project knowledge before making changes. Do not fetch everything at once — a single unfiltered get_context call with a high limit will miss important entries once the knowledge base grows beyond that limit. Instead, use multiple targeted queries:

  1. Discover available filters: Call list_tags and list_scopes to see what tags and scopes exist. This informs your subsequent queries and eliminates the _warnings on get_context.
  2. Load critical rules: Call get_context with priority: "high" — these are the non-negotiable rules, warnings, and decisions that every session needs regardless of task. This set stays small and focused.
  3. Check recent activity: Call get_recent_events with limit: 10 to see what happened since last session (deployments, incidents, migrations).
  4. Load task-specific context: Call get_context with tags and/or scope relevant to your current task. Working on CSS? Use tags: ["css", "design-system"]. Touching auth? Use scope: "auth".
# Step 1: Discover filters (always)
list_tags
list_scopes

# Step 2: Critical rules (always)
get_context → priority: "high"

# Step 3: Recent activity (always)
get_recent_events → limit: 10

# Step 4: Task-specific (varies per session)
get_context → tags: ["css", "frontend"], type: ["rule", "pattern"]

This approach scales as the knowledge base grows, ensures critical context is never lost below a limit cutoff, and avoids session warnings.

During Development

Writing context entries is part of the development workflow, not something you do after. As you work:

  • Made a decision? Store it as a decision with the rationale, so the next session doesn't revisit it.
  • Hit a gotcha? Store it as a warning immediately, while the details are fresh.
  • Established a pattern? Store it as a pattern so it gets followed consistently.
  • Discovered a fact? Store it as a fact so nobody has to rediscover it.
  • Found a bug? Store it as a bug with reproduction steps.
  • Need to do something later? Store it as a todo so it persists across sessions.
  • Applied a temporary hack? Store it as a workaround with removal criteria.
  • Found an external dependency constraint? Store it as a dependency.
  • Finished a deployment or migration? Log it as an event.

The quality of this knowledge base is your responsibility. If it contains crummy information, that's on you. If it's empty, that's on you too.

Storing a New Rule

When you discover a project convention or constraint:

{
  "name": "store_context",
  "arguments": {
    "type": "rule",
    "title": "Always use UUIDs for URL parameters",
    "body": "Never expose database primary keys in URLs. All URL parameters must use prefixed UUIDs (ctx_, prj_, acc_, etc.).",
    "scope": "api",
    "tags": ["security", "api", "routing", "urls"],
    "priority": "high"
  }
}

Logging a Deployment

After completing a deployment:

{
  "name": "log_event",
  "arguments": {
    "title": "Added user search to admin dashboard",
    "body": "Implemented search by email and status filtering on the accounts list page. Files changed: AccountController.php, admin/accounts/index.php.",
    "tags": ["feature", "admin", "accounts"]
  }
}

Last updated: 6 Apr 2026