craft-mcp-wrapper
Enables Perplexity AI to search and read content from multiple Craft documents, providing tools for listing documents, searching all notes or a specific document, and reading document structures or blocks.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@craft-mcp-wrappersearch all documents for meeting notes about Q4 planning"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Craft MCP Wrapper
A Model Context Protocol (MCP) server that wraps multiple Craft document APIs and makes them accessible to AI assistants like Perplexity AI, Claude Desktop, VS Code, and Cursor.
Note: This is an open-source project. Contributions are welcome!
π Quick Links: Quick Start | Contributing | AWS Deployment | Status
Overview
This MCP server provides a unified interface to search and read content from multiple Craft documents simultaneously. It aggregates results across configured documents while gracefully handling failures, making it ideal for querying distributed knowledge bases.
Related MCP server: Dewey
Features
5 MCP Tools:
list_documents- List all configured Craft documentssearch_all_notes- Search across all documents with aggregationsearch_document- Search within a specific documentread_document- Read entire document structureread_block- Read a specific block by ID
Dual Transport Modes:
Stdio Mode - For local AI assistants (Perplexity local, Claude Desktop)
SSE Mode - HTTP/SSE transport for remote connections
Robust Error Handling:
Graceful degradation when individual APIs fail
Partial results with error context
Input validation with Zod schemas
Easy Configuration:
JSON-based document configuration
Environment variables for server settings
No authentication required for Craft public share links
Installation
Clone the repository:
git clone https://github.com/mattymil/craft-mcp-wrapper.git cd craft-mcp-wrapperInstall dependencies:
npm installConfigure your Craft documents (see Configuration section below)
Build the project:
npm run build
Production Deployment (macOS)
For stable production use with MCP clients, deploy to a system-wide location:
# Build the project
npm run build
# Deploy to production location
sudo mkdir -p /usr/local/lib/craft-wrapper
sudo cp -r build config.json package.json node_modules /usr/local/lib/craft-wrapper/Then configure your MCP clients to use /usr/local/lib/craft-wrapper/build/index.js as the entry point.
Benefits:
Stable path that won't change with project updates
Separates production runtime from development workspace
Easy rollback by keeping previous versions
Configuration
Document Configuration (config.json)
Edit config.json to add your Craft document share links:
{
"documents": [
{
"name": "My Notes",
"apiEndpoint": "https://connect.craft.do/links/YOUR_SHARE_LINK_1/api/v1"
},
{
"name": "Project Documentation",
"apiEndpoint": "https://connect.craft.do/links/YOUR_SHARE_LINK_2/api/v1"
}
]
}To add more documents:
Get the Craft share link for your document
Add
/api/v1to the end of the linkAdd a new entry with a friendly name and the API endpoint
Environment Variables (.env)
Copy .env.example to .env and configure as needed:
# Transport mode: "stdio" or "sse"
MCP_TRANSPORT=stdio
# SSE mode configuration (only used when MCP_TRANSPORT=sse)
PORT=3000
SSE_ENDPOINT=/sse
# Optional: API key for SSE authentication
# MCP_API_KEY=your-secret-key-here
# Performance tuning
# Maximum response size in bytes (default: 1048576 = 1MB)
# Larger values may cause stdio blocking with slow connections
MAX_RESPONSE_SIZE=1048576Performance Configuration:
MAX_RESPONSE_SIZE- Maximum size of JSON responses in bytes (default: 1MB)Responses larger than this will be automatically truncated
Increase for large document reads, but be aware of stdio blocking
Decrease for faster performance with limited bandwidth
Running the Server
Local Development
Stdio Mode (Default)
For local AI assistants like Claude Desktop or Perplexity (local):
npm startThis starts the server in stdio mode, communicating via standard input/output.
SSE Mode (HTTP Server)
For remote connections or testing:
npm run start:sseOr explicitly:
node build/index.js --sseThe server will start on port 3000 (configurable via PORT env variable) with:
SSE endpoint:
http://localhost:3000/sseMessages endpoint:
http://localhost:3000/messagesHealth check:
http://localhost:3000/health
Local Lambda Testing
Test Lambda function locally with serverless-offline:
npm run offlineThis starts a local API Gateway emulator on http://localhost:3000
Development Mode
Auto-reload on file changes:
# Stdio mode
npm run dev
# SSE mode
npm run dev:sseAWS Lambda Deployment
Deploy the server as an AWS Lambda function with API Gateway.
Prerequisites
AWS CLI configured:
aws configureProvide your AWS Access Key ID, Secret Access Key, and default region.
AWS credentials: Ensure you have permissions to create:
Lambda functions
API Gateway HTTP APIs
CloudWatch Logs
IAM roles
Deploy to AWS
Deploy to default stage (dev):
npm run deployDeploy to specific stages:
# Development
npm run deploy:dev
# Production
npm run deploy:prodAfter deployment, Serverless Framework will output:
API Gateway endpoint URL
Lambda function name
CloudFormation stack name
View Deployment Info
npm run infoView Lambda Logs
# Tail logs in real-time
npm run logs
# Stage-specific logs
npm run logs:dev
npm run logs:prodRemove Lambda Deployment
# Remove default stage
npm run remove
# Remove specific stages
npm run remove:dev
npm run remove:prodEnvironment Variables for Lambda
Set environment variables in serverless.yml or via command line:
# Set API key for authentication
export MCP_API_KEY="your-secret-key"
npm run deployOr edit serverless.yml:
provider:
environment:
MCP_API_KEY: ${env:MCP_API_KEY, 'default-key'}Lambda Configuration
Default settings in serverless.yml:
Runtime: Node.js 20.x
Memory: 512 MB
Timeout: 30 seconds
Region: us-east-1
Modify these in serverless.yml as needed.
API Gateway Endpoints
After deployment, your Lambda provides a REST API at:
https://{api-id}.execute-api.{region}.amazonaws.com/Endpoints:
GET /health- Health checkcurl https://{api-id}.execute-api.{region}.amazonaws.com/healthGET /tools- List available toolscurl https://{api-id}.execute-api.{region}.amazonaws.com/toolsPOST /tools/call- Execute a toolcurl -X POST https://{api-id}.execute-api.{region}.amazonaws.com/tools/call \ -H "Content-Type: application/json" \ -d '{"name": "list_documents", "arguments": {}}'
Note: The Lambda deployment uses a simple REST API rather than the full MCP protocol. For MCP protocol support (required by Perplexity), use the local stdio or SSE server.
Cost Estimates
AWS Lambda:
Free tier: 1M requests/month + 400,000 GB-seconds compute
After free tier: $0.20 per 1M requests + $0.0000166667 per GB-second
API Gateway:
Free tier: None
HTTP API: $1.00 per million requests
Example: 10,000 requests/month with 512MB, 3s avg execution:
Lambda: Free (within free tier)
API Gateway: $0.01/month
Total: ~$0.01/month
Lambda Limitations
Cold starts: First request after idle period may be slower (1-2 seconds)
REST API only: Lambda provides a REST API, not full MCP protocol (use local server for MCP clients)
No stdio mode: Stdio mode is not supported in Lambda (serverless environment)
No SSE/streaming: Lambda REST API uses request/response, not Server-Sent Events
Timeout: Maximum 30 seconds (configurable up to 15 minutes)
Connecting AI Assistants
Perplexity AI
β οΈ Important: Perplexity requires the full MCP protocol via stdio mode. Use the local server, not Lambda.
Stdio Configuration: Add to Perplexity's MCP settings:
{
"mcpServers": {
"craft-wrapper": {
"command": "node",
"args": ["/usr/local/lib/craft-wrapper/build/index.js"]
}
}
}For development/custom installations, replace with your project path:
{
"mcpServers": {
"craft-wrapper": {
"command": "node",
"args": ["/path/to/your/craft-mcp-wrapper/build/index.js"]
}
}
}Note: The MCP_TRANSPORT environment variable defaults to stdio, so you don't need to specify it unless you've changed the default in your .env file.
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"craft-wrapper": {
"command": "node",
"args": ["/usr/local/lib/craft-wrapper/build/index.js"]
}
}
}For development/custom installations, replace with your project path.
VS Code / Cursor
For MCP-compatible extensions, configure the server path in your workspace settings:
{
"mcp.servers": {
"craft-wrapper": {
"command": "node",
"args": ["/usr/local/lib/craft-wrapper/build/index.js"]
}
}
}For development/custom installations, replace with your project path.
Remote SSE Connection
If using SSE mode remotely (local server only):
Server URL: http://your-server:3000/sseWith authentication (if MCP_API_KEY is set):
http://your-server:3000/sse?api_key=your-secret-key-hereLambda REST API (For Custom Integrations)
The Lambda deployment provides a REST API for custom integrations that don't require the MCP protocol:
Base URL: https://{api-id}.execute-api.{region}.amazonaws.com
Example - List Documents:
curl -X POST https://YOUR-API-ID.execute-api.us-east-1.amazonaws.com/tools/call \
-H "Content-Type: application/json" \
-d '{"name": "list_documents", "arguments": {}}'Example - Search All Notes:
curl -X POST https://YOUR-API-ID.execute-api.us-east-1.amazonaws.com/tools/call \
-H "Content-Type: application/json" \
-d '{
"name": "search_all_notes",
"arguments": {
"query": "leadership",
"caseSensitive": false
}
}'Response Format:
{
"success": true,
"result": {
// Tool-specific result data
}
}Tools Documentation
1. list_documents
Lists all configured Craft documents.
Parameters: None
Example Response:
{
"documents": [
{
"name": "My Notes",
"apiEndpoint": "https://connect.craft.do/links/YOUR_SHARE_LINK_1/api/v1"
},
{
"name": "Project Documentation",
"apiEndpoint": "https://connect.craft.do/links/YOUR_SHARE_LINK_2/api/v1"
}
],
"count": 2
}Use Case: Discover available documents before searching.
2. search_all_notes
Search across all configured documents simultaneously.
Parameters:
query(string, required) - Search patterncaseSensitive(boolean, optional) - Case-sensitive search (default: false)
Example JSON-RPC Request:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "search_all_notes",
"arguments": {
"query": "leadership",
"caseSensitive": false
}
},
"id": 1
}Example Response:
{
"query": "leadership",
"caseSensitive": false,
"totalResults": 5,
"documentsSearched": 2,
"results": [
{
"documentName": "Notes",
"results": [
{
"block": { "id": "...", "content": "..." },
"documentName": "Notes"
}
]
},
{
"documentName": "Bonhoeffer Notes",
"results": [...]
}
]
}Use Case: Find content across your entire Craft knowledge base without knowing which document contains it.
3. search_document
Search within a specific Craft document.
Parameters:
documentName(string, required) - Name of the documentquery(string, required) - Search patterncaseSensitive(boolean, optional) - Case-sensitive search (default: false)
Example JSON-RPC Request:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "search_document",
"arguments": {
"documentName": "Notes",
"query": "meeting notes",
"caseSensitive": false
}
},
"id": 2
}Use Case: Targeted search when you know which document contains the information.
4. read_document
Read the entire structure of a Craft document.
Parameters:
documentName(string, required) - Name of the documentmaxDepth(number, optional) - Maximum depth of block hierarchy
Example JSON-RPC Request:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "read_document",
"arguments": {
"documentName": "Notes",
"maxDepth": 3
}
},
"id": 3
}Use Case: Retrieve complete document structure for analysis or export.
5. read_block
Read a specific block by its ID.
Parameters:
documentName(string, required) - Name of the documentblockId(string, required) - ID of the block
Example JSON-RPC Request:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "read_block",
"arguments": {
"documentName": "Notes",
"blockId": "block-123-abc"
}
},
"id": 4
}Use Case: Retrieve specific content when you have a block ID from a previous search.
Performance Best Practices
Stdio Performance Optimization
This server is optimized for fast stdio communication with AI assistants like Perplexity:
Compact JSON: Response formatting (pretty-printing) is disabled to reduce payload size by ~40%
Response Size Limits: Large responses are automatically truncated to prevent stdio buffer blocking
Performance Logging: All tool executions log timing and size metrics to stderr for monitoring
Performance Metrics
Check stderr output for performance data:
[PERF] 2024-01-15T10:30:45.123Z search_all_notes 245ms size=15234bytes
[PERF] 2024-01-15T10:30:50.456Z read_document 1200ms size=524288bytesTips for Optimal Performance
Use Specific Searches: Prefer
search_documentoversearch_all_noteswhen you know which document contains the dataLimit Depth: Use
maxDepthparameter withread_documentto avoid fetching entire deep hierarchiesMonitor Truncation: Watch stderr for
[WARN] Response truncatedmessagesAdjust Size Limits: Increase
MAX_RESPONSE_SIZEif you frequently see truncation warningsQuery Optimization: Use specific search patterns instead of broad queries across all documents
When Responses Are Truncated
If a response exceeds MAX_RESPONSE_SIZE, you'll see:
A
[WARN]message in stderr with original and truncated sizesA
_metadatafield in the response indicating truncationPreserved top-level structure with truncated arrays/content
Solutions:
Increase
MAX_RESPONSE_SIZEin your.envfileUse more specific queries to reduce result set size
Use
read_blockinstead ofread_documentfor specific contentReduce
maxDepthwhen reading documents
Testing
Run Test Suite
npm run build
npm run testThe test suite validates:
All 5 tools with valid inputs
Error handling with invalid inputs
Configuration loading
API response structures
Manual Testing (SSE Mode)
Start the server:
npm run start:sseTest health endpoint:
curl http://localhost:3000/healthTest SSE connection:
curl http://localhost:3000/sseList available tools:
curl -X POST http://localhost:3000/messages \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 1
}'Architecture
High-Level Design
βββββββββββββββββββββββ
β AI Assistant β
β (Perplexity/Claude) β
ββββββββββββ¬βββββββββββ
β MCP Protocol
β (stdio or SSE)
ββββββββββββ΄βββββββββββ
β MCP Server β
β (craft-wrapper) β
β β
β βββββββββββββββββ β
β β Tool Registry β β
β βββββββββ¬ββββββββ β
β β β
β βββββββββ΄ββββββββ β
β β Craft API β β
β β Client β β
β β (axios) β β
β βββββββββ¬ββββββββ β
ββββββββββββΌβββββββββββ
β
ββββββββ΄ββββββββ
β β
βββββ΄βββββ ββββββ΄βββ
βCraft β βCraft β
βDoc 1 β βDoc 2 β
ββββββββββ βββββββββAggregation Strategy
When search_all_notes is called:
Create parallel promises for each configured document
Use
Promise.allSettled()to handle failures gracefullyCollect successful results with document name context
Include error messages for failed requests
Return aggregated results with summary statistics
Error Handling
Invalid document names: Returns error with list of available documents
Network failures: Caught and returned as structured errors
Malformed responses: Wrapped in error objects
Partial failures: Results from successful APIs still returned
Troubleshooting
Common Issues
"Failed to load config.json"
Ensure
config.jsonexists in the project rootVerify JSON syntax is valid
Check that all required fields are present
"Port 3000 already in use" (SSE mode)
Change the port:
PORT=3001 npm run start:sseOr update
.envfile
"No active SSE connection found"
Ensure you've opened the SSE endpoint (
/sse) before sending messagesCheck that the connection hasn't been closed
Network errors / timeout
Verify Craft share links are still valid
Check internet connectivity
Increase timeout in
craft-api.tsif needed (currently 30s)
Tools not appearing in AI assistant
Rebuild the project:
npm run buildRestart the AI assistant
Check server logs for errors (stderr in stdio mode)
Slow performance with Perplexity/Claude
Check stderr for
[PERF]logs to identify slow operationsLarge responses (>500KB) may cause delays - see "Response truncated" guidance below
Verify
MAX_RESPONSE_SIZEis set appropriately (default 1MB)Use more specific search queries instead of broad searches
"Response truncated" warnings in stderr
This means the response exceeded
MAX_RESPONSE_SIZEand was automatically truncatedCheck the
_metadatafield in responses for truncation detailsTo fix:
Increase
MAX_RESPONSE_SIZEin.env(e.g.,MAX_RESPONSE_SIZE=2097152for 2MB)Use more specific queries to reduce result size
Use
search_documentinstead ofsearch_all_notesLimit
maxDepthwhen callingread_document
Note: Setting
MAX_RESPONSE_SIZEtoo high may cause stdio blocking
Known Limitations
Lambda = REST API only: The Lambda deployment provides a REST API, not the full MCP protocol. For MCP clients (Perplexity, Claude Desktop), use the local stdio/SSE server.
Perplexity requires local server: Perplexity's MCP connector requires stdio mode, which only works with the local server.
Read-only: This MVP only supports READ operations (search, fetch). Write operations (insert, update, delete) are not implemented.
Authentication: Craft APIs must be publicly accessible share links. Private documents with authentication are not supported yet.
Rate limiting: No built-in rate limiting. Consider adding if making many requests.
License
MIT
Contributing
Contributions are welcome! Here's how you can help:
Fork the repository
Create a feature branch (
git checkout -b feature/amazing-feature)Commit your changes (
git commit -m 'Add amazing feature')Push to the branch (
git push origin feature/amazing-feature)Open a Pull Request
Development Setup
git clone https://github.com/mattymil/craft-mcp-wrapper.git
cd craft-mcp-wrapper
npm install
npm run buildRunning Tests
npm run testSupport
If you encounter any issues or have questions:
Open an issue on GitHub
Check existing issues for solutions
Review the Troubleshooting section
Built with:
Model Context Protocol by Anthropic
Craft.do Document API
TypeScript, Express, Axios, Zod
Star History
If you find this project useful, please consider giving it a β on GitHub!
Related Projects
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mattymil/craft-mcp-wrapper'
If you have feedback or need assistance with the MCP directory API, please join our Discord server