Frinus MCP Server
by frinus-ai
README.md
# Frinus MCP Server
> **φρήν + νοῦς** — Gives your Claude agent long-term, cognitive memory backed by the [Frinus](https://frinus.rdxsec.com.br) platform.
`frinus-mcp` is an MCP (Model Context Protocol) server. It is the **bridge** between your MCP client — Claude Code, Cursor, or Claude Desktop — and the **Frinus platform hosted at https://frinus.rdxsec.com.br**.
It does **not** run on its own. It stores nothing locally: every tool call is forwarded over HTTPS to your Frinus account. So before it does anything useful you need two things:
1. a **Frinus account** (free, no card), and
2. a **Frinus API key** (`sk-frinus-...`).
With those in place, the server exposes **70 tools** spanning cognitive memory, working memory, sessions, agents, the L0–L3 knowledge hierarchy, orchestration tasks, and training pipelines. It speaks stdio and works with any MCP-aware client.
- **Version:** 3.4.1
- **Tools:** 70 (see [Tools Reference](#tools-reference))
- **Platform:** https://frinus.rdxsec.com.br (hosted SaaS — the backend this server talks to)
- **npm package:** [`frinus-mcp`](https://www.npmjs.com/package/frinus-mcp)
## How it fits together
```
+-------------------+ +--------------+ +----------------------------+
| Your MCP client | stdio | frinus-mcp | HTTPS | Frinus platform |
| (Claude Code, | <----> | (this server,| <----> | frinus.rdxsec.com.br |
| Cursor, Desktop) | | via npx) | | (your memories live here) |
+-------------------+ +--------------+ +----------------------------+
```
The server validates your API key against the platform at startup, resolves your account + organisation, and routes every tool call there. No API key → it refuses to start.
## Rule Zero — MCP is mandatory
The Frinus MCP **is** the agent's long-term memory, identity, and intelligence. Without it the model is stateless across sessions. Every Claude agent that integrates with Frinus must:
1. Verify the MCP tools are reachable at conversation start (e.g. `session_start`, `memory_search`, `search_with_attention`).
2. If unreachable, surface the warning to the user: *"MCP Frinus is not connected. Long-term memory capabilities are unavailable."*
3. Execute the **BOOT protocol (P1)** before answering anything that is not a trivial greeting.
4. Persist learnings via `memory_store` before ending productive sessions.
The complete protocol set lives in the global `CLAUDE.md` (Frinus organisation), summarised below in [The 7 Protocols](#the-7-protocols).
## Before you start — account + API key
You need a Frinus account and an API key. Both are free to get.
### 1. Create a free account
Sign up at **https://frinus.rdxsec.com.br**. The **Free plan (R$0)** is enough to get started:
- 100 memories
- 20 queries/day
- no credit card required
### 2. Generate an API key
Once logged in, open your account **Settings → API Keys** and create a new key. You'll get a value shaped like:
```
sk-frinus-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
Copy it now — for security it's shown **only once**. This value goes into the `FRINUS_API_KEY` environment variable below. Treat it like a password; never commit it to a repo.
## Getting started (zero to first memory)
Five minutes, four steps.
### Step 1 — Create your account
Sign up at https://frinus.rdxsec.com.br (Free plan, no card). See [above](#1-create-a-free-account).
### Step 2 — Generate your API key
Settings → API Keys → create. Copy the `sk-frinus-...` value. See [above](#2-generate-an-api-key).
### Step 3 — Add the server to your client
You don't install anything — `npx` fetches and runs the package on demand. The only value you must provide is your API key; the platform URLs already default to production.
**Claude Code (one-liner):**
```bash
claude mcp add frinus --env FRINUS_API_KEY=sk-frinus-... -- npx -y frinus-mcp@latest
```
**Cursor / Claude Desktop / any client (config JSON):**
```json
{
"mcpServers": {
"frinus": {
"command": "npx",
"args": ["-y", "frinus-mcp@latest"],
"env": {
"FRINUS_API_KEY": "sk-frinus-..."
}
}
}
}
```
Config file locations:
- **Claude Code:** `~/.claude.json`, under `mcpServers`.
- **Claude Desktop:** `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `~/.config/claude/claude_desktop_config.json` (Linux). Or use the one-click `.mcpb` extension and just paste your API key.
- **Cursor:** `~/.cursor/mcp.json`, under `mcpServers`.
Restart the client so it picks up the new server.
> Replace `sk-frinus-...` with the real key from Step 2. You normally set **only** `FRINUS_API_KEY` — every backend URL already defaults to the hosted platform. See [Environment Variables](#environment-variables) for the full list and the self-host override.
### Step 4 — Validate with your first memory
In your client, ask the agent to store and recall something:
```
Store this in Frinus memory: "Our staging DB is reset every night at 02:00 UTC."
```
then in the same or a later session:
```
What time does our staging DB reset?
```
Behind the scenes the agent calls `memory_store` then `memory_search` / `search_with_attention`. If the recall comes back, the bridge is live. You can confirm the same memory appears in the web app at https://frinus.rdxsec.com.br.
## Environment Variables
In normal use you set **only** `FRINUS_API_KEY`. The service URLs already point at the hosted platform — leave them alone unless you self-host (see [Advanced — self-host](#advanced--self-host--local-dev)).
| Variable | Default (hosted platform) | Description |
|----------|---------------------------|-------------|
| `FRINUS_API_KEY` | **required** | Your personal API key (`sk-frinus-...`). Resolves account + organisation at boot. |
| `MEMORY_SERVICE_URL` | `https://frinus-memory.rdxsec.com.br` | Memory Engine base URL |
| `FRINUS_CP_URL` | `https://frinus-api.rdxsec.com.br` | Control Plane base URL (account, orgs, API keys, billing) |
| `AGENT_SERVICE_URL` | `https://frinus-agents.rdxsec.com.br` | Agent Service base URL (agents, invocation, skills) |
| `FRINUS_MEMORY_API_KEY` | — | Legacy fallback for `FRINUS_API_KEY` |
On startup the server validates the API key against the platform and resolves your organisation + logged-in user. If validation fails it aborts with `[FATAL]` so the client surfaces the error — re-check the key from Settings → API Keys.
## The 7 Protocols
| Protocol | When | Tools | Purpose |
|----------|------|-------|---------|
| **P1 — BOOT** | Start of every session | `session_start`, `working_memory_get`, `search_with_attention` | Load identity + recent state + relevant context |
| **P2 — CONSULT** | Before any action | `search_with_attention`, `session_context`, `memory_reinforce`, `memory_weaken` | Retrieve, rate, and reinforce relevant memories |
| **P3 — PLAN** | Planning a task | `memory_store(procedural)`, `working_memory_add`, `stream_capture` | Persist plans, working state, and architectural decisions |
| **P4 — CAPTURE** | Every 2–3 interactions | `heartbeat_tick`, `working_memory_add`, `memory_store(episodic)`, `stream_capture` | Continuous recording of progress, bugs, patterns |
| **P5 — LEARN** | New knowledge | `training_teach`, `training_qa`, `training_stats`, `stream_process`, `sleep_run` | Teach facts/procedures and run consolidation cycles |
| **P6 — AUDIT** | Maintenance | `consolidation_detect_conflicts`, `consolidation_resolve_conflict`, `consolidation_detect_redundant`, `hierarchy_consolidate` | Detect conflicts, redundancy, and consolidate memories |
| **P7 — CLOSE** | End of session | `session_summary`, `stream_process`, `memory_store`, `hierarchy_consolidate`, `session_end` | Summarise, promote stream items, persist learnings |
Detailed protocol scripts live in the agent's `CLAUDE.md`. Treat the table above as the contract every Frinus-integrated agent must respect.
## Tools Reference
70 tools grouped by domain. Every tool returns text content; payloads follow the MCP `Tool` spec. Full JSON schemas live in [`src/tools/definitions.ts`](src/tools/definitions.ts).
### Memory (7)
Cognitive long-term memory: episodic (what happened), semantic (what I know), procedural (how to do things).
| Tool | Description |
|------|-------------|
| `memory_store` | Create a memory. `agent_id`, `content` required. `memory_type` ∈ {episodic, semantic, procedural}. `scope` ∈ {user, agent, universe, organization}. `importance` 0–1. |
| `memory_search` | Semantic similarity search. Filters: `agent_id`, `memory_types`, `limit`. |
| `memory_get` | Fetch a memory by `memory_id` (full content, metadata, relevance). |
| `memory_list` | List memories for an `agent_id` with optional type filter. |
| `memory_delete` | Permanently delete a memory by `memory_id`. |
| `memory_reinforce` | Boost relevance of a useful memory (`memory_id`, `boost` 0–1, default 0.1). |
| `memory_weaken` | Penalise an outdated memory (`memory_id`, `penalty` 0–1, default 0.2). |
### Working Memory (3)
Short-term, context-bound state. Miller's Law: max 7 items per context, oldest auto-evict. Default TTL 30 min (max 2 h).
| Tool | Description |
|------|-------------|
| `working_memory_get` | Load current state for a context. Always call at task start. |
| `working_memory_add` | Persist current state. Context formats: `agent:{uuid}`, `universe:{uuid}`, `organization:{uuid}`. |
| `working_memory_clear` | Remove all items for a context. |
### Sessions (5)
Session = logical container for streams, working memory, and capture.
| Tool | Description |
|------|-------------|
| `session_start` | Begin a session for an agent. Returns `session_id`. Supports `parent_session_id` for subagent inheritance. |
| `session_end` | Terminate a session and finalise its summary. |
| `session_context` | Combined working + long-term retrieval, enhanced with extracted session topics. |
| `session_summary` | Generate a structured recap (decisions, learnings, pending items). |
| `session_clear` | Wipe a session's working state without ending it. |
### Stream (4)
Continuous capture pipeline. Items are batched, scored, and the important ones promoted to permanent memories.
| Tool | Description |
|------|-------------|
| `stream_capture` | Record an input / output / internal note tied to a session. |
| `stream_get_session` | Replay every captured item for a `session_id`. |
| `stream_get_recent` | Recent stream items across sessions (filterable). |
| `stream_process` | Promote pending items to long-term memory (manual trigger; scheduler also runs every 5 min). |
### Context & Attention (2)
| Tool | Description |
|------|-------------|
| `memory_get_context` | Build a token-bounded context window for a task description. |
| `search_with_attention` | RAG with task-type-aware weighting. `task_type` ∈ {implementation, debug, deploy, documentation, review} drives memory_type weights. |
### Users (2)
| Tool | Description |
|------|-------------|
| `user_register` | Register a user with the memory system (idempotent). |
| `user_get_context` | Retrieve combined user memories and tenant context. |
### Maintenance (2)
| Tool | Description |
|------|-------------|
| `heartbeat_tick` | Cheap tick for an agent — drives relevance decay and lightweight consolidation. |
| `sleep_run` | Trigger a sleep cycle. `phases` ⊆ {evaluation, forgetting, consolidation, relevance}. Mirrors the scheduler's normal/deep sleeps. |
### Consolidation (3)
| Tool | Description |
|------|-------------|
| `consolidation_detect_conflicts` | Surface candidate conflicting memories above a similarity threshold. |
| `consolidation_resolve_conflict` | Keep one memory, supersede the other with a written resolution note. |
| `consolidation_detect_redundant` | Find near-duplicates ready for merge or removal. |
### Memory Hierarchy (2)
| Tool | Description |
|------|-------------|
| `hierarchy_consolidate` | Roll several related memories into a higher-level summary memory. |
| `hierarchy_get_tree` | Inspect the consolidation tree for a root memory. |
### Agents (6)
Agent CRUD + orchestrated invocation.
| Tool | Description |
|------|-------------|
| `agent_create` | Create an agent (optionally from a template) scoped to a universe / team. |
| `agent_list` | List agents in the caller's tenant. Auto-scoped via API key. |
| `agent_get` | Fetch an agent by `agent_id`. |
| `agent_update` | Update persona, team, universe, etc. |
| `agent_delete` | Delete an agent. |
| `agent_invoke` | Programmatically invoke an agent with a task. Returns its tool calls and final answer. Used by delegation. |
### Universes (4)
Universe = tenant-scoped knowledge domain. Holds the L0–L3 hierarchy.
| Tool | Description |
|------|-------------|
| `universe_create` | Create a universe in the caller's org. Slug + name + description. |
| `universe_list` | List universes for the resolved org. |
| `universe_update` | Patch a universe (name, description). |
| `universe_hierarchy` | Walk the full L0 → L3 tree for a universe with status icons. |
### Knowledge Hierarchy L0–L3 (16)
```
Universe
└─ Concept (L0) body of knowledge
└─ Theme (L1) thematic split
└─ Topic (L2) unit of work (status: pending / in_progress / completed)
└─ Point (L3) atomic knowledge unit
```
Each level exposes `create`, `list`, `update`, `delete`:
- **L0 Concepts**: `concept_create`, `concept_list`, `concept_update`, `concept_delete`
- **L1 Themes**: `theme_create`, `theme_list`, `theme_update`, `theme_delete`
- **L2 Topics**: `topic_create`, `topic_list`, `topic_update`, `topic_delete`
- **L3 Points**: `point_create`, `point_list`, `point_update`, `point_delete`
`topic_update` and `point_update` accept a `status` field so agents can mark progress.
### Training Pipeline (6)
Teach the system explicitly — facts, procedures, Q&A pairs, full documents.
| Tool | Description |
|------|-------------|
| `training_teach` | Inject a fact or procedure. `type` ∈ {semantic, procedural}. |
| `training_qa` | Train with `pairs` of `{question, answer}`. |
| `training_stats` | Coverage statistics across the corpus. |
| `training_gaps` | Detected gaps in knowledge / weakly-covered topics. |
| `training_recent` | Most recently ingested memories from training. |
### Orchestration — Tasks (4)
Task table on the Memory Engine drives multi-agent orchestration.
| Tool | Description |
|------|-------------|
| `task_create` | Create a task (title, description, optional `assigned_agent_id`, parent task). |
| `task_get` | Fetch a task with its full state. |
| `task_list` | List tasks with filters (status, agent, parent). |
| `task_update` | Update status, output, or assignment. |
### Skills (4)
Reusable behaviours assigned to agents.
| Tool | Description |
|------|-------------|
| `skill_list` | Enumerate available skills in the tenant. |
| `skill_assign` | Attach a skill to an agent. |
| `skill_remove` | Detach a skill from an agent. |
| `skill_agent_list` | List the skills owned by a given agent. |
### Credential Vault (5) — `credential_exec` broker
Encrypted credentials stored in the Control Plane, referenced from memories via
`credential_ref`.
| Tool | Description |
|------|-------------|
| `credential_store` | Store an encrypted credential under a ref (e.g. `mysql_x`). |
| `credential_get` | Inspect **non-secret metadata only** (host/user/db/port + the env vars `credential_exec` will inject). Never returns the value. |
| `credential_exec` | **Run a command with the credential injected into the child process ENV.** Returns only stdout/stderr/exit_code — the secret never reaches the model, screen, or disk. |
| `credential_list` | List stored credential refs (no secret data). |
| `credential_delete` | Delete a stored credential. |
**Secret-handling principle — server-side broker, never by value.** The model
never receives a secret value: no plaintext, no temp files, no shell snippets that
carry the secret. To *use* a credential you call **`credential_exec`**. The MCP
server (already running locally via `npx -y frinus-mcp@latest`) fetches the
credential from the vault, injects its fields into the **environment** of a child
process — never into argv, never into any text the model sees — runs the command
with `shell:false` (no shell injection), and returns only the output.
```jsonc
// MYSQL_PWD / MYSQL_USER / MYSQL_HOST are pre-injected → standard clients just work
credential_exec(ref="mysql_prod", argv=["mysql", "-e", "SELECT 1"])
credential_exec(ref="pg_prod", argv=["psql", "-c", "SELECT 1"])
// For anything else, read the injected vars inside an explicit shell:
credential_exec(ref="jira_x", argv=["sh","-c",
"curl -sS -H \"Authorization: Bearer $CRED_TOKEN\" \"$CRED_BASE_URL/whoami\""])
```
Injected env vars (when present in the credential): password/secret/token →
`MYSQL_PWD`, `PGPASSWORD`, `CRED_PASSWORD`; `user`/`username` → `CRED_USER`,
`MYSQL_USER`, `PGUSER`; `host` → `CRED_HOST`, `MYSQL_HOST`, `PGHOST`; `port` →
`CRED_PORT`, `MYSQL_TCP_PORT`, `PGPORT`; `database` → `CRED_DATABASE`,
`PGDATABASE`; any other scalar → `CRED_<UPPER_SNAKE>` (e.g. `base_url` →
`CRED_BASE_URL`). `argv` must be an array of strings (no shell command string;
use `["sh","-c","..."]` if you really need a shell). 30s timeout, 256 KiB output
cap. Everything ships in the npm package — **the user installs nothing, edits no
PATH, and runs no extra command**; an up-to-date MCP is all that's required.
## Memory Types
| Type | Use Case | Example |
|------|----------|---------|
| `episodic` | Record what happened | `Bug: payment endpoint returned 500. Cause: missing null check on customer.address. Fix: guard + 422 response. File: services/payment.py` |
| `semantic` | Store facts and knowledge | `MemoryResponse now includes universe_id (UUID | None) so the frontend can group memories per universe in the graph view.` |
| `procedural` | Document how-to procedures | `Procedure: rotate-claude-credentials. Steps: 1) aws ecr login, 2) kubectl set image deployment/agent..., 3) verify pod is Ready. Caveat: deployment is named "agent", not "agent-service".` |
## Scopes
| Scope | Visibility | Use Case |
|-------|------------|----------|
| `user` | Only the storing user | Personal preferences and history |
| `agent` | Only the storing agent | Agent-private notes |
| `universe` | All agents inside the universe (department) | Shared domain knowledge |
| `organization` | All agents in the tenant | Org-wide procedures and facts |
> The legacy `agent / project / global` scopes were retired together with `project_id`. Universes replaced projects as the isolation boundary inside an organisation.
## Best Practices
Required formats for memories — make future retrieval deterministic:
- **Bug:** `Bug: <description>. Cause: <root cause>. Fix: <solution>. File: <path>`
- **Pattern:** `Pattern: <description>. When to use: <context>. File: <path>`
- **Procedure:** `Procedure: <name>. Steps: 1) ... 2) ... 3) .... Caveats: <warnings>`
Operational guidelines:
1. **Always boot first.** Call `session_start` + `working_memory_get` + `search_with_attention` before answering.
2. **Reinforce / weaken on use.** When a recalled memory helps, `memory_reinforce`. When it's wrong, `memory_weaken` (and replace it).
3. **Capture every 2–3 turns.** `working_memory_add` for state, `stream_capture` for decisions, `memory_store` for crystallised learnings.
4. **Pick the right `task_type`.** `search_with_attention` weights memory types per task. `debug` favours episodic, `documentation` favours semantic, `deploy` favours procedural.
5. **Close the loop.** End sessions with `session_summary` + `stream_process` + `session_end`. Run `sleep_run` for deeper consolidation when batches grow.
6. **Audit before clutter accumulates.** Periodic `consolidation_detect_conflicts` + `consolidation_detect_redundant` keep recall sharp.
## Architecture
```
+---------------------+ +------------------+ +----------------------+
| Claude Agent / | <---> | Frinus MCP | <---> | Memory Engine |
| Claude Code | stdio | (this server) | HTTPS | (memories, sessions, |
+---------------------+ +------------------+ | hierarchy, tasks) |
| +----------------------+
| |
| v
| +----------------------+
| | PostgreSQL+pgvector |
| | + Apache AGE (graph) |
| +----------------------+
|
+---HTTPS---> Control Plane (universes, orgs)
+---HTTPS---> Agent Service (agents, invocation, skills)
```
- **Memory Engine** owns memories, working memory, sessions, streams, the L0–L3 hierarchy, training, sleep cycles, tasks, skills.
- **Control Plane** owns orgs, universes, members, API keys, billing, credentials, white-label, LLM keys.
- **Agent Service** owns agent runtime, tool dispatch, team routing, persona, invocation.
Tenant isolation is database-per-tenant. The MCP resolves your tenant org ID from the API key at boot — you never pass `org_id` manually.
## Advanced — self-host / local dev
Everything above targets the hosted platform at https://frinus.rdxsec.com.br, which is what almost everyone wants. If you run your own Frinus stack (or develop the MCP against a local backend), build from source and override the three URLs:
```bash
git clone https://github.com/frinus-ai/frinus-mcp && cd frinus-mcp
npm install
npm run build # emits dist/index.js
```
```json
{
"mcpServers": {
"frinus": {
"command": "node",
"args": ["/absolute/path/to/mcp/dist/index.js"],
"env": {
"FRINUS_API_KEY": "sk-frinus-...",
"MEMORY_SERVICE_URL": "http://localhost:8001",
"FRINUS_CP_URL": "http://localhost:8000",
"AGENT_SERVICE_URL": "http://localhost:8002"
}
}
}
}
```
### Publishing (maintainers)
```bash
# 1) npm package — powers `npx -y frinus-mcp` everywhere
npm version <patch|minor|major>
npm publish # prepublishOnly runs the build
# 2) .mcpb bundle — powers the Claude Desktop one-click install
npm run pack:mcpb # -> frinus.mcpb
gh release upload v<version> frinus.mcpb --repo frinus-ai/frinus-mcp --clobber
# Frontend points at: releases/latest/download/frinus.mcpb
```
## Development
```
mcp/
src/
index.ts Entry: MCP server, dispatch, auth bootstrap
client/
memory-client.ts HTTP client + identity state for Memory Engine
cp-client.ts HTTP client for Control Plane
agent-client.ts HTTP client for Agent Service
tools/
definitions.ts Tool schemas (70 tools)
handlers.ts Tool handlers (70 handlers)
capture/
interaction-capture.ts Auto stream capture for every tool call
types/
index.ts Shared types
dist/ Compiled output (npm run build)
package.json
tsconfig.json
```
Scripts:
```bash
npm run build # tsc to dist/
npm run dev # tsx hot reload (src/index.ts)
npm start # node dist/index.js
```
Type checking: TypeScript 5.6+, ES modules, axios.
## License
See repository root for license terms.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues