Features
MCP Server & Agent Tools

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 / S3

Because 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 → Authenticate

Claude 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:

DomainToolsDocs
Workspaceslist_workspacesWorkspaces MCP tools
Ideaslist_ideas, create_idea, update_ideaIdeas MCP Tools
Postslist_posts, get_post, get_pipeline_statusPosts MCP Tools
GenAIgenerate_post, iterate_postGenAI MCP Tools
Scheduleget_schedulesee note below
Actionslist_actions, create_actionActions MCP Tools
Promptslist_promptsPrompts MCP Tools
Exampleslist_examplesExamples MCP Tools
Adminadmin_list_users, admin_approve_userAdmin 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:

  • Ideascreate_idea over MCP stores your title argument literally; the web app and REST API instead run it through Bedrock to generate a short title from your raw text. update_idea over MCP accepts any status string with no transition validation, unlike the REST API's new → converted-only rule.
  • Adminadmin_approve_user over 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 Cognito custom:approved claim — a half-approved state that looks fine in a DynamoDB scan but isn't functionally complete.
  • Actionscreate_action over MCP doesn't validate the assignee is a workspace member, and sends no Slack notification (the REST path does both).
  • Promptslist_prompts over 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