mcpservice
A proxy server that enables multiple tenants to connect to Integration App's MCP server with their own isolated credentials and access tools through the Model Context Protocol.
A proxy server that enables multiple tenants to connect to Integration App's MCP server with their own isolated credentials and access tools through the Model Context Protocol.
A multi-tenant Model Context Protocol (MCP) server that enables multiple tenants to connect to Integration App s MCP server with their own credentials.
Create a .env
file with the following variables:
# Server Configuration
PORT=3000
NODE_ENV=development
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/mcp_service"
# Security
ADMIN_API_KEY="your-admin-api-key"
Clone the repository:
git clone <repository-url>
cd mcp-service
Install dependencies:
npm install
Run database migrations:
npm run migrate
Start the server:
npm start
For development:
npm run dev
GET /health
POST /api/tenants
Authorization: Bearer <admin-api-key>
{
"integrationKey": "hubspot|notion|etc",
"integrationAppToken": "your-integration-app-token"
}
POST /api/tenant/:tenantId/tool
Authorization: Bearer <tenant-token>
{
"method": "listTools"
}
POST /api/tenant/:tenantId/tool
Authorization: Bearer <tenant-token>
{
"method": "tool-name",
"params": {
// tool parameters
}
}
Create a new Heroku app:
heroku create
Add PostgreSQL addon:
heroku addons:create heroku-postgresql:hobby-dev
Set environment variables:
heroku config:set NODE_ENV=production
heroku config:set ADMIN_API_KEY=your-admin-api-key
Deploy:
git push heroku main
Build the image:
docker build -t mcp-service .
Run the container:
docker run -p 3000:3000
-e DATABASE_URL=postgresql://user:[email protected]:5432/mcp_service
-e ADMIN_API_KEY=your-admin-api-key
mcp-service
Create a new migration:
npx prisma migrate dev --name migration-name
Apply migrations:
npm run migrate
Run tests:
npm test
Run linter:
npm run lint
The server acts as a multi-tenant proxy between MCP clients and Integration App s MCP server:
MCP Client -> Multi-tenant Server -> Integration App MCP Server
(proxy/router)
Each tenant gets: - Isolated MCP client connection - Separate Integration App credentials - Independent tool discovery - Audit logging
The /health
endpoint provides:
- Server status
- Active tenant count
- Database connection status
- Memory usage
- Uptime
MIT
This service provides a multi-tenant API for managing integrations and tools via the Model Context Protocol (MCP). Each tenant is isolated and can access only their own tools and data.
To create a new tenant, you must have an admin token. Use the following steps:
Send a POST request to /api/auth/token
with your admin API key:
curl -X POST https://<your-app-url>/api/auth/token
-H "Content-Type: application/json"
-d {"key": "<ADMIN_API_KEY>"}
Response:
{"token": "<ADMIN_JWT_TOKEN>"}
Send a POST request to /api/tenants
with the admin token in the Authorization
header:
curl -X POST https://<your-app-url>/api/tenants
-H "Content-Type: application/json"
-H "Authorization: Bearer <ADMIN_JWT_TOKEN>"
-d {
"name": "<Tenant Name>",
"integrationKey": "<integration-key>",
"integrationAppToken": "<integration-app-token>"
}
Response:
{
"tenantId": "tenant-xxxxxxx",
"apiKey": "<TENANT_API_KEY>",
...
}
To interact with the API as a tenant, you need a tenant JWT token. Generate it using the tenant s API key:
curl -X POST https://<your-app-url>/api/auth/tenant-token
-H "Content-Type: application/json"
-H "x-api-key: <TENANT_API_KEY>"
Response:
{"token": "<TENANT_JWT_TOKEN>"}
To list the tools available to a tenant, use the following endpoint with both the tenant API key and JWT token:
curl -X POST https://<your-app-url>/api/tenant/<tenantId>/tool
-H "Content-Type: application/json"
-H "x-api-key: <TENANT_API_KEY>"
-H "Authorization: Bearer <TENANT_JWT_TOKEN>"
-d {"method": "listTools"}
Response:
{
"tools": [
{ "name": "create-contact", ... },
...
]
}
To execute a tool (e.g., create a contact):
curl -X POST https://<your-app-url>/api/tenant/<tenantId>/tool
-H "Content-Type: application/json"
-H "x-api-key: <TENANT_API_KEY>"
-H "Authorization: Bearer <TENANT_JWT_TOKEN>"
-d {
"method": "create-contact",
"params": {
"email": "[email protected]",
"fullName": "Test User"
}
}
Response:
{
"content": [
{ "type": "text", "text": "{"id":"120688589560"}" }
],
"isError": false
}
To connect an MCP client as a tenant:
- Use the tenant s integrationKey
and integrationAppToken
(from the tenant creation response) to initialize the client.
- Authenticate API requests with both the tenant API key and the tenant JWT token as shown above.
Example Client Initialization:
const client = new IntegrationAppClient({
token: <integrationAppToken>
});
const integration = await client.integration( <integrationKey> ).get();
// ...
id
and not tenantId
for foreign key references in the database.app.set( trust proxy , 1)
if running behind a proxy (see Express rate-limit docs).DATABASE_URL=postgresql://user:password@host:port/dbname
ADMIN_API_KEY=your_admin_api_key
POST /api/auth/token
— Get admin tokenPOST /api/tenants
— Create tenant (admin only)POST /api/auth/tenant-token
— Get tenant JWT tokenPOST /api/tenant/:tenantId/tool
— List or execute tools as a tenantFor more details, see the code in src/server.ts
and src/api/auth.ts
.