A remote HTTP Model Context Protocol (MCP) server that provides access to AWS services including DynamoDB and S3. This server now uses the official MCP SDK for JSON-RPC handling and exposes prompts, resources, and tools via both JSON-RPC and legacy HTTP endpoints with bearer token authentication.
The codebase is organized into a clean, modular structure:
├── index.ts # Main HTTP entry point
├── src/
│ ├── auth/
│ │ └── auth-manager.ts # Authentication and namespace management
│ ├── aws/
│ │ └── clients.ts # AWS client configuration utilities
│ ├── mcp/
│ │ ├── handler.ts # Main MCP request handler
│ │ └── protocol-handlers.ts # MCP protocol-specific handlers (prompts, resources)
│ ├── storage/
│ │ ├── kv-store.ts # Namespaced DynamoDB key-value store
│ │ └── files-store.ts # Namespaced S3 files store
│ ├── tools/
│ │ ├── definitions.ts # Tool schema definitions
│ │ └── handlers/
│ │ ├── index.ts # Unified tool handlers export
│ │ ├── kv-tools.ts # Key-value store tool handlers
│ │ ├── files-tools.ts # Files store tool handlers
│ │ ├── code-tools.ts # Code execution tool handlers
│ │ └── openai-tools.ts # OpenAI API tool handlers
│ └── valtown/
│ └── client.ts # Val Town API client (for admin features)
└── README.md
This modular structure provides:
Authorization: Bearer <secret_key>
headerThe server includes OpenAI chat completion functionality using Val Town's built-in OpenAI integration. This provides seamless access to OpenAI's models without requiring additional API key configuration.
# Simple chat completion curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "openai-chat-completion", "arguments": { "messages": [ {"role": "user", "content": "Say hello in a creative way"} ], "model": "gpt-4o-mini", "max_tokens": 30 } }, "id": 1 }' # Chat with system prompt curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "openai-chat-completion", "arguments": { "messages": [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Explain quantum computing in simple terms."} ], "model": "gpt-4o-mini", "max_tokens": 500, "temperature": 0.7 } }, "id": 1 }'
The code-exec
tool allows you to execute JavaScript/TypeScript code with full access to all MCP tools (KV store and Files store operations). This enables powerful automation and data processing workflows.
The skill management system allows you to register stored code files as reusable tools with custom input schemas. The system supports both user-specific skills and system-wide skills managed by administrators.
The system uses a promotion-based approach for system skills, which simplifies management and ensures consistency:
register-skill
admin-promote-skill
system/skills/skillName.js
) to ensure complete isolation from the original user's namespaceadmin-update-promoted-skill
register-skill
tooladmin-promote-skill
tool to promote existing user skillsThe system includes a "system" folder that provides:
System files are stored with the system/
prefix and are accessible to all users but can only be modified by administrators.
When a skill is called, the system resolves it in this order:
Administrators can promote user skills to system-wide availability using the promotion-based approach:
{ "userNamespace": "user123", "skillName": "data-analyzer", "description": "Analyzes data from KV store and generates reports (promoted from user123)" }
Once registered, skills appear in the tools list and can be called directly:
{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "data-analyzer", "arguments": { "dataKey": "user-data-2024", "reportType": "detailed" } }, "id": 1 }
Skills can expose prompts that are evaluated dynamically at runtime, allowing for context-aware prompt generation:
// The getPrompts function receives the tools context for dynamic evaluation
export const getPrompts = (tools) => {
return [
{
name: "prompt-name",
description: "Description of the prompt",
arguments: [ // Must match base prompt argument structure
{
name: "arg1",
description: "Argument description",
required: true // Optional boolean field
}
],
// Content can be static string or async function
content: async (args) => {
// Dynamic content generation with access to tools
const data = await tools["kv-get"]({key: args.key});
return `Analyze this data: ${JSON.stringify(data)}`;
}
},
{
name: "static-prompt",
description: "A static prompt",
arguments: [], // Empty array for no arguments
content: "This is static content"
}
];
};
Required Fields:
name
(string): Unique prompt identifierdescription
(string): Human-readable descriptionOptional Fields:
arguments
(array): Array of argument definitions, each with:
name
(string): Argument namedescription
(string): Argument descriptionrequired
(boolean, optional): Whether argument is requiredcontent
(string | function): Static content or async function for dynamic generationgetPrompts()
is called at runtime, not registration timeSkills can be written in two formats:
Your code should be an ES6 module that exports the required functions:
// Required: Main execution function
export const execute = async (input, tools) => {
// Your skill logic here
const result = await tools["kv-get"]({key: input.key});
return { message: "Processing complete", data: result };
};
// Optional: Input schema definition
export const inputSchema = {
type: "object",
properties: {
key: {
type: "string",
description: "The key to process"
}
},
required: ["key"]
};
// Optional: Prompts exposed by this skill (evaluated dynamically at runtime)
export const getPrompts = (tools) => {
return [
{
name: "analyze-key",
description: "Analyze a specific key from storage",
arguments: [
{
name: "key",
description: "Key to analyze",
required: true
}
],
content: async (args) => {
// Dynamic content generation using tools context
const data = await tools["kv-get"]({key: args.key});
return `Please analyze this data: ${JSON.stringify(data)}`;
}
},
{
name: "static-prompt",
description: "A static prompt example",
arguments: [], // No arguments required
content: "This is a static prompt content"
}
];
};
// Optional: Additional metadata
export const metadata = {
version: "1.0.0",
author: "username",
tags: ["data", "analysis"]
};
For backward compatibility, you can still use the legacy function format by explicitly setting moduleType: "legacy"
:
async function execute(input, tools) {
// Your code logic here
const result = await tools["kv-get"]({key: input.key});
return { message: "Processing complete", data: result };
}
Note: Legacy format requires inputSchema
to be provided during registration and cannot expose prompts.
Within your executed code, you have access to all MCP tools via the tools
object:
tools["kv-get"](args)
- Get from your personal key-value storetools["kv-put"](args)
- Put to your personal key-value storetools["kv-delete"](args)
- Delete from your personal key-value storetools["kv-list"](args)
- List keys in your personal key-value storetools["kv-query"](args)
- Query your personal key-value storetools["files-get"](args)
- Get file from your personal file storetools["files-put"](args)
- Put file to your personal file storetools["files-delete"](args)
- Delete file from your personal file storetools["files-list"](args)
- List files in your personal file storetools["files-list-versions"](args)
- List file versions in your personal file storetools["files-move"](args)
- Move file in your personal file storetools["files-copy"](args)
- Copy file in your personal file storetools["files-exists"](args)
- Check if file exists in your personal file storetools["files-metadata"](args)
- Get file metadata from your personal file storetools["openai-chat-completion"](args)
- Create OpenAI chat completionsProvide the code directly in the request:
{ "code": "async function execute(input, tools) { /* your code */ }", "input": { "param1": "value1" } }
Store your code in your personal file store and reference it by key:
{ "key": "scripts/my-processor.js", "input": { "param1": "value1" } }
This approach is ideal for:
Set the following environment variables on your Val Town:
AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=your-access-key-id S3_BUCKET=your-bucket-name DYNAMODB_TABLE=your-table-name MCP_SERVER_NAME=aws-mcp-server MCP_SERVER_VERSION=1.0.0
Note: AWS_SECRET_ACCESS_KEY
is NOT set as an environment variable. Instead, it's passed via the Authorization header for security.
OpenAI Integration: OpenAI functionality uses Val Town's built-in OpenAI integration, which automatically handles API key management. No additional environment variables are required for OpenAI tools.
The KV Store requires a DynamoDB table with the following schema:
Table Configuration:
pk
(String) - Contains the user namespacesk
(String) - Contains the user's keyttl
if you want automatic expirationExample AWS CLI command to create the table:
aws dynamodb create-table \ --table-name your-table-name \ --attribute-definitions \ AttributeName=pk,AttributeType=S \ AttributeName=sk,AttributeType=S \ --key-schema \ AttributeName=pk,KeyType=HASH \ AttributeName=sk,KeyType=RANGE \ --billing-mode PAY_PER_REQUEST
Example CloudFormation template:
DynamoDBTable: Type: AWS::DynamoDB::Table Properties: TableName: your-table-name AttributeDefinitions: - AttributeName: pk AttributeType: S - AttributeName: sk AttributeType: S KeySchema: - AttributeName: pk KeyType: HASH - AttributeName: sk KeyType: RANGE BillingMode: PAY_PER_REQUEST TimeToLiveSpecification: AttributeName: ttl Enabled: true
Data Structure: Each item in the table has the following structure:
pk
(String): User namespace (e.g., "user123", "demo")sk
(String): User's key (e.g., "settings", "config-app")data
(Any): The actual value stored by the usercreated
(String): ISO timestamp when item was createdupdated
(String): ISO timestamp when item was last updatedttl
(Number, Optional): Unix timestamp for automatic expirationAll MCP operations should now use the JSON-RPC endpoint at POST /mcp
. This provides proper MCP protocol compliance and better error handling.
All authenticated requests require the Authorization header:
Authorization: Bearer your-aws-secret-access-key
curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "prompts/list", "params": {}, "id": 1 }'
curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "prompts/get", "params": { "name": "analyze-data", "arguments": { "table_key": "user123", "s3_key": "data/analytics.json" } }, "id": 1 }'
curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "resources/list", "params": {}, "id": 1 }'
curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "resources/read", "params": { "uri": "files://path/to/file.txt" }, "id": 1 }'
curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "tools/list", "params": {}, "id": 1 }'
# Store a file in your personal file store curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "files-put", "arguments": { "key": "documents/my-file.txt", "content": "Hello, World!", "contentType": "text/plain" } }, "id": 1 }' # Get a file from your personal file store curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "files-get", "arguments": { "key": "documents/my-file.txt" } }, "id": 1 }' # List files in your personal file store curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "files-list", "arguments": { "prefix": "documents/" } }, "id": 1 }' # List all versions of a file curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "files-list-versions", "arguments": { "key": "documents/my-file.txt" } }, "id": 1 }' # Get a specific version of a file curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "files-get", "arguments": { "key": "documents/my-file.txt", "versionId": "specific-version-id" } }, "id": 1 }' # Copy a file within your personal file store curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "files-copy", "arguments": { "sourceKey": "documents/my-file.txt", "destinationKey": "backup/my-file-backup.txt" } }, "id": 1 }' # Check if a file exists curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "files-exists", "arguments": { "key": "documents/my-file.txt" } }, "id": 1 }' # Get file metadata curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "files-metadata", "arguments": { "key": "documents/my-file.txt" } }, "id": 1 }' # Delete a file curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "files-delete", "arguments": { "key": "documents/my-file.txt" } }, "id": 1 }'
# Store a key-value pair in your personal store curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "kv-put", "arguments": { "key": "user-settings", "value": {"theme": "dark", "language": "en"}, "ttl": 3600 } }, "id": 1 }' # Get a value from your personal store curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "kv-get", "arguments": { "key": "user-settings" } }, "id": 1 }' # List keys in your personal store curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "kv-list", "arguments": { "prefix": "user-" } }, "id": 1 }' # Query key-value pairs by pattern curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "kv-query", "arguments": { "keyPattern": "config*" } }, "id": 1 }'
# Register an ES6 module skill (default) curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "register-skill", "arguments": { "name": "data-analyzer", "description": "Analyzes data from KV store and generates reports", "fileKey": "skills/data-analyzer.js" } }, "id": 1 }' # Register a legacy function-based skill curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "register-skill", "arguments": { "name": "legacy-processor", "description": "Legacy data processor", "fileKey": "skills/legacy-processor.js", "moduleType": "legacy", "inputSchema": { "type": "object", "properties": { "dataKey": { "type": "string", "description": "Key of data to process" } }, "required": ["dataKey"] } } }, "id": 1 }' # List registered skills curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "list-skills", "arguments": {} }, "id": 1 }' # Execute a registered skill curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "data-analyzer", "arguments": { "dataKey": "user-data-2024", "reportType": "detailed" } }, "id": 1 }' # Unregister a skill curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "unregister-skill", "arguments": { "name": "data-analyzer" } }, "id": 1 }'
# Promote a skill from your own namespace (userNamespace inferred from auth context) curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "admin-promote-skill", "arguments": { "skillName": "data-analyzer" } }, "id": 1 }' # Promote a skill from a specific user namespace curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "admin-promote-skill", "arguments": { "userNamespace": "user123", "skillName": "data-analyzer" } }, "id": 1 }' # List all promoted skills curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "admin-list-promoted-skills", "arguments": {} }, "id": 1 }' # Update a promoted skill with latest version from original user curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "admin-update-promoted-skill", "arguments": { "skillName": "data-analyzer" } }, "id": 1 }' # Demote a skill from system-wide availability curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "admin-demote-skill", "arguments": { "skillName": "data-analyzer" } }, "id": 1 }' # List all system skills (both promoted and directly registered) curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "admin-list-system-skills", "arguments": {} }, "id": 1 }'
# Read a project source file using Val Town API (admin only) curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "admin-read-val-file", "arguments": { "path": "src/auth/auth-manager.ts" } }, "id": 1 }' # Write/update a project source file using Val Town API (admin only) curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "admin-write-val-file", "arguments": { "path": "src/config/new-config.ts", "content": "export const config = { version: \"1.0.0\" };" } }, "id": 1 }' # List project files recursively using Val Town API (admin only) curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "admin-list-val-files", "arguments": { "path": "/src", "recursive": true } }, "id": 1 }' # Get comprehensive project information using Val Town API (admin only) curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "admin-project-info", "arguments": {} }, "id": 1 }'
# Execute code directly (inline) curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "code-exec", "arguments": { "code": "async function execute(input, tools) { const result = await tools[\"kv-get\"]({key: input.key}); return {message: \"Data retrieved\", data: result}; }", "input": { "key": "user-settings" }, "moduleType": "legacy" } }, "id": 1 }' # Execute code from files store curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "code-exec", "arguments": { "key": "scripts/data-processor.js", "input": { "operation": "analyze" }, "moduleType": "es6" } }, "id": 1 }'
You can send multiple JSON-RPC requests in a single HTTP request:
curl -X POST https://your-val-town-url.web.val.run/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-aws-secret-access-key" \ -d '[ { "jsonrpc": "2.0", "method": "prompts/list", "params": {}, "id": 1 }, { "jsonrpc": "2.0", "method": "tools/list", "params": {}, "id": 2 }, { "jsonrpc": "2.0", "method": "resources/list", "params": {}, "id": 3 } ]'
curl https://your-val-town-url.web.val.run/
curl https://your-val-town-url.web.val.run/health
Response:
{ "status": "healthy", "timestamp": "2024-01-01T00:00:00.000Z" }
To integrate with MCP clients like Claude Desktop, you can create a client that makes JSON-RPC requests to the /mcp
endpoint. Here's an example configuration:
{ "mcpServers": { "aws-http-mcp-server": { "command": "node", "args": ["mcp-http-client.js"], "env": { "MCP_SERVER_URL": "https://your-val-town-url.web.val.run", "AWS_SECRET_ACCESS_KEY": "${AWS_SECRET_ACCESS_KEY}" } } } }
{ "jsonrpc": "2.0", "result": { "content": [ { "type": "text", "text": "Response content here" } ] }, "id": 1 }
{ "jsonrpc": "2.0", "error": { "code": -32603, "message": "Error message description" }, "id": 1 }
-32700
: Parse error (Invalid JSON)-32600
: Invalid Request-32601
: Method not found-32602
: Invalid params-32603
: Internal error-32001
: Authentication error (custom){ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::your-bucket-name", "arn:aws:s3:::your-bucket-name/*" ] } ] }
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:DeleteItem", "dynamodb:Query" ], "Resource": "arn:aws:dynamodb:region:account:table/your-table-name" } ] }
Note: The KV Store uses DynamoDB Query operations with a composite key structure (partition key + sort key) for efficient namespace isolation and prefix matching. Scan operations are not required.
The server includes comprehensive error handling for:
All JSON-RPC errors follow the standard format with appropriate error codes.
HTTP endpoints return errors with HTTP status codes:
401
: Authentication errors400
: Bad request (invalid parameters)404
: Resource or tool not found500
: Server errors (AWS service errors, etc.)