
Security News
Deno 2.6 + Socket: Supply Chain Defense In Your CLI
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.
@tscodex/mcp-sdk
Advanced tools
TypeScript SDK for creating LLM tools based on Model Context Protocol
Website: tscodex.com
@tscodex/mcp-sdk is a TypeScript SDK for quickly creating MCP (Model Context Protocol) servers. The project serves as the foundation for building LLM tools, the first of which is MCP Manager β a desktop application for managing MCP servers with a visual interface.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TSCodex Ecosystem β
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β MCP SDK βββββΆβ MCP Manager βββββΆβ Cursor Bridgeβ β
β β (Core) β β (Desktop) β β (Extension) β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β β β β
β βββββββββββββββββββββ΄βββββββββββββββββββββ β
β β β
β βββββββββΌβββββββββ β
β β MCP Servers β β
β β (Examples) β β
β βββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π¦ MCP Manager β Desktop application for managing MCP servers
π Cursor Bridge β Extension for Cursor/VS Code
TSCodex is a platform for creating LLM tools. The SDK provides core functionality for quickly creating MCP servers via HTTP, without requiring MCP Manager. Servers can be run via npx, passing ENV parameters directly.
βββββββββββββββββββ
β MCP Server β β Built on SDK
β (npm package) β
ββββββββββ¬βββββββββ
β
βββββΆ Run via npx (standalone)
β βββΆ Pass ENV parameters
β
βββββΆ Run via MCP Manager
βββΆ Visual configuration
βββΆ Secrets management
βββΆ Access control
βββΆ Usage statistics
MCP Manager is a desktop application that manages MCP servers, allows configuring them, passing secrets, authorization, AI agent, and creating dynamic tools/resources for MCP.
When working with Cursor, each open project requires its own workspace. For example, the @tscodex/mcp-images server works with images and requires the path to the current project's root directory. MCP Manager enables:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MCP Manager β
β β
β ββββββββββββββββ ββββββββββββββββ β
β β Server βββββββββββΆβ Workspace A β β
β β (Images) β β /project/foo β β
β ββββββββββββββββ βββββββββββββββββ β
β β β
β β ββββββββββββββββ β
β ββββββββββΆβ Workspace B β β
β β /project/barβ β
β ββββββββββββββββ β
β β
β SDK receives headers from current workspace β
β and allows one server to be used with different WS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
MCP Manager provides a full-featured UI for server management:
βββββββββββββββββββββββββββββββββββββββββββ
β Global Secrets β β Level 1
β (Applied to all workspaces) β
βββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Workspace Secrets β β Level 2
β (Override global) β
βββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Server Secrets β β Level 3
β (Highest priority) β
βββββββββββββββββββββββββββββββββββββββββββ
Security:
Flexible access control system:
| Category | Controls |
|---|---|
| Environment | System environment variables |
| Context | Workspace/session information |
| Secrets | Available secret keys |
| AI Access | Access to AI agent |
Environment Configuration Example:
PATH, PATHEXTHOME, USERPROFILENODE_*, npm_*Secrets Configuration Example:
MCP Manager provides an OpenAI-compatible proxy for MCP servers:
How It Works:
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β MCP Server βββββΆβ AI Proxy βββββΆβ AI Provider β
β β β (Manager) β β (OpenAI/etc) β
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β β β
β β β
βββΆ MCP_AI_PROXY_URL β β
βββΆ MCP_AI_PROXY_TOKEN β
β
Keys are NOT passed
to server directly!
Features:
Usage in SDK:
import { getAIClient } from '@tscodex/mcp-sdk';
const ai = getAIClient();
if (await ai.isAvailable()) {
const result = await ai.complete('Summarize this text...');
}
MCP Manager includes a built-in MCP Tools server that allows creating tools, resources, and prompts without writing a separate package.
Tool Types:
AI-Assisted Generation:
HTTP Tool Example:
{
"name": "get_weather",
"description": "Get weather for a city",
"executor": {
"type": "http",
"method": "GET",
"url": "https://api.weather.com/v1/weather?city={{city}}&key={{SECRET_WEATHER_KEY}}"
}
}
Available Context in Function Executor:
async (params, context) => {
// Request parameters
const { param1, param2 } = params;
// Session context
context.session.workspaceId; // Current workspace ID
context.session.projectRoot; // Project path
context.session.clientType; // Client type (cursor, claude-code)
// Request context
context.request.timestamp; // Unix timestamp
context.request.requestId; // Unique request ID
// Utilities
await context.utils.fetch(url, options);
context.utils.log(message);
return { result: "..." };
}
Cursor Bridge is an extension for Cursor/VS Code that provides seamless integration with MCP Manager.
mcp.jsonβββββββββββββββββββ
β Cursor/VS Code β
β (project open) β
ββββββββββ¬βββββββββ
β
β 1. Bridge detects project path
βΌ
βββββββββββββββββββ
β Cursor Bridge β
β (Extension) β
ββββββββββ¬βββββββββ
β
β 2. Registers workspace in MCP Manager
β 3. Gets list of available servers
β 4. Updates mcp.json
βΌ
βββββββββββββββββββ
β MCP Manager β
β (Desktop App) β
βββββββββββββββββββ
npm install @tscodex/mcp-sdk
Requirements:
import { McpServer, Type } from '@tscodex/mcp-sdk';
const server = new McpServer({
name: 'hello-server',
version: '1.0.0',
description: 'Simple hello world MCP server'
});
// Define schema with TypeBox
const HelloSchema = Type.Object({
name: Type.Optional(Type.String({
description: 'Name to greet',
default: 'World'
}))
});
// Register tool with automatic type inference
server.addTool({
name: 'hello-world',
description: 'Greet someone with a personalized message',
schema: HelloSchema,
handler: async (params, context) => {
// params is automatically typed as { name?: string }
const name = params.name || 'World';
return {
content: [{
type: 'text',
text: `Hello, ${name}!`
}]
};
}
});
// Initialize and start
await server.initialize();
await server.start();
console.log(`Server running on port ${server.serverPort}`);
Standalone (via npx):
npx @tscodex/mcp-images
With ENV parameters:
MCP_PORT=3848 MCP_PROJECT_ROOT=/path/to/project npx @tscodex/mcp-images
Via MCP Manager:
import { McpServer, Type, Static } from '@tscodex/mcp-sdk';
const ConfigSchema = Type.Object({
apiKey: Type.String({ minLength: 10 }),
timeout: Type.Number({ default: 5000 }),
enabled: Type.Boolean({ default: true })
});
type Config = Static<typeof ConfigSchema>;
const server = new McpServer<Config>({
name: 'api-server',
version: '1.0.0',
description: 'API integration server',
configSchema: ConfigSchema,
loadConfig: async () => {
// Extension config is passed via process.env.MCP_CONFIG
const extensionConfig = process.env.MCP_CONFIG
? JSON.parse(process.env.MCP_CONFIG)
: {};
return {
timeout: 5000,
enabled: true,
...extensionConfig // Extension config takes priority
};
}
});
// Access configuration in handlers
server.addTool({
name: 'api-call',
schema: Type.Object({}),
handler: async (params, context) => {
// context.config contains full configuration including secrets
const timeout = context.config.timeout;
const apiKey = context.config.apiKey;
// ...
}
});
import { McpServer, Type, Static } from '@tscodex/mcp-sdk';
enum Roles {
ADMIN = 'admin',
USER = 'user'
}
const SessionSchema = Type.Object({
email: Type.String({ format: 'email' }),
role: Type.Enum(Roles)
});
type Session = Static<typeof SessionSchema>;
const server = new McpServer<Config, Roles, Session>({
name: 'secure-server',
version: '1.0.0',
description: 'Server with role-based access',
auth: {
roles: {
admin: (session, context) => {
const allowedAdmins = context.config.adminEmails || [];
return session.role === Roles.ADMIN &&
allowedAdmins.includes(session.email);
},
user: async (session, context) => {
return session.role === Roles.USER;
}
},
sessionSchema: SessionSchema,
requireSession: true,
loadSession: async (token, context) => {
// Validate token and fetch user data
const response = await fetch(`${context.config.apiUrl}/validate-token`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` }
});
return await response.json() as Session;
}
}
});
// Tools with access control
server.addTool({
name: 'delete-file',
description: 'Delete a file (admin only)',
schema: Type.Object({ path: Type.String() }),
access: [Roles.ADMIN], // Only admins can use
handler: async (params, context) => {
// context.session is typed as Session
console.log(`Admin ${context.session.email} deleted ${params.path}`);
// ...
}
});
// Register resource (URI automatically prefixed with server ID)
server.addResource({
uri: 'about', // Becomes: hello-server://about
name: 'About',
description: 'Server information',
handler: async (uri, context) => {
return {
contents: [{
uri,
mimeType: 'text/plain',
text: 'Server information...'
}]
};
}
});
// Register prompt
server.addPrompt({
name: 'explain-topic',
description: 'Explain a topic',
arguments: Type.Object({
topic: Type.String({ description: 'Topic to explain' })
}),
handler: async (params, context) => {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: `Explain ${params.topic}`
}
}]
};
}
});
SDK provides a ready-to-use client for working with AI providers via MCP Manager:
import { getAIClient } from '@tscodex/mcp-sdk';
const ai = getAIClient();
// Always check availability before using
if (await ai.isAvailable()) {
// Simple completion
const result = await ai.complete('Summarize this text...');
// Or full chat API
const response = await ai.chat({
messages: [{ role: 'user', content: 'Hello!' }],
temperature: 0.7,
});
}
Usage in Tools:
server.addTool({
name: 'summarize',
description: 'Summarize text using AI',
schema: Type.Object({
text: Type.String({ description: 'Text to summarize' }),
}),
handler: async ({ text }) => {
// Graceful degradation when AI is not available
if (!await ai.isAvailable()) {
return {
content: [{ type: 'text', text: 'AI summarization is not available' }],
isError: true,
};
}
const summary = await ai.completeWithSystem(
'You are a helpful assistant that creates concise summaries.',
`Please summarize the following text:\n\n${text}`
);
return {
content: [{ type: 'text', text: summary }],
};
},
});
SDK supports working with multiple workspaces via HTTP headers:
server.addTool({
name: 'list-files',
schema: Type.Object({}),
handler: async (params, context) => {
// projectRoot automatically reflects per-request header
// or falls back to server-level MCP_PROJECT_ROOT
const root = context.projectRoot;
// workspaceId is available for logging/caching (optional)
const wsId = context.workspaceId;
if (!root) {
return { content: [{ type: 'text', text: 'No project root configured' }] };
}
// Files are resolved relative to the correct workspace
const files = await fs.readdir(root);
return {
content: [{ type: 'text', text: files.join('\n') }]
};
}
});
HTTP Headers:
X-MCP-Project-Root β Path to workspace project rootX-MCP-Workspace-Id β Workspace identifier (optional)When multiple workspaces share a single MCP server process, the SDK supports per-request context via HTTP headers. This allows each request to have its own projectRoot and workspaceId.
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β Workspace A β β MCP Gateway β β MCP Server β
β /projects/foo ββββββΆβ (Proxy Layer) ββββββΆβ (Shared) β
βββββββββββββββββββ β β β β
β Adds headers: β β Reads via β
βββββββββββββββββββ β X-MCP-Project- β β AsyncLocal β
β Workspace B ββββββΆβ Root β β Storage β
β /projects/bar β β X-MCP-Workspaceβ β β
βββββββββββββββββββ β -Id β β β
βββββββββββββββββββ βββββββββββββββββββ
projectRoot is resolved with the following priority:
X-MCP-Project-Root) β highest priorityMCP_PROJECT_ROOT)SDK is designed for seamless work with Cursor/VSCode extensions.
--meta flag)SDK supports metadata mode for Extension integration. When started with --meta or --metadata flag:
stdout (no logs)stderrUsage:
node dist/index.js --meta
# or
node dist/index.js --metadata
Extension automatically passes configuration via environment variables:
MCP_PORT - Server port (default: 3848)MCP_HOST - Server host (default: '0.0.0.0')MCP_PROJECT_ROOT - Workspace root directoryMCP_CONFIG - Configuration as JSON stringMCP_AUTH_TOKEN - Authentication token (for auth-enabled servers)MCP_PATH - MCP endpoint path (default: '/mcp')MCP_AI_PROXY_URL - AI proxy endpoint URL (for AI Client)MCP_AI_PROXY_TOKEN - AI proxy authentication token (for AI Client)Important: Only environment variables with MCP_ prefix are loaded into application configuration (via loadConfig). This prevents accidental exposure of system environment variables.
SDK automatically creates endpoints for Extension:
GET /health - Health check with server informationGET /gateway/metadata - Get server metadata (tools, resources, prompts, config schema)POST /gateway/config/project-root - Update project rootGET /gateway/config/current - Get current configuration (public only)POST /gateway/config - Update configuration dynamically (deep merge)safePath() for file operations to prevent path traversalsanitizeFilename()McpServer<TConfig, TRoles, TSession>Main server class.
interface McpServerOptions<TConfig, TRoles, TSession> {
// REQUIRED
name: string; // Unique server name (must start with Latin letter)
version: string; // Version (semver)
description: string; // Server description
// OPTIONAL
id?: string; // Server ID for resource prefix (auto-generated from name)
configSchema?: TSchema; // TypeBox schema for configuration
loadConfig?: () => Promise<TConfig>; // Load local configuration
auth?: AuthConfig<TRoles, TSession, TConfig>; // Authentication config
mcpPath?: string; // MCP endpoint path (default: '/mcp')
corsOptions?: CorsOptions; // CORS configuration
httpOptions?: ServerHttpOptions; // HTTP server options
securityOptions?: ServerSecurityOptions; // Security options
handlerOptions?: ServerHandlerOptions; // Handler timeout options
errorHandler?: ErrorHandler<TConfig, TSession>; // Error handler
logger?: Logger; // Custom logger
}
// Initialization
await server.initialize(): Promise<void>;
await server.start(): Promise<void>;
await server.stop(): Promise<void>;
// Tool registration
server.addTool<TSchemaType>(config: ToolConfig<TSchemaType, TConfig, TRoles, TSession>): void;
// Resource registration
server.addResource(config: ResourceConfig<TConfig, TRoles, TSession>): void;
// Prompt registration
server.addPrompt<TSchemaType>(config: PromptConfig<TSchemaType, TConfig, TRoles, TSession>): void;
// Access methods
server.getConfig(): TConfig;
server.getProjectRoot(): string | undefined;
server.getSession(): TSession | undefined;
server.getTools(): string[];
server.getResources(): string[];
server.getPrompts(): string[];
server.getMetadata(): ServerMetadata; // Get server metadata
// Properties
server.serverId: string; // Server ID (resource prefix)
server.serverPort: number; // Server port
server.serverHost: string; // Server host
server.running: boolean; // Is server running
Check the examples/ directory for complete examples:
Run examples:
tsx examples/basic-server.ts
tsx examples/with-config.ts
tsx examples/with-auth.ts
1. Extension starts process
β (env vars: MCP_PORT, MCP_HOST, MCP_PROJECT_ROOT, MCP_CONFIG, MCP_AUTH_TOKEN)
2. new McpServer(options)
- Reads port/host/projectRoot from env vars
- Creates HTTP Server
- Creates MCP Server instance
3. server.initialize()
- Loads configuration from MCP_CONFIG
- Calls loadConfig() for local settings
- Merges configurations (Extension takes priority)
- Validates via configSchema
- Loads session if auth is configured
- Filters tools/resources/prompts by access
- Sets up Extension endpoints
- Registers MCP handlers
4. server.addTool/addResource/addPrompt
- Register functionality
5. server.start()
- Starts HTTP Server
- Sets up graceful shutdown handlers
6. Server running
- Handles MCP requests
- Provides Extension endpoints
- Configuration and session available via context
@tscodex/mcp-sdk/
βββ src/
β βββ server.ts # McpServer class
β βββ types.ts # TypeScript types
β βββ config.ts # Configuration management
β βββ transport.ts # HTTP transport
β βββ security.ts # Security utilities
β βββ extension.ts # Extension types
β βββ ai-client.ts # AI Client
β βββ index.ts # Main exports
βββ examples/ # Example servers
βββ dist/ # Compiled output
libsecret-1-dev and GNOME Keyring or KDE Walletsudo apt install libsecret-1-dev gnome-keyringMIT Β© unbywyd
If you want to help with the project, especially with code signing for macOS or other aspects, please contact me!
Version: 0.0.6
Status: Production Ready
FAQs
SDK for creating MCP servers with Extension support
The npm package @tscodex/mcp-sdk receives a total of 336 weekly downloads. As such, @tscodex/mcp-sdk popularity was classified as not popular.
We found that @tscodex/mcp-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.

Security News
New DoS and source code exposure bugs in React Server Components and Next.js: whatβs affected and how to update safely.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.