MCP (Model Context Protocol) Servers
August 21, 2026 · View on GitHub
The Model Context Protocol (MCP) is an open standard for connecting AI assistants to external tools, services, and data sources. Skales DevKit includes full MCP support for extending AI capabilities beyond built-in tools.
What is MCP?
The Model Context Protocol enables:
- Standardized Integration: A common interface for connecting external services
- Tool Discovery: Automatic detection of available tools from services
- Secure Communication: Authentication and permission management
- Real-time Data: Access to live data from services during conversations
- Cross-platform Compatibility: Works with Claude, Copilot, Cursor, and other tools
MCP servers expose resources and tools that the AI can use through JSON-RPC protocol calls.
MCP Configuration
MCP servers are configured in:
~/.skales-data/mcp-servers.json
This JSON file defines all available MCP servers and their connection settings.
Configuration File Format
The top-level key is servers, and it holds an array. It is not an object map, and it is not called mcpServers. A file in any other shape parses to zero servers, silently — Skales falls back to an empty list rather than reporting a format error, so a hand-written file in the wrong shape looks like "MCP is broken" rather than "the file is wrong".
{
"servers": [
{
"name": "filesystem",
"type": "stdio",
"enabled": true,
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
"env": {}
},
{
"name": "notion",
"type": "http",
"enabled": true,
"url": "https://mcp.notion.com/mcp",
"oauth": true
}
]
}
name is the identifier, not a display label — it is what skales mcp test <name> and the tool prefix mcp_<server>_<tool> use, so keep it short and stable.
Server Configuration Fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Identifier for the server; must be unique |
type | string | Yes | Transport: "stdio", "sse", or "http" |
enabled | boolean | Yes | A disabled server contributes no tools |
command | string | stdio only | Command to execute (e.g. npx, node, python) |
args | array | stdio only | Command arguments |
env | object | No | Environment variables for the child process |
url | string | sse / http | Endpoint |
headers | object | No | HTTP headers, for static-token servers |
oauth | boolean | No | Mark a remote server as OAuth-protected: Skales surfaces a Sign-in affordance and attaches the stored bearer token instead of a static key |
timeoutMs | number | No | How long a single tool call may run. Default 5 minutes, clamped to 5s–30min. Discovery calls keep their own short timeout regardless. |
Editing the file by hand is supported, but the skales mcp add command and the MCP Servers screen in Settings write the same file and validate as they go.
Transport Types
stdio (Standard Input/Output)
Child processes that communicate through stdin/stdout. Good for:
- Self-hosted servers
- Services running locally
- Secure, no network exposure
- File system access servers
http (Streamable HTTP)
The transport of the 2025 MCP spec: a single endpoint, one POST per request, an optional SSE upgrade for server-initiated messages, and session continuity through an Mcp-Session-Id header. Prefer this for any remote server that offers it.
sse (legacy HTTP + SSE)
The older two-endpoint HTTP transport. Good for:
- Cloud services (Notion, GitHub, Slack)
- Remote APIs
- Services with web endpoints
- Easier to debug with browser tools
Built-in MCP Server Templates
Skales includes pre-configured templates for popular services. These are starting points; you'll need to configure with your credentials.
Notion
Connect to Notion workspaces and access databases and pages.
{
"servers": [
{
"name": "notion",
"type": "sse",
"enabled": false,
"url": "https://api.notion.com/v1/mcp",
"headers": {
"Authorization": "Bearer your-notion-token",
"Notion-Version": "2024-02-15"
}
}
]
}
Tools Provided:
mcp_notion_list_databases- List all databasesmcp_notion_query_database- Query a database with filtersmcp_notion_get_page- Retrieve a pagemcp_notion_update_page- Update page properties
How to get a token:
- Visit notion.so/integrations
- Create a new integration
- Copy the Internal Integration Token
- Add the integration to your Notion workspace
GitHub
Connect to GitHub repositories, manage issues, PRs, and access code.
{
"servers": [
{
"name": "github",
"type": "sse",
"enabled": false,
"url": "https://api.github.com/graphql",
"headers": {
"Authorization": "Bearer your-github-token"
}
}
]
}
Tools Provided:
mcp_github_list_repositories- List accessible repositoriesmcp_github_search_code- Search code across reposmcp_github_get_issue- Retrieve issue detailsmcp_github_create_issue- Create new issuesmcp_github_list_pull_requests- List pull requests
How to get a token:
- Go to GitHub Settings → Developer settings → Personal access tokens
- Click "Generate new token (classic)"
- Select scopes:
repo,read:org - Copy the token and add to your config
Google Drive
Access files and folders in Google Drive.
{
"servers": [
{
"name": "google-drive",
"type": "sse",
"enabled": false,
"url": "https://www.googleapis.com/drive/v3",
"headers": {
"Authorization": "Bearer your-google-token"
}
}
]
}
Tools Provided:
mcp_gdrive_list_files- List files and foldersmcp_gdrive_search_files- Search by name or contentmcp_gdrive_get_file_content- Read file contentsmcp_gdrive_upload_file- Upload filesmcp_gdrive_create_folder- Create new folders
How to get a token:
- Visit Google Cloud Console
- Create a new project
- Enable Google Drive API
- Create OAuth 2.0 credentials
- Use the token with Skales DevKit
Slack
Send messages, read channels, and manage Slack workspaces.
{
"servers": [
{
"name": "slack",
"type": "sse",
"enabled": false,
"url": "https://slack.com/api",
"headers": {
"Authorization": "Bearer xoxb-your-bot-token"
}
}
]
}
Tools Provided:
mcp_slack_list_channels- List all channelsmcp_slack_get_messages- Retrieve channel messagesmcp_slack_send_message- Post messages to channelsmcp_slack_upload_file- Share files in channelsmcp_slack_get_user_info- Get user information
How to set up:
- Create a Slack App: api.slack.com/apps
- Enable Bot Token Scopes:
channels:read,chat:write,files:write - Install to workspace
- Copy Bot User OAuth Token (starts with
xoxb-)
Filesystem
Access local files and directories (sandboxed for security).
{
"servers": [
{
"name": "filesystem",
"type": "stdio",
"enabled": true,
"command": "node",
"args": ["/path/to/@modelcontextprotocol/server-filesystem/dist/index.js"],
"env": {
"ALLOWED_PATHS": "/home/user/projects,/tmp"
}
}
]
}
Tools Provided:
mcp_filesystem_read_file- Read file contentsmcp_filesystem_write_file- Create or update filesmcp_filesystem_list_directory- List files in a directorymcp_filesystem_delete_file- Remove files
Security Note:
Set ALLOWED_PATHS to restrict which directories can be accessed. Use comma-separated paths.
Adding a Custom MCP Server
Example: Creating a Custom API Server
- Create your server file (
my-server.js):
const express = require('express');
const app = express();
app.use(express.json());
// MCP-compatible endpoint
app.post('/api/tools', (req, res) => {
res.json({
tools: [
{
name: "fetch_weather",
description: "Get current weather",
inputSchema: {
type: "object",
properties: {
city: { type: "string" }
}
}
}
]
});
});
app.post('/api/call', (req, res) => {
const { tool, params } = req.body;
if (tool === "fetch_weather") {
res.json({ weather: "sunny", temp: 75 });
}
});
app.listen(4000, () => console.log('Server ready'));
- Add to
mcp-servers.json:
{
"servers": [
{
"name": "custom-weather",
"type": "sse",
"enabled": true,
"url": "http://localhost:4000",
"headers": {
"Authorization": "Bearer your-api-key"
}
}
]
}
- Restart Skales to load the new server
How Tools Are Discovered
When Skales starts, it:
- Reads
mcp-servers.json - Connects to each enabled server
- Queries available tools via JSON-RPC
- Prefixes tool names with
mcp_<server-name>_<tool-name> - Makes tools available to the AI in chat
Example: A GitHub server with a list_repos tool becomes mcp_github_list_repos in conversations.
Verifying Tools Are Available
Check the API Playground:
- Open Skales → Developer → API Playground
- Go to the Tools tab
- Search for
mcp_to see all MCP tools - Each tool shows its parameters and description
Or use the API:
curl http://localhost:3000/api/cli/tools \
-H "Authorization: Bearer your-token" | jq .
Transport Protocols Explained
stdio (Standard I/O)
How it works:
- Skales starts the server process
- Communicates via stdin/stdout pipes
- Process terminates when Skales closes
Advantages:
- No network exposure
- Direct process control
- Local-only operation
- Better for sensitive data
Use cases:
- Filesystem access
- Local development tools
- Sensitive APIs
Example config:
{
"command": "python",
"args": ["./my_server.py"],
"env": {
"LOG_LEVEL": "debug"
}
}
SSE (Server-Sent Events)
How it works:
- Server runs independently
- Skales connects via HTTP
- Bidirectional JSON-RPC over persistent HTTP connection
Advantages:
- Servers can run remotely
- Easier to debug (use browser DevTools)
- Can restart independently
- Better for web services
Use cases:
- Cloud APIs (Notion, GitHub, Slack)
- Remote services
- Public APIs
Example config:
{
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer token"
}
}
Example: Setting Up a Filesystem MCP Server
A complete walkthrough of setting up the filesystem server for local file access:
Step 1: Install the Server Package
npm install @modelcontextprotocol/server-filesystem
Step 2: Add to mcp-servers.json
{
"servers": [
{
"name": "filesystem",
"type": "stdio",
"enabled": true,
"command": "node",
"args": [
"./node_modules/@modelcontextprotocol/server-filesystem/dist/index.js",
"/home/user/projects",
"/tmp"
],
"env": {}
}
]
}
Step 3: Configure Allowed Paths
Edit the args to specify directories that can be accessed:
Every path after the script path is a directory the server may touch:
"args": [
"./node_modules/@modelcontextprotocol/server-filesystem/dist/index.js",
"/home/user/projects",
"/home/user/documents",
"/tmp"
]
JSON has no comments; the file must parse or Skales loads zero servers.
Step 4: Restart Skales
Close and reopen the Skales application to load the server.
Step 5: Test in Chat
Try a message like:
List the files in /home/user/projects
The AI now has access to your filesystem through the mcp_filesystem_* tools.
Authentication and Security
Storing Secrets Securely
Never hardcode tokens in mcp-servers.json. Instead, use environment variables:
{
"github": {
"type": "sse",
"enabled": true,
"url": "https://api.github.com/graphql",
"headers": {
"Authorization": "Bearer ${GITHUB_TOKEN}"
}
}
}
Then set the environment variable:
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
Skales will automatically expand ${VARIABLE_NAME} syntax.
Permission Best Practices
-
Create API tokens with minimal scopes
- GitHub: Only enable needed permissions
- Google: Use service account with limited scopes
- Notion: Create integration with access to specific databases
-
Rotate tokens regularly
- Set calendar reminders to refresh tokens
- Monitor token usage in provider dashboards
- Revoke tokens immediately if compromised
-
Audit access
- Check Slack app activity logs
- Review GitHub token usage
- Monitor Google Cloud audit logs
Troubleshooting MCP Servers
Server Not Connecting
Problem: "Connection refused" or "timeout"
Diagnosis:
- Check if server is running
- Verify connection details are correct
- Check firewall settings (for SSE servers)
Solution:
# For stdio servers, test directly
node ./my-server.js
# For SSE servers, test with curl
curl -H "Authorization: Bearer token" https://api.example.com/mcp
Tools Not Appearing
Problem: Tools don't show up in the Tools list
Diagnosis:
- Read the server's own output:
skales mcp logs <name> - Check
mcp-servers.jsonsyntax — a parse error, or a top-level key other thanservers, yields zero servers with no message - Verify the server is
enabled: trueand thatskales mcp test <name>reportsok
Solution:
- Restart Skales application
- Check logs at
~/.skales-data/logs/ - Verify server responds with tool definitions
Authentication Errors
Problem: 401, 403, or "Unauthorized" errors
Diagnosis:
- Check token is valid in the provider's dashboard
- Verify token hasn't expired
- Check token permissions/scopes
Solution:
- Generate a new token from the provider
- Update mcp-servers.json with new token
- Restart Skales
Performance Issues
Problem: Slow responses or timeouts when using MCP tools
Diagnosis:
- Check server performance metrics
- Monitor network latency (for SSE servers)
- Check for rate limiting
Solution:
- Reduce concurrent tool calls
- Increase timeout values in config
- Check server logs for errors
- Consider using caching for frequently accessed data
Best Practices
Organization
The file is one flat array; there is no grouping or nesting. Keep servers apart by name instead — a short, stable name becomes the tool prefix (mcp_<server>_<tool>), so github reads better in a tool list than dev-github-primary.
Servers you are not using should be "enabled": false rather than deleted: a disabled server contributes no tools and costs no connection, and its configuration is still there when you want it back.
Monitoring
Enable logging and periodically review:
- Which servers are used most
- Error rates and failure patterns
- Performance metrics
Updates
Keep MCP server packages up-to-date:
npm update @modelcontextprotocol/*
Testing
Test new MCP servers in isolation:
- Use the API Playground
- Try simple operations first
- Gradually increase complexity
- Monitor logs for issues
Common MCP Server Patterns
Authentication Flow
// SSE server with authentication
app.post('/api/auth', (req, res) => {
const token = req.headers.authorization?.split(' ')[1];
if (!isValidToken(token)) {
return res.status(401).json({ error: 'Invalid token' });
}
res.json({ authenticated: true });
});
Error Handling
// Proper error response format
try {
const result = await tool.execute(params);
res.json({ result });
} catch (error) {
res.status(400).json({
error: error.message,
code: error.code
});
}
Rate Limiting
// Client-side rate limiting
const queue = [];
const rateLimit = 100; // requests per minute
function executeWithRateLimit(tool, params) {
if (queue.length >= rateLimit) {
return { error: "Rate limit exceeded" };
}
queue.push({ tool, params });
// ... execute after delay
}
Advanced Configuration
Per-server call timeout
A single tool call may run for five minutes by default. Servers that legitimately take longer — video analysis, large scrapes, renders — can raise it per server with timeoutMs, clamped to between 5 seconds and 30 minutes:
{
"servers": [
{
"name": "video-analysis",
"type": "stdio",
"enabled": true,
"command": "npx",
"args": ["-y", "some-video-mcp-server"],
"timeoutMs": 900000
}
]
}
Discovery calls (initialize, tools/list) keep their own short timeout regardless: a server that needs minutes to list its tools is broken, not busy.
OAuth servers
Remote servers that sign you in instead of taking a static key are marked "oauth": true. Skales then shows a Sign-in affordance for that server and attaches the stored bearer token on every call; you do not put a token in headers.
There is no conditional loading, no per-context activation, and no primary/fallback pair. A server is enabled or it is not.
Support and Resources
- MCP Specification: modelcontextprotocol.io
- Official Servers: github.com/modelcontextprotocol
- Community Servers: Search GitHub for "mcp-server"
- Skales Docs: docs.skales.app
For setup help:
- Check the Getting Started Guide
- Review the API Reference
- Ask in GitHub Discussions
Key Takeaways
- MCP is an open protocol for connecting AI to external tools
- Configure servers in
~/.skales-data/mcp-servers.json, as an array under the keyservers - Use
stdiofor local servers,httpfor modern remote ones,ssefor older remote ones - Tools are auto-discovered and prefixed with
mcp_ - Built-in templates for Notion, GitHub, Google Drive, Slack, Filesystem
- Store credentials in environment variables, not config files
- Test servers in the API Playground before using in chat