DocsAI assistants
MCP tools reference
Every tool the Idea Bucket MCP server gives your assistant, with parameters, limits and example results, plus the REST endpoints for access keys.
On this page
This page lists every tool a connected assistant can use, what each one takes and what it returns. You don't need it to use a connector: the assistant picks the tools itself. It's handy when you want to know what an assistant can see, or you're building your own client. To connect an assistant, see Connect your AI.
How tools answer
- The server is at
https://ideabucket.app/mcp(MCP over Streamable HTTP). Sign in with OAuth, or send an access key asAuthorization: Bearer ib_…. - Every tool works only with your own ideas. Ideas in the trash are never shown.
- A successful call returns one text block holding JSON, like the examples below. A failed call returns a short plain-text message marked as an error, for example
No idea found with id …. - Tags are sent without the
#. A leading#is removed and tags are lowercased, so#Gardenandgardenmean the same tag. New tags must be single words of letters, numbers,-and_. - Ids are idea and note UUIDs, as returned by the other tools.
- Dates are ISO 8601 timestamps.
Ideas in results
Most tools describe ideas the same way:
| Field | Meaning |
|---|---|
id |
The idea's id. |
content |
The idea text, without its tags. |
tags |
The idea's tags, without #. |
created_at |
When it was dropped. |
archived |
true if the idea is archived. |
archived_by |
Only on archived ideas: you, assistant or automation. |
has_notes |
In lists: whether the idea has any notes. |
notes_count |
In lists, where known: how many notes it has. |
Usage limits
Some tools use Idea Bucket's AI service and count toward your hourly allowance, shared with the app:
| Allowance | Per hour | Used by |
|---|---|---|
| Search and indexing | 600 | search_ideas, add_idea, update_idea (only when the text changes), and POST /mcp/drop |
| Tag summaries | 60 | get_tag_context, only when it writes a new summary |
Over the limit, the tool fails with a message like Hourly limit reached for search and indexing, try again later. See Limits and privacy.
Reading tools
search_ideas
Searches your ideas by meaning and keywords, like Find, best matches first. Notes are searched too. Searches active ideas unless you ask for the archive.
| Parameter | Type | Required | Default | Limits |
|---|---|---|---|---|
query |
string | yes | 1 to 1000 characters | |
tags |
array of strings | no | Up to 20. Only ideas carrying all of these tags. | |
limit |
integer | no | 10 | 1 to 50 |
archived |
boolean | no | false |
true searches the archive instead |
Returns the search mode (semantic, or keyword when meaning search isn't available), a count and the ideas, each with a relevance score.
{
"mode": "semantic",
"count": 1,
"ideas": [
{
"id": "7c0e5a52-4f1e-4d0a-9a51-2b7f0c3d9e10",
"content": "Interview a beekeeper for the next episode",
"tags": ["podcast"],
"created_at": "2026-09-14T08:12:44.000Z",
"archived": false,
"has_notes": true,
"score": 0.734
}
]
}list_recent_ideas
Lists your most recently added ideas, newest first, optionally only those with one tag. With archived: true it lists the archive instead, most recently archived first.
| Parameter | Type | Required | Default | Limits |
|---|---|---|---|---|
limit |
integer | no | 10 | 1 to 50 |
tag |
string | no | One tag, without the # |
|
archived |
boolean | no | false |
true lists the archive instead |
{
"count": 1,
"ideas": [
{
"id": "1d2b3c4d-5e6f-4a1b-8c9d-0e1f2a3b4c5d",
"content": "Plant garlic along the south fence",
"tags": ["garden"],
"created_at": "2026-09-30T17:05:10.000Z",
"archived": false,
"has_notes": false,
"notes_count": 0
}
]
}get_idea
Fetches one idea by id, archived or not, with its notes thread, oldest first. Reading an idea this way counts as opening it, for "hasn't been opened" automations.
| Parameter | Type | Required | Default | Limits |
|---|---|---|---|---|
id |
string (UUID) | yes |
Each note has:
| Field | Meaning |
|---|---|
id |
The note's id, for edit_note. |
body |
The note, in Markdown. |
author |
Who wrote it: you for your own notes, otherwise the assistant's name (or the access key's name). Automations may sign notes too. |
author_kind |
user or assistant. |
created_at, updated_at |
When it was written and last changed. |
edited |
true if it was changed after it was written. |
yours |
true if the calling assistant wrote it, so it may edit it. |
If the idea was sent to a coding agent, agent_runs lists those runs, newest first: status is awaiting (waiting for your approval), queued or running (being sent), done (sent, with the agent's run_uuid), failed (with error) or skipped (with reason). decided_by says who approved it: you, or assistant:<name>.
{
"id": "7c0e5a52-4f1e-4d0a-9a51-2b7f0c3d9e10",
"content": "Interview a beekeeper for the next episode",
"tags": ["podcast"],
"created_at": "2026-09-14T08:12:44.000Z",
"archived": false,
"notes_count": 1,
"notes": [
{
"id": "b8f1c2d3-4e5f-4a6b-9c7d-8e9f0a1b2c3d",
"body": "Shortlist: two local keepers. Ask about winter losses.",
"author": "Claude",
"author_kind": "assistant",
"created_at": "2026-09-15T10:00:00.000Z",
"updated_at": "2026-09-15T10:00:00.000Z",
"edited": false,
"yours": true
}
]
}list_tags
Lists every tag with how many ideas carry it, most used first, and the color you gave it in the app, if any (blue, teal, green, amber, orange, red, pink or violet). Tags whose ideas are all archived are often finished projects. Takes no parameters.
{
"ideas": 182,
"archived_ideas": 64,
"count": 2,
"tags": [
{ "tag": "podcast", "open": 21, "archived": 9, "total": 30, "color": "violet" },
{ "tag": "garden", "open": 12, "archived": 3, "total": 15 }
]
}ideas is the number of active ideas in your bucket and archived_ideas the number archived. For each tag, open counts active ideas.
get_tag_context
Everything about one tag, treated as a project or topic, in one call: what it is, what shipped, what's open, recent activity and related tags. Archived ideas are included, as the project's changelog. Read-only, apart from caching the summary.
| Parameter | Type | Required | Default | Limits |
|---|---|---|---|---|
tag |
string | yes | 1 to 101 characters, without the # |
|
limit |
integer | no | 12 | 1 to 30. How many ideas to list in recent, changelog and open. |
refresh |
boolean | no | false |
true writes a new summary even when the saved one is current |
If no idea carries the tag, the call fails with No ideas carry #<tag>.
Status: open, done and closed
Each idea gets a status:
- open: not archived.
- done: archived, and it carries a likely done marker.
- closed: archived without a done marker. It may have shipped or been dropped.
Likely done markers
No tag means "done" by default, not even #done. Idea Bucket infers done markers from how you archive, and lists each one with its evidence in likely_done_markers. A tag is a likely done marker when either:
- an enabled automation archives ideas that get that tag (On #shipped → Archive), or
- all three of these hold, across your whole bucket:
- at least 3 ideas carry the tag;
- at least 80% of them are archived;
- that share is at least 25 percentage points higher than the archive rate of ideas with your other tags.
Only markers found on this tag's ideas are reported, and nothing is written back to your ideas. Marker tags are left out of related_tags.
The summary
summary has what_it_is (one or two sentences) and four lists: shipped, open, themes and open_questions. Each list holds up to 6 items, each with text and the ids of the ideas it rests on.
- Written by AI from the tag's newest 80 ideas and their latest notes (
source: "ai"), withgenerated_atandmodel. - Template for tags with 2 ideas or fewer: their titles stand in (
source: "template"). These don't count toward the summary allowance. - Cached. The summary is saved and reused (
cached: true) until something about the tag's ideas changes: an idea is added, edited, archived, restored, noted or trashed, or the done markers change. The next call then writes a new one.refresh: trueforces a new one. - If a new summary can't be written (for example over the hourly limit), everything else still comes back, with
summary_errorexplaining why. The last saved summary is returned markedstale: true, orsummaryisnullif there isn't one.
Other fields
| Field | Meaning |
|---|---|
counts |
total, open, archived, done and closed. |
first_activity, last_activity |
When the tag's first idea was dropped, and its latest change. |
recent |
Latest changes, newest first: id, title, status, at and why (new, edited, new note, archived or shipped). |
changelog |
Archived ideas, most recently archived first: total and items (id, title, archived_at, archived_by, status, markers). |
open |
Active ideas: total and items (id, title, other tags, last_change, notes_count). |
related_tags |
Up to 8 tags found on the same ideas: together (how many ideas share both) and, where known, that tag's ideas, archived and open counts. |
likely_done_markers |
Each marker's tag and evidence. |
agent_runs |
Recent hand-offs of this tag's ideas to a coding agent (up to 10), as in get_idea. |
truncated |
Only for tags with more than 5000 ideas: counts and lists cover the newest 5000. |
more |
Suggested follow-up calls for the full archive, open ideas, one idea or a related tag. |
{
"tag": "podcast",
"counts": { "total": 30, "open": 21, "archived": 9, "done": 6, "closed": 3 },
"first_activity": "2026-03-02T09:00:00.000Z",
"last_activity": "2026-09-30T18:20:00.000Z",
"summary": {
"what_it_is": "A weekly interview podcast about local food.",
"shipped": [{ "text": "Season one recorded and released.", "ids": ["3f6a…"] }],
"open": [{ "text": "Book guests for season two.", "ids": ["7c0e…"] }],
"themes": [],
"open_questions": [],
"source": "ai",
"cached": true,
"generated_at": "2026-09-30T18:21:05.000Z",
"model": "…"
},
"recent": [
{ "id": "7c0e…", "title": "Interview a beekeeper for the next episode", "status": "open", "at": "2026-09-30T18:20:00.000Z", "why": "new note" }
],
"changelog": { "total": 9, "items": [ { "id": "3f6a…", "title": "Release season one", "archived_at": "2026-08-01T12:00:00.000Z", "archived_by": "you", "status": "done", "markers": ["shipped"] } ] },
"open": { "total": 21, "items": [ { "id": "7c0e…", "title": "Interview a beekeeper for the next episode", "tags": [], "last_change": "2026-09-30T18:20:00.000Z", "notes_count": 1 } ] },
"related_tags": [{ "tag": "garden", "together": 2, "ideas": 15, "archived": 3, "open": 12 }],
"likely_done_markers": [{ "tag": "shipped", "evidence": "14 of 15 ideas with #shipped are archived (22% of ideas with other tags)" }],
"more": { "archived": "list_recent_ideas({\"tag\": \"podcast\", \"archived\": true, \"limit\": 50})", "…": "…" }
}Writing tools
add_idea
Saves a new idea. Assistants are told to use it only when you ask to save something. Inline #hashtags in the text become tags and are removed from the text, as in the app.
| Parameter | Type | Required | Default | Limits |
|---|---|---|---|---|
content |
string | yes | 1 to 10,000 characters. Must contain some text besides tags. | |
tags |
array of strings | no | Up to 20 extra tags, without the # |
{
"saved": true,
"idea": {
"id": "1d2b3c4d-5e6f-4a1b-8c9d-0e1f2a3b4c5d",
"content": "Plant garlic along the south fence",
"tags": ["garden"],
"created_at": "2026-09-30T17:05:10.000Z",
"archived": false
}
}update_idea
Changes an existing idea, only when you ask: its text, its tags, or whether it's archived. Pass at least one of content, add_tags, remove_tags or archived. Tags you don't mention are kept.
| Parameter | Type | Required | Default | Limits |
|---|---|---|---|---|
id |
string (UUID) | yes | ||
content |
string | no | 1 to 10,000 characters. Inline #hashtags are added as tags. |
|
add_tags |
array of strings | no | Up to 20. Existing tags are kept. | |
remove_tags |
array of strings | no | Up to 20. Other tags are kept. | |
archived |
boolean | no | true archives the idea, false restores it |
A tag can't be in both add_tags and remove_tags. An idea archived this way is marked as archived by an assistant.
Returns updated (false when nothing actually changed, for example archiving an idea that's already archived), the idea, and tag_changes when tags were involved: added, removed and not_found (tags you asked to remove that the idea didn't have).
{
"updated": true,
"idea": {
"id": "1d2b3c4d-5e6f-4a1b-8c9d-0e1f2a3b4c5d",
"content": "Plant garlic along the south fence",
"tags": ["garden", "autumn"],
"created_at": "2026-09-30T17:05:10.000Z",
"archived": false,
"has_notes": false,
"notes_count": 0
},
"tag_changes": { "added": ["autumn"], "removed": [], "not_found": [] }
}add_note
Adds a note to an idea: a short Markdown summary of what you and the assistant discussed, such as decisions, next steps or links. You see it in the idea's notes, signed with the assistant's name (or the access key's name). Assistants are asked to read the existing notes with get_idea first and add one note per conversation or topic.
| Parameter | Type | Required | Default | Limits |
|---|---|---|---|---|
idea_id |
string (UUID) | yes | ||
body |
string | yes | 1 to 20,000 characters, Markdown |
{
"saved": true,
"note": {
"id": "b8f1c2d3-4e5f-4a6b-9c7d-8e9f0a1b2c3d",
"body": "Shortlist: two local keepers. Ask about winter losses.",
"author": "Claude",
"author_kind": "assistant",
"created_at": "2026-09-15T10:00:00.000Z",
"updated_at": "2026-09-15T10:00:00.000Z",
"edited": false,
"yours": true
}
}edit_note
Replaces the text of a note the same assistant wrote earlier (yours: true in get_idea). An assistant can't edit your notes or another assistant's, and no tool deletes notes: only you can, in the app.
| Parameter | Type | Required | Default | Limits |
|---|---|---|---|---|
note_id |
string (UUID) | yes | A note this assistant wrote | |
body |
string | yes | 1 to 20,000 characters, the full new text in Markdown |
Returns updated (false if the text was the same) and the note, shaped as in add_note.
dispatch_to_agent
Sends an idea to your coding agent (Grok Bot) through a Dispatch Grok Bot automation, so the agent starts building it. Assistants are told to use it only when you explicitly ask. It approves the dispatch on your behalf, signed with the assistant's name. See Grok Bot dispatch.
| Parameter | Type | Required | Default | Limits |
|---|---|---|---|---|
idea_id |
string (UUID) | yes | ||
rule_id |
string (UUID) | no | Which Dispatch Grok Bot rule to use, when you have several turned on |
- With no Dispatch Grok Bot rule turned on, it fails and says to set one up under Automations.
- With several rules turned on and no
rule_id, it sends nothing and returns the rules to choose from (rule_id,tagand the start of the rule's instruction). - One dispatch per idea and rule: an idea sent before stays sent. You can Retry it in the app.
{
"dispatched": true,
"status": "queued",
"run_id": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
"rule": { "id": "0f1e2d3c-4b5a-4968-8776-655443322110", "tag": "build" },
"decided_by": "assistant:Claude",
"message": "Sent to the agent. In a few seconds get_idea shows the run_uuid and a \"Sent to Grok Bot\" note; the agent reports back with notes and tags."
}status is one of queued, running, done (sent earlier), failed (an earlier dispatch failed) or skipped.
REST endpoints
Two plain HTTP endpoints sit next to the MCP server for simple clients, like the iPhone and Mac apps' extras or your own scripts and shortcuts. They accept only an access key, not an assistant's sign-in.
POST /mcp/drop
Drops a new idea, as if you'd typed it. Inline #tags become tags.
curl -X POST https://ideabucket.app/mcp/drop \
-H "Authorization: Bearer ib_your_key_here" \
-H "Content-Type: application/json" \
-d '{"content": "Try a cold-brew stall at the market #garden"}'| Field | Type | Required | Notes |
|---|---|---|---|
content |
string | yes | Up to 10,000 characters, with some text besides tags |
source |
object | no | Where the idea came from (see below) |
source records where the idea came from. It must include app, and may include url, title and bundle_id. Other fields are refused.
| Field | Limit |
|---|---|
app |
Required, up to 100 characters, for example "Safari" |
bundle_id |
Up to 200 characters |
url |
Up to 2000 characters, starting http:// or https:// |
title |
Up to 300 characters; kept only together with a url |
{
"content": "Read this later #reading",
"source": { "app": "Safari", "url": "https://example.com/article", "title": "An article" }
}On success it returns 201 with the new idea's id:
{ "id": "1d2b3c4d-5e6f-4a1b-8c9d-0e1f2a3b4c5d" }GET /mcp/random
Returns one random active idea (never archived or trashed), or null if your bucket is empty.
curl https://ideabucket.app/mcp/random \
-H "Authorization: Bearer ib_your_key_here"{
"idea": {
"id": "7c0e5a52-4f1e-4d0a-9a51-2b7f0c3d9e10",
"content": "Interview a beekeeper for the next episode",
"tags": ["podcast"],
"created_at": "2026-09-14T08:12:44.000Z"
}
}Errors
Errors come back as JSON with an error message.
| Status | When | Example body |
|---|---|---|
400 |
Not JSON, no content, content too long or only tags, or an invalid source |
{"error": "content is required."} |
401 |
Missing, unknown or revoked access key | {"error": "invalid_key"} |
405 |
Wrong method (drop needs POST, random needs GET) |
{"error": "method_not_allowed"} |
429 |
Over the hourly search and indexing allowance (drop only) |
{"error": "Hourly limit reached for search and indexing, try again later"} |
500 |
Something went wrong saving or loading; try again | {"error": "Could not save the idea. Please try again."} |