diff --git a/wrike/README.md b/wrike/README.md
new file mode 100644
index 0000000..68bf7dc
--- /dev/null
+++ b/wrike/README.md
@@ -0,0 +1,30 @@
+Connect Wrike to help Captain find the task for a bug or request, check its status and comments, and add a comment when another customer reports it.
+
+## Setup
+
+1. In Wrike, open **Apps & Integrations → API** (the [App Console](https://www.wrike.com/appconsole.htm?#/api)), create an app, and select **Get token** to create a permanent access token. Copy it right away; Wrike shows it only once.
+2. Find your API host: it matches the address in your browser when you use Wrike, one of `www.wrike.com`, `app-eu.wrike.com`, or `app-us2.wrike.com`.
+3. Enter the token and select the host when installing.
+
+A permanent token has the same access as the user who created it and cannot be scoped. Create it from a user who only has access to the spaces you want Captain to see.
+
+## Tools
+
+- **Search Tasks:** Search tasks whose title contains the given text. Returns the 10 most recently updated matches with status, importance, due date, and task ID.
+- **Find Task by Permalink:** Find a task from its Wrike link, when you have a link instead of a task ID.
+- **Get Task:** Check one task's status, importance, dates, and description.
+- **List Task Comments:** Read the 10 most recent comments on a task.
+- **Find Folders and Projects:** Find folders and projects by title, with project status and dates. Returns up to 20 matches.
+- **List Folder Tasks:** List the 20 most recently updated tasks in a folder or project, including its subfolders.
+- **List Statuses:** List account-wide workflows and the name of each custom status ID.
+- **Add Task Comment:** Add a plain-text comment to a task, such as a note that another customer reported the same issue.
+
+Start with Search Tasks or Find Task by Permalink, then use the task ID with the other tools.
+
+## Notes
+
+- Wrike task IDs used by the API, such as `IEAAAAAQKQAB5FKP`, are different from the number in a task link. Use Find Task by Permalink to get the API ID from a link.
+- Requests sent to the wrong host fail, so the host must match your Wrike account's data center.
+- Tasks report custom statuses as IDs; List Statuses maps them to names. Workflows that belong to a single space are not listed.
+- Comments show their date and text. Wrike returns comment authors as user IDs, not names, so they are left out.
+- Add Task Comment posts as the user who created the token.
diff --git a/wrike/toolset.yml b/wrike/toolset.yml
new file mode 100644
index 0000000..d952854
--- /dev/null
+++ b/wrike/toolset.yml
@@ -0,0 +1,178 @@
+version: 0.0.1
+kind: captain_toolset
+name: Wrike
+author: chatwoot
+category: Others
+description: Search Wrike tasks and projects, check task status and comments, and add comments to tasks.
+
+inputs:
+ host:
+ label: Wrike API host
+ type: select
+ options:
+ - www.wrike.com
+ - app-eu.wrike.com
+ - app-us2.wrike.com
+ required: true
+
+secrets:
+ access_token:
+ label: Wrike permanent access token
+ type: password
+ required: true
+
+tools:
+ - id: search_tasks
+ title: Search Tasks
+ description: Search Wrike tasks whose title contains the given text, such as a bug or request a customer mentions. Use this first to find the task ID the other tools need. Returns the 10 most recently updated matches.
+ http_method: GET
+ endpoint_url: https://${{ inputs.host }}/api/v4/tasks?title={{ title | strip | url_encode }}&sortField=UpdatedDate&sortOrder=Desc&limit=10&fields=%5B%22briefDescription%22%5D
+ auth_type: bearer
+ auth_config:
+ token: ${{ secrets.access_token }}
+ param_schema:
+ - name: title
+ type: string
+ description: Text to look for in task titles. Use one or two distinctive words.
+ required: true
+ response_template: |-
+ {% if response.data %}{% for task in response.data limit: 10 %}- {{ task.title | truncate: 150 }} (task ID {{ task.id }}) · {{ task.status }} · {{ task.importance }} importance{% if task.dates.due %} · Due {{ task.dates.due | slice: 0, 10 }}{% endif %} · Updated {{ task.updatedDate | slice: 0, 10 }}
+ Custom status ID: {{ task.customStatusId | default: "none" }}
+ {{ task.permalink }}{% if task.briefDescription and task.briefDescription != "" %}
+ {{ task.briefDescription | strip_html | newline_to_br | replace: "
", " " | strip_newlines | truncate: 200 }}{% endif %}
+ {% else %}No tasks found with that text in the title.
+ {% endfor %}{% else %}Wrike returned an unexpected response.{% endif %}
+
+ - id: find_task_by_permalink
+ title: Find Task by Permalink
+ description: Find a Wrike task from its permalink, the task link copied from Wrike that looks like https://www.wrike.com/open.htm?id=123456789. Use this when you have a task link instead of a task ID.
+ http_method: GET
+ endpoint_url: https://${{ inputs.host }}/api/v4/tasks?permalink={{ permalink | strip | url_encode }}&fields=%5B%22briefDescription%22%5D
+ auth_type: bearer
+ auth_config:
+ token: ${{ secrets.access_token }}
+ param_schema:
+ - name: permalink
+ type: string
+ description: The full Wrike task permalink URL, exactly as copied from Wrike.
+ required: true
+ response_template: |-
+ {% if response.data %}{% for task in response.data limit: 5 %}- {{ task.title | truncate: 150 }} (task ID {{ task.id }}) · {{ task.status }} · {{ task.importance }} importance{% if task.dates.due %} · Due {{ task.dates.due | slice: 0, 10 }}{% endif %} · Updated {{ task.updatedDate | slice: 0, 10 }}
+ Custom status ID: {{ task.customStatusId | default: "none" }}
+ {{ task.permalink }}{% if task.briefDescription and task.briefDescription != "" %}
+ {{ task.briefDescription | strip_html | newline_to_br | replace: "
", " " | strip_newlines | truncate: 200 }}{% endif %}
+ {% else %}No task found with that permalink.
+ {% endfor %}{% else %}Wrike returned an unexpected response.{% endif %}
+
+ - id: get_task
+ title: Get Task
+ description: Get one Wrike task's details, including its status, importance, dates, and description. Use a task ID from Search Tasks, Find Task by Permalink, or List Folder Tasks. Call List Statuses to turn the custom status ID into a name.
+ http_method: GET
+ endpoint_url: https://${{ inputs.host }}/api/v4/tasks/{{ task_id | strip | url_encode }}
+ auth_type: bearer
+ auth_config:
+ token: ${{ secrets.access_token }}
+ param_schema:
+ - name: task_id
+ type: string
+ description: The Wrike task ID from Search Tasks, a letter-and-number code such as IEAAAAAQKQAB5FKP. This is not the number in the task link.
+ required: true
+ response_template: |-
+ {% if response.data.size == 0 %}No task found with this ID.{% elsif response.data[0].id %}{% assign task = response.data[0] %}{{ task.title }} (task ID {{ task.id }})
+ Status: {{ task.status }}{% if task.customStatusId %} (custom status ID {{ task.customStatusId }}){% endif %}
+ Importance: {{ task.importance }}{% if task.dates.start %}
+ Start: {{ task.dates.start | slice: 0, 10 }}{% endif %}{% if task.dates.due %}
+ Due: {{ task.dates.due | slice: 0, 10 }}{% endif %}
+ Created: {{ task.createdDate | slice: 0, 10 }} · Updated: {{ task.updatedDate | slice: 0, 10 }}{% if task.completedDate %} · Completed: {{ task.completedDate | slice: 0, 10 }}{% endif %}{% if task.subTaskIds.size > 0 %}
+ Subtasks: {{ task.subTaskIds.size }}{% endif %}{% if task.parentIds.size > 0 %}
+ Folder IDs: {{ task.parentIds | join: ", " | truncate: 200 }}{% endif %}
+ Link: {{ task.permalink }}{% if task.description and task.description != "" %}
+ Description: {{ task.description | replace: "
", " " | replace: "
", " " | strip_html | truncate: 1500 }}{% endif %}{% else %}Wrike returned an unexpected response.{% endif %}
+
+ - id: list_task_comments
+ title: List Task Comments
+ description: Read the 10 most recent comments on a Wrike task, such as progress updates from the team. Use a task ID from Search Tasks or Find Task by Permalink.
+ http_method: GET
+ endpoint_url: https://${{ inputs.host }}/api/v4/tasks/{{ task_id | strip | url_encode }}/comments?plainText=true
+ auth_type: bearer
+ auth_config:
+ token: ${{ secrets.access_token }}
+ param_schema:
+ - name: task_id
+ type: string
+ description: The Wrike task ID from Search Tasks, a letter-and-number code such as IEAAAAAQKQAB5FKP.
+ required: true
+ response_template: |-
+ {% if response.data %}{% assign comments = response.data | sort: "createdDate" | reverse %}{% for comment in comments limit: 10 %}- {{ comment.createdDate | slice: 0, 10 }}: {{ comment.text | newline_to_br | replace: "
", " " | strip_newlines | truncate: 500 }}
+ {% else %}No comments on this task.
+ {% endfor %}{% else %}Wrike returned an unexpected response.{% endif %}
+
+ - id: find_folders
+ title: Find Folders and Projects
+ description: Find Wrike folders and projects whose title contains the given text, to get the folder ID that List Folder Tasks needs or to check a project's status and dates. Returns up to 20 matches.
+ http_method: GET
+ endpoint_url: https://${{ inputs.host }}/api/v4/folders?title={{ title | strip | url_encode }}&pageSize=20
+ auth_type: bearer
+ auth_config:
+ token: ${{ secrets.access_token }}
+ param_schema:
+ - name: title
+ type: string
+ description: Text to look for in folder and project titles. Must not be blank.
+ required: true
+ response_template: |-
+ {% if response.data %}{% for folder in response.data limit: 20 %}- {{ folder.title | truncate: 150 }} (folder ID {{ folder.id }}) · {% if folder.project %}project · {{ folder.project.status }}{% if folder.project.startDate %} · Starts {{ folder.project.startDate | slice: 0, 10 }}{% endif %}{% if folder.project.endDate %} · Ends {{ folder.project.endDate | slice: 0, 10 }}{% endif %}{% else %}folder{% endif %}
+ {% else %}No folders or projects found with that text in the title.
+ {% endfor %}{% else %}Wrike returned an unexpected response.{% endif %}
+
+ - id: list_folder_tasks
+ title: List Folder Tasks
+ description: List the 20 most recently updated tasks in a Wrike folder or project, including tasks in its subfolders. Use a folder ID from Find Folders and Projects.
+ http_method: GET
+ endpoint_url: https://${{ inputs.host }}/api/v4/folders/{{ folder_id | strip | url_encode }}/tasks?descendants=true&sortField=UpdatedDate&sortOrder=Desc&limit=20
+ auth_type: bearer
+ auth_config:
+ token: ${{ secrets.access_token }}
+ param_schema:
+ - name: folder_id
+ type: string
+ description: The Wrike folder or project ID from Find Folders and Projects.
+ required: true
+ response_template: |-
+ {% if response.data %}{% for task in response.data limit: 20 %}- {{ task.title | truncate: 150 }} (task ID {{ task.id }}) · {{ task.status }} · {{ task.importance }} importance{% if task.dates.due %} · Due {{ task.dates.due | slice: 0, 10 }}{% endif %} · Updated {{ task.updatedDate | slice: 0, 10 }}
+ {% else %}No tasks in this folder or project.
+ {% endfor %}{% else %}Wrike returned an unexpected response.{% endif %}
+
+ - id: list_statuses
+ title: List Statuses
+ description: List the account-wide Wrike workflows and the name of each custom status ID. Use this to turn the custom status ID from Search Tasks or Get Task into a name such as In Review.
+ http_method: GET
+ endpoint_url: https://${{ inputs.host }}/api/v4/workflows
+ auth_type: bearer
+ auth_config:
+ token: ${{ secrets.access_token }}
+ response_template: |-
+ {% if response.data %}{% for workflow in response.data limit: 15 %}{% unless workflow.hidden %}{{ workflow.name }}:
+ {% for status in workflow.customStatuses limit: 30 %}{% unless status.hidden %}- {{ status.name }} (custom status ID {{ status.id }}, {{ status.group }})
+ {% endunless %}{% endfor %}{% endunless %}{% else %}No workflows found.
+ {% endfor %}{% else %}Wrike returned an unexpected response.{% endif %}
+
+ - id: add_task_comment
+ title: Add Task Comment
+ description: Add a plain-text comment to a Wrike task, for example to note that another customer reported the same issue, with a short summary. Use a task ID from Search Tasks or Find Task by Permalink. Only add a comment when the conversation needs one.
+ http_method: POST
+ endpoint_url: https://${{ inputs.host }}/api/v4/tasks/{{ task_id | strip | url_encode }}/comments?plainText=true&text={{ text | strip | url_encode }}
+ auth_type: bearer
+ auth_config:
+ token: ${{ secrets.access_token }}
+ param_schema:
+ - name: task_id
+ type: string
+ description: The Wrike task ID from Search Tasks, a letter-and-number code such as IEAAAAAQKQAB5FKP.
+ required: true
+ - name: text
+ type: string
+ description: The comment text, up to about 1,000 characters. Plain text only; it cannot be empty.
+ required: true
+ response_template: |-
+ {% if response.data[0].id %}Added the comment to the task.{% else %}Wrike returned an unexpected response.{% endif %}