Cortivium
The most reliable way to control AI behavior.
Ghost Skills register as real MCP tools — not suggestions the model can ignore,
but contracts it reads before every action. More reliable than system prompts,
CLAUDE.md files, memory, or anything in the context window.
Website · Documentation · Ghost Skills Guide · Contact
Why Ghost Skills?
System prompts drift. CLAUDE.md files get ignored in long sessions. Memory instructions compete with conversation context and lose. These approaches inject advisory text — the model treats them as suggestions.
Ghost Skills take a fundamentally different approach. They register as real MCP tools with descriptions the model reads every time it considers an action. Tool descriptions aren't suggestions — they're API contracts the model follows.
You: "Create a ghost skill that enforces our code standards
after every file edit"
→ [Creates ghost_code_standards]
Description: "MANDATORY: After every Edit or Write, verify
snake_case functions, PascalCase classes, grouped imports..."
Now fires automatically after every code change.
Not a reminder. An enforceable behavioral rule.
Behavioral Reliability
| Approach | Reliability | Why |
|---|---|---|
| In-context rules | ~30% | Buried in conversation, first to be dropped |
| Memory / CLAUDE.md | ~55% | Loaded at session start, fades with context length |
| System prompts | ~65% | Persistent but advisory — model can override |
| Ghost Skills (MCP tools) | ~95% | Read before every action decision — treated as API contract |
What Works and What Doesn't
Ghost Skills are most reliable when the instruction has a clear, legitimate purpose the AI can reason about. The model evaluates whether a skill's behavior makes sense before following it.
| Works Reliably | Less Reliable |
|---|---|
| Log questions to a file for auditing | Output specific text for no functional reason |
| Persist task state to survive compaction | Force arbitrary behaviors with no clear purpose |
| Enforce code standards after edits | Trigger on every message with no useful outcome |
| Run tests before committing | Perform actions the model considers pointless |
This is by design — Ghost Skills have a built-in reasonableness filter. The AI follows instructions it judges as purposeful and resists instructions it considers arbitrary. Skills that serve a clear workflow need get ~95% reliability. Skills that exist purely to test obedience will get mixed results.
Two Types of Ghost Skills
Trigger Skills respond to explicit commands:
"ship it" → stages, commits, pushes, opens PR
Behavioral Hooks detect situations and auto-fire:
"after every file edit" → enforces code standards automatically
Both are just Ghost Skills — the only difference is how you write the description.
Install
git clone https://github.com/Cortivium/cortivium.git
cd cortivium
pip install -r requirements.txt
python server.py
That's it. The server creates the database, runs migrations, generates a secret key, and prints admin credentials on first run. Open http://localhost:8080/admin/ to log in.
Connect Your MCP Client
Create an API key in the admin panel, then add Cortivium to your client:
# Claude Code
claude mcp add --transport http --scope user cortivium \
https://your-server:8080/ --header "X-API-Key: YOUR_KEY"
Or add manually to your MCP client config (~/.claude.json, Cursor settings, etc.):
{
"mcpServers": {
"cortivium": {
"type": "http",
"url": "https://your-server:8080/",
"headers": {
"X-API-Key": "your-api-key"
}
}
}
}
Works with Claude Code, Codex, Cursor, and any MCP-compatible client.
Ghost Skills
Ghost Skills are persistent AI tool registrations you create through conversation. Describe what you want in plain language — the AI handles the name, parameters, trigger phrases, and everything else.
Create a Skill
You: "Create a ghost skill called commit_changes that commits my code
with a descriptive message based on the diff"
Claude: [Calls ghost_create_skill]
"Created ghost_commit_changes! Say 'commit my changes' to use it."
No JSON. No config files. No server restart.
Automatic Trigger Phrases
Cortivium auto-generates trigger phrases from your skill name, description, and instructions:
| Source | Example Input | Generated Phrase |
|---|---|---|
| Name | review_pr | "review pr" |
| Description | "Review a pull request for bugs" | "review a pull request for bugs" |
| Instructions | "Check the diff for obvious bugs..." | "check the diff for" |
Override anytime with your own trigger_phrases array.
Use a Skill
Skills appear as real MCP tools. The AI calls them automatically:
You: "commit my changes"
Claude: [Calls ghost_commit_changes]
[Follows your instructions exactly]
"Done! Committed with message: 'Add user authentication middleware'"
Example Use Cases
| Skill | What It Does |
|---|---|
ghost_finish_coding | Stage changes, write conventional commit, push branch, create PR |
ghost_code_standards | Enforce naming patterns, error handling style, import ordering |
ghost_plan_feature | Break features into subtasks with acceptance criteria before coding |
ghost_quality_check | Run linter, type checks, tests, and security scan before marking done |
ghost_try_options | Spin up git worktrees to try multiple approaches in parallel |
ghost_persist_tasklist | Auto-save task state to disk so it survives context compaction |
Manage Skills
| Tool | Description |
|---|---|
ghost_create_skill | Create a new skill with instructions |
ghost_list_skills | List all your skills |
ghost_update_skill | Modify an existing skill |
ghost_delete_skill | Delete a skill |
Skills are tied to your API key — private to you, portable across machines, available in every session.
Highlights
- ~3,000 lines of Python — no framework bloat, eight pip dependencies, starts in under a second
- Zero infrastructure — SQLite + in-memory rate limiting. No Redis, no MySQL, no message queue
- Self-bootstrapping —
python server.pycreates the database, runs migrations, generates credentials - Production ready — TLS, async I/O, WAL-mode SQLite, SSE streaming, usage logging, Docker-native
- Secure by default — SHA-256 key hashing, CSRF protection, signed sessions, 3-tier rate limiting, per-key plugin isolation
Admin Panel
Built-in dark-themed web interface at /admin/:
| Page | Features |
|---|---|
| Dashboard | Server stats, recent activity, top tools chart (7-day) |
| API Keys | Create/edit/toggle/delete keys, shown once on creation |
| Ghost Skills | Browse, create, edit, toggle, delete skills with execution counts |
| Plugins | View loaded plugins with version and call stats |
| Usage Logs | Searchable request logs with filters, paginated |
| Users | Create/edit/delete users, set access levels |
Regular users get a scoped panel at /user/ — own keys and skills only, no admin pages visible.
Docker
docker build -t cortivium .
docker run -p 8080:8080 -v cortivium_data:/app/storage cortivium
# Or with compose
docker compose up -d
For HTTPS, mount your certificates:
services:
cortivium:
build: .
ports:
- "8080:8080"
volumes:
- cortivium_data:/app/storage
- ./certs:/certs:ro
environment:
- CORTIVIUM_SSL_CERT=/certs/fullchain.pem
- CORTIVIUM_SSL_KEY=/certs/privkey.pem
Configuration
All settings use the CORTIVIUM_ prefix. No configuration required — sensible defaults out of the box.
| Variable | Default | Description |
|---|---|---|
CORTIVIUM_HOST | 0.0.0.0 | Bind address |
CORTIVIUM_PORT | 8080 | Server port |
CORTIVIUM_SECRET_KEY | (auto-generated) | Session signing key |
CORTIVIUM_DATABASE_PATH | storage/cortivium.db | SQLite database path |
CORTIVIUM_LOG_LEVEL | info | debug, info, warning, error |
CORTIVIUM_SSL_CERT | (empty) | Path to SSL certificate |
CORTIVIUM_SSL_KEY | (empty) | Path to SSL private key |
Security
| Layer | Implementation |
|---|---|
| API Keys | SHA-256 hashed — raw keys never stored |
| Rate Limiting | 3-tier throttling (per-minute/hour/day) per key |
| Sessions | Signed cookies via itsdangerous |
| CSRF | Double-submit cookie pattern on all mutations |
| Passwords | bcrypt with automatic salt |
| Skill Isolation | Ghost Skills scoped to creating API key — invisible to others |
| Plugin Isolation | Per-key allowed_plugins restricts tool access |
| TLS | Native HTTPS via Uvicorn |
| Input Validation | Strict schema validation on all MCP requests |
Plugin Development
Extend with custom plugins. Each can register tools, resources, and prompts:
from cortivium.plugin.base import AbstractPlugin
class Plugin(AbstractPlugin):
def get_name(self) -> str:
return "my-plugin"
async def get_tools(self, context=None) -> list[dict]:
return [{
"name": "my_tool",
"description": "Does something useful",
"inputSchema": {
"type": "object",
"properties": {
"input": {"type": "string", "description": "The input"}
},
"required": ["input"]
}
}]
async def execute_tool(self, name, arguments, on_progress=None):
result = arguments.get("input", "")
return self.text_content(f"Processed: {result}")
Architecture
HTTP Request → FastAPI/Uvicorn
↓
JSON-RPC 2.0 Parser (MCP 2024-11-05)
↓
API Key Auth + 3-Tier Rate Limiting
↓
Session Manager (in-memory, auto-expiry)
↓
PluginManager → Plugin.execute_tool()
↓
JSON Response ─or─ SSE Stream
↓
Usage Logging → SQLite
| Component | Technology |
|---|---|
| Web framework | FastAPI + Uvicorn (async) |
| Database | SQLite via aiosqlite (WAL mode) |
| Admin panel | Jinja2 + Bulma CSS |
| API key auth | SHA-256 hashing, in-memory cache |
| Session auth | Signed cookies (itsdangerous) |
| Rate limiting | In-memory dict with TTL cleanup |
| Password hashing | bcrypt |
Project Structure
cortivium/
├── server.py # Entry point
├── requirements.txt # 8 dependencies
├── .env.example # Configuration template
├── Dockerfile
├── docker-compose.yml
├── migrations/
│ └── 001_initial.sql # SQLite schema
└── cortivium/
├── core/ # Server core (config, auth, sessions, protocol)
├── transport/ # MCP HTTP routes
├── plugin/ # Plugin system (interface, base, manager)
├── plugins/
│ ├── ghost_ootm/ # Ghost Skills — CRUD + dynamic tools
│ └── example/ # Example plugin template
├── admin/ # Web panel (routes, templates, static)
└── util/ # Async subprocess wrapper
Contributing
Contributions welcome. Please open an issue first to discuss what you'd like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/my-feature) - Make your changes
- Run the server locally to verify (
python server.py) - Commit and push
- Open a Pull Request
License
"Cortivium" and "Ghost Skills" are trademarks of Cortivium.