flask-apcore
Integrates Flask applications by providing auto-discovery of Flask routes as MCP tools with Pydantic schema inference, allowing AI agents to call Flask endpoints via MCP.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@flask-apcoreexpose my Flask routes as MCP tools"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
flask-apcore
Flask Extension for apcore (AI-Perceivable Core) integration. Expose your Flask routes as MCP tools with auto-discovery, Pydantic schema inference, and built-in observability.
Features
Route scanning -- auto-discover Flask routes and convert them to apcore modules
Annotation inference --
GET-> readonly+cacheable,DELETE-> destructive,PUT-> idempotentPydantic schema inference -- input/output schemas extracted from type hints automatically
Docstring enrichment -- parameter descriptions from docstrings injected into JSON Schema
@moduledecorator -- define standalone AI-callable modules with full schema enforcementYAML binding -- zero-code module definitions via external
.binding.yamlfilesPython output -- generate
@module-decorated Python files from scanned routesMCP server -- stdio and streamable-http transports via
flask apcore serveObservability -- distributed tracing, metrics, structured logging, error history, usage tracking
System modules -- built-in health, manifest, usage, and control modules (apcore 0.11.0+)
Input validation -- validate tool inputs against Pydantic schemas before execution
CLI-first workflow --
flask apcore scan+flask apcore servefor zero-intrusion integrationMCP Tool Explorer -- browser UI for inspecting modules via
flask apcore serve --explorerJWT authentication -- protect MCP endpoints with Bearer tokens via
--jwt-secretApproval system -- require approval for destructive operations via
--approvalAI enhancement -- enrich module metadata using local SLMs via
--ai-enhanceUnified entry point --
Apcoreclass provides property-based access to all components
Related MCP server: flask-mcp-server
Requirements
Python >= 3.11
Flask >= 3.0
apcore >= 0.13.0
apcore-toolkit >= 0.2.0
Installation
# Core
pip install flask-apcore
# With MCP server support (required for `flask apcore serve`)
pip install flask-apcore[mcp]
# All optional extras
pip install flask-apcore[mcp,smorest,restx]Quick Start
1. Add Apcore to your Flask app
from flask import Flask
from flask_apcore import Apcore
app = Flask(__name__)
apcore = Apcore(app)
@app.route("/greet/<name>", methods=["GET"])
def greet(name: str) -> dict:
"""Greet a user by name."""
return {"message": f"Hello, {name}!"}Or use the factory pattern:
from flask import Flask
from flask_apcore import Apcore
apcore = Apcore()
def create_app():
app = Flask(__name__)
# ... register routes / blueprints ...
apcore.init_app(app)
return app2. Scan routes and start MCP server
export FLASK_APP=app.py
# Scan Flask routes -> register as apcore modules
flask apcore scan
# Start MCP server (stdio, for Claude Desktop / Cursor)
flask apcore serveThat's it. Your Flask routes are now MCP tools.
3. Unified entry point
The Apcore instance provides property-based access to all components:
apcore = Apcore(app)
with app.app_context():
# Properties
apcore.registry # Registry
apcore.executor # Executor (lazy-created)
apcore.settings # ApcoreSettings
apcore.metrics # MetricsCollector | None
apcore.events # EventEmitter | None
apcore.error_history # ErrorHistory | None
apcore.usage # UsageCollector | None
# Convenience methods
apcore.call("task_stats.v1")
apcore.validate("task_stats.v1", {"key": "value"})
apcore.list_modules(tags=["api"])
apcore.describe("task_stats.v1")4. Connect an MCP client
For Claude Desktop, add to your config:
{
"mcpServers": {
"my-flask-app": {
"command": "flask",
"args": ["apcore", "serve"],
"env": { "FLASK_APP": "app.py" }
}
}
}For HTTP transport (remote access):
flask apcore serve --http --host 0.0.0.0 --port 9100Integration Paths
flask-apcore supports three ways to define AI-perceivable modules:
Route Scanning (zero-intrusion)
Scan existing Flask routes without modifying any code:
# Direct registration (in-memory)
flask apcore scan
# Generate YAML binding files (persistent)
flask apcore scan --output yaml --dir ./apcore_modules
# Generate Python module files
flask apcore scan --output python --dir ./apcore_modules
# Preview without side effects
flask apcore scan --dry-run
# Filter routes by regex
flask apcore scan --include "user.*" --exclude ".*delete"
# AI-enhanced module descriptions (requires APCORE_AI_ENABLED)
flask apcore scan --ai-enhance
# Verify written output
flask apcore scan --output yaml --verify@module Decorator (precise control)
Define standalone modules with full schema enforcement:
from flask_apcore import Apcore, module
from pydantic import BaseModel
class SummaryResult(BaseModel):
total: int
active: int
@module(id="user_stats.v1", tags=["analytics"])
def user_stats() -> SummaryResult:
"""Return user statistics."""
return SummaryResult(total=100, active=42)
app = Flask(__name__)
app.config["APCORE_MODULE_PACKAGES"] = ["myapp.modules"]
Apcore(app)YAML Binding (zero-code)
Define modules externally in .binding.yaml files:
# apcore_modules/greet.binding.yaml
bindings:
- module_id: greet.get
target: app.greet
description: "Greet a user by name"Set APCORE_AUTO_DISCOVER=True (default) to load bindings on startup.
CLI Commands
flask apcore scan
Scan Flask routes and generate apcore module definitions.
Options:
-s, --source [auto|native|smorest|restx] Scanner source (default: auto)
-o, --output [yaml|python] Output format; omit for direct registration
-d, --dir PATH Output directory (default: APCORE_MODULE_DIR)
--dry-run Preview without writing or registering
--include REGEX Only include matching module IDs
--exclude REGEX Exclude matching module IDs
--ai-enhance AI-enhance module metadata (requires APCORE_AI_ENABLED)
--verify Verify written outputflask apcore serve
Start an MCP server exposing registered modules as tools.
Options:
--stdio Use stdio transport (default)
--http Use streamable-http transport
--host TEXT HTTP host (default: 127.0.0.1)
-p, --port INT HTTP port (default: 9100)
--name TEXT MCP server name (default: apcore-mcp)
--validate-inputs Validate tool inputs against schemas
--log-level [DEBUG|INFO|WARNING|ERROR]
Module Filtering:
--tags TEXT Comma-separated tags to filter modules
--prefix TEXT Module ID prefix filter
Explorer:
--explorer Enable the MCP Tool Explorer UI
--explorer-prefix TEXT URL prefix for explorer (default: /explorer)
--allow-execute Allow Try-it execution in the explorer
--explorer-title TEXT Page title for Explorer UI
--explorer-project-name Project name shown in Explorer footer
--explorer-project-url Project URL shown in Explorer footer
Authentication:
--jwt-secret TEXT JWT secret key for MCP auth (HTTP only)
--jwt-algorithm ALGO JWT signing algorithm (default: HS256)
--jwt-audience TEXT Expected JWT audience claim
--jwt-issuer TEXT Expected JWT issuer claim
--require-auth/--no-require-auth Require auth for all requests (default: True)
--exempt-paths TEXT Comma-separated paths exempt from auth
Execution:
--approval [off|elicit|auto-approve|always-deny] Approval mode (default: off)
--output-formatter TEXT Output formatter dotted path (e.g., apcore_toolkit.to_markdown)Configuration
All settings use the APCORE_ prefix in app.config:
app.config.update(
# Core
APCORE_AUTO_DISCOVER=True, # Auto-load bindings and @module packages
APCORE_MODULE_DIR="apcore_modules/",# Directory for binding files
APCORE_BINDING_PATTERN="*.binding.yaml", # Glob pattern for binding files
APCORE_MODULE_PACKAGES=[], # Python packages to scan for @module functions
APCORE_SCANNER_SOURCE="auto", # Scanner: auto, native, smorest, restx
# System Modules (apcore 0.11.0+)
APCORE_SYS_MODULES_ENABLED=False, # Enable system modules (health, manifest, usage, control)
APCORE_SYS_MODULES_EVENTS_ENABLED=False, # Enable event system for platform notifications
# Middleware & Execution
APCORE_MIDDLEWARES=[], # Middleware dotted paths (e.g. ["myapp.mw.AuthMW"])
APCORE_ACL_PATH=None, # ACL file path (e.g. "acl.yaml")
APCORE_CONTEXT_FACTORY=None, # Custom ContextFactory dotted path
APCORE_EXECUTOR_CONFIG=None, # Executor config dict (passed to apcore.Config)
APCORE_EXTENSIONS=[], # Extension plugin dotted paths
# MCP Server
APCORE_SERVE_TRANSPORT="stdio", # Transport: stdio, streamable-http, sse
APCORE_SERVE_HOST="127.0.0.1", # HTTP host
APCORE_SERVE_PORT=9100, # HTTP port
APCORE_SERVER_NAME="apcore-mcp", # MCP server name
APCORE_SERVER_VERSION=None, # MCP server version string
APCORE_SERVE_VALIDATE_INPUTS=False, # Validate inputs against schemas
APCORE_SERVE_LOG_LEVEL=None, # Log level: DEBUG, INFO, WARNING, ERROR
APCORE_SERVE_TAGS=None, # Filter modules by tags (list of strings)
APCORE_SERVE_PREFIX=None, # Filter modules by ID prefix
# MCP Authentication
APCORE_SERVE_JWT_SECRET=None, # JWT secret key (enables auth when set)
APCORE_SERVE_JWT_ALGORITHM="HS256", # Signing algorithm
APCORE_SERVE_JWT_AUDIENCE=None, # Expected audience claim
APCORE_SERVE_JWT_ISSUER=None, # Expected issuer claim
APCORE_SERVE_REQUIRE_AUTH=True, # Require auth for all requests
APCORE_SERVE_EXEMPT_PATHS=None, # Paths exempt from auth (list of strings)
# MCP Approval (apcore-mcp 0.8.0+)
APCORE_SERVE_APPROVAL="off", # Approval mode: off, elicit, auto-approve, always-deny
APCORE_SERVE_OUTPUT_FORMATTER=None, # Output formatter dotted path
# MCP Tool Explorer
APCORE_SERVE_EXPLORER=False, # Enable Tool Explorer UI in MCP server
APCORE_SERVE_EXPLORER_PREFIX="/explorer",# URL prefix for explorer
APCORE_SERVE_ALLOW_EXECUTE=False, # Allow Try-it execution in explorer
APCORE_SERVE_EXPLORER_TITLE="MCP Tool Explorer", # Explorer page title
APCORE_SERVE_EXPLORER_PROJECT_NAME=None, # Project name in explorer footer
APCORE_SERVE_EXPLORER_PROJECT_URL=None, # Project URL in explorer footer
# Observability
APCORE_TRACING_ENABLED=False, # Enable distributed tracing
APCORE_TRACING_EXPORTER="stdout", # Exporter: stdout, memory, otlp
APCORE_TRACING_OTLP_ENDPOINT=None, # OTLP collector URL (e.g. "http://localhost:4317")
APCORE_TRACING_SERVICE_NAME="flask-apcore", # Service name for traces
APCORE_METRICS_ENABLED=False, # Enable metrics collection
APCORE_METRICS_BUCKETS=None, # Custom histogram buckets (list of floats)
APCORE_LOGGING_ENABLED=False, # Enable structured logging
APCORE_LOGGING_FORMAT="json", # Format: json, text
APCORE_LOGGING_LEVEL="INFO", # Level: trace, debug, info, warn, error, fatal
# Scan Options
APCORE_SCAN_AI_ENHANCE=False, # AI-enhance scanned modules (requires APCORE_AI_ENABLED)
APCORE_SCAN_VERIFY=False, # Verify written output by default
)Observability
Enable tracing, metrics, and structured logging:
app.config.update(
APCORE_TRACING_ENABLED=True,
APCORE_TRACING_EXPORTER="otlp",
APCORE_TRACING_OTLP_ENDPOINT="http://localhost:4317",
APCORE_METRICS_ENABLED=True,
APCORE_LOGGING_ENABLED=True,
APCORE_LOGGING_FORMAT="json",
)When observability is enabled, the following middleware is automatically wired into the Executor:
Middleware | Trigger | Purpose |
TracingMiddleware |
| Distributed tracing spans |
MetricsMiddleware |
| Latency histograms, call counts |
ObsLoggingMiddleware |
| Structured log entries |
ErrorHistoryMiddleware | Any of above | Ring buffer of recent errors |
UsageMiddleware |
| Per-module usage stats and trends |
PlatformNotifyMiddleware |
| Threshold-based event emission |
System Modules
Enable built-in system modules for introspection and control:
app.config.update(
APCORE_SYS_MODULES_ENABLED=True,
APCORE_SYS_MODULES_EVENTS_ENABLED=True, # Optional: enable event system
)This registers:
system.health.summary/system.health.module— Health statussystem.manifest.full/system.manifest.module— Module introspectionsystem.usage.summary/system.usage.module— Usage statisticssystem.control.toggle_feature/system.control.update_config/system.control.reload_module— Runtime control
MCP Tool Explorer
The MCP Tool Explorer is a browser UI provided by apcore-mcp for inspecting registered modules and executing them interactively.
Security: Without JWT authentication, Explorer endpoints are unauthenticated. Either enable
--jwt-secretor only expose in development/staging environments.
flask apcore serve --http --explorer --allow-execute \
--explorer-title "My API Tools" \
--explorer-project-name "My Project"Browse to http://127.0.0.1:9100/explorer/ to view the interactive explorer with Try-it execution.
JWT Authentication
Protect MCP endpoints with JWT Bearer tokens (requires apcore-mcp>=0.10.0, HTTP transports only):
flask apcore serve --http \
--jwt-secret "change-me-in-production" \
--jwt-algorithm HS256 \
--jwt-audience my-api \
--jwt-issuer https://auth.example.com \
--explorer --allow-executeWhen JWT is enabled:
All MCP endpoints require a valid
Authorization: Bearer <token>headerThe Explorer UI shows a token input field for authentication
Use
--no-require-authto allow unauthenticated accessUse
--exempt-pathsto bypass auth for specific paths
Approval System
Require approval for module execution (apcore-mcp 0.8.0+):
# Interactive approval via MCP elicitation
flask apcore serve --http --approval elicit
# Auto-approve all (testing)
flask apcore serve --http --approval auto-approveDocker Demo
A complete runnable demo is included in examples/demo/. It demonstrates the full pipeline: Flask CRUD routes with Pydantic schemas, route scanning, annotation inference, @module registration, MCP server, and observability.
cd examples/demo
docker compose up --buildSee examples/demo/README.md for full details.
Public API
from flask_apcore import (
Apcore, # Flask Extension (unified entry point)
module, # @module decorator
Registry, # Module registry
Executor, # Module executor with middleware pipeline
Context, # Request context
Identity, # User identity
ACL, # Access control list
Config, # Executor configuration
Middleware, # Middleware base class
ModuleAnnotations, # Behavioral hints (readonly, destructive, etc.)
ModuleDescriptor, # Module metadata
FunctionModule, # Module wrapper for functions
PreflightResult, # Preflight validation result
# Approval system
ApprovalHandler,
AutoApproveHandler,
AlwaysDenyHandler,
# Events
EventEmitter,
EventSubscriber,
ApCoreEvent,
# Cancellation
CancelToken,
# Errors
ModuleError,
ModuleNotFoundError,
ACLDeniedError,
SchemaValidationError,
InvalidInputError,
# System modules
register_sys_modules,
)Development
git clone https://github.com/aiperceivable/flask-apcore.git
cd flask-apcore
pip install -e ".[dev,mcp]"
pytestLicense
Apache-2.0
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/aiperceivable/flask-apcore'
If you have feedback or need assistance with the MCP directory API, please join our Discord server