MCP Server & Agent Tools
lk-wiz exposes a subset of its functionality to AI agents — Claude Code, Claude Desktop, or any other MCP-speaking client — through a hosted Model Context Protocol (MCP) server. Connect once, authenticate with the same account you use in the web app, and an agent can list your ideas, draft and iterate on posts with Bedrock, check the pipeline, and more, without you leaving your terminal or chat client.
This page is the architectural big picture. For the full authentication story and
a walkthrough of connecting a client, see MCP Overview,
MCP Authentication, and Client Setup.
For the exact parameters, return shapes, and error cases of every tool, see the
per-domain pages linked in Tool families below (or the
Tool Catalog). The authoritative spec behind this page is
specs/features/mcp.md in the repo.
How it's hosted
The server isn't a Lambda function and isn't a plain always-on box — it runs as a container on Amazon Bedrock AgentCore, which splits into two pieces:
Claude Code / Claude Desktop
│ Bearer <Cognito access token>, streamable-HTTP (no mcp-remote proxy)
▼
AgentCore Gateway ── public endpoint, RFC 9728 + OAuth 2.1 discovery
│
▼
Interceptor Lambda ── pass-through, forwards your Authorization header
│
▼
AgentCore Runtime ── hosts the FastMCP container, validates the JWT itself too
│
▼
FastMCP tool (ideas, posts, genai, schedule, actions, prompts, examples, admin, workspaces)
│
▼
DynamoDB / Bedrock / S3Because AgentCore Gateway speaks RFC 9728 (Protected Resource Metadata) and MCP OAuth 2.1 natively, connecting is just:
tofu output lkwiz_mcp_gateway_url
claude mcp add --transport http lkwiz <gateway-url>
# In Claude Code: /mcp → select lkwiz → AuthenticateClaude Code opens the Cognito Hosted UI in your browser, you log in exactly like you would to the web app, and the client stores the resulting token for you.
Authentication & who can use it
Both AgentCore layers (Gateway and Runtime) independently validate the caller's
Cognito access token. Then, inside the container itself, the tool-facing
middleware (lkwiz_mcp.auth.middleware) does a third check: it re-verifies the
token's RS256 signature against Cognito's JWKS endpoint, reads the sub claim, and
looks up USER#{sub}/PROFILE in DynamoDB — the exact same lookup the backend HTTP
API does for the web app. Only approved, registered users can successfully call
any tool; everyone else gets an authentication error at the first tool call.
The container's own JWT check is a genuine RS256/JWKS signature verification, not a
pass-through trust of the Gateway's earlier check — despite what some existing
onboarding notes for this server say. If you're relying on documentation that
describes the container as skipping signature validation "because the Gateway
already did it," treat that as outdated: see the "Authentication & identity"
section of specs/features/mcp.md for the accurate version, grounded directly in
services/mcp/src/lkwiz_mcp/auth/middleware.py.
Once authenticated, every tool call carries the caller's identity: user_id,
user_email, user_name, and a platform role (member or admin) read from
their profile — the same role the web app's admin console uses.
Tool families
Nine tool modules are registered on the server. Each is documented in full on its own page — parameters, exact response JSON, and every known behavioral quirk:
| Domain | Tools | Docs |
|---|---|---|
| Workspaces | list_workspaces | Workspaces MCP tools |
| Ideas | list_ideas, create_idea, update_idea | Ideas MCP Tools |
| Posts | list_posts, get_post, get_pipeline_status | Posts MCP Tools |
| GenAI | generate_post, iterate_post | GenAI MCP Tools |
| Schedule | get_schedule | see note below |
| Actions | list_actions, create_action | Actions MCP Tools |
| Prompts | list_prompts | Prompts MCP Tools |
| Examples | list_examples | Examples MCP Tools |
| Admin | admin_list_users, admin_approve_user | Admin MCP Tools |
A dedicated Schedule tools page doesn't exist yet — get_schedule is fully
implemented and callable today (services/mcp/src/lkwiz_mcp/tools/schedule.py),
it just isn't written up on its own page. Until that page lands, treat the source
file as ground truth: get_schedule(workspace_id, weeks=2) returns the workspace's
upcoming scheduled posts within the given window (default: next two weeks).
Every one of these tool families is a subset of what the REST API and web app can do for the same domain — there's no idea deletion, no workspace creation or membership management, no action status updates, no prompt or example editing, and so on. Think of MCP as an agent-friendly capture-and-check surface layered on top of the product, not a full programmatic replacement for the REST API.
Same logic as the API? Read this before you trust it
The goal is for MCP tools and REST endpoints to implement identical business logic against the same data, so an agent and a human see the same thing. That goal is only partially achieved today.
Every workspace-scoped tool module talks to DynamoDB directly with the raw AWS SDK
client, independently of the backend's own service layer (ideas_service,
actions_service, prompts_service, and so on). That's a deliberate architectural
choice for the MCP server, but it has a real consequence: the two surfaces have
drifted apart in ways that are easy to miss if you assume parity. A few examples
that matter if you're scripting against both:
- Ideas —
create_ideaover MCP stores yourtitleargument literally; the web app and REST API instead run it through Bedrock to generate a short title from your raw text.update_ideaover MCP accepts any status string with no transition validation, unlike the REST API'snew → converted-only rule. - Admin —
admin_approve_userover MCP only flips a DynamoDB flag. It does not call Cognito the way the REST endpoint does, so a user approved solely through this tool cannot actually authenticate anywhere that checks the Cognitocustom:approvedclaim — a half-approved state that looks fine in a DynamoDB scan but isn't functionally complete. - Actions —
create_actionover MCP doesn't validate the assignee is a workspace member, and sends no Slack notification (the REST path does both). - Prompts —
list_promptsover MCP returns every prompt in the workspace; the REST endpoint scopes results to prompts the caller created.
If you're building agent automation that also touches the REST API for the same
domain, read that domain's Deviations from REST section (linked from each page
in the table above) before assuming a fix or behavior on one side has landed on
the other. A change to ideas_service.py does not automatically reach
tools/ideas.py, and vice versa.
Access control in one sentence
Any workspace member — owner, editor, or viewer alike — can currently call any
workspace-scoped MCP tool; only the two admin tools additionally require the
caller's platform role to be admin. If you were expecting the same
owner/editor/viewer distinctions the web app enforces in some flows to also gate MCP
tool calls, they currently don't — every MCP tool's authorization check stops at
"are you a member of this workspace at all."
See also
- MCP Overview · MCP Authentication · Tool Catalog · Client Setup
- Per-domain tool pages: Workspaces, Ideas, Posts, GenAI, Actions, Prompts, Examples, Admin
specs/features/mcp.md— the full spec this page summarizes, including the request-path diagram through AgentCore Gateway/Interceptor/Runtime and the complete configuration and observability reference- API Reference — the REST surface each MCP tool is compared against