Posts MCP Tools
Three read-only tools give an AI client (Claude Desktop, Claude Code, or any MCP-speaking assistant) visibility into a workspace's post pipeline — list posts, fetch one, or get pipeline counts. There is currently no MCP tool to create, edit, or transition a post; use the REST API or the app UI for writes.
For the underlying business rules, see Features — Posts.
This page is based on specs/mcp/posts.md in the repo — see that spec for
the exact JSON shapes and DynamoDB access pattern behind each tool.
Access model
Every tool call is scoped to a workspace_id and enforces membership the
same way the REST API does — a direct DynamoDB lookup on
WS#{workspace_id} / MEMBER#{user_id}. If the authenticated MCP user
isn't a member, the tool raises and the client sees a tool error, not an
empty result.
All three tools return a JSON string, not a structured object — parse
it before use. This is consistent across all lkwiz_mcp post tools.
Tools
| Tool | Parameters | Description |
|---|---|---|
list_posts | workspace_id, status? | List posts in a workspace, optional status filter |
get_post | post_id, workspace_id | Fetch one post's content and metadata |
get_pipeline_status | workspace_id | Count posts per pipeline status |
list_posts
list_posts(workspace_id: str, status: str = "") -> strReturns every post under the workspace, optionally filtered to an exact
status match ("draft", "in_review", "approved", "scheduled",
"published", "archived", or "revision_requested" — the filter accepts
any of these; see the note on get_pipeline_status below for why one of
them doesn't show up in the counts tool).
{
"posts": [
{
"post_id": "post_abc",
"workspace_id": "ws_123",
"idea_id": "",
"title": "Why observability matters",
"content": "<p>...</p>",
"status": "draft",
"scheduled_at": "",
"created_at": "2026-07-11T10:00:00+00:00",
"updated_at": "2026-07-11T10:00:00+00:00"
}
]
}The idea_id field is always "" in practice — posts are stored with a
source_idea_id attribute, not idea_id, so this projection never finds
a value to read. Look up the post's linked idea via the REST API
(GET /api/posts/{id}, field source_idea_id) instead.
get_post
get_post(post_id: str, workspace_id: str) -> strReturns a single post (same shape as one item in list_posts's posts
array, but as the top-level object — not wrapped). Raises if the post
doesn't exist in that workspace.
get_pipeline_status
get_pipeline_status(workspace_id: str) -> strThe MCP equivalent of the kanban board's column headers — how many posts are in each stage.
{
"workspace_id": "ws_123",
"pipeline": {
"draft": 3,
"in_review": 1,
"approved": 2,
"scheduled": 1,
"published": 5,
"archived": 0
}
}revision_requested posts are not counted here — the counter map only
has the six keys shown above. A post in revision_requested is fetched
from DynamoDB along with everything else, but silently skipped when
tallying because its status string isn't one of the map's keys. If you
need a revision_requested count, use list_posts(status="revision_requested")
and count the results yourself.