About Module SDK
Module SDK is an MCP server in the Cloud category: sDK for building Odel modules — a thin, additive wrapper over the Model Context Protocol TypeScript SDK for Cloudflare Workers.
Recent commit activity is the strongest signal that reported issues will get attention.
Install
claude mcp add module-sdk -- npx -y @odel/module-sdknpx -y @odel/module-sdkThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Module SDK
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
Odel Module SDK

Fork of the Model Context Protocol TypeScript SDK with Odel-specific extensions for the Odel Platform
SDK for building Odel modules - full MCP protocol implementation with additional utilities for context management, error handling, and input validation.
Overview
This SDK provides:
- Full MCP protocol implementation (tools, resources, prompts)
- Odel context management (user info, secrets, request tracking)
- Standardized error handling with error codes
- Common validators for inputs (email, URL, API keys, etc.)
- Response schema helpers for consistent API responses
Installation
npm install @odel/module-sdk zod
This SDK has a required peer dependency on zod for schema validation.
Quick Start
import { McpServer } from '@odel/module-sdk/server';
import { z } from 'zod';
import { extractToolContext, getRequiredSecret, ModuleError, SuccessResponseSchema, validators } from '@odel/module-sdk/odel';
// Define your response schema
const SendEmailResponseSchema = SuccessResponseSchema(
z.object({
messageId: z.string(),
sentAt: z.string()
})
);
// Create your MCP server
const server = new McpServer({
name: 'email-module',
version: '1.0.0'
});
// Register a tool
server.tool(
'send-email',
'Send an email',
{
to: validators.email(),
subject: validators.nonEmptyString(),
body: z.string()
},
async (args, extra) => {
// Extract Odel context (userId, secrets, etc.)
const ctx = extractToolContext(extra.requestBody, process.env);
// Get required secrets
const apiKey = getRequiredSecret(ctx, 'RESEND_API_KEY');
try {
// Your implementation here
const result = await sendEmail(apiKey, args);
return {
content: [
{
type: 'text',
text: JSON.stringify({
success: true,
messageId: result.id,
sentAt: new Date().toISOString()
})
}
]
};
} catch (error) {
throw ModuleError.apiError('Failed to send email', {
originalError: error.message
});
}
}
);
Odel Extensions
All Odel-specific utilities are available from @odel/module-sdk/odel:
import {
// Context
extractContext,
createToolContext,
extractToolContext,
getRequiredSecret,
getOptionalSecret,
DEFAULT_MODULE_CONTEXT,
// Types
type ModuleContext,
type ToolContext,
type RequestBodyWithContext,
// Errors
ModuleError,
ErrorCode,
// Validators
validators,
// Schemas
SuccessResponseSchema,
SimpleSuccessSchema,
type SuccessResponse,
type ErrorResponse
} from '@odel/module-sdk/odel';
Context
The Odel platform injects context into every module request, including user information and decrypted secrets.
ModuleContext
interface ModuleContext {
userId: string; // Hashed user ID (privacy-preserving)
conversationId?: string; // Optional conversation ID
displayName?: string; // User's display name
timestamp: number; // Request timestamp
requestId: string; // Unique request identifier
secrets: Record<string, string>; // Decrypted user secrets
}
ToolContext
For Cloudflare Workers, ToolContext<Env> extends ModuleContext with typed environment bindings:
interface ToolContext<Env> extends ModuleContext {
env: Env; // Cloudflare Worker bindings
}
Context Functions
// Extract context from JSON-RPC request body
const moduleContext = extractContext(requestBody);
// Create tool context with env bindings
const toolContext = createToolContext(moduleContext, env);
// Or do both in one step
const toolContext = extractToolContext(requestBody, env);
// Access secrets safely
const apiKey = getRequiredSecret(ctx, 'API_KEY'); // Throws if missing
const webhook = getOptionalSecret(ctx, 'WEBHOOK_URL'); // Returns undefined if missing
Error Handling
Standardized error codes and a ModuleError class for consistent error responses.
Error Codes
| Range | Category | Codes |
|---|---|---|
| 1xxx | Validation | INVALID_INPUT, MISSING_REQUIRED_FIELD, INVALID_FORMAT |
| 2xxx | Auth | MISSING_SECRET, INVALID_SECRET, UNAUTHORIZED |
| 3xxx | API | API_ERROR, NETWORK_ERROR, TIMEOUT, NOT_FOUND |
| 4xxx | Rate Limit | RATE_LIMIT_EXCEEDED, QUOTA_EXCEEDED |
| 5xxx | Internal | INTERNAL_ERROR, NOT_IMPLEMENTED, CONFIGURATION_ERROR |
Factory Methods
// Validation errors
ModuleError.validationError('Invalid email format', { field: 'email' });
ModuleError.missingField('subject');
// Auth errors
ModuleError.missingSecret('RESEND_API_KEY');
ModuleError.invalidSecret('API_KEY', 'must start with sk-');
// API errors
ModuleError.apiError('Service unavailable', { statusCode: 503 });
ModuleError.networkError('Connection refused');
ModuleError.timeout('API call', 30000);
ModuleError.notFound('User', 'user_123');
// Rate limiting
ModuleError.rateLimitError(60); // retryAfter in seconds
ModuleError.quotaExceeded('API calls');
// Internal
ModuleError.internalError('Unexpected state');
ModuleError.notImplemented('bulk export');
ModuleError.configurationError('Missing database binding');
JSON Serialization
const error = ModuleError.apiError('Service unavailable', { statusCode: 503 });
console.log(error.toJSON());
// {
// success: false,
// error: 'Service unavailable',
// code: 3001,
// metadata: { statusCode: 503 }
// }
Validators
Pre-built Zod schemas for common input validation:
import { validators } from '@odel/module-sdk/odel';
import { z } from 'zod';
const inputSchema = z.object({
// Email validation
email: validators.email(),
recipients: validators.emailList(), // Array or comma-separated string
// URL validation
website: validators.url(), // http or https
webhook: validators.httpsUrl(), // https only
// API keys
apiKey: validators.apiKey(), // Min 10 chars
openaiKey: validators.apiKey('sk-'), // With prefix
// Strings
name: validators.nonEmptyString(),
bio: validators.trimmedString(), // Auto-trims, rejects empty
title: validators.boundedString(1, 100), // Length constraints
nickname: validators.optionalString(), // Empty string → undefined
// Numbers
count: validators.positiveInt(), // > 0, integer
offset: validators.nonNegativeInt(), // >= 0, integer
port: validators.port(), // 1-65535
// Other
id: validators.uuid(),
createdAt: validators.isoDate(), // ISO 8601 datetime
status: validators.enumFrom(['draft', 'published', 'archived'] as const),
config: validators.json<{ enabled: boolean }>() // Parse JSON string
});
Response Schemas
Standardized success/error response pattern:
import { SuccessResponseSchema, SimpleSuccessSchema } from '@odel/module-sdk/odel';
import { z } from 'zod';
// Define a response schema with data fields
const EmailResponseSchema = SuccessResponseSchema(
z.object({
messageId: z.string(),
sentAt: z.string()
})
);
// Type inference
type EmailResponse = z.infer<typeof EmailResponseSchema>;
// = { success: true; messageId: string; sentAt: string }
// | { success: false; error: string }
// Usage with type narrowing
function handleResponse(response: EmailResponse) {
if (response.success) {
console.log(`Sent: ${response.messageId}`);
} else {
console.error(`Failed: ${response.error}`);
}
}
// Simple success/error without data
const result = SimpleSuccessSchema.parse({ success: true });
MCP Core Concepts
This SDK includes the full MCP TypeScript SDK. Key concepts:
Servers and Transports
- Streamable HTTP for remote servers (recommended)
- HTTP + SSE for backwards compatibility
- stdio for local integrations
Tools, Resources, Prompts
- Tools: Let LLMs take actions (computation, API calls, side effects)
- Resources: Expose read-only data to clients
- Prompts: Reusable templates for consistent model interactions
Capabilities
- Sampling: Server tools can request LLM completions from clients
- Elicitation: Request structured input via forms or secure browser flows
- Tasks: Long-running operations with polling/resumption
For detailed MCP documentation, see:
- docs/server.md - Building MCP servers
- docs/client.md - Using the MCP client
- docs/capabilities.md - Advanced capabilities
Documentation
License
This project is licensed under the MIT License—see the LICENSE file for details.
Based on the Model Context Protocol TypeScript SDK.
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.