Skip to main content

MCP server that exposes the Knora institutional-memory platform to AI agents

Project description

Knora MCP Server

An MCP (Model Context Protocol) server that exposes the full Knora institutional-memory platform to AI agents. Once connected, Claude (or any MCP-compatible agent) can search, query, create, and manage your organisation's knowledge base directly from a conversation.


What the server does

The Knora MCP server wraps the Knora REST API and exposes it as ~80 MCP tools organised into these categories:

Category What agents can do
Query & Search Ask natural-language questions (RAG), semantic search, view query history, find documentation gaps
Knowledge Management Create/read/update/delete entries, verify, flag, relate, bulk import/export, manage tags and departments
Capture Quick notes, voice upload (Whisper), document upload (PDF/Word/Excel/image), interviews, shift logs
Admin Invite/manage members, update roles, org settings, API keys, webhooks, integrations
Analytics Dashboard overview, bus factor risk, knowledge health score, staleness report, query analytics

Security boundaries

This MCP server is designed for per-org customer access, not platform administration. The following invariants are enforced:

  1. Org-isolated — all operations are scoped to the authenticated user's organisation. Agents cannot see or modify data belonging to another org.
  2. No superadmin tools — the admin endpoints (/api/v1/admin/…) are not exposed here and must not be added.
  3. No plan/billing changes through MCP — subscription upgrades and cancellations must go through the Stripe checkout flow, which requires human-initiated payment.

Installation

# From the repo root
pip install -e ./mcp

# Or install directly from the mcp/ directory
cd mcp
pip install -e .

Requirements: Python 3.11+, a running Knora backend.


Configuration

All configuration is via environment variables. No config file is required.

Required — API endpoint

Variable Default Description
KNORA_API_URL http://localhost:5001/api/v1 Base URL of the Knora REST API

Required — Authentication (one of the following)

Authentication is resolved in this priority order:

Option 1 — API key (recommended for production)

export KNORA_API_KEY=kn_xxxxxxxxxxxxxxxxxxxx

API keys are long-lived and org-scoped. Create one via knora_create_api_key or the Knora web app (Growth plan required).

Option 2 — JWT token

export KNORA_JWT_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Short-lived access token. The client refreshes it automatically when it expires.

Option 3 — Email + password (development)

export KNORA_EMAIL=admin@acme.com
export KNORA_PASSWORD=your-password

The server logs in on startup and acquires a JWT automatically.

Optional — HTTP client tuning

Variable Default Description
KNORA_TIMEOUT 30 Request timeout in seconds
KNORA_MAX_RETRIES 3 Max retries on 429 / 5xx
KNORA_RETRY_BACKOFF 1.0 Initial back-off delay in seconds

Rate limits

The two most frequently called endpoints enforce per-user rate limits:

Tool Limit
knora_ask 20 requests / minute
knora_search 40 requests / minute

The client automatically retries on 429 Too Many Requests with exponential back-off (controlled by KNORA_MAX_RETRIES and KNORA_RETRY_BACKOFF). Agents running in tight loops should add a small delay between calls to stay within these limits.


Running the server

# Stdio transport — default for agent integrations
python -m knora_mcp

# Equivalent: run the server module directly
python -m knora_mcp.server

# Via the MCP CLI (after pip install)
mcp run knora-mcp

# Direct CLI entry point (after pip install)
knora-mcp

The server communicates over stdio (stdin/stdout), which is the standard transport for Claude Desktop and Claude Code integrations.


Adding to Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "knora": {
      "command": "python",
      "args": ["-m", "knora_mcp"],
      "env": {
        "KNORA_API_URL": "https://api.knora.io/api/v1",
        "KNORA_API_KEY": "kn_xxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

If you installed into a virtual environment, use the full path to the Python interpreter:

{
  "mcpServers": {
    "knora": {
      "command": "/path/to/venv/bin/python",
      "args": ["-m", "knora_mcp"],
      "env": {
        "KNORA_API_URL": "https://api.knora.io/api/v1",
        "KNORA_API_KEY": "kn_xxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

Restart Claude Desktop after saving the file.


Adding to Claude Code

Add the server to .claude/settings.json in your project (or ~/.claude/settings.json for global access):

{
  "mcpServers": {
    "knora": {
      "command": "python",
      "args": ["-m", "knora_mcp"],
      "env": {
        "KNORA_API_URL": "https://api.knora.io/api/v1",
        "KNORA_API_KEY": "kn_xxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

Or use the Claude Code CLI:

claude mcp add knora -- python -m knora_mcp

Then set the env vars in your shell before starting Claude Code, or add them to the env block above.


Tool Reference

Query & Search

knora_ask

Ask a natural-language question and receive an AI-generated answer with source citations (RAG). If no relevant knowledge exists, the question is logged as a gap for managers to review. Rate-limited to 20 requests/minute.

{
  "question": "How do we handle supplier delays?"
}

Parameters: question (required, max 2000 characters). Supports Arabic and English automatically — no language selection needed.

Returns { answer, sources[], confidence, language, query_id }.


knora_search

Semantic search — finds entries by meaning, not just keywords. Faster than knora_ask; returns raw entries without generating an answer. Cross-language: an Arabic query finds English entries and vice versa. Rate-limited to 40 requests/minute.

{
  "query": "onboarding process for new hires",
  "limit": 5,
  "department": "Engineering"
}

knora_query_history

Return the current user's recent query history.

{ "limit": 50 }

knora_list_gaps

List questions that were asked but could not be answered — these are documentation gaps that should be filled. Requires manager or admin role.

{ "department": "Operations", "limit": 20 }

knora_resolve_gap

Mark a documentation gap as resolved by linking it to a knowledge entry that answers it.

{ "gap_id": "<uuid>", "entry_id": "<uuid>" }

knora_query_analytics

Aggregate query analytics: total queries, answer rate, trending topics, and unanswered questions. Requires admin role and Growth plan.


Knowledge Management

knora_list_knowledge

List knowledge entries with optional filters and pagination.

{
  "status": "active",
  "language": "en",
  "search": "maintenance",
  "per_page": 20
}

Filters: page, per_page, department_id, tag_ids, status (active|archived|needs_review|outdated), visibility, language (ar|en|mixed), confidence (high|medium|low), search.


knora_get_entry

Fetch a single knowledge entry by UUID with all metadata, tags, department, related entries, and version count.

{ "entry_id": "550e8400-e29b-41d4-a716-446655440000" }

knora_create_knowledge

Create a new knowledge entry. Immediately stored — no async processing.

{
  "title": "Supplier delay escalation process",
  "content": "When a supplier reports a delay of more than 48 hours...",
  "language": "en",
  "tag_ids": ["<tag-uuid>"],
  "department_id": "<dept-uuid>",
  "confidence": "high"
}

knora_update_knowledge

Update an existing entry. Only supply the fields to change — all others are preserved. A version record is created automatically.

{
  "entry_id": "<uuid>",
  "content": "Updated content...",
  "status": "active"
}

knora_delete_knowledge

Soft-delete (archive) a knowledge entry. Not permanently removed.

{ "entry_id": "<uuid>" }

knora_verify_entry

Mark an entry as verified. Verified entries have higher trust and appear first in query results. Requires manager or admin role.

{ "entry_id": "<uuid>" }

knora_flag_knowledge

Flag an entry as needing review — useful when content may be stale, inaccurate, or incomplete.

{ "entry_id": "<uuid>" }

knora_get_versions

List the full version history of a knowledge entry, newest first.

{ "entry_id": "<uuid>" }

knora_relate_entries

Link two knowledge entries as "related". Related entries appear together in query results and the knowledge graph.

{ "entry_id": "<uuid>", "related_entry_id": "<uuid>" }

knora_unrelate_entries

Remove the relationship link between two entries.

{ "entry_id": "<uuid>", "related_id": "<uuid>" }

knora_find_similar

Find entries semantically similar to a given entry using vector embeddings. Results are ranked by cosine similarity.

{ "entry_id": "<uuid>", "limit": 5 }

knora_find_duplicates

Find potential duplicate entries. Supply entry_id to check a specific entry, or omit to trigger an org-wide async scan.

{ "entry_id": "<uuid>", "threshold": 0.92 }

knora_bulk_import

Import multiple entries at once from a JSON array. Requires Growth plan. Each entry must have title and content.

{
  "entries": [
    { "title": "Entry A", "content": "..." },
    { "title": "Entry B", "content": "..." }
  ]
}

knora_export_knowledge

Export all knowledge entries as a JSON array. Requires Growth plan.

{ "status": "active", "language": "en" }

knora_list_tags

List all tags in the organisation.


knora_create_tag

Create a new tag. Requires manager or admin role.

{ "name": "safety", "color": "#FF5733" }

knora_delete_tag

Delete a tag and remove it from all entries. Requires manager or admin role.

{ "tag_id": "<uuid>" }

knora_list_departments

List all departments in the organisation.


knora_create_department

Create a new department. Requires manager or admin role.

{ "name": "Maintenance", "description": "Field maintenance teams" }

knora_update_department

Update a department. Requires manager or admin role.

{ "dept_id": "<uuid>", "name": "Field Maintenance" }

Capture

knora_quick_note

Fastest capture path — store a piece of knowledge immediately. Title is auto-generated if not supplied.

{
  "content": "Discovered that the valve seal on unit 7 must be replaced every 6 months, not annually.",
  "tags": ["<tag-uuid>"]
}

knora_upload_document

Upload a PDF, Word, Excel, or image file. Knora extracts text and creates knowledge entries asynchronously. Poll with knora_check_job.

{
  "file_path": "/tmp/maintenance_manual.pdf"
}

Returns { job_id, status }.


knora_check_job

Poll a document or voice capture job for completion. Status: pendingprocessingcompleted | failed. On completion, result_entry_id contains the created entry UUID.

{ "job_id": "<uuid>", "job_type": "document" }

knora_list_document_jobs / knora_get_document_job

List or inspect document capture jobs.


knora_upload_voice

Upload an audio file for voice-to-knowledge processing. Transcribed via Whisper, then Claude extracts structured knowledge. Formats: mp3, mp4, m4a, wav, webm, ogg, flac (max 25 MB).

{ "file_path": "/tmp/interview_recording.m4a" }

knora_list_voice_jobs / knora_get_voice_job

List or inspect voice capture jobs.


knora_list_templates

List structured interview templates. Requires Growth plan.


knora_get_template

Fetch a single interview template by UUID. Requires Growth plan.

{ "template_id": "<uuid>" }

knora_create_template

Create an interview template with ordered questions. Requires manager or admin role and Growth plan.

{
  "name": "Maintenance Supervisor Handover",
  "role_target": "maintenance_supervisor",
  "questions": [
    {"order": 1, "text": "What incidents occurred during your shift?"},
    {"order": 2, "text": "What equipment is currently out of service?"},
    {"order": 3, "text": "What tasks are pending for the next shift?"}
  ]
}

Each question object requires order (integer, 1-based) and text. Optional fields: category, follow_up_prompt.


knora_update_template

Update an interview template (name, description, questions, etc.). Requires manager or admin role.

{
  "template_id": "<uuid>",
  "questions": [
    {"order": 1, "text": "What incidents occurred during your shift?"},
    {"order": 2, "text": "What handover items are critical for the next shift?"}
  ]
}

knora_delete_template

Deactivate (soft-delete) an interview template. Requires manager or admin role.

{ "template_id": "<uuid>" }

knora_start_interview

Start a structured interview session. Returns session_id and the first question.

{ "template_id": "<uuid>", "interviewee_id": "<uuid>" }

knora_answer_question

Submit an answer to the current interview question. Returns the next question or status: complete when done.

{
  "session_id": "<uuid>",
  "answer_text": "Pump 3 was offline for 2 hours due to a seal failure.",
  "question_index": 0
}

knora_list_sessions

List interview sessions. Requires Growth plan. Non-admin/manager users only see their own sessions.

{ "status": "completed", "template_id": "<uuid>", "per_page": 20 }

Filters: status, interviewee_id, template_id, page, per_page.


knora_get_session

Fetch a single interview session with all answers. Requires Growth plan.

{ "session_id": "<uuid>" }

knora_complete_session

Complete an interview session and trigger asynchronous knowledge extraction. Claude processes all answers and creates knowledge entries.

{ "session_id": "<uuid>" }

knora_cancel_session

Cancel an in-progress interview session.

{ "session_id": "<uuid>" }

knora_create_shift_log

Create a supervisor shift-end log (saved as draft). Requires Growth plan.

{
  "shift_date": "2026-06-01T08:00:00",
  "notes": "Replaced seal on unit 7. Pump 3 back online by 10:30.",
  "department_id": "<uuid>"
}

knora_list_shift_logs

List shift logs. Requires Growth plan. Non-admin/manager users see only their own.

{ "status": "draft", "department_id": "<uuid>", "date_from": "2026-06-01" }

Filters: user_id, department_id, date_from, date_to, status (draft|submitted), page, per_page.


knora_get_shift_log

Fetch a single shift log by UUID. Requires Growth plan.

{ "log_id": "<uuid>" }

knora_update_shift_log

Update a draft shift log. Cannot update already-submitted logs.

{
  "log_id": "<uuid>",
  "notes": "Updated notes: also replaced filter on unit 9.",
  "location": "Site B"
}

knora_submit_shift_log

Submit a shift log and trigger asynchronous knowledge extraction. Cannot be edited after submission.

{ "log_id": "<uuid>" }

Admin

knora_get_me

Return the authenticated user's profile.


knora_update_me

Update the authenticated user's name or department.

{ "name": "Baraa Al-Rashid", "department": "Engineering" }

knora_invite_member

Invite a new user to the organisation. Requires admin or manager role.

{
  "email": "new.hire@acme.com",
  "name": "Jane Smith",
  "role": "member",
  "department": "Operations"
}

knora_list_members

List all active members of the organisation.


knora_update_member_role

Change a member's role. Requires admin role.

{ "user_id": "<uuid>", "role": "manager" }

knora_remove_member

Deactivate a member (soft removal). Requires admin role.

{ "user_id": "<uuid>" }

knora_get_org / knora_update_org

Get or update organisation settings (name, default language).


knora_list_connectors

List available integration connectors. Requires admin or manager role.


knora_list_integrations

List active integrations with sync status and last sync timestamp. An organisation may have multiple integrations of the same connector type (e.g. two Slack workspaces).


knora_trigger_sync

Trigger an immediate manual sync for a connected integration. Requires admin role.

{ "integration_id": "<uuid>" }

knora_list_api_keys / knora_create_api_key / knora_revoke_api_key

Manage API keys. The full key value is returned once on creation — save it immediately. Requires Growth plan.

{ "name": "Claude Code integration" }

knora_api_key_usage

Get aggregate request usage statistics for all API keys in the organisation. Requires admin or manager role and Growth plan.


knora_list_webhooks / knora_create_webhook / knora_delete_webhook

Manage webhook endpoints for real-time event notifications. Events: knowledge.created, knowledge.updated, knowledge.deleted, member.invited, member.removed, query.asked. Requires Growth plan.

{
  "url": "https://your-service.com/hooks/knora",
  "events": ["knowledge.created", "query.asked"]
}

Analytics

knora_dashboard_overview

Dashboard snapshot: total_entries, total_users, health_score, recent_activity, query counts, and all activity metrics. Requires admin or manager role and Growth plan.


knora_dashboard_activity

Recent activity feed: entry creates, verifications, queries, flags.

{ "limit": 20 }

knora_dashboard_departments

Per-department statistics: entry count, coverage percentage, risk level.


knora_dashboard_trending

Most frequently asked questions in the last N days.

{ "days": 7 }

knora_bus_factor

Organisation-wide bus factor risk analysis: risk overview, critical-risk people, and per-department scores. Requires admin or manager role and Growth plan.


knora_bus_factor_person

Bus factor risk score for a specific person, including what knowledge they exclusively own.

{ "user_id": "<uuid>" }

knora_bus_factor_department

Bus factor risk breakdown for a specific department.

{ "dept_id": "<uuid>" }

knora_bus_factor_critical

Only the people and departments at CRITICAL risk level — use for dashboard alerts.


knora_staleness_report

Knowledge staleness report: entries not reviewed within the threshold window, plus aggregate stats.

{ "days": 30 }

Returns { stale_entries[], stats: { stale_count, total_entries, review_rate } }.


knora_health_score

Knowledge health score (0–100) broken into: coverage, freshness, verification rate, gap rate. Requires admin or manager role and Growth plan.


knora_get_graph

Knowledge graph: nodes (entries), edges (relationships), and clusters (topic groupings). Optionally filter by department.

{ "max_nodes": 100, "department": "<uuid>" }

knora_auto_link

Trigger automatic linking of semantically similar entries via a background task. Requires admin or manager role.


knora_plan_info

Current subscription plan, usage, limits, and trial days remaining.


knora_health

Check whether the Knora backend is reachable. No authentication required.


Example workflows

Research + capture loop

1. knora_ask("What is our current process for X?")
2. knora_search("X process", limit=5)          # find related entries
3. knora_quick_note("Learned today: ...")       # capture new insight
4. knora_relate_entries(new_id, related_id)     # link to existing entries

Knowledge audit

1. knora_dashboard_overview()                   # health overview
2. knora_staleness_report(days=60)              # find stale content
3. knora_list_gaps()                            # find missing documentation
4. knora_bus_factor_critical()                  # find knowledge silos

Document ingestion

1. knora_upload_document(file_path="~/documents/manual.pdf")
2. knora_check_job(job_id=..., job_type="document") until status=="completed"
3. knora_get_entry(entry_id=result_entry_id)
4. knora_verify_entry(entry_id=...)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

knora_mcp-0.3.0.tar.gz (38.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

knora_mcp-0.3.0-py3-none-any.whl (36.9 kB view details)

Uploaded Python 3

File details

Details for the file knora_mcp-0.3.0.tar.gz.

File metadata

  • Download URL: knora_mcp-0.3.0.tar.gz
  • Upload date:
  • Size: 38.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for knora_mcp-0.3.0.tar.gz
Algorithm Hash digest
SHA256 e4420b38ed32cb608f3cac12b1c9152c0ff6c395153c67ec0754d41bc9ae9bd6
MD5 fe6ad5f0153f2370185a17ec50792454
BLAKE2b-256 9ed62fb71dde7bcaf3f1fcb13019a7ee8ab660206999e82c7dca3c5888dc0267

See more details on using hashes here.

File details

Details for the file knora_mcp-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: knora_mcp-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 36.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for knora_mcp-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8246ebf31116d0f4a394bbfe794f353bb76d4501c9d057ed76986a7431c1495e
MD5 8d5733a17840e7743d75b2291ebd14cd
BLAKE2b-256 47e224199774fa3997255290ddc80e7fd3f9f7ecb5ca607cae1d62ebd5fbb7ca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page