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.
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.
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)]
- 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
cp .env.example .env
composer install
php artisan key:generate
touch database/database.sqlite
php artisan migrate --seed
php artisan serveOpen http://localhost:8000. The default API key is local-demo-key.
The local provider needs no external service. To use OpenAI, update .env:
AI_PROVIDER=openai
OPENAI_API_KEY=your-key
OPENAI_CHAT_MODEL=gpt-4.1-mini
OPENAI_EMBEDDING_MODEL=text-embedding-3-smallNever commit the real .env file.
docker compose up -d postgres redis
docker compose run --rm app php artisan migrate --seed
docker compose up -d app workerThe Docker environment enables pgvector retrieval and runs ingestion through Redis.
All API requests accept X-API-Key: local-demo-key.
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."
}'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.
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.
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.
The MCP endpoint is POST /api/mcp. It supports initialize, ping, tools/list, and tools/call.
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_searchsearches only within the supplied workspace.support_ticket_createrequires an explicit approved flag. The built-in agent supplies it only after the approval endpoint locks and updates a pending action.
php artisan test
./vendor/bin/pint --testThe suite covers API-key protection, ingestion, workspace isolation, cited retrieval, MCP discovery and calls, and the approval-based ticket workflow.
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
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 mainCreate the empty knowledgeops-ai repository in your GitHub account before the last two commands.
- 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.
MIT