@variant/mcp-server
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., "@@variant/mcp-serverset up and start the MCP server with my custom 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.
@variant/mcp-server
Shared MCP HTTP server infrastructure for plugin projects.
Intended to use with Claude plugin projects with colocated MCP and Skills, but can also be used to build standalone MCP servers for other purposes. See marketplace plugin template for usage examples.
It provides:
Express + Streamable HTTP MCP transport setup
OAuth/OIDC auth helpers
Runtime configuration loading from environment variables and plugin config
Plugin tool registration helpers
MCP widget registration and HTML loading
A Vite-based widget build CLI
Install
pnpm add @variant/mcp-serverRelated MCP server: mcp-core
Server Usage
import {
createAndStartMcpServer,
definePluginTools,
readPluginMcpServerConfig,
} from '@variant/mcp-server';
import { registerWhoami } from '../tools/whoami/whoami.js';
const registerTools = definePluginTools([registerWhoami]);
const config = readPluginMcpServerConfig();
await createAndStartMcpServer(config, registerTools);Plugin projects are expected to run from a plugin root containing:
mcp-server/assets/icon.png.claude-plugin/plugin.jsonoptional
skills/*/tools/*/index.htmlwidget source directories
Tool Authoring
import { getRequestContext, log, type McpServer } from '@variant/mcp-server';
import { z } from 'zod';
export function registerMyTool(server: McpServer): void {
server.registerTool(
'my-tool',
{
title: 'My Tool',
description: 'Does something useful',
inputSchema: { param: z.string() },
},
async ({ param }) => {
const context = getRequestContext();
log('info', 'my-tool called', { userId: context?.userId });
return { content: [{ type: 'text', text: param }] };
},
);
}Widgets
Widget projects can use the shared Vite config:
import { defineWidgetViteConfig } from '@variant/mcp-server/vite';
export default defineWidgetViteConfig();Build widgets from the plugin root:
pnpm exec variant-build-widgets
pnpm exec variant-build-widgets -- --watch --mode developmentThe CLI discovers skills/*/tools/*/index.html directories and writes built widgets to mcp-server/dist/widgets/<tool-name-kebab>/index.html.
Browser widget entrypoints can use:
import { mountWidget } from '@variant/mcp-server/widget';Server-side tools can register widget resources with:
import { registerWidgetTool } from '@variant/mcp-server';Runtime Configuration
Configuration is read from environment variables, with defaults optionally committed by the
host project in mcp-server.config.json (env vars always win, and the file is validated on load
— see Configuring without environment variables
for the file/programmatic forms and its mcp-server.config.schema.json for editor autocomplete).
Variable | Default | Description |
|
| HTTP bind host |
|
| HTTP bind port |
|
| Streamable HTTP MCP route |
|
| Public base URL used in metadata and OAuth endpoint URLs |
|
| Max concurrent MCP sessions |
|
| Rate limit applied to auth endpoints |
|
| Passed to Express |
The full shape (exported as Config) is what loadConfig() / readPluginMcpServerConfig().runtime
returns. This is exactly what you get with no env vars and no mcp-server.config.json set — i.e. the
actual defaults, auth included:
import type { Config } from '@variant/mcp-server';
const defaults: Config = {
host: '0.0.0.0',
port: 8080,
mcpPath: '/mcp',
publicUrl: 'http://localhost:8080',
allowedRedirectOrigins: ['http://localhost', 'http://127.0.0.1', 'https://claude.ai'],
mcpMaxSessions: 200,
rateLimitPerMinute: 60,
trustProxy: 1,
auth: {
provider: 'none', // 'none' | 'generic-oidc' | 'oidc' | 'entra' | 'auth0' | 'okta' | 'keycloak' | 'cognito' | 'zitadel'
issuerUrl: '',
clientId: '',
clientSecret: '',
audience: '',
acceptedAudiences: [],
acceptedIssuers: [],
scopes: ['openid', 'profile', 'email', 'offline_access'],
scopeAliases: [],
compatibilityProxy: false,
clientRegistration: 'provider', // 'none' | 'provider' | 'static'
},
};See Authentication below for what each auth field does and how to set it.
Authentication
There's no separate on/off flag. AUTH_PROVIDER defaults to none (auth disabled); setting it
to a real provider is what turns auth on. Setting AUTH_ISSUER_URL or AUTH_CLIENT_ID while
AUTH_PROVIDER is left as none fails startup with a clear error instead of silently doing
nothing.
AUTH_PROVIDER=auth0 # none | generic-oidc | oidc | entra | auth0 | okta | keycloak | cognito | zitadel
AUTH_ISSUER_URL=https://your-tenant.auth0.com
AUTH_CLIENT_ID=your-client-idSee docs/auth for the full variable reference, the mcp-server.config.json
form, and a setup guide per provider.
Exports
@variant/mcp-server@variant/mcp-server/vite@variant/mcp-server/widget@variant/mcp-server/build-widgets
Development
pnpm install
pnpm typecheck # tsc --noEmit
pnpm lint # biome check .
pnpm format # biome format --write .
pnpm test # vitest run
pnpm build # tsc
pnpm check-exports # validate published types/exports resolve for ESM consumers
pnpm verify # run all of the abovePublishing
pnpm install
pnpm build
pnpm publish --access publicTool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
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.
Related MCP Connectors
Hosted MCP server with managed OAuth for 15+ toolkits: Google Workspace, Fitbit, Oura, Kalshi, etc.
Streamable HTTP MCP server for Google Calendar and Sheets with OAuth login.
OAuth-protected, read-only-by-default MCP server for provenance-labeled QuillCaddie project memory.
The official MCP Server from Mia-Platform to interact with Mia-Platform Console
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceA simple HTTP-based MCP server that provides demo tools (get_test_string, echo, check_maintenance), greeting prompts, and test resources, with optional OAuth 2.1 support.-
- FlicenseNot gradedqualityCmaintenanceProvides shared MCP-server machinery for Flask apps, including streamable HTTP transport, token-based auth, caller identity resolution, tool registry with permissions, and audit logging, enabling developers to build consistent and secure MCP servers.-
- FlicenseNot gradedqualityCmaintenanceA universal MCP server for registering internal, external, and OpenAPI-based APIs as MCP tools. It exposes them to MCP clients via Streamable HTTP and provides admin portal, RBAC/session auth, credential injection, and audit logging.-
- AlicenseNot gradedqualityBmaintenanceProvides a reusable MCP server foundation with explicit tool registration, operation-mode separation, scope-based permissions, structured results, and built-in health/status tools.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- 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/varianter/mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server