Advanced MCP Platform
Provides OpenTelemetry tracing and metrics for MCP tool calls and HTTP requests, exporting spans to an OTLP endpoint.
Click on "Deploy 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., "@Advanced MCP Platform search my workspace roots for files containing TODO"
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.
Advanced MCP Platform
A Python 3.11+ FastMCP service that retains the original tool names while adding signed tenant capabilities, per-user workspace roots, bounded tool input, audit-friendly JSON logs, metrics, OpenTelemetry spans, and authenticated Streamable HTTP.
Architecture
Related MCP server: mcp-gateway
MCP note: what it is and why use it
The Model Context Protocol (MCP) is an open standard for connecting AI applications (clients) to external capabilities and context (servers). A client can discover the server's available tools and call them through a consistent protocol, rather than using a different custom integration for every service. MCP also defines related capabilities such as resources, prompts, progress notifications, and client-controlled sampling.
In this project, the client initializes an MCP session, discovers tools such as list_root_files and search_in_roots, and sends structured tool requests. The server checks the caller's permissions, performs allowed work, then returns results and (where supported) progress/log notifications. For sampling, the server asks the client to generate text; the client remains responsible for whether and how it uses a model.
MCP is useful when you want reusable integrations with clear capability boundaries. It does not itself make a tool safe: the application still has to authenticate callers, validate inputs, enforce file access, and decide which capabilities to grant.
The dashboard's MCP explained section has a clickable process diagram; select a step to read its role in the request flow.
MCP client
├─ stdio (local trusted process) ──────────────────────────────┐
└─ Streamable HTTP + JWT → trace/auth middleware → FastMCP │
├─ tools ─────┤
├─ sandbox │
└─ sampling ←─┘The control flow is: verify bearer token and required MCP scope; bind stateful MCP sessions to the tenant/user that initialized them; resolve signed workspace grants; enforce a per-principal tool rate limit; validate input; execute within a traced tool span; return a normal MCP result/error. The HTTP health/readiness routes are public; the MCP endpoint is not. No protocol extensions are introduced.
Module layout
mcp_advanced/
config.py Typed environment settings and startup validation
security.py JWT verifier, capability checks, rate limits, path sandbox
observability.py JSON logging, audit events, metrics, OTel HTTP/tool spans
server.py FastMCP tools, auth configuration, health/metrics endpoints
cli.py Operator token issuer
server.py Backward-compatible server entry point
client.py Feature demo and authenticated HTTP client
webapp.py Loopback-only interactive local demo dashboard
frontend/ Dashboard UI, event filtering, approval prompt, run history
tests/ Sandbox, auth, stdio, HTTP, and dashboard integration testsLocal setup
py -3.11 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[test,sampling]"
python -m pytestThe core sampling example uses a local stub; .[sampling] installs the optional Anthropic client for real sampling. Never put provider keys in the repository.
stdio demo
python client.py stdiostdio is intended for a local trusted parent process. The root is MCP_ROOT when set, otherwise the project directory. Do not expose a stdio process with an untrusted caller as its parent.
Authenticated, stateful HTTP
Set the same signing secret for the server and operator token issuer. Use a randomly generated value of at least 32 characters and keep it in a secret manager in deployed environments.
$env:MCP_JWT_SECRET = python -c "import secrets; print(secrets.token_urlsafe(48))"
$env:MCP_DATA_DIR = "$PWD\.mcp-data"
# Create the server-side workspace root. Files for this user belong beneath it.
New-Item -ItemType Directory -Force "$env:MCP_DATA_DIR\tenants\acme\alice\roots\src" | Out-Null
# Issue a short-lived, least-privilege token. Copy its output for the client.
$token = python -m mcp_advanced.cli issue-token `
--tenant acme --user alice --root src `
--scope mcp:tools --scope files:read --scope sampling:request
# Terminal 1
python server.py --transport http
# Terminal 2
$env:MCP_JWT_SECRET = "<same signing secret>"
$env:MCP_DATA_DIR = "$PWD\.mcp-data"
$env:MCP_ACCESS_TOKEN = "<issued token>"
python client.py http http://127.0.0.1:8000/mcpThe token's tenant_id, sub, scopes, audience, issuer, expiry, and relative roots are validated. Tenant roots live beneath MCP_DATA_DIR/tenants/<tenant>/<user>/roots; relative grants cannot contain traversal. Supported scopes are mcp:tools, files:read, and sampling:request. The admin CLI is the trusted token issuer; do not expose it as an unauthenticated endpoint.
Useful settings:
Variable | Default | Purpose |
| unset | Required for HTTP; at least 32 characters |
|
| Expected JWT issuer |
|
| Expected JWT audience |
|
| Short-lived token lifetime |
|
| Tenant-isolated workspace storage |
| project directory | Trusted local stdio root |
|
| Per-user process-local tool rate |
|
| Stateful session idle timeout |
|
| Maximum active stateful sessions |
|
| File read/search size bound |
|
| Search file-count bound |
|
| Use stateless Streamable HTTP |
|
| Disable SSE response streaming |
| unset | Enable OTLP trace export |
Configuration is parsed at startup and invalid security-sensitive values fail closed. HTTP startup without MCP_JWT_SECRET fails.
Stateless HTTP
$env:MCP_JWT_SECRET = "<random secret, at least 32 characters>"
$env:MCP_STATELESS_HTTP = "true"
python server.py --transport httpStateless mode supports authenticated tools and signed per-user roots. As defined by Streamable HTTP/MCP behavior, it cannot preserve a client session for server-initiated sampling or a standing progress/log stream. The demo client skips those two exercises in stateless mode; summarize_text and review_file return a clear sampling_unavailable error if explicitly called. JSON-response mode likewise does not provide live notification delivery.
Local browser dashboard
python webapp.py
# Visit http://127.0.0.1:8080The dashboard shows live tool/log/progress events, supports filtering, keeps recent run summaries in process memory, and pauses sampling for a human to approve/reject or edit the prompt. It binds only to a loopback IP because it has no authentication. It launches the local stdio demo, not the multi-tenant HTTP service; never expose it to a network or use it as a production tenant console.
Docker Compose
$env:MCP_JWT_SECRET = python -c "import secrets; print(secrets.token_urlsafe(48))"
docker compose up --buildThe container runs as a non-root user, drops Linux capabilities, uses a read-only root filesystem, and keeps workspace data in a named volume. The compose port is loopback-bound by default. Configure an external OTLP collector by setting OTEL_EXPORTER_OTLP_ENDPOINT.
Render deployment
This repository includes a Render Blueprint at render.yaml for the authenticated MCP HTTP service. It provisions a web service, generates MCP_JWT_SECRET in Render, stores tenant workspaces on a persistent disk, and checks /ready.
Push or merge this repository to GitHub.
In Render, choose New → Blueprint, connect
AHAAkash/Own_MCP_Server, and select the branch containingrender.yaml.Review the Blueprint resources and confirm creation. Render may require a paid Starter service for the persistent disk.
Wait for the service to become healthy. Its MCP endpoint is
https://<your-render-service>.onrender.com/mcp;/health,/ready, and/metricsare also available.In Render's environment settings, copy the generated
MCP_JWT_SECRETinto a trusted local terminal (do not commit it), then issue a short-lived token:
$env:MCP_JWT_SECRET = "<copy from Render environment settings>"
$env:MCP_JWT_ISSUER = "https://auth.local.invalid"
$env:MCP_JWT_AUDIENCE = "advanced-mcp"
$token = python -m mcp_advanced.cli issue-token `
--tenant acme --user alice --root src `
--scope mcp:tools --scope files:read --scope sampling:request
$env:MCP_ACCESS_TOKEN = $token
python client.py http https://<your-render-service>.onrender.com/mcpCreate or upload authorized workspace files beneath the persistent disk's /var/data/tenants/<tenant>/<user>/roots/<root> path using a trusted deployment workflow before requesting file tools. Do not make the disk publicly accessible.
Render deploys the MCP HTTP service only. The browser dashboard remains a loopback-only stdio demo and is intentionally not exposed by this Blueprint. Stateless mode is not enabled because the default demo uses MCP sampling and notifications. The service and disk incur Render charges according to your Render plan.
Security and error model
Authentication: HMAC-SHA256 JWTs with issuer, audience, expiry, user, tenant, scopes, and relative roots. There is no anonymous HTTP MCP access and no hard-coded development signing key.
Capabilities: each tool checks its required scope. A file token does not automatically grant sampling.
Session isolation: the stateful HTTP boundary binds the MCP session ID to the tenant/user that initialized it; session state itself is held in the FastMCP process.
Filesystem: traversal, out-of-root absolute paths, and symlinks are rejected; hidden virtual environments and VCS trees are excluded from listing/search. Reads and searches have size, result, and file-count bounds and execute off the event loop.
Isolation: HTTP workspace paths are separated by tenant and user; signed root grants are relative to that user's directory. The container uses a dedicated persistent volume. For mutually hostile tenants, use separate OS/container or volume boundaries as well; directory names alone are not a kernel security boundary.
Rate limits: token-bucket limits are per user, but currently process-local.
Auditing: authenticated tool calls, sampling requests/failures, and file read attempts emit structured JSON logs to stdout. Ship these logs to a protected centralized sink for durable retention.
Errors: input, capability, path, sampling, and rate-limit failures include stable prefixes such as
invalid_input,insufficient_scope,path_forbidden,sampling_unavailable, andrate_limited.Observability: tool and HTTP request spans, W3C trace-context extraction, sampling spans, tool latency, HTTP request counts, sampling success/failure, progress notification drops, and stateful HTTP session-duration metrics are available. Metrics are in process memory and exposed at
/metrics;/healthand/readyare unauthenticated liveness/readiness probes.
Operational boundaries
This is a security-oriented single-process foundation and demo, not a finished multi-replica hosted service. Specifically:
FastMCP's stateful session manager and the current rate limiter/metrics are in memory. Stateful HTTP must stay on one instance (or use deployment-level sticky routing); a Redis/Postgres session-store adapter and distributed rate limiter are not implemented.
Workspace directories share the configured volume at the OS level; hostile-tenant deployments need stronger container/volume isolation.
JSON audit output is not a durable audit database. Configure log collection, retention, redaction, alerting, and key rotation before production use.
Sampling has timeouts and explicit errors but no circuit breaker. The dashboard approval queue/run history are process-local and intentionally loopback-only.
MCP resources for files/prior results and persistent project/run-history APIs are not implemented.
OTLP traces export only when the endpoint is configured. Protect trace/log backends and avoid recording sensitive prompt/file contents there.
Do not treat a successful build or a local demo as evidence of compliance or production approval. Before internet-facing deployment, add an organizational identity/token issuer, secret rotation and revocation, shared distributed state/rate-limit storage, durable audit retention, per-tenant runtime isolation, resource quotas, and load/security testing.
Tests
python -m pytest
mypy mcp_advanced client.py webapp.py server.py testsThe suite covers token validation, capabilities, traversal/symlink rejection, tenant root separation, rate limiting, stdio operation from a different working directory, authenticated and unauthenticated stateful HTTP, stateless HTTP file tools, and dashboard sampling approval/history.
Available Tools
7 toolslist_root_filesC
List non-symlink files under tenant-granted workspace roots.
Inputs: pattern, max_results. Returns: result
long_running_taskB
Simulate bounded work and stream log + progress notifications.
Inputs: delay, steps. Returns: result
read_root_fileA
Read a text file, only if it lies inside a tenant-granted workspace root.
Inputs: path (required). Returns: result
review_fileC
Read a file from a tenant workspace, then have the client's LLM review it.
Inputs: path (required). Returns: result
search_in_rootsC
Search bounded, non-symlink files in tenant-granted workspace roots.
Inputs: query (required), glob, max_hits. Returns: result
server_infoB
Report transport configuration and negotiated client capabilities.
Inputs: no named parameters.
summarize_textB
Summarize text using the client's language model (MCP sampling).
Inputs: text (required), max_words. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Most tools have clearly distinct purposes: file listing, reading, searching, text summarization, file review, long-running task simulation, and server info. There is minor overlap between read_root_file and review_file, and between summarize_text and review_file, since both review_file and summarize_text invoke the client LLM on content.
The action-oriented tools mostly follow a predictable verb_noun pattern: summarize_text, review_file, list_root_files, read_root_file, search_in_roots. The exceptions are long_running_task and server_info, which are noun phrases rather than verb-led names, but they remain readable and understandable.
Seven tools is a well-scoped set for a platform demonstrating text processing, file/root operations, long-running work, and server metadata. Each tool appears to earn its place without excessive breadth.
The surface covers read-only workspace operations, LLM-based summarization/review, task progress streaming, and server introspection, which fits the apparent tenant-root read-only model. Minor gaps exist around explicit task lifecycle management or write operations, but these may be intentionally out of scope for a roots-based platform.
Maintenance
Related MCP Connectors
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Persistent cloud workspaces for AI agents: run commands, edit files, use git and a browser.
The Remote MCP server acts as a standardized bridge between LLM applications (like Claude, ChatGPT, and Cursor) and external services, enabling AI agents to access external tools and resources. Its primary capability is providing a centralized search tool to discover other MCP servers and their respective tools. Unlike local implementations, it runs remotely with OAuth authentication and permission controls for security.
Context and control for any AI. Agent identity, scoped access, and proof across tools.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables local, permissioned development workflows from compatible AI clients, including filesystem editing, interactive terminals, durable jobs, Git operations, and semantic browser testing.37 npm1Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables secure exposure of internal tools to LLM clients with API-key authentication, tenant isolation, per-tool guardrails, PII scrubbing, rate limiting, audit logging, and telemetry over stdio and HTTP/SSE.MIT
- FlicenseNot gradedqualityNot gradedmaintenanceExposes a governed suite of 38 tools over one OAuth-gated MCP endpoint so web AI chat clients can read and edit files, run whitelisted shell commands, search, query Git/SQLite, drive browsers via DevTools, and manage background jobs on the local machine. Remote access runs through Tailscale Funnel while local tools connect straight to 127.0.0.1, keeping operations permission-scoped rather than granting unrestricted shell access.-
- AlicenseNot gradedqualityAmaintenanceExposes a governed suite of 38 OAuth-gated tools that let web-based AI chat clients read, write, edit, and search local files, run whitelisted shell commands, inspect databases and localhost APIs, drive browsers and DevTools, and manage background tasks, Git, clipboard, notifications, and ports. Local IDEs connect directly over loopback, while remote clients reach the same machine through a secure tunnel.MIT