AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Litestar Mcp

skill-litestar-org-litestar-skills-litestar-mcp · by litestar-org

Auto-activate for litestar_mcp, LitestarMCP, MCPConfig, MCPAuthConfig, MCPAuthBackend, mcp_tool=, mcp_resource=, Streamable HTTP, or OIDC MCP endpoints. Not for non-Litestar MCP.

No reviews yet
0 installs
32 views
0.0% view→install

Install

$ agentstack add skill-litestar-org-litestar-skills-litestar-mcp

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-litestar-org-litestar-skills-litestar-mcp)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Litestar Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

litestar-mcp

litestar-mcp exposes explicitly marked Litestar route handlers as Model Context Protocol (MCP) tools, resources, and prompts over MCP Streamable HTTP and JSON-RPC 2.0.

Mark routes by passing mcp_tool="name", mcp_resource="name", or mcp_prompt="name" directly to the Litestar route decorator — Litestar funnels unknown kwargs into handler.opt, so no opt={...} wrapper is needed. The @mcp_tool / @mcp_resource / @mcp_prompt decorators (importable from litestar_mcp) still exist and are worth reaching for when you need the extra fields they expose — output_schema, annotations, scopes, task_support, prompt title, arguments, and icons. Route opt keys mirror those names (mcp_prompt_title, mcp_prompt_arguments, mcp_prompt_icons). There is no opt={"mcp_tool_name": ...} form and no mcp_exclude key; neither is read. To hide a route, simply leave it unmarked (discovery is opt-in).

Code Style Rules

  • PEP 604 unions: T | None, never Optional[T]
  • Consumer Litestar app modules MAY use from __future__ import annotations
  • Async all I/O - handlers exposed through MCP must be async def

Quick Reference

Install

pip install litestar-mcp

Basic Setup

from litestar import Litestar, get, post
from litestar.openapi.config import OpenAPIConfig
from litestar_mcp import LitestarMCP, MCPConfig

@get("/users", mcp_tool="list_users")
async def list_users() -> list[dict]:
    return [{"id": 1, "name": "Alice"}]

@post("/analyze", mcp_tool="analyze_data")
async def analyze_data(data: dict) -> dict:
    return {"count": len(data)}

@get("/config", mcp_resource="app_config")
async def get_app_config() -> dict:
    return {"debug": False}

app = Litestar(
    route_handlers=[list_users, analyze_data, get_app_config],
    plugins=[LitestarMCP(MCPConfig(name="My API"))],
    openapi_config=OpenAPIConfig(title="My API", version="1.0.0"),
)

The default MCP surface is:

| Endpoint | Purpose | | --- | --- | | GET /mcp | Server-Sent Events stream when requested by the client | | POST /mcp | JSON-RPC endpoint for initialize, ping, tools/*, resources/*, prompts/*, completion/complete, and optional task methods | | DELETE /mcp | Terminate the current MCP session | | GET /.well-known/mcp-server.json | MCP server manifest | | GET /.well-known/agent-card.json | Agent card metadata | | GET /.well-known/oauth-protected-resource | OAuth protected-resource metadata (always registered; populated from auth) |

MCPConfig

| Option | Type | Default | Description | | --- | --- | --- | --- | | base_path | str | "/mcp" | URL prefix for the MCP Streamable HTTP endpoint | | include_in_schema | bool | False | Include MCP routes in OpenAPI | | name | str \| None | None | Server name; defaults to OpenAPI title | | guards | list[Any] \| None | None | Litestar guards applied to the MCP router | | allowed_origins | list[str] \| None | None | Restrict accepted Origin headers | | include_operations | list[str] \| None | None | Only expose matching operation names | | exclude_operations | list[str] \| None | None | Exclude matching operation names | | include_tags | list[str] \| None | None | Only expose routes with matching OpenAPI tags | | exclude_tags | list[str] \| None | None | Exclude routes with matching OpenAPI tags | | auth | MCPAuthConfig \| None | None | OAuth protected-resource metadata | | tasks | bool \| MCPTaskConfig | False | Enable experimental in-memory MCP task support | | list_page_size | int | 100 | Page size for tools/list, resources/list, resources/templates/list, prompts/list (clients page via opaque cursors) | | opt_keys | MCPOptKeys | MCPOptKeys() | Rename the handler.opt keys the plugin reads (e.g. to avoid collisions) | | session_store | Store \| None | None | Litestar Store backing MCP sessions; defaults to an in-memory store | | session_max_idle_seconds | float | 3600.0 | Idle timeout before an MCP session is evicted | | sse_max_streams | int | 10000 | Max concurrent SSE streams | | sse_max_idle_seconds | float | 3600.0 | Idle timeout for an SSE stream |

> Filters (include_tags / exclude_tags / include_operations / exclude_operations) gate both list responses and direct invocation. A filtered tool/resource/template behaves like an unknown name or URI in tools/call / resources/read; still use guards / auth for real access control.

Route Marking

from litestar import get, post

@get("/products", mcp_resource="product_list")
async def list_products() -> list[dict]: ...

@post("/cart/items", mcp_tool="add_to_cart")
async def add_to_cart(data: CartItem) -> Cart: ...

@get(
    "/products/{product_id:int}",
    mcp_resource="product",
    mcp_resource_template="shop://products/{product_id}",
)
async def get_product(product_id: int) -> dict: ...

@get("/products/{product_id:int}/blurb", mcp_prompt="product_blurb")
async def product_blurb(product_id: int) -> str:
    """Write a short marketing blurb for a product."""
    ...

mcp_resource_template only takes effect alongside mcp_resource — the resource supplies the name the template binds to. A handler can expose more than one MCP role (a tool and a resource) at once; the description-override keys (mcp_description vs mcp_resource_description) are kind-specific so each surface can carry its own prose.

Register prompts not bound to a route with the @mcp_prompt decorator plus LitestarMCP(prompts=[...]):

from litestar_mcp import LitestarMCP, mcp_prompt

@mcp_prompt("summarize", description="Summarize a document for the user.")
def summarize(text: str) -> str:
    return f"Summarize the following:\n\n{text}"

app = Litestar(plugins=[LitestarMCP(prompts=[summarize])])

Use structured metadata when the agent needs sharper tool selection:

@post(
    "/reports",
    mcp_tool="generate_report",
    mcp_description="Generate a report for an existing account.",
    mcp_when_to_use="Use after the user has confirmed the account and date range.",
    mcp_returns="A report id and queued status.",
)
async def generate_report(data: ReportRequest) -> ReportQueued: ...

Hiding Routes

Discovery is opt-in: a handler that carries no mcp_* marker never appears in MCP. There is no per-route exclude flag — opt={"mcp_exclude": True} is ignored.

@get("/internal/metrics")  # unmarked — never exposed to MCP clients
async def metrics() -> dict: ...

To drop marked routes in bulk, use the MCPConfig filters (exclude_tags / exclude_operations, or an include_tags / include_operations allowlist). Filtered tools/resources/templates are absent from list responses and fail direct calls as unknown; enforce real access control with guards or auth.

JSON-RPC Call

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "add_to_cart",
    "arguments": { "product_id": 42, "quantity": 3 }
  }
}

Built-in OpenAPI Resource

LitestarMCP exposes the app OpenAPI schema as:

  • URI: litestar://openapi
  • MIME type: application/json
  • Method: resources/read

Auth

Authentication is a Litestar middleware concern. Apps with existing auth middleware get request.user / request.auth before tool handlers run.

The supported auth paths are:

  • Bring your own Litestar auth middleware; MCP routes inherit it.
  • Use MCPAuthBackend with OIDCProviderConfig.
  • Build a validator with create_oidc_validator() and pass shared JWKS behavior through JWKSCache when your app already manages discovery/cache lifetimes.

For OIDC-backed MCP endpoints, pair MCPAuthConfig metadata with token validation:

from litestar import Litestar
from litestar.middleware import DefineMiddleware
from litestar_mcp import LitestarMCP, MCPAuthBackend, MCPConfig, OIDCProviderConfig
from litestar_mcp.auth import MCPAuthConfig

app = Litestar(
    route_handlers=[...],
    plugins=[
        LitestarMCP(
            MCPConfig(
                auth=MCPAuthConfig(
                    issuer="https://company.okta.com",
                    audience="api://mcp-tools",
                )
            )
        )
    ],
    middleware=[
        DefineMiddleware(
            MCPAuthBackend,
            providers=[
                OIDCProviderConfig(
                    issuer="https://company.okta.com",
                    audience="api://mcp-tools",
                )
            ],
            user_resolver=lambda claims, app: MyUser(sub=claims["sub"]),
        )
    ],
)

Workflow

Step 1: Install

pip install litestar-mcp

Step 2: Decide What to Expose

List only the routes that should be callable by AI clients. Mark those routes with mcp_tool=, mcp_resource=, or mcp_prompt= (add mcp_resource_template= next to mcp_resource= for templated resources). There are no method-based defaults — unmarked routes are never exposed.

Step 3: Add the Plugin

Wire LitestarMCP(MCPConfig(name=...)) into Litestar(plugins=[...]). Use include_tags or include_operations when you need a second allowlist.

Step 4: Add Auth

For public endpoints, configure bearer-token validation and MCPAuthConfig metadata. For internal deployments, use guards=[...] or existing app auth middleware.

Step 5: Verify

Hit POST /mcp with tools/list and resources/list. Confirm only marked routes appear. Call one representative tool and read one representative resource.

Guardrails

  • Mark routes explicitly - unmarked routes should not appear in MCP clients.
  • Default to allowlists - include_tags / include_operations keep the tool set small and also gate direct invocation; pair them with guards / auth for authorization.
  • Never expose admin or destructive routes by default - require a human-confirmation workflow before any irreversible operation.
  • Prefer resources for read-only reference data - agents may read resources speculatively.
  • Keep DTOs precise - loose dict[str, Any] request schemas produce weak tool contracts.
  • Use MCPAuthConfig plus token validation for public MCP - metadata alone does not authenticate requests.
  • Set allowed_origins for browser-accessible MCP clients - leave it None only for trusted server-to-server deployments.

Validation Checkpoint

Before delivering an MCP integration, verify:

  • [ ] LitestarMCP is in app.plugins
  • [ ] Exposed routes use mcp_tool=, mcp_resource=, or mcp_resource_template=
  • [ ] Admin / internal routes are left unmarked, or kept outside include_* / inside exclude_* — with guards or auth enforcing access
  • [ ] Auth is configured for the deployment boundary
  • [ ] POST /mcp tools/list returns only intended tools
  • [ ] POST /mcp resources/list includes only intended resources plus litestar://openapi
  • [ ] Filtered tools/resources/templates fail direct invocation as unknown
  • [ ] Provider-declared query parameters appear in tool inputSchema and forward during tools/call
  • [ ] Exposed handlers are async def and return JSON-serializable types
  • [ ] Tool argument DTOs are specific enough for generated schemas

Example

Task: Expose product listing as a resource and add-to-cart as a tool. Hide internal metrics.

from litestar import Litestar, get, post
from litestar_mcp import LitestarMCP, MCPConfig

@get("/products", mcp_resource="product_list", tags=["public"])
async def list_products() -> list[dict]:
    return [{"id": 1, "name": "Widget"}]

@post("/cart/items", mcp_tool="add_to_cart", tags=["public"])
async def add_to_cart(data: CartItem) -> Cart: ...

@get("/internal/metrics")  # unmarked — stays out of MCP
async def metrics() -> dict: ...

app = Litestar(
    route_handlers=[list_products, add_to_cart, metrics],
    plugins=[
        LitestarMCP(
            MCPConfig(
                name="E-Commerce API",
                include_tags=["public"],
            )
        )
    ],
)

References Index

  • Use this skill for route marking, Streamable HTTP endpoint behavior, MCP auth metadata, and verification requests.
  • Use [litestar-auth-guards](../litestar-auth-guards/SKILL.md) when auth logic lives in normal Litestar guards or middleware.

Official References

Shared Styleguide Baseline

  • [General Principles](../litestar-styleguide/references/general.md)
  • [Python](../litestar-styleguide/references/python.md)
  • [Litestar](../litestar-styleguide/references/litestar.md)

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.