This MCP (Model Context Protocol) server allows Claude Desktop to interact with your Obsidian Inbox service.
The MCP server runs locally on your machine and communicates with your remote Val.town API. This keeps the MCP logic separate from the serverless service and allows for better local development and control.
Claude Desktop → Local MCP Server → Remote Val.town API → SQLite/Blob Storage
First, ensure your Val.town service is deployed and accessible. You'll need:
- The public URL of your Val.town service (e.g.,
https://yourusername-inbox.val.town) - An API token (set as
API_TOKENin Val.town secrets)
The MCP server requires two environment variables:
INBOX_API_URL: The base URL of your deployed Val.town serviceINBOX_API_TOKEN: The API bearer token for authentication
Edit your Claude Desktop configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Add the following configuration:
{ "mcpServers": { "obsidian-inbox": { "command": "deno", "args": [ "run", "--allow-net", "--allow-env", "https://esm.town/v/drewmcdonald/inbox/mcp.ts" ], "env": { "INBOX_API_URL": "https://yourusername-inbox.val.town", "INBOX_API_TOKEN": "your-api-token-here" } } } }
Note: The MCP script is hosted on Val.town, so Deno will fetch and run it directly from the URL. No local installation needed!
After updating the configuration, restart Claude Desktop for the changes to take effect.
Once configured, Claude will have access to the following tools:
Retrieve all unprocessed records from the inbox.
Example: "Show me what's in my inbox"
Create a new inbox record.
Parameters:
raw(required): The raw contentsummary(optional): Brief summaryfrom(optional): Source identifiersubject(optional): Subject/titledate(optional): When receivedattachmentBlobIds(optional): Array of blob IDs
Example: "Add a note to my inbox: 'Remember to review the Q4 budget'"
Mark a record as processed by ID.
Parameters:
id(required): Record UUID
Example: "Mark record abc-123 as processed"
Get attachment metadata for a record.
Parameters:
recordId(required): Record UUID
Example: "What attachments does record abc-123 have?"
Download attachment data (base64-encoded).
Parameters:
recordId(required): Record UUIDblobId(required): Blob UUID
Example: "Download the attachment xyz-456 from record abc-123"
Make sure INBOX_API_URL and INBOX_API_TOKEN are set in your Claude Desktop config.
Check that your INBOX_API_TOKEN matches the API_TOKEN secret in your Val.town service.
Verify your INBOX_API_URL is correct and the service is deployed.
- Check that the path to
mcp.tsis absolute and correct - Ensure Deno is installed:
deno --version - Check Claude Desktop logs for errors
- Restart Claude Desktop after config changes
You can test the MCP server without Claude Desktop:
# Set environment variables export INBOX_API_URL="https://yourusername-inbox.val.town" export INBOX_API_TOKEN="your-token" # Run the MCP server deno run --allow-net --allow-env mcp.ts
The MCP server is in mcp.ts and uses:
apiClient.ts- HTTP client for the remote APItypes.ts- Shared TypeScript types between MCP and API
When you modify the API endpoints or schemas, update types.ts to keep the client and server in sync.
Why run locally?
- Easier development and debugging
- No serverless constraints (can maintain state if needed)
- Better authentication handling (token stored locally)
- Separation of concerns (MCP logic vs API logic)
Type sharing
All TypeScript types are defined in types.ts and imported by both the API (InboxService.ts, httpHandler.ts) and the MCP client (mcp.ts, apiClient.ts). This ensures type safety across the boundary.
No breaking changes to Val.town service The HTTP API remains unchanged. The MCP server is just a client that calls those endpoints. You can still use the API directly with curl, Postman, or other HTTP clients.