Kaiku
REMOTE · MCP.KAIKU.TECH · 2 COMPONENTS · SCANNED SEP 23
Issue tracker and wiki for teams and their agents: find, file and update issues, write pages.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →
Endpoint Security89
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- Authorisation is enforced on tool calls, but the challenge carries no valid RFC 9728 metadata, so a client cannot discover where to get a token. See how to fix → View diagnostics → Fail
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
Schema Quality & AI Usability66
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 20317 tokens (~274/item across 74 items; 74 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management3
- Stability observed for 1 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
Tool Safety75
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- 0 of 12 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "admin_bank_transfer" implies "transfer" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
- An AI judge read all 75 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the Kaiku MCP server?
Kaiku is a hosted endpoint at https://mcp.kaiku.tech/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
remote · mcp.kaiku.tech
claude mcp add --transport http tech-kaiku-kaiku 'https://mcp.kaiku.tech/mcp'
{
"mcpServers": {
"tech-kaiku-kaiku": {
"url": "https://mcp.kaiku.tech/mcp"
}
}
} {
"servers": {
"tech-kaiku-kaiku": {
"type": "http",
"url": "https://mcp.kaiku.tech/mcp"
}
}
} [mcp_servers.tech-kaiku-kaiku] url = "https://mcp.kaiku.tech/mcp"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"tech-kaiku-kaiku": {
"type": "remote",
"url": "https://mcp.kaiku.tech/mcp",
"enabled": true
}
}
} openclaw mcp add tech-kaiku-kaiku --url 'https://mcp.kaiku.tech/mcp' --transport streamable-http
mcp_servers:
tech-kaiku-kaiku:
url: "https://mcp.kaiku.tech/mcp" {
"McpServers": {
"tech-kaiku-kaiku": {
"Transport": "http",
"Url": "https://mcp.kaiku.tech/mcp"
}
}
} assistant mcp add tech-kaiku-kaiku -t streamable-http -u 'https://mcp.kaiku.tech/mcp'
{
"mcpServers": {
"tech-kaiku-kaiku": {
"type": "http",
"url": "https://mcp.kaiku.tech/mcp"
}
}
} The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 23 Sept 26 0
- The server rewrote its instructions, which are the text every model session reads security
- Tool “add_attachment” rewrote its description, which is the text the model reads security
- Tool “add_wiki_attachment” rewrote its description, which is the text the model reads security
- Tool “get_attachment” rewrote its description, which is the text the model reads security
- Tool “get_wiki_attachment” rewrote its description, which is the text the model reads security
- Stability: unverified → 0.03 ▲ functional
- New tool “local_files_setup” functional
- 22 Sept 26 74
First indexed and scored.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 23 Sept 2026 · Probed https://mcp.kaiku.tech/mcp
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=*.kaiku.tech | CN=YR1,O=Let's Encrypt,C=US | 23 Aug 2026 | 21 Nov 2026 | RSA 4096 | SHA256-RSA | 6c9d9025f51a369dcf0d95953df9c2a41a6 |
| SANs: *.kaiku.tech | ||||||
| CN=YR1,O=Let's Encrypt,C=US (CA) | CN=Root YR,O=ISRG,C=US | 3 Sept 2025 | 2 Sept 2028 | RSA 2048 | SHA256-RSA | a20253f15f2691c05dc1ce13b9bcca4e |
| CN=Root YR,O=ISRG,C=US (CA) | CN=ISRG Root X1,O=Internet Security Research Group,C=US | 13 May 2026 | 2 Sept 2032 | RSA 4096 | SHA256-RSA | f24b6d17f9d9ad7cb1c9fea78782699f |
Background: What to check on a remote MCP endpoint →
DNSSEC insecure
Validation of mcp.kaiku.tech. — Not signed
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | trust_anchor | 20326, 38696 | 8, 8 | Verified |
| tech. | present | 2185 | 13 | Verified |
| kaiku.tech. | absent | Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation |
Authentication Challenged, unverified
The endpoint asked for a token, but we could not retrieve and validate the RFC 9728 metadata that tells a client how to obtain one.
| Result | Challenged, unverified |
|---|---|
| Enforced | On tool calls |
| HTTP status | 200 |
WWW-Authenticate challenge Bearer realm="mcp"
Bearer realm="mcp" | Header | Value |
|---|---|
| strict-transport-security | max-age=31536000 |
Protected resource metadata
| Retrieved | No |
|---|---|
| Problem | no_resource_metadata |
Background: How OAuth 2.1 works in the 2026 MCP spec →
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://mcp.kaiku.tech/mcp | Verified | 200 | |
| http (plaintext) | http://mcp.kaiku.tech/mcp | HTTPS enforced | 301 | https://mcp.kaiku.tech/mcp |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
list_wiki_spaces ~31
List the wiki spaces visible to this token. Every project has exactly one space, keyed like the project.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
local_files_setup ~126
How the person connects pm-files — a small local MCP server that attaches files from their own computer to issues and wiki pages by path, and saves attachments back to files, so no bytes pass through the conversation. Call it when you need a local file (a screenshot, a document, anything past the base64 ceiling) and pm-files is not among your tools: hand the person the command for their client, with this workspace's address already in it. It never contains a token, and you must never ask for one — the command takes it from the person's clipboard. Changes nothing.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
move_issue ~268
Move an issue into another project, taking its comments, history, attachments, links and sub-tasks with it. The key does NOT change: 'PM-12' stays 'PM-12' wherever it lives, so every existing link and branch name goes on working. Call it with apply=false first (the default): the answer says what the move would cost — values in columns the target project does not have are LOST, the sprint is cleared, and a secret attached to the issue becomes readable by the target project's lead. Refuses when the target has no state by the issue's status name; say what that state becomes with 'statuses'. A sub-task cannot move on its own — move its parent. Needs full write access in BOTH projects.
| Name | Type | Req | Description |
|---|---|---|---|
| apply | boolean | – | false (the default) answers what the move would do and changes nothing. true does it. |
| key | string | yes | The issue to move, e.g. 'PM-12'. |
| statuses | string|null | – | What each source status becomes in the target project, as 'In Review=Review, Blocked=On hold'. Only needed for states the target does not already have under the same name. |
| toProject | string | yes | Project key to move it into, e.g. 'CRM'. |
No output schema declared.
No examples provided.
read_code ~107
Read one file from a repository connected to a project. A long file arrives cut and says so; generated and binary files are not read.
| Name | Type | Req | Description |
|---|---|---|---|
| path | string | yes | The file's path inside the repository, e.g. 'src/app/main.ts'. Not a URL. |
| reference | string|null | – | Branch, tag or commit. Omit for the default branch. |
| repo | string|null | – | Which repository, as 'group/repo'. Omit when only one is open. |
No output schema declared.
No examples provided.
remove_track ~139
Undeclare a track. THE LABEL STAYS ON THE WORK: what goes is the declaration, so the issues keep their tag and declaring the track again brings exactly the same ones back. Nothing here can lose work — but the name, icon and place ARE lost, and the track's issues count as 'outside every track' afterwards. For a track that is merely finished, archive it instead: set_track with archived=true. Needs permission to write in the project.
| Name | Type | Req | Description |
|---|---|---|---|
| projectKey | string | yes | Project key, e.g. 'TH'. |
| tag | string | yes | The track's tag, e.g. 'cherry-orchard'. |
No output schema declared.
No examples provided.
reply_to_requester ~145
Write to the person who opened a support request. The text becomes a comment the requester can read on their page and is emailed to them — unlike add_comment, which is always internal and never reaches the requester. Write it to the customer, in their language (get_support_request says which). Requires full write access to the support project. Answers with the comment id and whether the letter went ('emailed'; 'emailError' when it failed — the reply is kept either way).
| Name | Type | Req | Description |
|---|---|---|---|
| body | string | yes | What to tell the requester. Markdown is kept as written. |
| key | string | yes | Issue key of the request, e.g. 'SUPPORT-12'. |
No output schema declared.
No examples provided.
report_agent_usage ~394
Record what one agent run cost an issue (local or mirrored/upstream): tokens by kind and machine time. Re-sending the same 'source' + 'externalId' updates that record instead of adding a second one, so a retry never doubles the spend. Omit a metric you did not measure — omitted is 'not reported', which is different from zero. Requires permission to edit the issue.
| Name | Type | Req | Description |
|---|---|---|---|
| agent | string|null | – | Which agent did the work, e.g. 'claude-code'. |
| agentSeconds | integer|null | – | Wall-clock seconds the run took. Machine time, not a worklog. |
| cacheReadTokens | integer|null | – | Cache-read tokens. |
| cacheWriteTokens | integer|null | – | Cache-write tokens. |
| costUsd | number|null | – | Cost in USD, if you know the rates that applied. |
| endedAt | string|null | – | When the run ended (ISO 8601). |
| externalId | string | yes | Your own key for this record (usually the run id). Re-sending it updates the record. |
| host | string|null | – | Which host it ran on. |
| inputTokens | integer|null | – | Input (prompt) tokens. |
| key | string | yes | Issue key, e.g. 'UK-1'. |
| model | string|null | – | Which model it ran on, e.g. 'claude-opus-5'. |
| note | string|null | – | Short note, e.g. the outcome. |
| outputTokens | integer|null | – | Output (completion) tokens. |
| runId | string|null | – | The run this record belongs to, when one run reports several records (different models or hosts). |
| source | string | yes | Who is reporting, e.g. 'bg-agent-api'. Idempotency is scoped to it. |
| startedAt | string|null | – | When the run started (ISO 8601). |
No output schema declared.
No examples provided.
reveal_credential ~118
Read one credential's value, by the id from list_credentials. This is the same act as pressing reveal on the screen and carries the same cost: it is recorded against the token you are using, and the person who owns the secret can see that you read it. Call it when you are about to use the value, not to have it on hand. The answer is marked secret: do not copy it into a comment, a description, a merge request or a log.
| Name | Type | Req | Description |
|---|---|---|---|
| id | integer | yes | Credential id, from list_credentials. |
No output schema declared.
No examples provided.
search_code ~177
Find where a string appears in the code of the repositories connected to a project, with the file, the line number and the lines around it. Only repositories whose owners opened them to agents are searched, and the answer says when what it searched was out of date.
| Name | Type | Req | Description |
|---|---|---|---|
| caseSensitive | boolean | – | Match case. Off by default. |
| path | string|null | – | Narrow to files whose path contains this, such as 'src/' or '.ts'. |
| query | string | yes | What to look for, taken literally unless regexp is set. A space is a space, not two terms. |
| regexp | boolean | – | Read query as a regular expression. One with no literal in it may not finish in time. |
| repo | string|null | – | Which repository, as 'group/repo'. Omit to search every repository open here. |
No output schema declared.
No examples provided.
search_issues ~774
Search the issues visible to this token, with a JQL query — the same JQL the Jira REST surface takes, read by the same parser. A query naming a field this tracker does not have is REFUSED and named, never run: it would match everything and read as an answer. Without `jql`, the shorthand arguments filter instead. Most recently created first unless the query says ORDER BY. Archived issues are left out unless the query names `archived`, and `archivedLeftOut` says how many matches that hid — an empty list with it is not "there are none".
| Name | Type | Req | Description |
|---|---|---|---|
| jql | string|null | – | A JQL query, e.g. `assignee = currentUser() AND statusCategory != Done ORDER BY updated DESC`. FIELDS: project, status, statuscategory, issuetype, type, priority, resolution, assignee, reporter, crea… |
| limit | integer | – | Max issues to return (default 25, max 100). |
| projectKey | string|null | – | Shorthand for `project = …` (must be visible to the token). Narrows the query further when `jql` is given too. |
| status | string|null | – | Shorthand for `status = …` (e.g. 'In Progress', 'Done'). Narrows the query further when `jql` is given too. |
| text | string|null | – | Shorthand for `key ~ … OR summary ~ …`. Narrows the query further when `jql` is given too. |
No output schema declared.
No examples provided.
search_wiki ~119
Search wiki pages visible to this token by free text (matched in the title, the body, and the labels written on an attached SVG diagram). Optionally restrict to one space key. Most recently updated first.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Max pages to return (default 25, max 100). |
| spaceKey | string|null | – | Restrict to this space key (e.g. 'PM'). |
| text | string|null | – | Free text to match in the page title, its body, or the text of an attached SVG diagram. |
No output schema declared.
No examples provided.
set_issue_fields ~185
Fill in a project's own columns on one issue, by their NAMES: 'Segment=AI; Country=Poland; Started=2026-08-01', or a JSON object. A country column takes the country's name or its two-letter code. An empty value clears the field, which is not the same as an empty one. A value that does not fit the field's kind — an option nobody offered, a date that is not one, a country that is neither — refuses the WHOLE call rather than writing part of it.
| Name | Type | Req | Description |
|---|---|---|---|
| key | string | yes | Issue key, e.g. 'CRM-1'. |
| values | string | yes | Field names to values, as 'Segment=AI; Country=Poland' or a JSON object. List values are given by option name, people by username, dates as 2026-08-21. |
No output schema declared.
No examples provided.
set_project_field ~377
Add a column to a project, or edit the one that already has this name. Keyed by name rather than by id: 'make sure there is a Segment field with these options' is the request, and a name is what you just read. A field's KIND cannot be changed once it exists. Project lead or admin only.
| Name | Type | Req | Description |
|---|---|---|---|
| icon | string|null | – | The glyph that mark wears, from the palette list_project_fields returns. Not for a country field: that one marks a card with the flag of the country the issue holds, so passing an icon is refused rat… |
| kind | string|null | – | What it holds: 'text', 'number', 'date', 'user', 'select' (a list) or 'country' (a country, written as its name or its two-letter code and shown with a flag). Required when creating; ignored when the… |
| name | string | yes | Field name, e.g. 'Segment'. An existing field with this name is edited rather than duplicated. |
| newName | string|null | – | Rename the field to this. Leave out to keep the name. |
| options | string|null | – | For a list: its options, as 'AI:green, Skins:orange, GameCards' or a JSON array of {name, color}. A colour is optional and must be one of: orange, amber, red, pink, purple, blue, teal, green. Options… |
| projectKey | string | yes | Project key, e.g. 'CRM'. |
| showIcon | boolean|null | – | Mark a board card when this field has a value: true to switch the mark on, false off. Leave out to keep it as it is. |
No output schema declared.
No examples provided.
set_project_parent ~193
Make an existing project a subproject of another, or take it back out with an empty parentKey. This is about ACCESS, not about names or issues: everyone who may reach the parent may reach the subproject too, in the role they hold there. Nothing is renamed, no issue moves, and the keys stay ordinary keys. Attaching needs an admin or somebody who leads BOTH projects, since neither can be volunteered by whoever leads the other; detaching needs a lead of either, since it only takes access away. One level: a subproject cannot have subprojects.
| Name | Type | Req | Description |
|---|---|---|---|
| parentKey | string|null | – | Key of the project it becomes a subproject of, e.g. 'KYC'. Leave it out (or empty) to detach it and leave it a project of its own. |
| projectKey | string | yes | Key of the project to move, e.g. 'KYCB2B'. |
No output schema declared.
No examples provided.
set_track ~458
Declare a track on a project, or edit the one that already has this tag. The tag is the LABEL issues carry to join it ('cherry-orchard'), so it cannot contain a space — labels are stored space-separated. The name is what a reader sees ('The Cherry Orchard'); leave it out and the tag speaks for itself. Declaring a track writes nothing to any issue: the ones already carrying the label are in it at once. Needs permission to write in the project.
| Name | Type | Req | Description |
|---|---|---|---|
| archived | boolean|null | – | true takes the track off the row above the board WITHOUT undeclaring it — a play that has been staged: its name, icon, place and tag are kept, its issues stay in it (they do not become 'outside every… |
| icon | string|null | – | One or two emoji shown BESIDE the name, never instead of it. Leave it out to keep what is there; send an empty string to take it off. Anything that is not an emoji is refused rather than ignored. |
| name | string|null | – | What a reader sees, e.g. 'The Cherry Orchard'. Leave it out to keep what is there; send an empty string to drop it and let the tag speak. |
| newTag | string|null | – | Rename the tag to this. The label on existing issues is NOT rewritten, so work in the old tag leaves the track — rename only when the issues are being relabelled too. |
| position | integer|null | – | Where it sits in the row above the board, counting from 1. Leave it out and a new track goes last, an existing one stays where it is. |
| projectKey | string | yes | Project key, e.g. 'TH'. |
| tag | string | yes | The label that puts an issue in this track, e.g. 'cherry-orchard'. No spaces. An existing track with this tag is edited rather than duplicated; matched exactly, so 'Hamlet' and 'hamlet' are two tags,… |
No output schema declared.
No examples provided.
unlink_issues ~209
Remove a link between two issues: name both ends (and, when more than one link joins them, the phrase — 'blocks', 'relates to'), or give the 'linkId' get_issue returned. Ambiguity is refused rather than guessed: two issues joined twice and no phrase given comes back with the links listed. Requires permission to edit BOTH issues. The issues themselves are untouched.
| Name | Type | Req | Description |
|---|---|---|---|
| from | string|null | – | One end, e.g. 'PM-419'. Not needed when 'linkId' is given. |
| linkId | integer|null | – | The link's id, as get_issue returns it in 'links'. |
| to | string|null | – | The other end, e.g. 'PM-417'. Not needed when 'linkId' is given. |
| type | string|null | – | Which link, when the two issues are joined by more than one: the phrase as get_issue says it ('blocks', 'is blocked by', 'relates to'). |
No output schema declared.
No examples provided.
unlink_wiki_page ~125
Remove the link between an issue and a wiki page. Identify the page by 'pageId', or by 'spaceKey' + 'title'. Requires permission to edit the issue. The page itself is not touched.
| Name | Type | Req | Description |
|---|---|---|---|
| issueKey | string | yes | Issue key, e.g. 'UK-1'. |
| pageId | integer|null | – | Page id (as returned by search_wiki). |
| spaceKey | string|null | – | Space key, when identifying the page by title. |
| title | string|null | – | Exact page title, when identifying the page by title. |
No output schema declared.
No examples provided.
update_comment ~381
Edit a comment on an issue: pass 'body' to replace the whole of it, or 'edits' to change part of it — exact find-and-replace against the comment as get_comments hands it back, each 'oldText' occurring exactly once. One body axis per call. With 'edits' the answer says where each one landed rather than giving the comment back, so correcting one number in a long comment costs neither a resend nor a re-read. Nothing here takes a version and none is needed: an 'oldText' is matched against the comment as it stands now, so an edit whose text somebody has since rewritten is refused rather than applied over their words. The author may edit their own comment; anyone with full write access in the project may edit any. Answers with 'notified' — and note that this is only the people the *edit* newly reaches: names already present in the old text are not notified again, and the comment is not re-announced to watchers.
| Name | Type | Req | Description |
|---|---|---|---|
| body | string|null | – | The new body, replacing the old one entirely. Markdown is kept as written, and carries $…$ / $$…$$ LaTeX formulas and [~username] mentions. |
| commentId | integer | yes | The comment's id, as returned by get_comments or add_comment. |
| edits | array|null | – | Exact replacements in the comment, changing part of it in place. Matched against the body as get_comments returns it — stored as written, so what you read is what an 'oldText' has to equal, whitespac… |
| key | string | yes | Issue key the comment is on, e.g. 'UK-1'. |
No output schema declared.
No examples provided.
update_issue ~760
Update an issue: any of summary, description, type, assignee, priority, labels, dueDate, parentKey, or status (which performs the transition, and fires the project's rules — a rule may append a checklist to the description, in which case 'description' is listed in 'changed'). Only the fields you pass are changed. A project's workflow may put conditions on a move — that only certain people may make it, or that it must set certain fields — and a refusal names the condition and, where it is about who you are, lists the states you CAN reach. Fields a move requires must be sent in this same call, with 'resolution' and 'fields': a value set by an earlier call does not satisfy the condition. Answers with 'notified' (who this actually reaches) and 'unresolvedMentions' (what looked like a mention and reached nobody, each with a reason) — a wrong handle is stored as written and never refused, so that list is the only sign it did not land.
| Name | Type | Req | Description |
|---|---|---|---|
| assignee | string|null | – | Assignee username or email. Pass an empty string to unassign. 'agent:<role>' (e.g. 'agent:product') hands the issue to that agent instead: you become the assignee and the agent works on your behalf —… |
| description | string|null | – | New description. Markdown, with $…$ / $$…$$ LaTeX formulas and [~username] mentions. |
| detachParent | boolean | – | Take this issue out from under its parent and leave it top-level. The reliable way to detach: unlike an empty parentKey it cannot arrive as the two characters "" or be dropped as «nothing was sent».… |
| dueDate | string|null | – | The day this is due, as YYYY-MM-DD. A calendar day, not a timestamp. Pass an empty string to clear it. |
| fields | string|null | – | The project's own columns to fill in with this update, by their NAMES: 'Segment=AI; Country=Poland', or a JSON object. Same shape as set_issue_fields — this exists here because a move a workflow cond… |
| key | string | yes | Issue key, e.g. 'UK-1'. |
| labels | string|null | – | Labels to set, space or comma separated. Replaces the existing set. |
| parentKey | string|null | – | Key of the issue this one hangs off, e.g. 'PM-276' — moves it under that story or epic. To DETACH it instead, send detachParent: true; an empty string still works but is easy to lose on the way. Noth… |
| priority | string|null | – | Priority name, e.g. 'High'. |
| resolution | string|null | – | Resolution name to set, e.g. 'Fixed', 'Won't Do'. Some workflows require one on the move into a finished state; sending it here is how that condition is met. |
| status | string|null | – | Status name to move the issue to, e.g. 'In Progress', 'Done'. |
| summary | string|null | – | New summary (title). |
| type | string|null | – | New issue type name, e.g. 'Task', 'Bug', 'Story', 'Epic'. |
No output schema declared.
No examples provided.
update_project_rule ~731
Change a project rule, by its id from list_project_rules. Only what you pass changes: pass just 'enabled' to switch a rule on or off, or any of the others to edit it. An empty string for 'type' or 'label' removes that condition; for a duty, an empty 'status', 'agentActions', 'agentFields' or 'doneStatus' clears that one. A rule's action cannot change. A rule appends its checklist to an issue's description when the issue ENTERS the rule's state — from the board, the Jira API or update_issue alike. The block starts with a hidden marker line '[//]: # (pm-rule:<id>)'; while that line is in the description, entering the state again adds nothing (the journal says 'alreadyThere'). A [~username] in the template is a mention: that person is notified when the checklist lands. A checklist that would make the description too long is not added and the journal says 'tooLong'; the move itself still happens. A rule with action 'agent' is a DUTY instead: it says which issues may be handed to an agent role (agentRole, e.g. 'product') and what the agent may do with them. Its 'template' is then the INSTRUCTION — what doing such an issue means in this project — and nothing is appended anywhere. A duty may have no state (pass an empty 'status'): then an issue is handed only by a person. agentActions is a list from: describe, subtasks, ask, wiki, report, support. agentFields names the fields it may set: priority, labels, duedate, or the project's own fields by name. doneStatus is the state it moves the issue to when done — never a finished one. capUsd raises what one task may cost, up to 5 dollars. Commenting is always allowed; finishing, deleting, reassigning and anything outside the issue never are. Saving or switching on a duty makes it yours: it runs on your behalf and access, and is switched off if you lose the project. Project lead or admin only.
| Name | Type | Req | Description |
|---|---|---|---|
| agentActions | string|null | – | For a duty: the whole new list of actions, comma-separated. |
| agentFields | string|null | – | For a duty: the whole new list of fields, comma-separated. |
| agentRole | string|null | – | For a duty: a new agent role key. |
| capUsd | number|null | – | For a duty: what one task may cost, in dollars, at most 5; 0 goes back to the ordinary ceiling. |
| doneStatus | string|null | – | For a duty: a new review state; an empty string and it no longer moves the issue. |
| enabled | boolean|null | – | true to switch the rule on, false to switch it off. |
| id | integer | yes | The rule's id, from list_project_rules. |
| label | string|null | – | Only issues with this label. An empty string means any label. |
| name | string|null | – | A new name. |
| projectKey | string | yes | Project key, e.g. 'ONB'. |
| status | string|null | – | A new state to fire on, by name. |
| template | string|null | – | A new checklist template (Markdown). Replaces the old one for issues that enter the state from now on; checklists already added stay as they are. |
| type | string|null | – | Only issues of this type, by name. An empty string means any type. |
No output schema declared.
No examples provided.
update_wiki_comment ~494
Edit a comment on a wiki page — your own, or anyone's with full write access in that project. Read it first with get_wiki_page(withMarkdown: true), which gives each comment its 'markdown' and 'version'. Pass 'markdown' to replace the whole comment, or 'edits' to change part of it (exact find-and-replace on that Markdown, each 'oldText' occurring exactly once) — the answer then says where each landed, not the comment. An inline comment's anchor moves with 'inlineSelection': the page text it should point at, copied exactly; an empty string turns it into an ordinary footer comment, which is the only way it ever stops being anchored. Mention someone as [@Their Name](user:username), the wiki's own form. Answers with 'notified' — only the people the *edit* newly reaches, since names already in the old text are not notified again and the page is not re-announced to its watchers.
| Name | Type | Req | Description |
|---|---|---|---|
| commentId | integer | yes | The comment's id, as get_wiki_page lists it or add_wiki_comment returned. |
| edits | array|null | – | Exact replacements in the comment's Markdown — the text get_wiki_page returns as a comment's 'markdown'. Every 'oldText' is matched against it as you read it (not against the result of the other edit… |
| expectedVersion | integer|null | – | The version you read (from get_wiki_page). If the comment has moved on since, the edit is refused instead of overwriting somebody else's. |
| inlineMatch | integer|null | – | Which occurrence of 'inlineSelection' on the page to anchor to, counted from 1. Only needed when the text occurs more than once. |
| inlineSelection | string|null | – | Move the inline anchor: the page text this comment should point at, copied exactly from the page. An empty string detaches it, making it a footer comment. Refused when the page does not carry that te… |
| markdown | string|null | – | The whole comment, replacing what is there. Markdown, which also carries $…$ / $$…$$ LaTeX formulas. |
No output schema declared.
No examples provided.
update_wiki_page ~783
Edit a wiki page: retitle it, change its body, move it under another parent (or to the top of its space), or set its labels. Identify it by 'id', or by 'spaceKey' + 'title'. To change part of the body, pass 'edits' (exact find-and-replace on the Markdown source, each 'oldText' occurring exactly once) or 'replaceSection' — the answer says where each landed, not the page, so a one-line fix to a long page costs one line. 'markdown' replaces the whole body — read it first with get_wiki_page(withMarkdown: true) and edit that, or the page's links, images and macros are dropped; 'appendMarkdown' adds to the end and leaves what is there untouched. Mention someone as [@Their Name](user:username), the wiki's own form. Requires permission to edit the page. Answers with 'notified' (who this actually reaches) and 'unresolvedMentions' (what looked like a mention and reached nobody, each with a reason) — a wrong handle is stored as written and never refused, so that list is the only sign it did not land.
| Name | Type | Req | Description |
|---|---|---|---|
| appendMarkdown | string|null | – | Markdown to add to the end of the page, leaving the rest as it is. Same syntax as 'markdown'. |
| edits | array|null | – | Exact replacements in the page's Markdown source — the text get_wiki_page returns with 'section', 'offset' or withMarkdown: true. Every 'oldText' is matched against the page as you read it (not again… |
| expectedVersion | integer|null | – | The version you read (from get_wiki_page). If the page has moved on since, the edit is refused instead of overwriting someone else's. |
| id | integer|null | – | Page id (as returned by search_wiki). |
| labels | string|null | – | Labels to set, space or comma separated. Replaces the existing set. |
| markdown | string|null | – | The complete new body as Markdown — replaces what is there. Carries $…$ / $$…$$ LaTeX formulas and the wiki's macros on a line of their own ({toc}, {children}, {info} … {info}, {expand:title=…} … {ex… |
| message | string|null | – | Short note for the page history, e.g. why you changed it. |
| minorEdit | boolean | – | Mark this as a minor edit in the history. |
| newTitle | string|null | – | New title. The page's existing links follow the rename. |
| parentId | integer|null | – | Move the page under this parent page id. |
| parentTitle | string|null | – | Move the page under the page with this title, in the same space. |
| replaceSection | object|null | – | Replace one whole section: 'section' names it as get_wiki_page's 'section' does (anchor or heading text), 'markdown' is what replaces it — heading line included, as reading the section returned it. C… |
| spaceKey | string|null | – | Space key, when identifying the page by title. |
| title | string|null | – | Current page title, when identifying the page by title. |
| toTopLevel | boolean | – | Move the page to the top of its space, out from under any parent, so it sits beside the space's other root pages. Use this instead of parentId/parentTitle — a tool argument has no way to say 'no pare… |
No output schema declared.
No examples provided.
upsert_mcp_connection ~162
Admin only: create or update a project's external MCP connection. Pass 'id' to update an existing one (omit to create). 'token' is stored server-side and never returned; omit it to keep the current token when updating.
| Name | Type | Req | Description |
|---|---|---|---|
| enabled | boolean|null | – | Whether the connection is enabled. |
| id | integer|null | – | Existing connection id to update; omit to create a new one. |
| name | string|null | – | Connection display name (required when creating). |
| projectKey | string | yes | Project key, e.g. 'UK'. |
| token | string|null | – | Bearer auth token. Omit to keep the current token when updating. |
| url | string|null | – | MCP server URL — use https (required when creating). |
No output schema declared.
No examples provided.
withdraw_issue_question ~94
Take back a question you asked, when it no longer needs answering — you worked it out, or the task moved on. The comment stays in the thread (the conversation happened) and the question stops counting on the other person's list. The person who asked, or anybody with full write access in the project.
| Name | Type | Req | Description |
|---|---|---|---|
| questionId | integer | yes | The question's id, as returned by list_issue_questions or ask_issue_question. |
No output schema declared.
No examples provided.
What is the Kaiku MCP server?
Kaiku is an MCP server listed in the public MCP registry as tech.kaiku/kaiku. Issue tracker and wiki for teams and their agents: find, file and update issues, write pages. This page covers its hosted endpoint (https://mcp.kaiku.tech/mcp).
Is the Kaiku MCP server safe to use?
Kaiku scores 74 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the Kaiku MCP server expose?
Kaiku exposes 74 tools: add_attachment, add_comment, add_wiki_attachment, add_wiki_comment, admin_bank_transfer, and 69 more. Their descriptions and schemas cost roughly 18,469 tokens of context every time the server is loaded.
Does the Kaiku MCP server require authentication?
Yes. Kaiku asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.
Is the Kaiku MCP server still maintained?
Kaiku is still listed as active in the MCP registry. We last reached this channel on 23 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.