@kieksme/mcp-http-kit 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +197 -2
- package/SECURITY.md +19 -0
- package/dist/auth/bearer.d.ts +14 -0
- package/dist/auth/bearer.d.ts.map +1 -0
- package/dist/auth/bearer.js +43 -0
- package/dist/auth/bearer.js.map +1 -0
- package/dist/auth/context.d.ts +7 -0
- package/dist/auth/context.d.ts.map +1 -0
- package/dist/auth/context.js +46 -0
- package/dist/auth/context.js.map +1 -0
- package/dist/auth/index.d.ts +25 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +34 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/oauth.d.ts +25 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/oauth.js +161 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/config.d.ts +30 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +201 -0
- package/dist/config.js.map +1 -0
- package/dist/http/app.d.ts +32 -0
- package/dist/http/app.d.ts.map +1 -0
- package/dist/http/app.js +127 -0
- package/dist/http/app.js.map +1 -0
- package/dist/http/host-guard.d.ts +22 -0
- package/dist/http/host-guard.d.ts.map +1 -0
- package/dist/http/host-guard.js +46 -0
- package/dist/http/host-guard.js.map +1 -0
- package/dist/http/index.d.ts +4 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +4 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/node.d.ts +36 -0
- package/dist/http/node.d.ts.map +1 -0
- package/dist/http/node.js +74 -0
- package/dist/http/node.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/start.d.ts +16 -0
- package/dist/start.d.ts.map +1 -0
- package/dist/start.js +84 -0
- package/dist/start.js.map +1 -0
- package/dist/test/helpers.d.ts +35 -0
- package/dist/test/helpers.d.ts.map +1 -0
- package/dist/test/helpers.js +171 -0
- package/dist/test/helpers.js.map +1 -0
- package/dist/test/index.d.ts +2 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +2 -0
- package/dist/test/index.js.map +1 -0
- package/dist/types.d.ts +123 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/upstream.d.ts +17 -0
- package/dist/upstream.d.ts.map +1 -0
- package/dist/upstream.js +49 -0
- package/dist/upstream.js.map +1 -0
- package/docs/migration.md +125 -0
- package/package.json +87 -4
- package/templates/Dockerfile +46 -0
- package/templates/railway.json +13 -0
- package/templates/server.json +79 -0
- package/templates/smithery.yaml +31 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Migrating existing kieksme MCP servers to `@kieksme/mcp-http-kit`
|
|
2
|
+
|
|
3
|
+
This guide covers moving servers off hand-rolled HTTP/auth helpers onto the shared kit.
|
|
4
|
+
|
|
5
|
+
## SDK decision
|
|
6
|
+
|
|
7
|
+
The kit targets **MCP TypeScript SDK v2**:
|
|
8
|
+
|
|
9
|
+
- `@modelcontextprotocol/server`
|
|
10
|
+
- `@modelcontextprotocol/node`
|
|
11
|
+
|
|
12
|
+
v2 is the current stable release line (spec 2026-07-28). The monolithic
|
|
13
|
+
`@modelcontextprotocol/sdk` (v1) is legacy. New and migrated kieksme servers
|
|
14
|
+
should use v2; do not keep a v1 adapter in the kit.
|
|
15
|
+
|
|
16
|
+
| Before | After |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| `mcp-enhancv`, `mcp-balena` | Already on v2 — swap local `http.ts` for the kit |
|
|
19
|
+
| `mcp-contabo`, `mcp-listmonk`, `mcp-swetrix`, `mcp-hashnode` | On v1 `@modelcontextprotocol/sdk` — upgrade packages + imports, then adopt the kit |
|
|
20
|
+
|
|
21
|
+
## Env var rename map
|
|
22
|
+
|
|
23
|
+
| Legacy | Canonical |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| `MCP_HTTP_AUTH_TOKEN` / `MCP_SERVER_AUTH_TOKEN` | `MCP_AUTH_TOKEN` (comma list OK) |
|
|
26
|
+
| `MCP_HTTP_PORT` (as primary) | `PORT` (fallback still reads `MCP_HTTP_PORT`) |
|
|
27
|
+
| `MCP_HTTP_ALLOWED_HOSTS` | `MCP_ALLOWED_HOSTS` |
|
|
28
|
+
| `MCP_HTTP_ALLOWED_ORIGINS` | `MCP_ALLOWED_ORIGINS` |
|
|
29
|
+
| `MCP_HTTP_ENDPOINT` | `MCP_HTTP_PATH` (default `/mcp`) |
|
|
30
|
+
| `HEALTH_ENDPOINT` | `MCP_HEALTH_PATH` (default `/health`) |
|
|
31
|
+
|
|
32
|
+
Legacy names still work and emit a one-line warning.
|
|
33
|
+
|
|
34
|
+
New knobs:
|
|
35
|
+
|
|
36
|
+
- `MCP_AUTH_MODE=bearer|oauth|none`
|
|
37
|
+
- `MCP_AUTH_ALLOW_NONE=true` (only for public read-only demos off localhost)
|
|
38
|
+
- OAuth: `MCP_OAUTH_RESOURCE`, `MCP_OAUTH_AUTHORIZATION_SERVERS`, `MCP_OAUTH_AUDIENCES`, `MCP_OAUTH_JWKS_URL`, `MCP_OAUTH_REQUIRED_SCOPES`, `MCP_OAUTH_SCOPES_SUPPORTED`
|
|
39
|
+
|
|
40
|
+
## Code shape
|
|
41
|
+
|
|
42
|
+
**Before (enhancv-style):** local `parseHttpConfig` + `createHttpServer` + Host check before `/health`.
|
|
43
|
+
|
|
44
|
+
**After:**
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { McpServer } from '@modelcontextprotocol/server';
|
|
48
|
+
import { loadConfig, startMcpServer } from '@kieksme/mcp-http-kit';
|
|
49
|
+
|
|
50
|
+
function createServer(ctx) {
|
|
51
|
+
const server = new McpServer({ name: 'my-mcp', version: '1.0.0' });
|
|
52
|
+
// register tools; ctx.auth.scopes available under oauth
|
|
53
|
+
return server;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
await startMcpServer({ createServer, config: loadConfig(process.env, { realm: 'my-mcp' }) });
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Important behavior change: **`/health` is served before Host/Origin checks** so Railway (and similar) healthchecks keep working when `MCP_ALLOWED_HOSTS` is tight.
|
|
60
|
+
|
|
61
|
+
If you previously exposed `/healthz` (listmonk) or custom health JSON, use:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const config = loadConfig(process.env, {
|
|
65
|
+
realm: 'my-mcp',
|
|
66
|
+
healthPathAliases: ['/healthz'], // or MCP_HEALTH_ALIASES=/healthz
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await startMcpServer({
|
|
70
|
+
createServer,
|
|
71
|
+
config,
|
|
72
|
+
getHealthInfo: () => ({ version: VERSION, tools: TOOL_COUNT }),
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Per-request upstream credentials
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { resolveUpstreamCredential } from '@kieksme/mcp-http-kit';
|
|
80
|
+
|
|
81
|
+
const cred = resolveUpstreamCredential(ctx.headers, {
|
|
82
|
+
mode: process.env.UPSTREAM_CREDENTIAL_MODE === 'header' ? 'header' : 'env',
|
|
83
|
+
envVar: 'CONTABO_API_KEY',
|
|
84
|
+
headerName: 'X-Contabo-Api-Key',
|
|
85
|
+
authMode: ctx.auth.mode,
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Header mode is rejected when `MCP_AUTH_MODE=none`.
|
|
90
|
+
|
|
91
|
+
## Deploy templates
|
|
92
|
+
|
|
93
|
+
Copy from this repo’s `templates/`:
|
|
94
|
+
|
|
95
|
+
- `Dockerfile` — multi-stage, non-root, `HEALTHCHECK` on `/health`
|
|
96
|
+
- `railway.json` — `healthcheckPath: /health`
|
|
97
|
+
- `server.json` — npm + OCI + `remotes` streamable-http for the official registry
|
|
98
|
+
- `smithery.yaml` — container runtime, HTTP start command
|
|
99
|
+
|
|
100
|
+
## Contract tests
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { createMcpHttpApp } from '@kieksme/mcp-http-kit';
|
|
104
|
+
import { createAppTestClient, createKitContractAssertions } from '@kieksme/mcp-http-kit/test';
|
|
105
|
+
|
|
106
|
+
const config = loadConfig({ /* test env */ });
|
|
107
|
+
const app = createMcpHttpApp({ createServer, config });
|
|
108
|
+
const client = createAppTestClient(app, config);
|
|
109
|
+
const assertions = createKitContractAssertions(client, config);
|
|
110
|
+
|
|
111
|
+
await assertions.healthUnauthenticated();
|
|
112
|
+
await assertions.unauthorizedWithoutToken();
|
|
113
|
+
await assertions.forbiddenOnBadHost();
|
|
114
|
+
await assertions.initializeAndListTools(token);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Checklist
|
|
118
|
+
|
|
119
|
+
1. Bump to `@modelcontextprotocol/server` + `@modelcontextprotocol/node` (drop v1 sdk).
|
|
120
|
+
2. Add `@kieksme/mcp-http-kit` dependency.
|
|
121
|
+
3. Replace local HTTP/auth modules with `loadConfig` + `startMcpServer`.
|
|
122
|
+
4. Rename Railway/Docker env vars (or keep aliases temporarily).
|
|
123
|
+
5. Ensure `/health` is what Railway probes (kit default).
|
|
124
|
+
6. Copy deploy templates; publish `server.json` via `mcp-publisher` if applicable.
|
|
125
|
+
7. Import kit contract assertions in CI.
|
package/package.json
CHANGED
|
@@ -1,6 +1,89 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kieksme/mcp-http-kit",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Shared Streamable HTTP transport, auth (bearer + OAuth 2.1 resource server), and deploy tooling for kieksme MCP servers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./test": {
|
|
14
|
+
"types": "./dist/test/index.d.ts",
|
|
15
|
+
"import": "./dist/test/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./package.json": "./package.json"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"templates",
|
|
22
|
+
"docs",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"SECURITY.md"
|
|
26
|
+
],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22.14.0"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/kieksme/mcp-http-kit.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/kieksme/mcp-http-kit#readme",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/kieksme/mcp-http-kit/issues"
|
|
37
|
+
},
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"keywords": [
|
|
40
|
+
"mcp",
|
|
41
|
+
"model-context-protocol",
|
|
42
|
+
"streamable-http",
|
|
43
|
+
"oauth",
|
|
44
|
+
"railway",
|
|
45
|
+
"kieksme"
|
|
46
|
+
],
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public",
|
|
49
|
+
"provenance": true
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"prebuild": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\"",
|
|
53
|
+
"build": "tsc -p tsconfig.build.json",
|
|
54
|
+
"prepare": "node scripts/prepare.mjs",
|
|
55
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
56
|
+
"test": "vitest run",
|
|
57
|
+
"test:watch": "vitest",
|
|
58
|
+
"lint": "eslint .",
|
|
59
|
+
"lint:fix": "eslint . --fix",
|
|
60
|
+
"pack:check": "node scripts/pack-check.mjs",
|
|
61
|
+
"example:echo": "tsx examples/echo-server/src/index.ts"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@modelcontextprotocol/node": "^2.1.0",
|
|
65
|
+
"@modelcontextprotocol/server": "^2.3.0",
|
|
66
|
+
"jose": "^6.2.13"
|
|
67
|
+
},
|
|
68
|
+
"peerDependencies": {
|
|
69
|
+
"@modelcontextprotocol/node": "^2.1.0",
|
|
70
|
+
"@modelcontextprotocol/server": "^2.3.0"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@eslint/js": "^9.39.5",
|
|
74
|
+
"@modelcontextprotocol/client": "^2.3.1",
|
|
75
|
+
"@types/node": "^22.0.0",
|
|
76
|
+
"eslint": "^9.39.2",
|
|
77
|
+
"tsx": "^4.20.0",
|
|
78
|
+
"typescript": "^5.9.3",
|
|
79
|
+
"typescript-eslint": "^8.71.1",
|
|
80
|
+
"vitest": "^3.2.4",
|
|
81
|
+
"zod": "^4.6.7"
|
|
82
|
+
},
|
|
83
|
+
"pnpm": {
|
|
84
|
+
"onlyBuiltDependencies": [
|
|
85
|
+
"esbuild"
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
"packageManager": "pnpm@10.33.2"
|
|
89
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
#
|
|
3
|
+
# Template Dockerfile for a kieksme MCP server using @kieksme/mcp-http-kit.
|
|
4
|
+
# Copy next to your server package.json and adjust COPY paths / labels.
|
|
5
|
+
#
|
|
6
|
+
# Runtime secrets (never bake into the image):
|
|
7
|
+
# MCP_AUTH_TOKEN — bearer token(s), comma-separated for rotation
|
|
8
|
+
# <SERVICE>_API_KEY — upstream API credentials
|
|
9
|
+
#
|
|
10
|
+
# Railway / containers: PORT is honored by the kit (fallback MCP_HTTP_PORT).
|
|
11
|
+
|
|
12
|
+
ARG NODE_VERSION=22-alpine
|
|
13
|
+
ARG PNPM_VERSION=10.33.2
|
|
14
|
+
|
|
15
|
+
# ---- build ----
|
|
16
|
+
FROM node:${NODE_VERSION} AS build
|
|
17
|
+
ARG PNPM_VERSION
|
|
18
|
+
WORKDIR /app
|
|
19
|
+
RUN npm install -g pnpm@${PNPM_VERSION}
|
|
20
|
+
COPY package.json pnpm-lock.yaml ./
|
|
21
|
+
RUN pnpm install --frozen-lockfile
|
|
22
|
+
COPY tsconfig.json tsconfig.build.json ./
|
|
23
|
+
COPY src ./src
|
|
24
|
+
RUN pnpm build && pnpm prune --prod
|
|
25
|
+
|
|
26
|
+
# ---- runtime ----
|
|
27
|
+
FROM node:${NODE_VERSION} AS runtime
|
|
28
|
+
LABEL org.opencontainers.image.title="REPLACE_WITH_SERVER_NAME" \
|
|
29
|
+
org.opencontainers.image.description="MCP server (Streamable HTTP)" \
|
|
30
|
+
org.opencontainers.image.source="https://github.com/kieksme/REPLACE_WITH_REPO" \
|
|
31
|
+
org.opencontainers.image.licenses="MIT"
|
|
32
|
+
ENV NODE_ENV=production \
|
|
33
|
+
MCP_TRANSPORT=http \
|
|
34
|
+
MCP_HTTP_HOST=0.0.0.0 \
|
|
35
|
+
PORT=3000 \
|
|
36
|
+
MCP_ALLOWED_HOSTS=localhost,127.0.0.1
|
|
37
|
+
WORKDIR /app
|
|
38
|
+
COPY --from=build --chown=node:node /app/package.json ./package.json
|
|
39
|
+
COPY --chown=node:node LICENSE ./LICENSE
|
|
40
|
+
COPY --from=build --chown=node:node /app/dist ./dist
|
|
41
|
+
COPY --from=build --chown=node:node /app/node_modules ./node_modules
|
|
42
|
+
USER node
|
|
43
|
+
EXPOSE 3000
|
|
44
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
45
|
+
CMD node -e "fetch('http://127.0.0.1:'+(process.env.PORT||process.env.MCP_HTTP_PORT||3000)+'/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
|
|
46
|
+
CMD ["node", "dist/index.js"]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://railway.com/railway.schema.json",
|
|
3
|
+
"build": {
|
|
4
|
+
"builder": "DOCKERFILE",
|
|
5
|
+
"dockerfilePath": "Dockerfile"
|
|
6
|
+
},
|
|
7
|
+
"deploy": {
|
|
8
|
+
"healthcheckPath": "/health",
|
|
9
|
+
"healthcheckTimeout": 30,
|
|
10
|
+
"restartPolicyType": "ON_FAILURE",
|
|
11
|
+
"restartPolicyMaxRetries": 3
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.kieksme/REPLACE_WITH_SERVER_NAME",
|
|
4
|
+
"title": "REPLACE_WITH_TITLE",
|
|
5
|
+
"description": "REPLACE_WITH_DESCRIPTION",
|
|
6
|
+
"repository": {
|
|
7
|
+
"url": "https://github.com/kieksme/REPLACE_WITH_REPO",
|
|
8
|
+
"source": "github"
|
|
9
|
+
},
|
|
10
|
+
"websiteUrl": "https://github.com/kieksme/REPLACE_WITH_REPO#readme",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"packages": [
|
|
13
|
+
{
|
|
14
|
+
"registryType": "npm",
|
|
15
|
+
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
|
+
"identifier": "@kieksme/REPLACE_WITH_NPM_NAME",
|
|
17
|
+
"version": "0.1.0",
|
|
18
|
+
"runtimeHint": "npx",
|
|
19
|
+
"transport": {
|
|
20
|
+
"type": "stdio"
|
|
21
|
+
},
|
|
22
|
+
"environmentVariables": [
|
|
23
|
+
{
|
|
24
|
+
"name": "REPLACE_WITH_UPSTREAM_API_KEY_ENV",
|
|
25
|
+
"description": "Upstream API key for the service this MCP server wraps.",
|
|
26
|
+
"isRequired": true,
|
|
27
|
+
"isSecret": true,
|
|
28
|
+
"format": "string"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"registryType": "oci",
|
|
34
|
+
"identifier": "ghcr.io/kieksme/REPLACE_WITH_REPO",
|
|
35
|
+
"version": "0.1.0",
|
|
36
|
+
"transport": {
|
|
37
|
+
"type": "streamable-http",
|
|
38
|
+
"url": "http://localhost:3000/mcp"
|
|
39
|
+
},
|
|
40
|
+
"environmentVariables": [
|
|
41
|
+
{
|
|
42
|
+
"name": "MCP_AUTH_TOKEN",
|
|
43
|
+
"description": "Bearer token MCP clients must send (Authorization: Bearer …). Comma-separated list allowed for rotation.",
|
|
44
|
+
"isRequired": true,
|
|
45
|
+
"isSecret": true,
|
|
46
|
+
"format": "string"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "REPLACE_WITH_UPSTREAM_API_KEY_ENV",
|
|
50
|
+
"description": "Upstream API key for the service this MCP server wraps.",
|
|
51
|
+
"isRequired": true,
|
|
52
|
+
"isSecret": true,
|
|
53
|
+
"format": "string"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "MCP_ALLOWED_HOSTS",
|
|
57
|
+
"description": "Comma-separated Host allowlist (required when binding beyond localhost).",
|
|
58
|
+
"isRequired": true,
|
|
59
|
+
"isSecret": false,
|
|
60
|
+
"format": "string"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"remotes": [
|
|
66
|
+
{
|
|
67
|
+
"type": "streamable-http",
|
|
68
|
+
"url": "https://REPLACE_WITH_PUBLIC_HOST/mcp",
|
|
69
|
+
"headers": [
|
|
70
|
+
{
|
|
71
|
+
"name": "Authorization",
|
|
72
|
+
"description": "Bearer token (MCP_AUTH_TOKEN). Format: Bearer <token>",
|
|
73
|
+
"isRequired": true,
|
|
74
|
+
"isSecret": true
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Smithery project config — https://smithery.ai/docs/build/project-config
|
|
2
|
+
#
|
|
3
|
+
# Container runtime: Smithery builds the Dockerfile and connects over
|
|
4
|
+
# Streamable HTTP. The kit honors PORT (Smithery sets it) and serves MCP at
|
|
5
|
+
# /mcp by default. Copy to the server repo root and fill configSchema.
|
|
6
|
+
|
|
7
|
+
runtime: container
|
|
8
|
+
|
|
9
|
+
build:
|
|
10
|
+
dockerfile: Dockerfile
|
|
11
|
+
dockerBuildPath: .
|
|
12
|
+
|
|
13
|
+
startCommand:
|
|
14
|
+
type: http
|
|
15
|
+
configSchema:
|
|
16
|
+
type: object
|
|
17
|
+
properties:
|
|
18
|
+
mcpAuthToken:
|
|
19
|
+
type: string
|
|
20
|
+
title: MCP bearer token
|
|
21
|
+
description: Value for MCP_AUTH_TOKEN (clients send Authorization: Bearer …).
|
|
22
|
+
upstreamApiKey:
|
|
23
|
+
type: string
|
|
24
|
+
title: Upstream API key
|
|
25
|
+
description: Service API key mapped to your server's env var.
|
|
26
|
+
required:
|
|
27
|
+
- mcpAuthToken
|
|
28
|
+
- upstreamApiKey
|
|
29
|
+
exampleConfig:
|
|
30
|
+
mcpAuthToken: "replace-me"
|
|
31
|
+
upstreamApiKey: "replace-me"
|