remote-mcp-starter
Serves as an example target SaaS for a hosted MCP integration, wrapping Toggl's API so tools can be exposed for time tracking tasks (with OAuth delegated to the upstream service, dry-run write previews, and scope-gated access).
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
remote-mcp-starter
A production-minded starting point for remote MCP servers that wrap a SaaS API (Jobber, FreshBooks, Toggl, ...).
Most community MCP servers are local stdio processes that ask the user to paste an API key. Business users can't install those, and their admins won't allow them. This starter gives you what a hosted integration needs, so each new integration is mostly tool definitions:
Streamable HTTP, stateless. A fresh server per request, so any replica can serve any request.
OAuth 2.1 broker. The MCP client logs in through your server, which delegates the login to the upstream SaaS. Upstream tokens stay server-side, encrypted at rest; MCP clients only see tokens you issued, bound to this server (RFC 8707 audience).
Client registration both ways. Client ID Metadata Documents (CIMD) and Dynamic Client Registration.
Safety layer on every tool.
Writes default to dry-run and return the planned change first.
Read-only mode hides write tools entirely.
mcp:read/mcp:writescopes.Correct
readOnlyHint/destructiveHintannotations.
Audit log. One JSON line per tool call: who, which tool, outcome, duration, arguments with secrets redacted.
Mock upstream. A built-in fake SaaS (OAuth login + notes API), so the whole flow runs locally and in tests with no real account.
Targets MCP protocol 2025-11-25, the latest supported by @modelcontextprotocol/sdk 1.32.
How the login works
MCP client this server upstream SaaS
│ /authorize (PKCE) ──▶│ │
│ │── redirect to upstream login ──────▶│ user approves
│ │◀── /oauth/callback?code ────────────│
│ │ exchange code, keep upstream tokens (sealed)
│◀── redirect ?code ────│
│ /token ─────────────▶│ issue our own access + refresh token
│ POST /mcp (Bearer) ─▶│ tool → upstream API with the user's upstream token
│ │ (refreshed automatically when close to expiry)Related MCP server: Remote MCP Server Template
Quick start
npm install
npm run dev # http://localhost:3000/mcp, using the mock upstreamConnect from Claude Code. Your browser opens the mock login page; click Approve:
claude mcp add --transport http demo http://localhost:3000/mcpThen try: "List my notes", "Create a note titled Hello" (you get a dry-run preview first), "OK, apply it".
Adding tools
Tools live in src/tools/. notes.ts is the reference:
export const deleteNote = defineTool({
kind: 'write', // 'read' | 'write'
name: 'delete_note',
title: 'Delete note',
description: 'Permanently delete a note by id. Use list_notes to find the id first.',
destructive: true,
idempotent: true,
input: { id: z.string() },
// What would change. May read upstream, must not write.
preview: async ({ id }, { upstream }) => ({ action: 'delete', note: await upstream.request(`notes/${encodeURIComponent(id)}`) }),
run: async ({ id }, { upstream }) => {
await upstream.request(`notes/${encodeURIComponent(id)}`, { method: 'DELETE' });
return { deleted: id };
},
});The framework (src/tools/framework.ts) adds the dryRun parameter, scope checks, annotations, error handling and audit records. Write preview and run; nothing else.
Tips for good tools:
Design around user tasks ("quote from a request"), not one tool per endpoint.
Write descriptions for the model: when to use the tool, what it returns.
Keep outputs small.
Pointing at a real SaaS
Register an OAuth app with the vendor. Set its redirect URI to
https://<your-host>/oauth/callback.Set the
UPSTREAM_*variables (see.env.example), and setMOCK_UPSTREAM=false.Replace
identifyinsrc/app.tswith the vendor's "who am I" call (for Jobber, a GraphQLaccount { id name }query).If the vendor's OAuth deviates from the standard (non-JSON token response, PKCE required, etc.), implement
UpstreamProvider(src/upstream/types.ts) yourself.
Configuration
Variable | Default | Purpose |
|
| Issuer and resource base. Must be |
| PUBLIC_URL host | Host header allowlist (DNS rebinding protection) |
|
| Hide all write tools |
|
|
|
| stdout | JSON-lines audit file |
| ephemeral | 32-byte base64 key for upstream tokens at rest |
| 1h / 30d | Lifetimes of tokens issued to MCP clients |
|
| Allow |
| mock | Upstream OAuth app and API base |
|
| Mount the fake upstream at |
Production checklist
MOCK_UPSTREAM=false; a persistentTOKEN_ENCRYPTION_KEYfrom a secret managerReplace
MemoryStorewith Redis or similar (implementKVStoreinsrc/auth/store.ts). Required for restarts and for more than one replicaTerminate TLS in front; set
PUBLIC_URLandALLOWED_HOSTSto the public hostnameBehind a proxy, set Express
trust proxyso the SDK's rate limiting sees real client IPsShip the audit log somewhere durable
Development
npm test # end-to-end tests: OAuth flow, CIMD, scopes, dry-run, read-only, refresh, revocation
npm run typecheck
npm run lint
npm run build && npm startLicense
MIT © Rowan Zhao. See LICENSE.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Host any HTTP API as MCP tools with a tamper-evident cross-agent settlement ledger.
Hosted MCP server with managed OAuth for 15+ toolkits: Google Workspace, Fitbit, Oura, Kalshi, etc.
Managed MCP gateway with OAuth, per-agent permissions, shared accounts and activity logs.
One OAuth connector for your team's remote MCP servers, with Tool Packs, guardrails and logs.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA 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 gradedqualityCmaintenanceEnables MCP clients to connect over stateless Streamable HTTP and authenticate through an existing OAuth 2.1 / OpenID Connect authorization server, with JWT validation, per-tool scope enforcement, and step-up challenges. It ships example scoped tools for reading and creating per-user notes that developers replace with their own.MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to securely connect to your data through a remote deployment with OAuth 2.1 and PKCE, configurable sign-in, read/write consent, and audit logging. It exposes public tools without sign-in and authenticated tools that respect each user's permissions while validating arguments and recording every call.Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables running a stateless Streamable HTTP MCP server on AWS Lambda behind API Gateway with JWT bearer authentication, per-scope tool allowlists, OAuth protected-resource metadata, and a CDK construct for deployment.MIT