MCP tools

Tool payloads and ACL alignment.

Spectron's MCP server exposes seven tools at /mcp. Each tool maps to one or more REST endpoints and carries the same authentication and scope semantics.

All tools use Authorization: Bearer authentication (same as REST). Pass the token in the MCP configuration:

{
"mcpServers": {
"spectron": {
"url": "https://spectron.example.com/mcp",
"headers": {
"Authorization": "Bearer sk-...",
"X-Spectron-Context": "acme-prod"
}
}
}
}

X-Spectron-Context in MCP client configs is a convenience for templating; the server resolves context from each tool's context_id argument.

Scope is layered on each tool call:

  1. Grant region (from the API key's principal) – enforced server-side; cannot be widened past what the key allows.

  2. Per-call scopes / lens argument – DNF selector narrowing the operation within the grant (scopes on writes, lens on recall/context).

Register paths with spectron scopes create before first use.

Store a memory from the current conversation. Auto-classifies into Identity / Knowledge / Context categories and reconciles against existing memory.

Principal required: agent or management.

Input:

{
"content": "I just got promoted to CTO.", // required
"role": "user", // optional, default "user"
"session_id": "sess_abc123", // optional – creates implicit session if omitted
"scopes": [["org/acme/user/alice"]]
}

Output:

{
"turn_id": "turn:01HF...",
"entities": [{ "id": ["Person", "alice"], "action": "updated" }],
"attributes": [{ "key": "role", "value": "CTO", "action": "superseded" }],
"relations": [],
"instructions": [],
"uncertainties": [],
"corrections": [],
"traceId": "…"
}

Underlying REST endpoint: POST /api/v1/{context_id}/facts (or POST .../facts/batch for multi-turn capture)

Retrieve relevant memory and knowledge for a query. Returns a formatted context block ready for prompt injection.

Principal required: any (agent, supervisor, management).

Input:

{
"query": "What does Alice do at Acme?", // required
"k": 10, // optional, default 10
"lens": [["org/acme"]]
}

Output:

{
"context": "Alice – CTO at Acme Corp. Currently leading the Q3 roadmap review.",
"tier": "direct",
"queryMs": 12,
"traceId": "…"
}

The context field is intended for direct injection into the system prompt. The tier field indicates the resolution path: direct, cache, hybrid, or full_context.

Underlying REST endpoint: POST /api/v1/{context_id}/context

Synthesise patterns or insights from existing memory. Can optionally persist the reflection as new experiential memory attributes.

Principal required: any for persist: false; supervisor or management for persist: true.

Input:

{
"query": "What recurring complaints have customers raised this month?",
"persist": true, // optional, default false
"lens": [["org/acme"], ["project/support"]] // OR: org-wide OR project/support involvement
}

Output:

{
"reflection": "Three recurring patterns emerged: billing confusion (8 tickets), …",
"evidence": ["memory_chunk:01HF...", "attribute:..."],
"persisted_attributes": [],
"traceId": "…"
}

When persist: true, persisted_attributes lists the attributes stored from this reflection.

Underlying REST endpoint: POST /api/v1/{context_id}/reflect

Get the aggregated profile for the active scope – static facts, dynamic context, preferences, and active instructions – formatted for system prompt injection.

Principal required: any.

Input:

{
"scopes": [["org/acme/user/alice"]]
}

Output:

{
"static": [
{ "key": "name", "value": "Alice" },
{ "key": "role", "value": "CTO" }
],
"dynamic": [
{ "key": "current_task", "value": "Q3 roadmap review" }
],
"preferences": [
{ "key": "editor", "value": "Neovim" }
],
"instructions": [
{ "label": "tone", "description": "Concise and direct" }
]
}

Underlying REST endpoint: GET /api/v1/{context_id}/profile

Search the authoritative authoritative knowledge base. Returns ranked document chunks with source references.

Principal required: any.

Input:

{
"query": "What is the return window for unopened items?", // required
"mode": "hybrid", // optional: vector | bm25 | hybrid | hybrid_graph
"k": 5, // optional, default 5
"threshold": 0.5, // optional
"filter": { "mime_type": ["application/pdf"] } // optional
}

Output:

{
"results": [
{
"chunk": {
"id": "knowledge_chunk:...",
"text": "Unopened items may be returned within 30 days of purchase...",
"section": "Eligibility",
"position": 7
},
"score": 0.87,
"document": {
"id": "document:0197...",
"title": "Returns Policy (2026 revision)",
"source": "returns.pdf"
}
}
],
"queryMs": 38,
"traceId": "…"
}

Underlying REST endpoint: POST /api/v1/{context_id}/query (unified recall) or POST .../documents/query (document passages only)

Fetch a specific document, chunk, or typed knowledge node by ID. Use this after knowledge_search has identified the source – fetching by ID is faster and more deterministic than re-searching.

Principal required: any.

Input:

{
"kind": "document", // document | chunk | node
"id": "document:0197...", // for kind=document or kind=chunk
"node": { "kind": "product", "slug": "airpods_pro_2" } // for kind=node
}

Output: A typed payload matching the underlying endpoint – document metadata and status, a paginated chunk list, or a knowledge node with its content and related edges.

Underlying REST endpoints:

  • GET /api/v1/{context_id}/documents/{id}

  • GET /api/v1/{context_id}/documents/{id}/chunks

  • GET /api/v1/{context_id}/entities/{entity_type}/{entity_name}

Upload a document to the knowledge layer. Bytes are base64-encoded on the wire; processing is asynchronous (chunk, embed, index).

Principal required: agent or management (with memory:write grant).

Input:

{
"context_id": "acme-prod", // required
"bytes_base64": "<RFC 4648 bytes>", // required
"title": "Returns Policy",
"source": "returns.pdf",
"mime_type": "application/pdf",
"filename": "returns.pdf",
"scopes": [["org/acme/team/eng"]], // optional — narrower than memory:write
"labels": ["team=eng"] // optional — stamped on document rows
}

Output:

{
"id": "doc:01hx9…",
"status": "queued",
"content_hash": "blake3:…",
"deduplicated": false,
"version": 1
}

Underlying REST endpoint: POST /api/v1/{context_id}/documents

Stop believing something. Sets valid_until on attributes that semantically match the query. Does not physically delete records.

Principal required: agent or management.

Input:

{
"query": "anything about my previous role at the old company", // required
"scopes": [["org/acme/user/alice"]]
}

Output:

{
"deleted": 3,
"traceId": "…"
}

The deleted count reflects attributes soft-deleted (marked with valid_until).

Underlying REST endpoint: POST /api/v1/{context_id}/forget

Operation failures return an isError: true tool result (HTTP transport stays 200), not a JSON-RPC protocol error. The result includes the same HTTP status the REST API would return:

{
"isError": true,
"structuredContent": {
"error": {
"status": 404,
"message": "Document not found"
}
}
}
StatusMeaningAgent action
401Missing or invalid keyFix credentials; missing Context is masked as 401 (not 404)
403Grant deniedNarrow scope or request access
404Resource not foundAdjust query or id
429Rate or token limitBack off and retry
500Server faultRetry; details are redacted

JSON-RPC error responses are reserved for protocol faults only — malformed params (-32602), unknown tool (-32601), oversized k, and similar.

Denied operations emit the same authz.denied audit events and error metrics as REST.

Toolagentsupervisormanagement
memory_store
memory_recall
memory_reflect (no persist)
memory_reflect (persist=true)
memory_profile
knowledge_search
knowledge_get
memory_forget

Most tools are synchronous – the full response is returned in a single payload.

memory_reflect with persist: true on a large corpus may take several seconds. The server emits MCP progress notifications while the underlying reflection handler runs.

Was this page helpful?