Remote MCP Server
Deploy @flowrag/mcp as a centralized HTTP server so multiple AI assistants can share a single knowledge base.
Architecture
┌──────────────┐ ┌──────────────┐
│ Kiro (user A)│ │Claude (user B)│
└──────┬───────┘ └──────┬───────┘
│ HTTPS │
└────────┬───────────┘
▼
┌───────────────┐
│ MCP Server │ Fargate / ECS
│ (HTTP) │
└───────┬───────┘
│ VPC
┌───────────┼───────────┐
▼ ▼ ▼
┌───────┐ ┌──────────┐ ┌───────┐
│ Redis │ │OpenSearch │ │Bedrock│
└───────┘ └──────────┘ └───────┘Server Configuration
Create flowrag.config.json:
{
"data": "./data",
"docs": "./content",
"schema": {
"entityTypes": ["SERVICE", "DATABASE", "PROTOCOL"],
"relationTypes": ["USES", "PRODUCES", "CONSUMES"]
},
"storage": {
"kv": { "provider": "redis", "url": "redis://redis.internal:6379" },
"vector": { "provider": "opensearch", "node": "https://os.internal:9200", "dimensions": 1024 },
"graph": { "provider": "opensearch", "node": "https://os.internal:9200" }
},
"embedder": { "provider": "bedrock" },
"extractor": { "provider": "bedrock" },
"namespace": "team-docs",
"transport": "http",
"port": 3000,
"auth": {
"token": "${FLOWRAG_AUTH_TOKEN}"
}
}Set the token in .env:
FLOWRAG_AUTH_TOKEN=your-secret-token
AWS_REGION=eu-central-1Client Configuration
Clients just need a URL and token — no local config, no command/args:
Kiro (mcp.json)
{
"mcpServers": {
"flowrag": {
"url": "https://flowrag.internal.company.com/mcp",
"headers": {
"Authorization": "Bearer ${FLOWRAG_TOKEN}"
}
}
}
}Claude Desktop
{
"mcpServers": {
"flowrag": {
"url": "https://flowrag.internal.company.com/mcp",
"headers": {
"Authorization": "Bearer my-secret-token"
}
}
}
}Storage Backends
Each storage type can be configured independently. Omitted types fall back to local storage.
KV Storage
| Provider | Config | Package |
|---|---|---|
redis | { "url": "redis://..." } | @flowrag/storage-redis + redis |
s3 | { "bucket": "...", "prefix": "...", "region": "..." } | @flowrag/storage-s3 |
Vector Storage
| Provider | Config | Package |
|---|---|---|
opensearch | { "node": "https://...", "dimensions": 1024 } | @flowrag/storage-opensearch + @opensearch-project/opensearch |
redis | { "url": "redis://...", "dimensions": 384 } | @flowrag/storage-redis + redis |
Graph Storage
| Provider | Config | Package |
|---|---|---|
opensearch | { "node": "https://..." } | @flowrag/storage-opensearch + @opensearch-project/opensearch |
Authentication
Bearer token authentication protects all MCP endpoints. The token supports environment variable interpolation:
{ "auth": { "token": "${FLOWRAG_AUTH_TOKEN}" } }Requests without a valid Authorization: Bearer <token> header receive a 401 response.
TIP
For a team-internal server behind a VPC, a bearer token is sufficient. The MCP SDK supports OAuth if you need it later.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /mcp | MCP requests (initialize, tool calls) |
| GET | /mcp | SSE stream for server-initiated messages |
| DELETE | /mcp | Session termination |
| GET | /health | Health check ({ "status": "ok" }) |
Docker
A complete example is available in examples/fargate/.
Dockerfile
Multi-stage build, no secrets in the image:
FROM node:24-slim AS build
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci --omit=dev
FROM node:24-slim
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY flowrag.config.json .
ENV NODE_ENV=production
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s \
CMD node -e "fetch('http://localhost:3000/health').then(r=>{if(!r.ok)throw r})" || exit 1
ENTRYPOINT ["node", "node_modules/@flowrag/mcp/dist/index.mjs"]
CMD ["--config", "flowrag.config.json"]Build and run
docker build -t flowrag-mcp .
docker run -p 3000:3000 \
-e FLOWRAG_AUTH_TOKEN=my-secret \
-e AWS_REGION=eu-central-1 \
flowrag-mcpWARNING
Never COPY .env into the image — pass secrets as environment variables at runtime. In ECS/Fargate, use the task definition environment or reference Secrets Manager / SSM Parameter Store.
Fargate Deployment
The MCP server is a good fit for Fargate/ECS:
- Always-on: No cold starts for users
- Long-running indexing: No Lambda 15-minute timeout
- Connection pooling: Persistent connections to Redis/OpenSearch
- SSE streaming: Native support for progress notifications
Use the health check endpoint (/health) for your load balancer target group.
Graceful Shutdown
The server handles SIGINT and SIGTERM signals:
- Stops accepting new connections
- Closes all active MCP sessions
- Exits cleanly
ECS sends SIGTERM before stopping a task, so sessions are cleaned up properly.
Namespace
Use the namespace field to isolate data for different teams or projects sharing the same storage backends:
{
"namespace": "team-payments",
"storage": { ... }
}See Multi-Tenancy for details on how namespacing works.