Skip to main content
Glama
tagnonkoua-ux

Kobo MCP Server

README.md
# Kobo MCP Server

[![Tests](https://img.shields.io/badge/tests-11%2F11%20passing-brightgreen)](#testing)
[![MCP](https://img.shields.io/badge/MCP-1.3.0-blue)](#)
[![Python](https://img.shields.io/badge/python-3.10%2B-blue)](#)

An [MCP](https://modelcontextprotocol.io/) server that lets Claude (Desktop, Code, or any MCP client) **read and write** to KoBoToolbox. Create forms from a chat, deploy them, attach media, submit data, all without leaving the conversation.

> Forked and extended from [PYI-SOE-LTD/kobo-mcp-server](https://github.com/PYI-SOE-LTD/kobo-mcp-server), which was read-only. This fork adds 10 new write tools (form creation in JSON or XLSForm, multilingual support, media attachments, deploy, update, clone, submissions).

---

## ✨ Features

- 🌍 **Multilingual forms** β€” create surveys in multiple languages at once (e.g. French + Lingala)
- πŸ“ **Two creation modes** β€” JSON schema (simple) or XLSForm Excel (standard)
- πŸš€ **Full lifecycle** β€” create β†’ attach media β†’ deploy β†’ submit β†’ update β†’ redeploy β†’ clone
- πŸ–ΌοΈ **Media attachments** β€” logos, reference images, audio prompts, video, from local file or URL
- πŸ”’ **Token in `.env`** β€” never hardcoded, never committed

## 🧰 18 tools exposed

### Read (6)
`listProjects` Β· `getProjectSummary` Β· `getProjectSchema` Β· `queryProjectData` Β· `getCountsBy` Β· `getTimeWindowSummary`

### Write β€” forms (7)
`createForm` Β· `createFormFromXLSForm` Β· `deployForm` Β· `redeployForm` Β· `updateForm` Β· `createSubmission` Β· `cloneForm`

### Write β€” media (3)
`attachMedia` Β· `listMedia` Β· `removeMedia`

### Public access (2)
`enablePublicSubmissions` Β· `disablePublicSubmissions` β€” let anyone fill the form via its Enketo link, no Kobo login required

---

## πŸš€ Quick start

### 1. Get a KoBo API token

- Global: https://kf.kobotoolbox.org/token/
- OCHA/Humanitarian: https://eu.kobotoolbox.org/token/
- Self-hosted: `https://<your-host>/token/`

### 2. Install

```bash
git clone https://github.com/tagnonkoua-ux/kobo-mcp-server.git
cd kobo-mcp-server
pip install -r requirements.txt
```

### 3. Configure

```bash
cp .env.example .env
# Edit .env and paste your KOBO_TOKEN
```

### 4. Register the MCP server in Claude

**Claude Code** (recommended):

```bash
claude mcp add kobo python /absolute/path/to/kobo-mcp-server/mcp_server.py
```

Or edit `~/.claude.json` manually:

```json
{
  "mcpServers": {
    "kobo": {
      "command": "python",
      "args": ["/absolute/path/to/kobo-mcp-server/mcp_server.py"],
      "env": {
        "KOBO_BASE": "https://kf.kobotoolbox.org/api/v2",
        "KOBO_TOKEN": "your_token_here",
        "PYTHONIOENCODING": "utf-8"
      }
    }
  }
}
```

**Claude Desktop**: copy the same block into `claude_desktop_config.json` (see [`claude_desktop_config.json`](./claude_desktop_config.json) for the template).

> πŸ’‘ On Windows, use double-backslashes in JSON paths: `"C:\\Users\\you\\kobo-mcp-server\\mcp_server.py"`.

### 5. Restart Claude

The 16 Kobo tools should now appear. Try:

> *"Create a customer satisfaction survey with 5 questions in French and English, deploy it, and give me the public link."*

---

## πŸ“ Simple JSON schema for `createForm`

### Mono-lingual

```json
{
  "title": "Customer satisfaction",
  "language": "English (en)",
  "questions": [
    {"name": "your_name", "type": "text", "label": "Your name?", "required": true},
    {"name": "rating", "type": "integer", "label": "Rate us 1-10",
     "constraint": ". >= 1 and . <= 10"},
    {"name": "city", "type": "select_one", "label": "City?",
     "choices": ["Brazzaville", "Pointe-Noire", "Dolisie"]}
  ]
}
```

### Multilingual (label as dict)

```json
{
  "title": "Survey",
  "languages": ["English (en)", "FranΓ§ais (fr)", "Lingala (ln)"],
  "default_language": "FranΓ§ais (fr)",
  "questions": [
    {"name": "name", "type": "text", "required": true,
     "label": {"en": "Your name?", "fr": "Votre nom ?", "ln": "Nkombo na yo ?"}},
    {"name": "city", "type": "select_one",
     "label": {"en": "City?", "fr": "Ville ?", "ln": "Engumba ?"},
     "choices": [
       {"name": "bzv", "label": {"en": "Brazzaville", "fr": "Brazzaville", "ln": "Brazzaville"}},
       {"name": "pnr", "label": {"en": "Pointe-Noire", "fr": "Pointe-Noire", "ln": "Pointe-Noire"}}
     ]}
  ]
}
```

### Supported types

`text`, `integer`, `decimal`, `select_one`, `select_multiple`, `date`, `time`, `datetime`, `note`, `geopoint`, `geotrace`, `geoshape`, `image`, `audio`, `video`, `file`, `barcode`, `calculate`, `acknowledge`, `range`, `rank`, `begin_group`/`end_group`, `begin_repeat`/`end_repeat`.

### Per-question fields

`required` Β· `relevant` (skip logic) Β· `constraint` Β· `constraint_message` Β· `default` Β· `appearance` Β· `calculation` Β· `read_only` Β· `parameters` Β· `hint`.

---

## πŸ§ͺ Testing

Run the live test suite against your Kobo account (creates ephemeral forms, cleans them up automatically):

```bash
python tests/test_write_ops.py
```

Expected: **11/11 passed**.

The tests cover: list, create (mono & multilingual), deploy, submit, update + redeploy, clone, XLSForm upload, media attach/list/remove.

---

## πŸ”’ Security

- Token lives in `.env` only β€” `.env` is `.gitignore`d.
- The original upstream repo had a hardcoded token in `run.sh`. This fork loads from `.env` instead.
- The server logs only the first 6 chars of the token to stderr (e.g. `abc123...`).
- All HTTP goes to your configured Kobo host (default `kf.kobotoolbox.org`) and KoBoCAT (`kc.kobotoolbox.org`) for submissions.

If you accidentally leak your token, regenerate it at https://kf.kobotoolbox.org/token/ β€” the old one stops working instantly.

---

## 🌐 Other Kobo instances

Just change `KOBO_BASE`:

```
# OCHA / humanitarian
KOBO_BASE=https://eu.kobotoolbox.org/api/v2

# Self-hosted
KOBO_BASE=https://kobo.your-org.example.com/api/v2
```

The submission code derives the KoBoCAT host automatically by replacing `kf.` / `kpi.` with `kc.` in the hostname.

---

## πŸ› οΈ Architecture

```
kobo-mcp-server/
β”œβ”€β”€ kobo_client.py       # HTTP client for the KPI v2 + KoBoCAT APIs
β”œβ”€β”€ xlsform_builder.py   # JSON β†’ .xlsx XLSForm converter
β”œβ”€β”€ mcp_server.py        # MCP stdio server (16 tools)
β”œβ”€β”€ server.py            # Optional FastAPI HTTP server (legacy)
β”œβ”€β”€ tests/
β”‚   └── test_write_ops.py
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ .env.example
└── README.md
```

---

## πŸ“œ License

MIT β€” see [LICENSE](./LICENSE). Original work Β© PYI-SOE-LTD. Extensions Β© 2026.

## πŸ™ Credits

- Base server: [PYI-SOE-LTD/kobo-mcp-server](https://github.com/PYI-SOE-LTD/kobo-mcp-server)
- KoBoToolbox API: [kobotoolbox/kpi](https://github.com/kobotoolbox/kpi)
- MCP protocol: [modelcontextprotocol.io](https://modelcontextprotocol.io/)