Project Oracle
Caches eslint command results, returning cached output when source files have not changed.
Caches git status, git diff, and other git command results to avoid redundant calls and provide fast access to repository state.
Caches npm test command results for fast retrieval when no relevant source changes have occurred.
Caches pnpm test command results to avoid re-running tests on unchanged code.
Caches pytest command results, providing instant responses for unchanged test suites.
Caches ruff command results, skipping redundant linting on unchanged files.
Caches cargo test and cargo build command results, reducing wait times for repeated builds on unchanged code.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Project Oraclecheck if src/app.py has changed since last read"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Project Oracle
A stateful MCP server that remembers what your AI agent has already seen.
Project Oracle sits between Claude Code and your codebase, caching file reads, command results, and git state across sessions. When the agent re-reads an unchanged file, Oracle returns "No changes since last read" instead of the full content — saving hundreds of tokens per call and cutting repeat-read costs by 95%+.
Table of Contents
Related MCP server: MeshMind
The Problem
AI coding agents waste tokens on three patterns that compound over long sessions:
Re-reading files — Agent reads a file, context compacts, agent reads the same unchanged file again. Every re-read costs hundreds to thousands of tokens for content already processed.
Multi-step tool choreography —
git status→git diff→ read 3 files → grep for something. Five round trips when one structured query would suffice.Rediscovering project structure — Every new session: glob for files, read configs, figure out the tech stack, find test commands. The agent pays this cost repeatedly for knowledge that rarely changes.
These compound across sessions. Project Oracle eliminates the redundancy.
How It Works
Oracle is a Model Context Protocol (MCP) server that acts as a smart proxy between the agent and your project:
Agent (Claude Code)
│
│ calls oracle_read("src/auth.py")
│
▼
Project Oracle (MCP server)
│
├─ Cache miss? → Read from disk, compress with zstd, store in SQLite, return full content
├─ Cache hit, unchanged? → Return "No changes since last read (2m ago)" [~3 tokens]
└─ Cache hit, changed? → Compute unified diff, return only the deltaThree layers of agent integration:
Layer | Mechanism | What it does |
Passive learning | PostToolUse hooks | When the agent uses built-in |
Active nudging | PreToolUse AYLO hooks | Before the agent re-reads a file, a question nudges it toward |
Direct tools | 7 MCP tools |
|
State persists in per-project SQLite databases, so the agent picks up where it left off across sessions.
Why It Gets Better Over Time
Oracle tracks which files have been returned with full content during the current session (an in-memory _session_seen set). This is the key to how savings work:
First read of a file in a session: Always returns full content. If the file is already in the SQLite cache, Oracle validates the stored SHA-256 against the file on disk — a cache hit skips the disk read and decompression, but the agent still gets the complete text it needs to work.
Second+ reads of the same file in a session: The file is in
_session_seen. If unchanged, Oracle returns"No changes since last read"(~3 tokens). If changed, it returns a compact unified diff.Mid-session: Most of the working set is in
_session_seen. Every re-read costs 3 tokens instead of 800. Agents re-read files constantly — after context compaction, after editing other files, after switching tasks — so this adds up fast.Cross-session: The SQLite cache persists between sessions. When a new session starts,
_session_seenis empty, so the first read of each file returns full content (the agent needs it). But the cache validates files via SHA-256 without redundant disk I/O.oracle_statusandoracle_runreturn cached project state and command results instantly — no re-runninggit status, no re-discovering the tech stack.
Token Savings (Projected)
Not yet benchmarked. Per-operation math is straightforward (3-token cache hit vs. 800-token file re-read). We'll measure real session-level savings from
agent_logdata once the server is deployed.
Scenario | Without Oracle | With Oracle | Projected Savings |
Re-read unchanged 200-line file | ~800 tokens | ~3 tokens | ~99% |
Re-read file with 5 lines changed | ~800 tokens | ~50 tokens | ~94% |
Repeat | ~100 tokens | ~2 tokens | ~98% |
Repeat grep (same results) | ~300 tokens | ~6 tokens | ~98% |
Project overview (cached) | ~500 tokens | ~80 tokens | ~84% |
Tools
oracle_status()
Use at session start instead of running git status, git branch, and config globs separately. Returns one cached snapshot: language stack, package manager, git branch, clean/dirty state, and cached file count — built from data Oracle already has, so it costs nothing to refresh.
oracle_ask(question)
Replaces: the "what's going on with this project?" multi-tool dance (git log, read configs, grep for entry points, ask the agent to summarize) with one intent-routed call. A keyword classifier maps the question to the cheapest handler that can answer it — no LLM is used for routing.
"what changed?" → git cache (free)
"are we ready to push?" → readiness check (free)
"are tests passing?" → command cache (free)
"what's the tech stack?"→ project overview (free)
"find auth middleware" → chunkhound or grep (free)
"explain this pattern" → Claude Haiku fallback (~$0.001)This is the intent-grouped front door modeled on the "search/execute" MCP pattern. When you don't know which specific tool you need, ask first.
oracle_run(commands)
Use instead of running pytest / ruff / mypy (etc.) directly through Bash when you might be re-running against unchanged code. Oracle keys results by source-file SHA-256, so when nothing relevant has changed since the last invocation, you get the cached output back in milliseconds rather than waiting for the command to actually execute. Arbitrary shell commands are rejected.
Default allowlist: pytest, ruff, mypy, go test, go build, npm test, pnpm test, eslint, tsc, cargo test, cargo build
oracle_read(path)
Tells you what changed since last read. On the first read of a file in a session, this tool returns the full content with no token savings vs. the built-in Read — you pay one MCP round trip in exchange for caching the file for next time. The savings show up on the second and subsequent reads in the same session:
Repeat, unchanged:
"No changes since last read (2m ago)"— about 3 tokensRepeat, changed: Returns only the unified diff of what changed
Reach for this when you suspect a file may have changed and want to confirm cheaply, not as a blanket replacement for Read on first contact.
oracle_grep(pattern, path=".")
Tells you whether a previously run grep would now return different matches. Use this to re-check a search you already ran earlier in the session — Oracle compares the current matches against the cached result and surfaces the delta. This is cache introspection, not a Grep replacement: for a brand-new pattern with no prior cache entry, the built-in Grep is just as good and avoids the MCP round trip.
oracle_forget(path)
Clear the cache for a specific file. The next oracle_read returns full content. Use when you need a guaranteed fresh read.
oracle_stats()
Returns an adoption and savings scorecard for the current session and cumulatively. You get the cache hit rate with the underlying counts (e.g., 25% (5/20 oracle calls)), tokens saved this session, and an oracle-vs-built-in adoption breakdown for read / grep / run with per-category call counts. When prior sessions exist, it also reports how this session's hit rate and adoption rate compare to the recent-session average. Call it mid-session to check whether your tool choices are paying off, or at session end to capture cumulative savings before the context clears.
Installation
Prerequisites
Install
# Clone the repository
git clone https://github.com/mikelane/project-oracle.git
cd project-oracle
# Install with uv (recommended)
uv sync
# Or with pip
pip install -e .Verify
# Should print server info and exit
uv run project-oracle --helpConfiguration
1. Register the MCP server
Add to your Claude Code settings (~/.claude/settings.json):
{
"mcpServers": {
"project-oracle": {
"type": "stdio",
"command": "uv",
"args": ["run", "--directory", "/path/to/project-oracle", "project-oracle"]
}
}
}⚠️ Warning: register Oracle at user scope only
Register Oracle in
~/.claude/settings.json(user scope) as shown above. Do not register Oracle in a project-level.mcp.jsonfile.Due to upstream bug anthropics/claude-code#13898, custom subagents cannot reach MCP servers configured at project scope. Instead of erroring, they silently hallucinate plausible-looking results — meaning custom subagents will return fabricated Oracle results with no error indicator. Made-up
oracle_readdeltas, made-uporacle_statussnapshots, made-up cache hits. The subagent reports success and the agent acts on the fabricated data.What works correctly:
User-scope registration in
~/.claude/settings.json(the example above).The built-in
general-purposesubagent — use it when subagent invocation is required. It is unaffected by this bug.There is no Oracle-side workaround; the bug is in Claude Code's subagent MCP plumbing.
Last verified: 2026-04-26. Remove this warning when anthropics/claude-code#13898 is closed AND a Claude Code release notes entry confirms the fix.
2. Install the AYLO hooks
Copy the hook scripts and register them in your Claude Code settings:
# Copy hooks to your Claude config
cp hooks/lights-on-oracle-pre.sh ~/.claude/hooks/
cp hooks/lights-on-oracle-post.sh ~/.claude/hooks/
chmod +x ~/.claude/hooks/lights-on-oracle-pre.sh
chmod +x ~/.claude/hooks/lights-on-oracle-post.shAdd to ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Read",
"hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/lights-on-oracle-pre.sh" }]
},
{
"matcher": "Grep",
"hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/lights-on-oracle-pre.sh" }]
},
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/lights-on-oracle-pre.sh" }]
}
],
"PostToolUse": [
{
"matcher": "Read",
"hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/lights-on-oracle-post.sh" }]
},
{
"matcher": "Grep",
"hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/lights-on-oracle-post.sh" }]
},
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/lights-on-oracle-post.sh" }]
}
]
}
}3. (Optional) Configure the Anthropic API key
Only needed if you want the oracle_ask Haiku fallback for unroutable questions:
export ANTHROPIC_API_KEY="sk-ant-..."Environment variables
Variable | Default | Description |
|
| Root directory for all Oracle state |
| — | Required only for |
Architecture
┌─────────────────────────────────────────────────┐
│ Agent (Claude Code) │
│ Calls oracle_* tools or built-in tools │
└──────────┬──────────────────────────────────────┘
│ MCP stdio
┌──────────▼──────────────────────────────────────┐
│ Project Oracle Server (FastMCP) │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ Tools │ │
│ │ oracle_read → FileCache → full or delta │ │
│ │ oracle_grep → ripgrep wrapper │ │
│ │ oracle_status → GitCache + StackInfo │ │
│ │ oracle_run → CommandCache (allowlisted) │ │
│ │ oracle_ask → intent router │ │
│ │ oracle_forget → cache invalidation │ │
│ └───────────────┬────────────────────────────┘ │
│ │ │
│ ┌───────────────▼────────────────────────────┐ │
│ │ Caches │ │
│ │ FileCache — zstd compression + SHA-256 │ │
│ │ GitCache — branch, status, log deltas │ │
│ │ CommandCache — allowlisted cmd results │ │
│ └───────────────┬────────────────────────────┘ │
│ │ │
│ Storage: SQLite (WAL mode) per project │
│ ~/.project-oracle/projects/<hash>/state.db │
└──────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────┐
│ Claude Code Hooks (run in parallel) │
│ │
│ PreToolUse: AYLO nudges → "use oracle instead" │
│ PostToolUse: passive ingest → feed to cache │
└──────────────────────────────────────────────────┘Project detection
Oracle auto-detects project roots by walking up from file paths, looking for .git, package.json, pyproject.toml, go.mod, or Cargo.toml. Each detected project gets its own SQLite database. No configuration needed.
Stack detection
Once a project root is found, Oracle identifies the language and package manager:
Marker | Language | Package Manager Detection |
| Python |
|
| Node.js |
|
| Go | go |
| Rust | cargo |
Cache invalidation
A filesystem watcher (watchfiles, Rust-backed) monitors each project root:
File modified → cached entry marked stale via
disk_sha256update.git/HEADchanged → git state refreshedFile deleted → removed from cache
The watcher filters out .git, .venv, node_modules, __pycache__, and .mypy_cache.
Cache eviction
Files not read in 30 days → evicted
Command results older than 24 hours → evicted
Per-project cache exceeds 50 MB → LRU eviction by
last_read
Data layout
~/.project-oracle/
├── registry.json # project root → ID mapping
├── ingest/ # file queue from PostToolUse hooks
│ └── *.json
└── projects/
└── a1b2c3d4/ # SHA-256(project_root)[:8]
├── state.db # SQLite — all cached state
└── meta.json # stack info, last session timestampChunkhound Integration
Oracle optionally delegates code understanding queries to chunkhound's AST-based semantic indexing:
Claude Code → (stdio) → Project Oracle → (stdio) → Chunkhound MCPConcern | Owner |
AST parsing, semantic chunking, vector search | Chunkhound |
File caching, delta diffing, agent interaction history | Oracle |
"What imports X?" / "Find auth code" | Chunkhound |
"Has this changed since I last looked?" | Oracle |
Chunkhound understands code. Oracle understands the agent's relationship to the code.
If chunkhound is not installed or fails to start, Oracle degrades gracefully — code understanding queries fall back to keyword-based grep, and unroutable questions fall back to Claude Haiku. The agent never sees an error.
Development
Setup
git clone https://github.com/mikelane/project-oracle.git
cd project-oracle
uv sync --all-groupsTesting
The project uses strict TDD with multiple testing layers:
# Run all tests
uv run pytest
# Run with coverage (95% minimum enforced)
uv run coverage run --branch -m pytest
uv run coverage report --fail-under=95
# Run mutation testing
uv run pytest --gremlins src/oracle/cache/file_cache.py
# Run BDD scenarios
uv run behave
# Type checking
uv run mypy src/
# Linting
uv run ruff check src/ tests/Test categories
Tests follow Google test size classification:
Size | Constraints | Marker |
Small (default) | No I/O, no network, no sleep, single thread | None |
Medium | Localhost only, threads OK |
|
Large | No constraints |
|
Project structure
src/oracle/
├── server.py # FastMCP entry point, tool definitions
├── project.py # Project root + stack detection
├── registry.py # Path → ProjectState mapping
├── intent.py # Keyword-based intent classifier
├── ingest.py # File queue processing from hooks
├── watcher.py # FS watcher for cache invalidation
├── cache/
│ ├── file_cache.py # zstd compression + delta diffing
│ ├── git_cache.py # Git state snapshots + deltas
│ └── command_cache.py# Allowlisted command result caching
├── tools/
│ ├── read.py # oracle_read handler
│ ├── grep.py # oracle_grep handler
│ ├── status.py # oracle_status handler
│ ├── run.py # oracle_run handler
│ ├── ask.py # oracle_ask intent router
│ └── forget.py # oracle_forget handler
├── integrations/
│ └── chunkhound.py # MCP client to chunkhound subprocess
└── storage/
└── store.py # SQLite persistence layer (WAL mode)
hooks/
├── lights-on-oracle-pre.sh # PreToolUse AYLO nudges
└── lights-on-oracle-post.sh # PostToolUse passive ingest
features/
├── file_caching.feature # BDD: file read/delta behavior
├── git_state.feature # BDD: git status caching
├── command_caching.feature # BDD: command result caching
└── natural_language.feature # BDD: oracle_ask routingLicense
MIT
Available Tools
7 toolsoracle_askC
Ask a natural-language question about the project. Routes to cache, grep, or Haiku.
| Name | Required | Description | Default |
|---|---|---|---|
| question | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose behavioral traits. It reveals that the tool routes to different backends (cache, grep, Haiku), providing some transparency. However, it omits details like side effects, permissions, or output format.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single short sentence, which is concise but lacks structure. It could be expanded to provide more value without being verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has one parameter and no annotations, the description is insufficient. It does not explain what the output schema contains or what 'Haiku' means, leaving the agent without enough context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%. The description adds that the question is about the project and natural-language, but provides no further semantic detail about the 'question' parameter, such as valid formats or constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool asks a natural-language question about the project. It hints at routing to cache, grep, or Haiku, distinguishing it from sibling tools like oracle_grep or oracle_read, though it does not explicitly name them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. The mention of routing to cache, grep, or Haiku implies it is a general question tool, but lacks when-not scenarios or comparisons with sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
oracle_forgetA
Clear the file cache for a path. Next oracle_read returns full content.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses the destructive nature (clearing cache) and the effect on reads, but it does not detail potential side effects, authorization needs, or error states. Some transparency is present but could be richer.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. It is front-loaded with the main action and includes a relevant consequence. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single parameter, no annotations, and an existing output schema (not shown), the description provides the core function and effect. However, it lacks usage context, error handling, or dependencies (e.g., must have previously read the file). It is minimally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not add any additional meaning for the 'path' parameter beyond what the schema provides (type string, required). The parameter is obvious, but the description should have explained path format or allowed values to compensate for low coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('clear the file cache') and the resource ('for a path'). It also explains the consequence ('next oracle_read returns full content'), which distinguishes it from sibling tools like oracle_read and oracle_grep. The purpose is specific and non-tautological.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when one wants to force a fresh read, but it does not explicitly state when to use or when not to use this tool. No alternatives are mentioned, nor are any preconditions or exclusions provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
oracle_grepB
Search source files for a regex pattern. Returns up to 50 matches.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | . | |
| pattern | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals the result limit of 50 matches, which is a behavioral trait. However, it does not mention other important behaviors like case sensitivity, recursion behavior, or file type filtering. Since no annotations are provided, the description carries the full burden but only partially fulfills it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the purpose. Every word serves a purpose, with no unnecessary information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the existence of an output schema and low complexity, the description is partially complete. It mentions a result limit but omits return format details and parameter behavior, which may leave gaps for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage, the description adds no meaning to the parameters. It does not explain the 'pattern' format or the 'path' default behavior, which is essential for correct usage. The description fails to compensate for the lack of schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Search', the resource 'source files', and the action 'for a regex pattern'. It also mentions a result limit, distinguishing it from sibling tools like oracle_read or oracle_run.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like oracle_read or oracle_run. The description does not specify scenarios, limitations, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
oracle_readA
Read a file, returning full content on first read or a compact delta on repeat reads.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses a key behavioral trait: returning full content on first read and a compact delta on repeat reads, which is helpful. However, it does not cover other aspects like permissions or error handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no wasted words. It efficiently communicates the tool's purpose and unique behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one required parameter) and the presence of an output schema, the description covers the key behavioral distinction. It could mention file existence or encoding, but it is mostly complete for a basic read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does not describe the 'path' parameter beyond the bare schema, leaving the agent without guidance on format, valid paths, or prerequisites.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'Read' and resource 'file', and adds distinguishing behavior between first and repeat reads, clearly differentiating it from siblings like oracle_grep.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for reading files but provides no explicit guidance on when to use this tool versus alternatives like oracle_grep or oracle_run. No exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
oracle_runB
Run allowlisted commands through the cache layer. Returns cached results when unchanged.
| Name | Required | Description | Default |
|---|---|---|---|
| commands | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description mentions caching behavior and that results are returned when unchanged. However, it does not clarify whether these commands have side effects, require specific permissions, or what happens on cache miss. Given no annotations, this is insufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences effectively communicate the core functionality. No unnecessary words; front-loaded with the action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers caching and return behavior, but misses details on execution when cache is outdated, error handling, and command constraints. Given the presence of an output schema, some missing context is acceptable, but more is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'commands' has no schema description (0% coverage), and the description only adds that commands must be 'allowlisted'. It does not explain the format, constraints, or example values, leaving ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs allowlisted commands through a cache layer and returns cached results when unchanged. This distinguishes it from sibling tools like oracle_read or oracle_ask, but 'allowlisted commands' could be more specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives like oracle_ask or oracle_grep. The description implies it is for executing commands, but lacks context for proper selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
oracle_statsA
Return token savings stats for the current session and cumulative across all sessions.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden for behavioral disclosure. It only states that it returns stats, but does not mention side effects, authentication needs, or whether it is read-only. For a read-only tool, this is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that is front-loaded and contains no unnecessary words. It efficiently communicates the tool's function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters and an output schema exists, the description is mostly complete. However, it could benefit from noting that it is a read-only operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so baseline is 4. The description adds no extra meaning beyond the schema, but this is acceptable given the lack of parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns token savings stats and distinguishes between current session and cumulative across all sessions. The verb 'Return' and resource are specific, and it is distinct from sibling tools like oracle_ask.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No usage guidelines are provided. The description does not specify when to use this tool versus alternatives, nor does it provide any context about prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
oracle_statusA
Return current project status: stack info, git branch, clean/dirty state.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries full burden. It discloses the tool is a read operation returning status data, but does not mention potential side effects, authentication needs, or rate limits. Adequate but basic.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single, clear sentence with no wasted words. Information is front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and the simple nature of the tool, the description adequately covers what the tool does. An output schema exists but is not provided; the description mentions key return fields, which is sufficient for this context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so schema coverage is 100% trivially. Per guidelines, baseline for 0 params is 4. The description does not need to add param info.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns current project status, listing specific items (stack info, git branch, clean/dirty state). It uses a specific verb and resource, and distinguishes from siblings like oracle_ask or oracle_run.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use or when-not-to-use guidance is provided. The context implies use for status checks, but no alternatives or exclusions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v0.1.0- First observed
oracle_ask - First observed
oracle_forget - First observed
oracle_grep - First observed
oracle_read - First observed
oracle_run - First observed
oracle_stats - First observed
oracle_status
TDQS
Scored across 7 tools
Each tool has a distinct purpose: ask natural-language questions, clear cache, search files, read files, run commands, show stats, and show status. There is no functional overlap.
All tools follow the consistent pattern 'oracle_verb' in lowercase snake_case (ask, forget, grep, read, run, stats, status). Even 'stats' and 'status' are noun-like but are used as imperative verbs in this context, maintaining a uniform style.
Seven tools is an ideal size for a focused project assistant. Each tool covers a necessary operation without being too few or overwhelming.
The set covers key operations: querying, reading, searching, running commands, caching, and stats. A minor gap might be the lack of a tool to list directory contents, but oracle_ask can potentially handle that via natural language.
Maintenance
Related MCP Connectors
Cloud-hosted MCP server for durable AI memory
An MCP server that gives your AI access to the source code and docs of all public github repos
Related MCP Servers
FlicenseNot gradedqualityBmaintenanceRemote MCP server that gives LLMs access to run network commands63-- AlicenseAqualityCmaintenanceA single MCP server that merges three context-engineering ideas into one toolset for AI agents79 npm1MIT
- AlicenseNot gradedqualityDmaintenanceA local MCP server that gives AI coding agents persistent memory and context across sessions.24 npmMIT
- -licenseNot gradedqualityNot gradedmaintenanceAST-aware code exploration MCP server for AI agents, optimized for token efficiency.-