LimeSurvey MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MCP_HTTP_HOST | No | Streamable HTTP bind address | 127.0.0.1 |
| MCP_HTTP_PATH | No | Streamable HTTP endpoint | /mcp |
| MCP_HTTP_PORT | No | Streamable HTTP port | 3000 |
| MCP_TRANSPORT | No | stdio or http | stdio |
| LIMESURVEY_URL | Yes | Exact RemoteControl URL, for example https://survey.example.com/index.php/admin/remotecontrol | |
| LIMESURVEY_PASSWORD | Yes | Service account password | |
| LIMESURVEY_USERNAME | Yes | LimeSurvey service account | |
| LIMESURVEY_READ_ONLY | No | Block every non-read-only MCP tool before an RPC call | false |
| LIMESURVEY_THEME_DIR | No | Dedicated output directory for generated theme ZIPs | |
| LIMESURVEY_EXPORT_DIR | No | Dedicated output directory for decoded exports | |
| LIMESURVEY_IMPORT_DIR | No | Dedicated input directory for import_data_path reads (falls back to LIMESURVEY_EXPORT_DIR) | |
| LIMESURVEY_TIMEOUT_MS | No | RemoteControl request timeout | 30000 |
| MCP_HTTP_BEARER_TOKEN | No | Required for every non-loopback HTTP binding | |
| LIMESURVEY_AUTH_PLUGIN | No | LimeSurvey authentication plugin | Authdb |
| MCP_HTTP_ALLOWED_HOSTS | No | Comma-separated exact Host allowlist | |
| MCP_HTTP_ALLOWED_ORIGINS | No | Comma-separated exact browser Origin allowlist | |
| LIMESURVEY_MAX_EXPORT_BYTES | No | Maximum decoded export size | 104857600 |
| LIMESURVEY_MAX_IMPORT_BYTES | No | Maximum file size accepted via import_data_path | 52428800 |
| LIMESURVEY_MAX_RESPONSE_CHARS | No | Maximum inline result size | 50000 |
| LIMESURVEY_MAX_THEME_ASSET_BYTES | No | Maximum logo and theme entry size | 5242880 |
| LIMESURVEY_ENABLE_EXPERIMENTAL_METHODS | No | Enable non-standard list_response_exports | false |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| limesurvey_get_session_keyA | Open and cache an authenticated RemoteControl session without exposing its key. Calls LimeSurvey RemoteControl method |
| limesurvey_release_session_keyA | Release the cached RemoteControl session. Calls LimeSurvey RemoteControl method |
| limesurvey_get_available_site_settingsA | List global setting names available to a super administrator. Calls LimeSurvey RemoteControl method |
| limesurvey_get_site_settingsB | Read one global LimeSurvey setting. Calls LimeSurvey RemoteControl method |
| limesurvey_add_surveyA | Create an empty survey with minimum settings. Calls LimeSurvey RemoteControl method |
| limesurvey_delete_surveyA | Permanently delete a survey. Requires confirm_destructive_action=true. Calls LimeSurvey RemoteControl method |
| limesurvey_import_surveyA | Import an LSA, CSV, TXT, or LSS survey. Use import_data_path for files at or above roughly 50 KB so the server reads and base64-encodes them itself; reserve inline import_data for small files under 200,000 characters of base64 text. The returned sid is the survey ID LimeSurvey actually used: it keeps the ID embedded in the file when that ID is free, destination_survey_id overrides it when set, and on an ID collision LimeSurvey silently assigns a random 6-digit sid instead of failing (verified against the LimeSurvey XMLImportSurvey/insertNewSurvey source). Calls LimeSurvey RemoteControl method |
| limesurvey_copy_surveyA | Copy an existing survey under a new name. Calls LimeSurvey RemoteControl method |
| limesurvey_get_survey_propertiesA | Read selected survey properties (any column of the surveys table; unknown names are dropped silently). usetokens is only a stored column in LimeSurvey 6.17.11: the core never evaluates it, so it neither tells whether a participant table exists nor whether the survey is closed. Closed access follows access_mode ("C" closed, "O" open) and the participant table; use limesurvey_get_participant_table_status for a ready-made answer. Verified against the LimeSurvey 6.17.11 source; older releases may differ. Calls LimeSurvey RemoteControl method |
| limesurvey_set_survey_propertiesA | Update editable survey properties. Writable fields: owner_id, gsid, admin, expires, startdate, adminemail, anonymized, format, savetimings, template, datestamp, usecookie, allowregister, allowsave, autonumber_start, autoredirect, allowprev, printanswers, ipaddr, ipanonymize, refurl, datecreated, showsurveypolicynotice, showregisterpolicy, showtokenpolicy, publicstatistics, publicgraphs, listpublic, htmlemail, sendconfirmation, tokenanswerspersistence, assessments, usecaptcha, usetokens, bounce_email, attributedescriptions, emailresponseto, emailnotificationto, tokenlength, showxquestions, showgroupinfo, shownoanswer, showqnumcode, bouncetime, bounceprocessing, bounceaccounttype, bounceaccounthost, bounceaccountpass, bounceaccountencryption, bounceaccountuser, showwelcome, showprogress, questionindex, navigationdelay, nokeyboard, alloweditaftercompletion, googleanalyticsstyle, googleanalyticsapikey, tokenencryptionoptions, access_mode, lastmodified. NOT writable through RemoteControl (the call is rejected before any request is sent): sid, active, language, additional_languages. Titles, descriptions and texts are per-language settings: use limesurvey_set_language_properties. Activation: limesurvey_activate_survey. Languages: limesurvey_add_language / limesurvey_delete_language. While the survey is active, anonymized, datestamp, savetimings, ipaddr and refurl are refused. access_mode and usetokens are plain column writes: they do not create or remove the participant table. Keys LimeSurvey does not report back are returned in warnings. Verified against the LimeSurvey 6.17.11 source; older releases may differ. Calls LimeSurvey RemoteControl method |
| limesurvey_activate_surveyA | Activate a survey after LimeSurvey consistency checks. Requires confirm_activation=true. Calls LimeSurvey RemoteControl method |
| limesurvey_export_statisticsA | Export survey statistics as a base64-encoded PDF, XLS, or HTML document. Calls LimeSurvey RemoteControl method |
| limesurvey_export_timelineA | Return response counts by day or hour for a date range. Calls LimeSurvey RemoteControl method |
| limesurvey_get_summaryA | Read response and participant summary counters. The answer "No available data" is not a call error: for token_* statistics it means the survey has no participant table (no participant statistics; error hint_code NO_PARTICIPANT_TABLE; access is decided by access_mode, check limesurvey_get_participant_table_status), for response statistics it means the survey has no response table: never activated or deactivated (hint_code NO_RESPONSE_TABLE). With statistic=all only the available parts are returned. Calls LimeSurvey RemoteControl method |
| limesurvey_add_languageB | Add a language to a survey. Calls LimeSurvey RemoteControl method |
| limesurvey_delete_languageA | Remove a non-base language from a survey. Requires confirm_destructive_action=true. Calls LimeSurvey RemoteControl method |
| limesurvey_get_language_propertiesA | Read localized survey properties. The attachments field is returned exactly as LimeSurvey stores it (a JSON string since DB version 647, a PHP serialize string on older instances; keep it unchanged for a round trip to set_language_properties). When it is part of the answer, attachments_parsed is added: { : [ { file_name, url, size, relevance } ] } with the mail types invitation, reminder, registration, confirmation, admin_notification and admin_detailed_notification; an empty value gives {} and an unparsable one gives null plus a warning. LimeSurvey drops requested property names that are not a column of the survey language settings without saying so: such names are listed in the warning unknown_fields (if every name is unknown the call fails with the no-data hint). An unknown or missing language silently falls back to the base language. RemoteControl has no method that lists the uploaded survey files themselves; attachments only references them by server path. Calls LimeSurvey RemoteControl method |
| limesurvey_set_language_propertiesA | Update localized survey properties. Writable fields: surveyls_title, surveyls_description, surveyls_welcometext, surveyls_endtext, surveyls_policy_notice, surveyls_policy_error, surveyls_policy_notice_label, surveyls_url, surveyls_urldescription, surveyls_email_invite_subj, surveyls_email_invite, surveyls_email_remind_subj, surveyls_email_remind, surveyls_email_register_subj, surveyls_email_register, surveyls_email_confirm_subj, surveyls_email_confirm, surveyls_dateformat, surveyls_attributecaptions, surveyls_alias, email_admin_notification_subj, email_admin_notification, email_admin_responses_subj, email_admin_responses, surveyls_numberformat, attachments. NOT writable through RemoteControl (the call is rejected before any request is sent): surveyls_language, surveyls_survey_id. Select the language row with the language parameter and send only the localized settings. LimeSurvey answers status OK even when single fields could not be saved; such fields are reported in warnings. Keys LimeSurvey does not report back are returned in warnings. Verified against the LimeSurvey 6.17.11 source; older releases may differ. Calls LimeSurvey RemoteControl method |
| limesurvey_add_groupB | Add an empty question group to a survey. Calls LimeSurvey RemoteControl method |
| limesurvey_delete_groupA | Delete a question group from a survey. Requires confirm_destructive_action=true. Calls LimeSurvey RemoteControl method |
| limesurvey_import_groupB | Import a question group into a survey. Use import_data_path for files at or above roughly 50 KB instead of inline import_data. Calls LimeSurvey RemoteControl method |
| limesurvey_get_group_propertiesA | Read selected question-group properties. LimeSurvey identifies the group by group_id alone, so a wrong ID reads another survey's group. Pass the optional survey_id to cross-check: the result's sid must match, otherwise the call fails with GROUP_SURVEY_MISMATCH (survey_id is never sent to LimeSurvey). Calls LimeSurvey RemoteControl method |
| limesurvey_set_group_propertiesA | Update question-group properties. Writable fields: group_order, randomization_group, grelevance, group_name, description. NOT writable through RemoteControl (the call is rejected before any request is sent): sid, gid, group_l10ns. A group cannot be moved to another survey or restructured through RemoteControl; re-import it (limesurvey_import_group with import_data_path) or use the LimeSurvey admin UI. Localized texts (group_name, description) need a language: {"language": "de", "group_name": "..."}. group_name and description are localized: pass them with data.language (this tool has no language parameter); the server moves them into questiongroupl10ns[language], so the other text field is never blanked. Keys LimeSurvey does not report back are returned in warnings. Verified against the LimeSurvey 6.17.11 source; older releases may differ. Calls LimeSurvey RemoteControl method |
| limesurvey_delete_questionA | Delete a question from its survey. Requires confirm_destructive_action=true. Calls LimeSurvey RemoteControl method |
| limesurvey_import_questionA | Import a question into a survey group. Use import_data_path for files at or above roughly 50 KB instead of inline import_data. Calls LimeSurvey RemoteControl method |
| limesurvey_get_question_propertiesA | Read selected question properties. LimeSurvey identifies the question by question_id alone, so a wrong ID reads another survey's question. Pass the optional survey_id to cross-check: the result's sid must match, otherwise the call fails with QUESTION_SURVEY_MISMATCH (survey_id is never sent to LimeSurvey). Calls LimeSurvey RemoteControl method |
| limesurvey_set_question_propertiesA | Update question properties. Writable fields: title, preg, other, mandatory, encrypted, question_order, scale_id, same_default, relevance, question_theme_name, modulename, same_script, question, help, script. NOT writable through RemoteControl (the call is rejected before any request is sent): attributes, question_attributes, questionattributes, answers, answeroptions, answer_options, subquestions, defaultvalues, default_values, conditions, qid, gid, sid, parent_qid, type, question_l10ns. Question attributes, answer options and subquestions can only be changed by re-importing the question (limesurvey_import_question, or limesurvey_import_group / limesurvey_import_survey, all with import_data_path) or in the LimeSurvey admin UI; limesurvey_replace_question swaps a question of an inactive survey for the question in a .lsq file (inactive surveys only). Localized texts (question, help, script) are written with a language: {"language": "de", "question": "..."} or {"questionl10ns": {"de": {"question": "..."}}}. question, help and script are localized: pass them with data.language (or the language parameter); the server moves them into questionl10ns[language], so the other text fields are never blanked (LimeSurvey's legacy form would reset a field you did not send to an empty string). question_order is refused for questions that have legacy condition dependencies, and the group is renumbered after each change. Keys LimeSurvey does not report back are returned in warnings. Verified against the LimeSurvey 6.17.11 source; older releases may differ. Calls LimeSurvey RemoteControl method |
| limesurvey_activate_tokensA | Create the survey participant table and optional custom attributes. Calls LimeSurvey RemoteControl method |
| limesurvey_add_participantsA | Add one or more participants to a survey. Calls LimeSurvey RemoteControl method |
| limesurvey_delete_participantsA | Delete participants by token-table row IDs. Requires confirm_destructive_action=true. Calls LimeSurvey RemoteControl method |
| limesurvey_get_participant_propertiesA | Read selected properties for a participant matched by token or token-table ID. Calls LimeSurvey RemoteControl method |
| limesurvey_set_participant_propertiesA | Update a participant matched by token or token-table ID. Writable fields: participant_id, firstname, lastname, email, emailstatus, token, language, blacklisted, sent, remindersent, remindercount, completed, usesleft, validfrom, validuntil, mpid, attribute_N. NOT writable through RemoteControl (the call is rejected before any request is sent): tid. Participant rows are changed by token or tid in query; the participant table must exist (check limesurvey_get_participant_table_status). attribute_N stands for the custom attribute columns of the participant table (attribute_1, attribute_2, ...). Validation errors (for example an invalid email) are returned as an error. Keys LimeSurvey does not report back are returned in warnings. Verified against the LimeSurvey 6.17.11 source; older releases may differ. Calls LimeSurvey RemoteControl method |
| limesurvey_list_participantsA | List and filter survey participants with server-side pagination. Calls LimeSurvey RemoteControl method |
| limesurvey_mail_registered_participantsA | Send registration emails to survey participants. Requires confirm_send_email=true. Calls LimeSurvey RemoteControl method |
| limesurvey_invite_participantsA | Send survey invitation emails to selected or eligible participants. Preview first with dry_run=true: it sends nothing and never calls invite_participants, it simulates the selection from the participant list and reports would_receive and would_not_receive with a reason for every participant who is skipped (completed, already_invited, emailstatus_not_ok, invalid_email_address, not_valid_yet, expired, ...). Without continue_on_error LimeSurvey stops at the first participant whose validity window fails; the preview names that participant as stops_at_tid. The report stays within LIMESURVEY_MAX_RESPONSE_CHARS regardless of the table size: unselected participants (token_ids) are only counted as not_selected, and would_receive, would_not_receive and not_reached list at most 100 entries each (truncated_lists says which were cut, counts hold the full numbers). send_email=false is NOT a dry run: it resends the invitation to those who were already invited. Verified against the LimeSurvey 6.17.11 source; older releases may differ. Requires confirm_send_email=true unless dry_run=true. Calls LimeSurvey RemoteControl method |
| limesurvey_remind_participantsA | Send reminder emails to selected or eligible participants. Requires confirm_send_email=true. Calls LimeSurvey RemoteControl method |
| limesurvey_list_groupsA | List question groups in a survey. Calls LimeSurvey RemoteControl method |
| limesurvey_list_questionsA | List questions and subquestions in a survey or group. Calls LimeSurvey RemoteControl method |
| limesurvey_list_quotasA | List quotas configured for a survey. Calls LimeSurvey RemoteControl method |
| limesurvey_add_quotaB | Create a quota with minimum details. Calls LimeSurvey RemoteControl method |
| limesurvey_delete_quotaA | Delete a survey quota. Requires confirm_destructive_action=true. Calls LimeSurvey RemoteControl method |
| limesurvey_get_quota_propertiesA | Read selected quota properties. Calls LimeSurvey RemoteControl method |
| limesurvey_set_quota_propertiesA | Update quota properties. Writable fields: name, qlimit, action, active, autoload_url. NOT writable through RemoteControl (the call is rejected before any request is sent): id, sid, limit, quotals_message, quotals_url, quotals_urldescrip. Localized quota texts (message, URL, URL description) can only be edited in the LimeSurvey admin UI. Unknown keys are ignored silently by LimeSurvey; the server reports them in warnings. Keys LimeSurvey does not report back are returned in warnings. Verified against the LimeSurvey 6.17.11 source; older releases may differ. Calls LimeSurvey RemoteControl method |
| limesurvey_list_surveysA | List surveys visible to a user, optionally filtered by survey group. Calls LimeSurvey RemoteControl method |
| limesurvey_list_survey_groupsA | List survey groups visible to a user. Calls LimeSurvey RemoteControl method |
| limesurvey_list_usersA | List administration users, optionally filtered by ID or username. Calls LimeSurvey RemoteControl method |
| limesurvey_add_responseA | Insert a response into a survey response table. Calls LimeSurvey RemoteControl method |
| limesurvey_update_responseB | Update a response; include its response ID in the data. Calls LimeSurvey RemoteControl method |
| limesurvey_delete_responseA | Permanently delete a response. Requires confirm_destructive_action=true. Calls LimeSurvey RemoteControl method |
| limesurvey_upload_fileA | Upload a base64-encoded file for a file-upload question. Calls LimeSurvey RemoteControl method |
| limesurvey_export_responsesA | Export responses as a base64-encoded document. Calls LimeSurvey RemoteControl method |
| limesurvey_export_responses_by_tokenA | Export responses for selected participant tokens as a base64-encoded document. Calls LimeSurvey RemoteControl method |
| limesurvey_get_response_idsA | Find response IDs for a participant token. Calls LimeSurvey RemoteControl method |
| limesurvey_get_uploaded_filesA | Return uploaded file metadata and base64 content for a token or response. Calls LimeSurvey RemoteControl method |
| limesurvey_get_fieldmapA | Return the survey response field map. Calls LimeSurvey RemoteControl method |
| limesurvey_cpd_importParticipantsA | Import records into the central participant database. Calls LimeSurvey RemoteControl method |
| limesurvey_find_surveysA | Find visible surveys by ID or title with bounded client-side pagination. |
| limesurvey_get_survey_languagesA | Return the base and additional language codes configured for a survey. |
| limesurvey_add_participantC | Add one participant using a simple participant object. |
| limesurvey_list_filtered_participantsB | List participant rows with explicit filters, selected fields, and bounded pagination. |
| limesurvey_get_participant_table_statusA | Report whether a survey has a participant table, how many participants it holds, and whether the survey is closed-access. Read-only: get_summary(token_count) decides existence (a number means the table exists, the answer "No available data" means it does not), get_survey_properties adds access_mode, active, and allowregister on a best-effort basis. Closed access follows access_mode ("C") on LimeSurvey versions that have it; otherwise the existence of the participant table decides (closed_access_basis names which). The survey property usetokens is NOT evaluated by LimeSurvey 6.17.11 and is not used here. Without access_mode, a survey without a participant table has open access. Verified against the LimeSurvey 6.17.11 source; older releases may differ. |
| limesurvey_validate_participantsA | Read-only check of the whole participant table before an invitation run: leading/trailing whitespace (email, firstname, lastname, token), duplicate email addresses (trimmed, case-insensitive) and tokens, address format (every address of a comma/semicolon list, with the pattern LimeSurvey's invite_participants uses), validfrom/validuntil against the server time, validfrom after validuntil, emailstatus other than OK, and missing email or token. Returns issues [{tid, field, code, detail}] and counts_by_code (codes WHITESPACE, DUPLICATE_EMAIL, DUPLICATE_TOKEN, INVALID_EMAIL, NOT_YET_VALID, EXPIRED, INVALID_VALIDITY_RANGE, EMAILSTATUS_NOT_OK, MISSING_EMAIL, MISSING_TOKEN). The server time is the HTTP Date header of the LimeSurvey answer; validfrom/validuntil are read in the server's local time, whose UTC offset is server_utc_offset_minutes or, without it, the timezone of the MCP host (time_basis says which). Entries within 60 minutes of the current time are listed under borderline. Uses only list_participants. The answer stays within LIMESURVEY_MAX_RESPONSE_CHARS: with too many issues, issues and borderline are cut (issues_truncated, issues_total) while counts_by_code stays complete. |
| limesurvey_list_response_export_formatsA | Call the optional list_response_exports LimeSurvey extension to discover plugin-aware export formats. |
| limesurvey_export_responses_to_fileC | Export responses and securely decode the base64 result inside LIMESURVEY_EXPORT_DIR. |
| limesurvey_export_responses_by_token_to_fileB | Export responses for selected tokens and securely decode the result inside LIMESURVEY_EXPORT_DIR. |
| limesurvey_export_statistics_to_fileB | Export survey statistics and securely decode the result inside LIMESURVEY_EXPORT_DIR. |
| limesurvey_get_instance_infoA | Report server-side configuration without any RemoteControl call by default: server_version, instance_host, password_source (file or env, never the path or the content), transport, read_only (true only for write scope none), write_scope and write_scope_source, experimental_methods_enabled, configured export/import/theme directories (each with a local exists/writable check), and a capabilities summary. capabilities are booleans computed after the write scope and the configuration; capability_blocked_by has the same keys and holds null (available) or the reason a capability is unavailable. Set probe_instance=true to additionally call list_surveys (connectivity/auth proof, count only) and get_site_settings("versionnumber") — the latter requires a superadmin service account and degrades to permission_level="standard" with instance_version=null otherwise. The probe also fills server_time (ISO-8601 UTC) and server_time_source ("http_date_header"): RemoteControl has no clock method, so the time comes from the HTTP Date header of the answer; without the probe both are null and server_time_hint says so. server_time_note explains that this is the web server's UTC clock, not the LimeSurvey time zone. Call this before relying on file export/import or theming tools. |
| limesurvey_export_survey_to_fileA | Attempt to export a survey's structure as .lss and write it inside LIMESURVEY_EXPORT_DIR, returning a path instead of base64. Core LimeSurvey 6 RemoteControl has neither export_survey nor export_survey_structure (verified against the LimeSurvey 6.17.11 source). The tool asks export_survey_structure(sessionKey, surveyId) first and export_survey(sessionKey, surveyId) second, so it only works if a plugin on the LimeSurvey side serves one of them; it requires LIMESURVEY_ENABLE_EXPERIMENTAL_METHODS=true and otherwise fails with EXPORT_UNSUPPORTED. Facts (checked 2026-10-11): no known 6.x plugin offers a structure export over RemoteControl (no verified plugin known); the RemoteControl handler class itself cannot be extended by a plugin, but a plugin can answer additional methods on the core URL (see LimeSurvey 6.17.11 source). Upstream, LimeSurvey pull request #5384 adds export_survey_structure for the 7.x line (open, not in any release); an own small plugin with that method works with this tool. Without an export, limesurvey_verify_survey_against_lss compares a .lss file with the live survey using read-only calls only. |
| limesurvey_verify_survey_against_lssA | Read-only comparison of the live survey with a LimeSurvey structure file (.lss). The file must be inside LIMESURVEY_IMPORT_DIR (LIMESURVEY_EXPORT_DIR as a fallback; same path check and size limit as import_data_path). The live survey is read with list_groups, list_questions and get_question_properties only, so read access to the survey content is enough; without a language the base language is taken from list_groups. Groups (name and order), questions (code, type, mandatory, relevance, other, text, help, position), subquestions, answer options and question attributes are matched by code, never by ID, because IDs change on import. Returns { survey_id, lss_file, language, summary { groups, questions, subquestions, answers, attributes { missing_in_live, extra_in_live, changed } }, differences [{ kind, group, question, item, field, lss, live }], differences_total, truncated, limitations }. At most 500 differences are listed; truncated=true says more exist and differences_total holds the full number. limitations names what is not compared (conditions, quotas, assessments, ...). language defaults to the base language of the live survey. Use it to check an import or a hand-edited survey against its source file. |
| limesurvey_replace_questionA | Replace one main question of an INACTIVE survey by the question in a .lsq file, in the same group and at the same position, using only official RemoteControl methods. This is how question attributes, answer options and subquestions are changed, because set_question_properties cannot write them. Steps: check that the survey is inactive (get_survey_properties); read the old question (get_question_properties; it must belong to survey_id and have parent_qid 0); read the group (list_questions); parse the file; if the file has the same code, give the old question a temporary code (set_question_properties); import_question (the new question goes to the end of the group; its mandatory flag is taken from the file because import_question always overwrites it); set_question_properties question_order to the old position; read the old question back and delete_question exactly that question; verify the result. The code, type, texts, attributes, answer options and subquestions come from the file (new_question_title is not offered). Any failure after the first write is rolled back (the question this call imported is deleted, the old code is restored); the error says which step failed and, if a rollback step failed too, lists manual_cleanup. The only question that can be deleted is question_id. Requires confirm_destructive_action=true and the write scope content. Question IDs change; references by code (relevance expressions) keep working; legacy conditions that reference the old question ID are not migrated, and delete_question refuses a question that other questions depend on through legacy conditions (the replacement is then rolled back). Exactly one of import_data (small base64 payload) or import_data_path (file inside LIMESURVEY_IMPORT_DIR) must be set. |
| limesurvey_generate_survey_themeA | Create a validated GPL-2.0-or-later ZIP theme that inherits the official Bootstrap 5 vanilla theme for LimeSurvey 7 or 6. LimeSurvey installs the theme under the ZIP file name without .zip and dots: the result's installed_theme_name (for example acme_feedback-100-ls7), at most 45 characters. Upload the ZIP unrenamed and assign that name. |
| limesurvey_validate_survey_themeA | Validate a ZIP inside LIMESURVEY_THEME_DIR against the LimeSurvey 7.5.1 import: valid=true means LimeSurvey imports and uses the package. errors cover archive safety (more than 1000 entries, unsafe paths, size limits, CRC-32 mismatches, content signatures of images and fonts; the archive checks stop before anything is decompressed) and real import obstacles (installed name from the ZIP file name over 45 characters or with other characters, files the import would silently skip, a config.xml that is not well-formed or not at the root, a missing metadata/title or views/ directory). Warnings starting with "policy:" mark what LimeSurvey accepts but the generator does not produce, for example JavaScript, Twig templates, a parent other than vanilla, a missing css/mcp-theme.css, LICENSE.txt or GPL license, more than 50 entries, or external URLs in CSS; review them before the import. Returns installed_theme_name. |
| limesurvey_get_theme_publication_guideA | Return version-aware installation, preview, assignment, accessibility, rollback, and optional community-publication steps for a survey theme, including installed_theme_name, the name LimeSurvey gives the package on import. |
| limesurvey_assign_survey_themeA | Assign an already imported LimeSurvey survey theme: read the current template (previous_theme), set the new one through set_survey_properties, and read it back with get_survey_properties. theme_name is the installed name (for a generated package its installed_theme_name, such as acme_feedback-100-ls7). LimeSurvey answers {"template": true} even when it keeps another theme; a different read-back value, or a refused save ({"template": false}), fails with THEME_NOT_APPLIED; a failed or empty read-back with THEME_NOT_VERIFIED (written: true); an unreadable previous theme with THEME_PREVIOUS_UNKNOWN (written: false). Results and THEME_NOT_APPLIED name previous_theme and changed. inherit is refused; set it with limesurvey_set_survey_properties or in the admin interface. This does not upload or install the theme package. |
| limesurvey_list_installed_themesA | LimeSurvey RemoteControl2 has no official method to enumerate installed survey themes (verified 2026-07-24 against api.limesurvey.org and the LimeSurvey source). This tool combines two best-effort signals instead: generated_packages lists ZIPs/folders already generated locally in LIMESURVEY_THEME_DIR, and themes_in_use lists the distinct template names actually assigned to surveys visible to this account (via list_surveys + get_survey_properties), which works without a superadmin account. Always includes the documented admin-UI fallback for the complete installed-theme list. |
| limesurvey_validate_specA | Check a survey description (spec) and report every problem at once. kind says what the spec is: survey ({ survey, groups }), group (one group with its questions) or question (one question). Returns { valid, kind, errors [{ path, message, fix }], errors_total, warnings [{ path, message }], warnings_total, truncated, summary, checked_against_survey, skipped_checks }. errors and warnings show at most 200 entries and are cut further to stay within LIMESURVEY_MAX_RESPONSE_CHARS; errors_total and warnings_total hold the full numbers and truncated says whether a list was cut. Paths are 0-based, for example groups[1].questions[3].answers[0].code; for kind group and question they are relative to the checked object (for example code). The check covers keys, question codes (pattern, length, reserved words, duplicates), question types and the subquestions and answers each type needs, answer and subquestion codes, attribute names, attributes that some question theme defines but the theme of the question does not (plugin attributes and unknown themes are not checked), a question_theme_name of another question type, language codes (each once, none equal to the base language), survey.format, survey.expires (a real date and time), XML-forbidden characters and embedded data URIs. A text is one string (for every language) or a map per language; the map must name exactly the languages of the survey (a default value may name fewer); an empty question, subquestion or answer text is a warning. An attribute takes a map when it is stored per language (prefix, suffix, ...) or when no question theme lists it (a plugin attribute), not when it is known to be language independent. default is refused on questions with subquestions and on types R and |. An entry of a Ranking question may have a code of up to 20 characters and a relevance only on LimeSurvey 7: without survey_id this is a warning, with survey_id and kind group or question the version of the instance decides. Without survey_id nothing is sent to LimeSurvey and skipped_checks lists the checks that need the survey (for kind survey the languages come from the spec itself); with survey_id the tool reads the survey (read methods only) and also reports question codes that already exist in it and holds language maps to its languages. The types with a second scale are checked with their scale_id: type 1 needs subquestions (scale 0) and answers on scale 0 and 1, the types : and ; need subquestions on scale 0 (rows) and 1 (columns) and take no answers; codes are unique per scale; scale_id 1 elsewhere and default values on these three types are errors. The tool does not create or change anything; limesurvey_create_survey_from_spec creates a survey from a valid survey spec and limesurvey_get_survey_spec reads a survey, group or question as a spec. |
| limesurvey_create_survey_from_specA | Create a new survey from a survey description (spec { survey, groups }). The spec is checked first: an invalid spec answers SPEC_INVALID with errors [{ path, message, fix }] and sends nothing to LimeSurvey. A valid spec becomes a LimeSurvey structure file (.lss) that import_survey imports; the new survey stays inactive and is not activated. The tool then reads the survey back (read methods only) and compares it with the spec. Returns { survey_id, title, languages, groups, questions, active, verification { ok, differences [{ path, expected, actual, and for a subquestion or answer its code and, on scale 1, scale_id }], differences_total, truncated }, truncated }, plus warnings, missing_translations and unreadable (each with a _total) when there are any. A list shows at most 200 entries and is cut further to stay within LIMESURVEY_MAX_RESPONSE_CHARS; the _total fields hold the full numbers and truncated says whether a list was cut. A difference is a finding of the comparison, not an error of the call. If LimeSurvey answers the import with an error, the tool answers CREATE_SURVEY_FAILED with LimeSurvey's message and details.created false (nothing was created). If the import call itself fails (transport or JSON-RPC error, or no survey ID in the answer), details.created is "unknown" with manual_cleanup, the title and a recovery that names limesurvey_find_surveys: look for the survey before calling again. If only the read-back fails, CREATE_SURVEY_FAILED names the created survey_id. The tool takes no file path, adds nothing to existing surveys, activates nothing and deletes nothing. A spec can be checked beforehand with limesurvey_validate_spec; limesurvey_get_survey_spec returns the spec of an existing survey in this format. A text is one string (for every language) or a map per language. A spec with a Ranking question makes the tool read the generation of the instance once (get_group_properties for group 0): on LimeSurvey 7 the entries are written as subquestions of type R (code up to 20 characters, with relevance), on LimeSurvey 6 as answers (code up to 5 characters, no relevance). The second scale of the types 1 (answers) and : and ; (subquestions, the columns) is given with scale_id 1. Needs the write scope content. |
| limesurvey_get_survey_specA | Read a survey, one group or one question as a survey description (spec), with read methods only. With survey_id alone the whole survey is read (level survey); with group_id one group (level group); with question_id one question (level question); group_id and question_id exclude each other. Returns { level, survey_id, group_id (level group), question_id (level question), languages, active, spec, ids, position, fingerprint, unreadable [{ code, detail }], missing_translations [{ path, language }] }. spec has the format of limesurvey_create_survey_from_spec: level survey { survey, groups }, level group one group, level question one question; every text is a map per language, line breaks are \n and HTML entities are decoded except the markup characters; attribute values equal to the default of the question theme are left out; subquestions and answers come ordered by scale, and scale_id appears only for scale 1 (the columns of : and ;, the second answer scale of 1). spec holds no IDs: ids lists them by path (level survey: groups [{ path, group_id }] and questions [{ path, code, question_id }]; level group: group_id and questions; level question: question_id and group_id) and position gives the 1-based place of a group in the survey or of a question in its group. fingerprint is the SHA-256 of the spec. unreadable lists what RemoteControl cannot read and the spec therefore lacks (conditions of the old condition table, quota members, URL parameter assignments, stored attributes that the type, theme or a plugin does not define, archived response columns, at level survey the survey settings outside the spec, the default of the "Other" option of M and P questions, texts of a question that has no text row in a language); an entry that belongs to an element also has path and language. missing_translations lists the texts that have no row in a survey language, which the map then lacks. The spec can be checked with limesurvey_validate_spec and, at level survey, creates a copy with limesurvey_create_survey_from_spec. The tool never shortens the answer: if it would exceed LIMESURVEY_MAX_RESPONSE_CHARS it answers SPEC_TOO_LARGE with an outline (level survey: group_id, title, questions and estimated_chars per group) so that groups can be read one by one. An ID of another survey answers GROUP_SURVEY_MISMATCH or QUESTION_SURVEY_MISMATCH. The tool changes nothing and needs no write scope. |
| limesurvey_add_question_from_specA | Insert one new question into a group of an inactive survey, described as a question spec (the format limesurvey_get_survey_spec returns at level question; every text is one string for all survey languages or a map per language). position is the 1-based place in the group, { before: code } or { after: code }; without it the question goes to the end. The spec is checked against the survey first (its languages; the code must be free in the whole survey, case ignored): SPEC_INVALID, CODE_CONFLICT, SURVEY_ACTIVE, GROUP_SURVEY_MISMATCH and POSITION_INVALID write nothing. The question is imported (import_question) and only the new question is moved to its place; no other question is changed. It is then read back and compared with the spec. Returns { survey_id, group_id, question_id, code, position { index }, verification { ok, differences, differences_total, truncated }, side_effects, warnings }; a difference is a finding, not an error. import_question fills every text of the survey that has no row in an additional language with the base-language text, which cannot be undone: if the survey has such gaps, the tool answers TRANSLATION_GAPS (the gaps with path, language and question or group) and writes nothing, unless acknowledge contains fill_translation_gaps; side_effects then lists the filled gaps (paths as after the insertion). If a step after the import fails, the new question is deleted again (nothing else) and ADD_QUESTION_FAILED reports failed_step, rolled_back, manual_cleanup and cause_code. If the outcome of the import itself is unknown (lost answer, an error after the creation), nothing is deleted: created is "unknown" and candidates and cleanup_hint say what to check. An active survey is refused. A whole group goes with limesurvey_add_group_from_spec. A Ranking question makes the tool read the LimeSurvey generation once (entries as subquestions on 7, as answers on 6). Needs the write scope content. |
| limesurvey_add_group_from_specA | Insert one new group with its questions into an inactive survey, described as a group spec (the format limesurvey_get_survey_spec returns at level group; every text is one string for all survey languages or a map per language). position is the 1-based place among the groups, { before: group_id } or { after: group_id }; without it the group goes to the end. The spec is checked against the survey first (its languages; every question code must be free in the whole survey, case ignored, because the import would rename it silently): SPEC_INVALID, CODE_CONFLICT, SURVEY_ACTIVE and POSITION_INVALID write nothing. The group is imported (import_group) with exactly the survey languages and only the new group is moved to its place; no other group is changed. It is then read back and compared with the spec. Returns { survey_id, group_id, position { index }, questions [{ code, question_id }], verification { ok, differences, differences_total, truncated }, side_effects, warnings }; a difference is a finding, not an error. If a step after the import fails, the new group is deleted again (nothing else) and ADD_GROUP_FAILED reports failed_step, rolled_back, manual_cleanup and cause_code. If the outcome of the import itself is unknown (lost answer, an unexpected answer), nothing is deleted: created is "unknown" and candidates and cleanup_hint say what to check. The .lsg import fills no translation gaps. An active survey is refused. A single question goes with limesurvey_add_question_from_spec. A Ranking question makes the tool read the LimeSurvey generation once (entries as subquestions on 7, as answers on 6). Needs the write scope content. |
| limesurvey_update_question_from_specA | Change one existing question to the end state given as a question spec (typically the spec of limesurvey_get_survey_spec at level question, changed). The tool compares the end state with the question and picks the mode: none (nothing differs, nothing is written); texts (only question, help and subquestion texts: written in place with set_question_properties questionl10ns, also at an active survey); columns (code, mandatory, relevance, preg, other, same_default, same_script, encrypted, question_theme_name, modulename, inactive survey only: written in place, the question ID stays); replace (anything else: subquestions, answers and answer texts, attributes, defaults, type, script; inactive survey only): the end state is imported as a new question, moved to the place of the old one and read back completely; only if it matches is the old question deleted, otherwise the new one is deleted again and the old one keeps everything. Texts the end state does not change are written back as LimeSurvey stores them. dry_run true only reads (write scope none) and returns { survey_id, question_id, survey_active, mode (none, texts, columns, replace, or rejected when an active survey would need more than texts), changes [{ path, kind (text, column, structure), current, desired, and for a subquestion or answer its code and, on scale 1, scale_id }], changes_total, risks [{ code, blocking, acknowledgeable, detail, locations }], plan, fingerprint }. The real run needs expected_fingerprint (of get_survey_spec or the dry run; STALE_SPEC if the question changed since) and confirm_destructive_action true, and returns the same plus applied, verification { ok, differences } and, after a replacement, the new question_id and old_question_id. Blocking risks stop the call with UPDATE_QUESTION_BLOCKED before anything is written: qid_bound_links (every replacement: URL parameters, archived responses, quota memberships of the old ID), quota_members, other_default, removals, translation_gaps (import_question fills missing translations of the survey) and unreadable_texts (texts of the question that cannot be read in a language get the base-language text; both acknowledged with fill_translation_gaps) and answer_code_references can be acknowledged; code_references (the old code or removed fields such as CODE_SQ, CODE_SQcomment, CODE_other named anywhere, the end state of the question included; free texts are searched inside {...} only), sgqa_references and data_uri cannot. Each risk lists at most a part of its locations (locations_total). Errors: SPEC_INVALID, STALE_SPEC, SURVEY_ACTIVE (with the changes that need an inactive survey), UPDATE_QUESTION_BLOCKED, QUESTION_SURVEY_MISMATCH, REPLACE_QUESTION_FAILED (failed_step, rolled_back, manual_cleanup, differences), UPDATE_QUESTION_FAILED (texts and columns; the old values are written back and read back, manual_cleanup names what is not back), VERIFY_READ_FAILED (written: true; only the read-back failed). Texts of the survey, groups and questions alone go with limesurvey_update_survey_texts; a new question with limesurvey_add_question_from_spec. Needs the write scope content (dry run: none). |
| limesurvey_update_survey_textsA | Change texts of a survey by code, also at an active survey: survey title, description, welcometext and endtext (set_language_properties per language), group title and description by group_id (set_group_properties with questiongroupl10ns) and question, help and subquestion texts by question code (set_question_properties with questionl10ns on the question or subquestion). Every text is one string for every survey language or a map with some of them. Before anything is written the tool refuses: answers or attributes in texts (TEXT_NOT_WRITABLE: RemoteControl cannot write them; at an inactive survey use limesurvey_update_question_from_spec), an unknown code or a language the survey lacks (SPEC_INVALID with the path), a group of another survey (GROUP_SURVEY_MISMATCH), a row that holds an embedded data URI in any field, which LimeSurvey would remove on saving (DATA_URI_PRESENT), and an expected_fingerprint that does not match (STALE_SPEC). Returns { survey_id, survey_active, changes [{ path, language, current, desired }], changes_total, applied, verification { ok, differences }, side_effects (for example empty mail templates LimeSurvey fills on saving), collateral_changes (other fields of the saved rows that changed), fingerprint }. dry_run true only reads (write scope none) and shows the changes; its fingerprint can be passed as expected_fingerprint. If a write fails, every text the call wrote is reset and read back (TEXT_UPDATE_FAILED with rolled_back; manual_cleanup names the old values that are not back); if only the read-back after the writes fails, VERIFY_READ_FAILED says written: true. A subquestion, question or group named twice answers SPEC_INVALID. Needs the write scope content (dry run: none). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 82 tools
The 82 tools cover many distinct operations, but several groups overlap heavily: export_responses vs export_responses_to_file, export_responses_by_token variants, add_participants vs add_participant, list_participants vs list_filtered_participants, list_surveys vs find_surveys, and multiple text-update tools (set_language_properties, update_survey_texts, update_question_from_spec). Detailed descriptions help, but the sheer number and similarity make misselection likely.
Almost all tools follow the limesurvey_ prefix and snake_case verb_noun pattern. The main deviation is limesurvey_cpd_importParticipants (camelCase) and a few compound names like get_fieldmap, but these are minor.
82 tools is far beyond the 3–15 well-scoped range and exceeds even the 50+ extreme mismatch threshold. While LimeSurvey is complex and many operations map to RemoteControl methods, the count is unwieldy for an agent and suggests insufficient consolidation.
The surface covers CRUD for surveys, groups, questions, participants, responses, and quotas, plus import/export, spec-based creation/validation, themes, and instance info. Some gaps remain (e.g., direct condition/assessment management, single-response retrieval, user/permission CRUD), but workarounds exist via spec and replace tools.