Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ REQUIRE_HTTPS=false
# Restrict allowed hosts (comma-separated)
# ALLOWED_HOSTS=localhost,yourdomain.com

# Session secret (use a secure random string in production)
SESSION_SECRET=dev-session-secret-change-in-production

# ===== OAuth Dynamic Client Registration (DCR) Configuration =====
# Storage backend: auto (default), memory, file, redis
# DCR_STORE_TYPE=auto
Expand Down
1 change: 0 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,6 @@ The following environment variables affect API behavior:
- `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET` for Microsoft OAuth
- `ALLOWED_ORIGINS`: Comma-separated list of allowed CORS origins
- `ALLOWED_HOSTS`: Comma-separated list of allowed hosts
- `SESSION_SECRET`: Secret key for session management

## Security Considerations

Expand Down
1 change: 0 additions & 1 deletion docs/dual-mode-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ EXPOSE 8080
- [ ] Configure real Google OAuth credentials
- [ ] Set `REQUIRE_HTTPS=true`
- [ ] Configure `ALLOWED_ORIGINS`
- [ ] Set secure `SESSION_SECRET`
- [ ] Configure SSL/TLS certificates
- [ ] Set up reverse proxy (nginx, etc.)
- [ ] Configure monitoring and logging
Expand Down
1 change: 0 additions & 1 deletion docs/oauth-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,6 @@ export NODE_ENV=production
export MCP_MODE=streamable_http
export REQUIRE_HTTPS=true
export ALLOWED_ORIGINS=https://yourdomain.com
export SESSION_SECRET=your-secure-session-secret
# Set provider-specific credentials
```

Expand Down
2 changes: 0 additions & 2 deletions docs/vercel-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,6 @@ Generic OAuth provider support is planned but not yet implemented. Currently sup

```bash
NODE_ENV=production
SESSION_SECRET=random-secret-at-least-32-chars
SESSION_TIMEOUT_MINUTES=60
REQUIRE_HTTPS=true
```

Expand Down
9 changes: 0 additions & 9 deletions packages/config/src/base-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,3 @@ export const BaseConfigSchema = z.object({
});

export type BaseConfig = z.infer<typeof BaseConfigSchema>;

/**
* Session secret schema (separate for security)
*/
export const SessionSecretSchema = z.object({
SESSION_SECRET: z.string().default('dev-session-secret-change-in-production'),
});

export type SessionSecret = z.infer<typeof SessionSecretSchema>;
25 changes: 6 additions & 19 deletions packages/config/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { z } from 'zod';
import { BaseConfigSchema, SessionSecretSchema, TransportMode } from './base-config.js';
import { BaseConfigSchema, TransportMode } from './base-config.js';
import { OAuthConfigSchema, OAuthSecretsSchema } from './oauth-config.js';
import { LLMSecretsSchema } from './llm-config.js';
import { StorageConfigSchema } from './storage-config.js';
Expand All @@ -25,8 +25,7 @@ export const ConfigurationSchema = BaseConfigSchema
/**
* Secret configuration schema (never log)
*/
export const SecretsSchema = SessionSecretSchema
.merge(OAuthSecretsSchema)
export const SecretsSchema = OAuthSecretsSchema
.merge(LLMSecretsSchema);

/**
Expand Down Expand Up @@ -124,7 +123,6 @@ export class EnvironmentConfig {
REQUIRE_HTTPS: process.env.REQUIRE_HTTPS === 'true',
ALLOWED_ORIGINS: process.env.ALLOWED_ORIGINS,
ALLOWED_HOSTS: process.env.ALLOWED_HOSTS,
SESSION_SECRET: process.env.SESSION_SECRET ?? 'dev-session-secret-change-in-production',
NODE_ENV: process.env.NODE_ENV ?? 'development',

// LLM Provider API keys
Expand Down Expand Up @@ -169,20 +167,11 @@ export class EnvironmentConfig {

for (const key of secretKeys) {
const value = env[key];
// Special handling for SESSION_SECRET which has a default value
if (key === 'SESSION_SECRET') {
if (value && value !== 'dev-session-secret-change-in-production') {
configured.push(key);
} else {
missing.push(key);
}
// Check if secret has a value
if (value) {
configured.push(key);
} else {
// For all other secrets, just check if they have a value
if (value) {
configured.push(key);
} else {
missing.push(key);
}
missing.push(key);
}
}

Expand Down Expand Up @@ -355,15 +344,13 @@ export class EnvironmentConfig {
requireHttps: boolean;
allowedOrigins: string[] | undefined;
allowedHosts: string[] | undefined;
sessionSecret: string;
} {
const env = this.get();

return {
requireHttps: env.REQUIRE_HTTPS || this.isProduction(),
allowedOrigins: env.ALLOWED_ORIGINS ? env.ALLOWED_ORIGINS.split(',') : undefined,
allowedHosts: env.ALLOWED_HOSTS ? env.ALLOWED_HOSTS.split(',') : undefined,
sessionSecret: env.SESSION_SECRET,
};
}

Expand Down
20 changes: 0 additions & 20 deletions packages/config/test/environment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ describe('EnvironmentConfig', () => {
delete process.env.REQUIRE_HTTPS;
delete process.env.ALLOWED_ORIGINS;
delete process.env.ALLOWED_HOSTS;
delete process.env.SESSION_SECRET;
delete process.env.NODE_ENV;
delete process.env.ANTHROPIC_API_KEY;
delete process.env.OPENAI_API_KEY;
Expand All @@ -47,7 +46,6 @@ describe('EnvironmentConfig', () => {
expect(security.requireHttps).toBe(false);
expect(security.allowedOrigins).toBeUndefined();
expect(security.allowedHosts).toBeUndefined();
expect(security.sessionSecret).toBe('dev-session-secret-change-in-production');
});

test('parses provided environment variables into strongly typed configuration', () => {
Expand All @@ -58,7 +56,6 @@ describe('EnvironmentConfig', () => {
process.env.REQUIRE_HTTPS = 'true';
process.env.ALLOWED_ORIGINS = 'https://one.example,https://two.example';
process.env.ALLOWED_HOSTS = 'one.example,two.example';
process.env.SESSION_SECRET = 'super-secret';
process.env.NODE_ENV = 'production';

EnvironmentConfig.reset();
Expand Down Expand Up @@ -86,7 +83,6 @@ describe('EnvironmentConfig', () => {
'one.example',
'two.example'
]);
expect(security.sessionSecret).toBe('super-secret');
});

describe('Secret Status Reporting', () => {
Expand Down Expand Up @@ -124,21 +120,5 @@ describe('EnvironmentConfig', () => {
expect(status.secrets.missing).toContain('GOOGLE_CLIENT_ID');
expect(status.secrets.missing).toContain('GOOGLE_CLIENT_SECRET');
});

it('correctly reports SESSION_SECRET as missing only when using default value', () => {
// Test with default value - should be missing
delete process.env.SESSION_SECRET;
EnvironmentConfig.reset();
let status = EnvironmentConfig.getConfigurationStatus();
expect(status.secrets.missing).toContain('SESSION_SECRET');
expect(status.secrets.configured).not.toContain('SESSION_SECRET');

// Test with custom value - should be configured
process.env.SESSION_SECRET = 'my-custom-secret';
EnvironmentConfig.reset();
status = EnvironmentConfig.getConfigurationStatus();
expect(status.secrets.configured).toContain('SESSION_SECRET');
expect(status.secrets.missing).not.toContain('SESSION_SECRET');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ REQUIRE_HTTPS=false
# Restrict allowed hosts (comma-separated)
# ALLOWED_HOSTS=localhost,yourdomain.com

# Session secret (use a secure random string in production)
SESSION_SECRET=dev-session-secret-change-in-production

# ===== OAuth Dynamic Client Registration (DCR) Configuration =====
# Storage backend: auto (default), memory, file, redis
# DCR_STORE_TYPE=auto
Expand Down
1 change: 0 additions & 1 deletion packages/example-mcp/test/integration/admin-routes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ describe('Admin Routes Integration', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: true,
sessionSecret: 'test-secret',
enableResumability: true,
enableJsonResponse: true,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ describe('Admin Token Management Endpoints Integration', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: true,
sessionSecret: 'test-secret',
enableResumability: true,
enableJsonResponse: true,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ describe('OAuth 2.0 Dynamic Client Registration (DCR) Endpoints', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: true,
sessionSecret: 'test-secret-dcr',
enableResumability: true,
enableJsonResponse: true,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ describe('OAuth Discovery Endpoints Integration', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: true,
sessionSecret: 'test-secret',
enableResumability: true,
enableJsonResponse: true,
});
Expand Down Expand Up @@ -105,7 +104,6 @@ describe('OAuth Discovery Endpoints Integration', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: false,
sessionSecret: 'test-secret',
});

await serverNoAuth.initialize();
Expand Down Expand Up @@ -155,7 +153,6 @@ describe('OAuth Discovery Endpoints Integration', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: false,
sessionSecret: 'test-secret',
});

await serverNoAuth.initialize();
Expand Down Expand Up @@ -206,7 +203,6 @@ describe('OAuth Discovery Endpoints Integration', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: false,
sessionSecret: 'test-secret',
enableResumability: false,
});

Expand Down Expand Up @@ -262,7 +258,6 @@ describe('OAuth Discovery Endpoints Integration', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: false,
sessionSecret: 'test-secret',
});

await serverNoAuth.initialize();
Expand Down
2 changes: 0 additions & 2 deletions packages/example-mcp/test/integration/health-routes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ describe('Health Routes Integration', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: true,
sessionSecret: 'test-secret',
enableResumability: true,
enableJsonResponse: true,
});
Expand Down Expand Up @@ -298,7 +297,6 @@ describe('Health Routes Integration', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: false,
sessionSecret: 'test-secret',
enableResumability: false,
enableJsonResponse: false,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ describe('OpenAPI Compliance Integration Tests', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: false, // No auth for compliance testing
sessionSecret: 'test-secret',
});

await server.initialize();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ describe('Route Coverage - Detect Undocumented Routes', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: false,
sessionSecret: 'test-secret',
});

await server.initialize();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ describe('Session Reconstruction Integration Tests', () => {
host: 'localhost',
endpoint: '/mcp',
requireAuth: false, // Skip OAuth for testing
sessionSecret: 'test-secret',
enableResumability: true, // REQUIRED for session reconstruction tests
enableJsonResponse: true,
toolRegistry: toolRegistry, // Pass pre-populated tool registry for session reconstruction
Expand Down
1 change: 0 additions & 1 deletion packages/http-server/src/server/streamable-http-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export interface StreamableHttpServerOptions {
requireAuth: boolean;
allowedOrigins?: string[];
allowedHosts?: string[];
sessionSecret: string;
enableResumability?: boolean;
enableJsonResponse?: boolean;
toolRegistry?: ToolRegistry;
Expand Down
2 changes: 0 additions & 2 deletions packages/http-server/src/transport/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ export class StreamableHTTPTransportManager implements TransportManager {
requireAuth: this.options.requireAuth,
allowedOrigins: this.options.allowedOrigins,
allowedHosts: this.options.allowedHosts,
sessionSecret: this.options.sessionSecret,
enableResumability: this.options.enableResumability,
enableJsonResponse: this.options.enableJsonResponse,
toolRegistry: this.toolRegistry, // Pass the tool registry for session reconstruction
Expand Down Expand Up @@ -276,7 +275,6 @@ export class TransportFactory implements ITransportFactory {
requireAuth: !EnvironmentConfig.shouldSkipAuth(),
allowedOrigins: streamableSecurityConfig.allowedOrigins,
allowedHosts: streamableSecurityConfig.allowedHosts,
sessionSecret: streamableSecurityConfig.sessionSecret,
enableResumability: true, // Enable resumability by default
enableJsonResponse: true, // Use JSON responses for HTTP clients
});
Expand Down
1 change: 0 additions & 1 deletion packages/http-server/src/transport/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export interface StreamableHTTPTransportOptions {
requireAuth: boolean;
allowedOrigins?: string[];
allowedHosts?: string[];
sessionSecret: string;
enableResumability?: boolean;
enableJsonResponse?: boolean;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ describe('MCPStreamableHttpServer', () => {
host: '127.0.0.1',
endpoint: '/stream',
requireAuth: false,
sessionSecret: 'secret',
enableResumability: false,
enableJsonResponse: false,
...options
Expand Down
6 changes: 1 addition & 5 deletions packages/http-server/test/transport/factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('TransportFactory', () => {
it('creates streamable HTTP transport with resumability enabled', () => {
vi.spyOn(EnvironmentConfig, 'getTransportMode').mockReturnValue(TransportMode.STREAMABLE_HTTP);
vi.spyOn(EnvironmentConfig, 'getServerConfig').mockReturnValue({ port: 3000, host: 'localhost', mode: TransportMode.STREAMABLE_HTTP });
vi.spyOn(EnvironmentConfig, 'getSecurityConfig').mockReturnValue({ allowedOrigins: undefined, allowedHosts: undefined, sessionSecret: 'secret', requireHttps: false });
vi.spyOn(EnvironmentConfig, 'getSecurityConfig').mockReturnValue({ allowedOrigins: undefined, allowedHosts: undefined, requireHttps: false });
vi.spyOn(EnvironmentConfig, 'shouldSkipAuth').mockReturnValue(true);

const transport = TransportFactory.createFromEnvironment();
Expand All @@ -50,7 +50,6 @@ describe('TransportFactory', () => {
requireAuth: false,
allowedOrigins: [],
allowedHosts: [],
sessionSecret: 'secret',
enableResumability: false,
enableJsonResponse: false
});
Expand Down Expand Up @@ -92,7 +91,6 @@ describe('TransportFactory', () => {
requireAuth: true,
allowedOrigins: ['http://example.com'],
allowedHosts: ['example.com'],
sessionSecret: 'test-secret',
enableResumability: true,
enableJsonResponse: true
};
Expand Down Expand Up @@ -192,7 +190,6 @@ describe('TransportFactory', () => {
requireAuth: false,
allowedOrigins: ['*'],
allowedHosts: ['localhost'],
sessionSecret: 'test-session-secret',
enableResumability: true,
enableJsonResponse: false
};
Expand Down Expand Up @@ -224,7 +221,6 @@ describe('TransportFactory', () => {
requireAuth: true,
allowedOrigins: [],
allowedHosts: [],
sessionSecret: 'secure-secret',
enableResumability: true,
enableJsonResponse: true
});
Expand Down
Loading