MCP Service -- Host and Manage MCP Servers
Host production MCP servers with OAuth authentication, tool discovery, capability negotiation, and streamable HTTP transport. Integrate with Claude Desktop, Claude Code, and any MCP-compatible client.
On this page
TL;DR: systemprompt.io hosts production MCP (Model Context Protocol) servers as standalone Rust binaries with OAuth authentication, typed tool schemas, and streamable HTTP transport. Each server registers tools that AI models discover and invoke automatically. The platform handles routing, authentication, RBAC enforcement, artifact persistence, and integration with clients like Claude Desktop and Claude Code.
What MCP Is and Why It Matters
AI models reason well but cannot act on the world directly. They cannot query databases, call APIs, manage files, or interact with external systems without tooling. The Model Context Protocol (MCP) is an open standard that solves this by defining how AI clients discover and invoke tools hosted on remote servers.
MCP matters because it replaces ad-hoc tool integrations with a single protocol. Instead of building custom integrations for every AI client, you build one MCP server and every compatible client -- Claude Desktop, Claude Code, or any other -- can use it immediately.
systemprompt.io takes this further. Rather than running MCP servers as local stdio processes, the platform hosts them as authenticated HTTP services. This means your tools are available from anywhere, secured by OAuth, and managed through a unified control plane.
Architecture
MCP in systemprompt.io follows a client-server model with three layers:
┌─────────────────────┐ ┌──────────────────────┐ ┌─────────────────┐
│ AI Client │ │ systemprompt.io │ │ MCP Server │
│ (Claude Desktop, │────▶│ Router + OAuth │────▶│ (Rust binary) │
│ Claude Code) │ │ /api/v1/mcp/{name}/ │ │ port 5010-5999 │
└─────────────────────┘ └──────────────────────┘ └─────────────────┘
- MCP Server -- A Rust binary implementing
ServerHandlerfrom thermcpcrate. Exposes tools, resources, and capabilities over the MCP protocol. - Router -- An Axum HTTP layer that terminates streamable HTTP transport, enforces OAuth, and proxies requests to the correct server process.
- AI Client -- Any MCP-compatible client that connects over HTTP, discovers tools, and calls them during conversations.
Each server runs as an independent process on its own port within the configured range (default 5000-5999). The platform router maps /api/v1/mcp/{server-name}/mcp to the correct backend.
Server Hosting with OAuth
Every MCP server is configured with a YAML manifest and an optional OAuth policy. The platform enforces authentication before any tool call reaches your handler code.
Manifest Configuration
Each server has a manifest.yaml in its extension directory:
# extensions/mcp/marketplace/manifest.yaml
extension:
type: mcp
name: marketplace
binary: systemprompt-mcp-marketplace
description: Marketplace MCP Server - Manage skills, secrets, and sync
port: 5050
build_type: workspace
enabled: true
OAuth Configuration
OAuth is configured per-server in the service YAML files under services/mcp/:
mcp_servers:
marketplace:
binary: "systemprompt-mcp-marketplace"
package: "marketplace"
port: 5050
endpoint: "http://localhost:8080/api/v1/mcp/marketplace/mcp"
enabled: true
display_in_web: true
description: "Marketplace MCP Server"
oauth:
required: true
scopes: ["admin"]
audience: "mcp"
| OAuth Field | Type | Description |
|---|---|---|
required |
boolean | Enforce authentication on all tool calls |
scopes |
string[] | Required OAuth scopes (e.g., admin, user, tools:read) |
audience |
string | Expected JWT audience claim |
client_id |
string | Optional restriction to a specific OAuth client |
When oauth.required is true, the platform middleware calls enforce_rbac_from_registry before dispatching to the server handler. Unauthenticated requests are rejected before your code runs.
Server Configuration Fields
| Field | Type | Description |
|---|---|---|
binary |
string | Compiled binary name |
package |
string | Cargo package/crate name |
port |
number | Listening port (5000-5999 range) |
endpoint |
string | Full API endpoint URL |
enabled |
boolean | Whether the server is active |
display_in_web |
boolean | Show in the admin web UI |
description |
string | Human-readable server description |
Tool Discovery and Capability Negotiation
MCP servers advertise their capabilities during the initialization handshake. When a client connects, it receives the server's protocol version, supported capabilities, and metadata.
Initialization Response
Every server implements get_info() which returns:
- Protocol version -- Currently
V_2025_06_18(the latest version supported by the rmcp crate) - Capabilities -- Which features the server supports (tools, resources, experimental)
- Server info -- Name, version, icons, website URL
- Instructions -- Guidance for the AI model on how to use the server
Tool Listing
Clients call tools/list to discover available tools. Each tool is defined with:
- Name and title -- Machine-readable identifier and human-readable label
- Description -- Detailed usage instructions for the AI model
- Input schema -- JSON Schema defining required and optional parameters
- Output schema -- JSON Schema describing the response structure
- UI metadata -- Hints for rendering in visual clients
Resource Listing
Servers can also expose resources (static or dynamic content) through resources/list and resources/read. For example, the systemprompt server exposes an artifact viewer as a UI resource with content security policies.
Discovery Endpoints
| Endpoint | Description |
|---|---|
/api/v1/mcp/registry |
List all registered MCP servers |
/api/v1/mcp/{server}/mcp |
Individual server endpoint (streamable HTTP) |
The AI service uses the registry endpoint to auto-discover servers and make their tools available to agents.
Building MCP Servers
MCP servers in systemprompt.io are Rust binaries built with the rmcp crate. The platform provides helper utilities for routing, OAuth enforcement, response building, and artifact persistence.
Project Structure
extensions/mcp/marketplace/
├── Cargo.toml
├── manifest.yaml
└── src/
├── main.rs # Entry point: config, listener, router
├── lib.rs # Re-exports server type
├── server/
│ ├── mod.rs # ServerHandler implementation
│ └── constructor.rs # Server initialization with services
└── tools/
├── mod.rs # Tool registry and dispatch
├── create_skill/
│ ├── mod.rs # Tool definition (schema, metadata)
│ ├── schema.rs # Input/output JSON schemas
│ └── handler.rs # Tool execution logic
└── list_skills/
└── ...
Entry Point
The main.rs initializes configuration, creates the server, builds the router, and starts listening:
let server = MarketplaceServer::new(
ctx.db_pool().clone(),
service_id.clone(),
ctx.clone(),
).await?;
let router = systemprompt::mcp::create_router(server, ctx.db_pool());
let listener = TcpListener::bind(&addr).await?;
axum::serve(listener, router).await?;
The create_router function wraps the server handler with streamable HTTP transport and OAuth middleware.
Implementing ServerHandler
Each server implements the ServerHandler trait from rmcp:
impl ServerHandler for MarketplaceServer {
fn get_info(&self) -> ServerInfo { /* capabilities */ }
async fn initialize(&self, request, ctx) -> Result<InitializeResult, McpError> { ... }
async fn list_tools(&self, request, ctx) -> Result<ListToolsResult, McpError> { ... }
async fn call_tool(&self, request, ctx) -> Result<CallToolResult, McpError> { ... }
async fn list_resources(&self, request, ctx) -> Result<ListResourcesResult, McpError> { ... }
async fn read_resource(&self, request, ctx) -> Result<ReadResourceResult, McpError> { ... }
}
Inside call_tool, enforce authentication before processing:
let auth_result = enforce_rbac_from_registry(&ctx, self.service_id.as_str())
.await?
.expect_authenticated("requires OAuth")?;
Defining Tools
Each tool has a schema module and a handler module. The schema defines typed input/output:
pub fn input_schema() -> serde_json::Value {
serde_json::json!({
"type": "object",
"properties": {
"skill_id": {
"type": "string",
"description": "The skill UUID to analyze"
}
},
"required": ["skill_id"]
})
}
Tools are registered in the list_tools() function of the tools module and dispatched by name in call_tool.
Available MCP Servers
systemprompt.io ships with three MCP servers:
| Server | Port | Tools | Purpose |
|---|---|---|---|
systemprompt |
5010 | systemprompt (CLI executor) |
Execute CLI commands with artifact rendering |
content-manager |
5040 | research_blog, create_blog_post, generate_featured_image |
AI-powered content creation pipeline |
marketplace |
5050 | create_skill, update_skill, list_skills, analyze_skill, manage_secrets, get_secrets, sync_skills |
Skill and secret management |
Integration with Claude Desktop and Claude Code
Claude Desktop
Add your MCP server to the Claude Desktop configuration file:
{
"mcpServers": {
"systemprompt": {
"url": "https://your-domain.com/api/v1/mcp/systemprompt/mcp",
"transport": "streamable-http"
}
}
}
For local development, use http://localhost:8080/api/v1/mcp/systemprompt/mcp.
Claude Code
Claude Code supports MCP servers through its configuration. Add the server URL and it will discover tools automatically during sessions.
Any MCP Client
Any client that supports the MCP protocol over streamable HTTP can connect. The server responds to standard MCP methods: initialize, tools/list, tools/call, resources/list, and resources/read.
Security Model
MCP security in systemprompt.io operates at multiple layers:
- Transport security -- HTTPS in production. All endpoints behind TLS.
- OAuth authentication -- JWT tokens validated on every tool call. Configurable scopes and audience per server.
- RBAC enforcement -- The
enforce_rbac_from_registrymiddleware checks the token against the server's registered OAuth policy before dispatching to the handler. - Scope-based access control -- Common scope patterns:
admin-- Full administrative accessuser-- Standard user operationstools:read-- Read-only tool accesstools:write-- Tool execution permission
- Per-server isolation -- Each server runs as a separate process with its own port, database pool, and service dependencies.
- Secret encryption -- Secrets managed through MCP tools are encrypted at rest in the database.
- Content Security Policy -- UI resources served by MCP servers include strict CSP headers.
Managing MCP Servers
Syncing Configuration
After modifying MCP server YAML files, sync to the database:
systemprompt cloud sync local mcp --direction to-db -y
Building Servers
MCP servers are built as part of the workspace:
# Build all MCP servers
systemprompt build mcp
# Build a specific server
cargo build --package systemprompt-mcp-marketplace --release
CLI Reference
| Command | Description |
|---|---|
systemprompt plugins mcp list |
List MCP server configurations |
systemprompt plugins mcp status |
Show running server status with binary info |
systemprompt plugins mcp show <name> |
Show details for a specific server |
systemprompt plugins mcp tools <name> |
List tools from a running server |
systemprompt plugins mcp call <tool> |
Execute a tool on an MCP server |
systemprompt plugins mcp validate |
Validate MCP connection |
systemprompt plugins mcp logs <name> |
View MCP server logs |
systemprompt plugins mcp list-packages |
List package names for build |
Run systemprompt plugins mcp <command> --help for detailed options.
Troubleshooting
Server not discovered -- Verify enabled: true in the manifest. Check that the endpoint is accessible and the AI service has auto_discover: true set.
Tool execution fails -- Inspect server logs with systemprompt plugins mcp logs <name>. Confirm the OAuth token carries the required scopes. Increase timeout settings for long-running tools.
Authentication errors -- Ensure the client token includes the correct scopes and audience. Cross-check the oauth block in the server's YAML configuration.
Connection refused -- Confirm the server process is running on the expected port. Use systemprompt plugins mcp status to check binary and port status.
Build failures -- Run systemprompt plugins mcp list-packages to verify package names. Check that Cargo.toml dependencies are up to date.
Related Documentation
- MCP Tool Structure -- How tools are defined and structured
- MCP Responses -- Response building and artifact persistence
- MCP Resources -- Exposing resources from MCP servers
- MCP Skills -- Skill integration with MCP tools
- MCP Domain Extension -- The MCP extension domain
- MCP-AI Integration -- How MCP connects to the AI service
- Connect MCP Guide -- Step-by-step guide for connecting clients
- AI Service -- The AI service that consumes MCP tools