knowledgeops-ai
README.md
# KnowledgeOps AI
A Laravel knowledge assistant that combines cited RAG answers, an MCP server, and a guarded agent workflow. The agent can propose a support ticket, but it cannot execute the tool until a human approves the stored action.
## Why this project
Many AI demos stop at a chat box. KnowledgeOps AI demonstrates the backend concerns needed for a safer production system:
- workspace-scoped document ingestion and retrieval;
- deterministic local embeddings for a zero-cost demo;
- optional OpenAI embeddings and generated answers;
- PostgreSQL with pgvector search and an SQLite fallback;
- JSON-RPC MCP tools with typed input schemas;
- human approval before state-changing agent actions;
- queues, audit records, API-key protection, and automated tests.
## Architecture
```mermaid
flowchart LR
Client[API or MCP client] --> Laravel[Laravel API]
Laravel --> Ingest[Queued ingestion]
Ingest --> Chunk[Chunk + embed]
Chunk --> Vector[(PostgreSQL + pgvector)]
Laravel --> Retrieve[Hybrid retrieval]
Retrieve --> Vector
Retrieve --> LLM[LLM or local fallback]
LLM --> Answer[Cited answer]
Answer --> Agent[Guarded agent]
Agent --> Pending[(Pending action)]
Pending --> Approval{Human approval}
Approval -->|approved| MCP[MCP tool registry]
MCP --> Ticket[(Support ticket)]
```
## Stack
- PHP 8.3 and Laravel 13
- OpenAI Responses and Embeddings APIs, or a local deterministic fallback
- PostgreSQL 17 with pgvector; SQLite is supported for quick local development
- Redis queues and cache in Docker
- MCP-compatible JSON-RPC endpoint
- PHPUnit feature and unit tests
## Quick start with SQLite
```bash
cp .env.example .env
composer install
php artisan key:generate
touch database/database.sqlite
php artisan migrate --seed
php artisan serve
```
Open [http://localhost:8000](http://localhost:8000). The default API key is `local-demo-key`.
The local provider needs no external service. To use OpenAI, update `.env`:
```dotenv
AI_PROVIDER=openai
OPENAI_API_KEY=your-key
OPENAI_CHAT_MODEL=gpt-4.1-mini
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
```
Never commit the real `.env` file.
## Docker with pgvector and Redis
```bash
docker compose up -d postgres redis
docker compose run --rm app php artisan migrate --seed
docker compose up -d app worker
```
The Docker environment enables pgvector retrieval and runs ingestion through Redis.
## API walkthrough
All API requests accept `X-API-Key: local-demo-key`.
### 1. Ingest a document
```bash
curl -X POST http://localhost:8000/api/documents \
-H "Content-Type: application/json" \
-H "X-API-Key: local-demo-key" \
-d '{
"workspace_id": "demo",
"title": "Remote Work Policy",
"source": "handbook://remote-work",
"content": "Employees may work remotely three days per week. Manager approval is required for fully remote arrangements."
}'
```
### 2. Ask a cited RAG question
```bash
curl -X POST http://localhost:8000/api/rag/ask \
-H "Content-Type: application/json" \
-H "X-API-Key: local-demo-key" \
-d '{"workspace_id":"demo","question":"How many remote days are allowed?"}'
```
The response contains an answer plus source labels, document IDs, excerpts, and retrieval scores.
### 3. Run the agent
```bash
curl -X POST http://localhost:8000/api/agent/run \
-H "Content-Type: application/json" \
-H "X-API-Key: local-demo-key" \
-d '{"workspace_id":"demo","question":"Create a ticket for a company-wide payment outage"}'
```
The agent returns `requires_approval: true` and stores a pending action. It does not create a ticket yet.
### 4. Approve the proposed action
```bash
curl -X POST http://localhost:8000/api/agent/actions/1/approve \
-H "Content-Type: application/json" \
-H "X-API-Key: local-demo-key" \
-d '{"workspace_id":"demo"}'
```
Approval is single-use. A repeated approval returns HTTP 409 and cannot create a duplicate ticket.
## MCP endpoint
The MCP endpoint is `POST /api/mcp`. It supports `initialize`, `ping`, `tools/list`, and `tools/call`.
```bash
curl -X POST http://localhost:8000/api/mcp \
-H "Content-Type: application/json" \
-H "X-API-Key: local-demo-key" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
```
Available tools:
- `knowledge_search` searches only within the supplied workspace.
- `support_ticket_create` requires an explicit approved flag. The built-in agent supplies it only after the approval endpoint locks and updates a pending action.
## Tests and code style
```bash
php artisan test
./vendor/bin/pint --test
```
The suite covers API-key protection, ingestion, workspace isolation, cited retrieval, MCP discovery and calls, and the approval-based ticket workflow.
## Repository layout
```text
app/
├── Http/Controllers API and MCP transport
├── Jobs queued document ingestion
├── Models documents, chunks, actions, tickets
└── Services
├── Ai chunking, embeddings, retrieval, RAG, agent
└── Mcp tool definitions and execution
database/
├── migrations workspace-scoped schema and pgvector setup
└── seeders runnable support-handbook example
```
## Push to GitHub
```bash
git init
git add .
git commit -m "Build KnowledgeOps AI Laravel RAG and MCP agent"
git branch -M main
git remote add origin https://github.com/YOUR_USERNAME/knowledgeops-ai.git
git push -u origin main
```
Create the empty `knowledgeops-ai` repository in your GitHub account before the last two commands.
## Deliberate safety choices
- Workspace ID is applied to every retrieval and action query.
- The LLM receives retrieved passages, not unrestricted database access.
- State-changing tools require approval, which is recorded and locked in a transaction.
- Tool inputs are validated again at execution time.
- Local mode makes tests deterministic and prevents accidental external AI calls.
## License
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues