Skip to main content
Tools are primarily used in local mode where you configure MCP servers yourself. For the standard cloud experience with smart folders, see the Quickstart.
Tools are MCP servers exposed as executables in your Airstore filesystem. They let Claude (and you) take actions—create issues, send messages, query APIs.

Where tools live

ls ~/airstore/tools/
# filesystem  github  memory  wikipedia
Each tool is a virtual executable that wraps an MCP server.

Running a tool

~/airstore/tools/wikipedia search "something"
Output is JSON:
{
  "results": [
    {
      "title": "Something",
      "page_id": 8041208,
      "excerpt": "Something may refer to: Something (concept)..."
    }
  ]
}

Available commands

Each tool has multiple commands. List them with --help:
~/airstore/tools/filesystem --help
Available commands:
  list_directory    List contents of a directory
  read_file         Read a file
  write_file        Write to a file
  create_directory  Create a directory
  move_file         Move or rename a file
Command names and argument formats are defined by the underlying MCP server, not Airstore. Different servers may use different conventions (e.g., list_directory vs list-directory). Use --help to see the exact syntax for each tool.

Tool examples

Filesystem

# List a directory
~/airstore/tools/filesystem list_directory /tmp

# Read a file
~/airstore/tools/filesystem read_file /tmp/notes.txt

Memory

The memory tool provides a knowledge graph:
# Create entities
~/airstore/tools/memory create_entities '[{"name": "project", "type": "note", "observations": ["Started Q1 2024"]}]'

# Search entities
~/airstore/tools/memory search_entities "project"

Wikipedia

# Search Wikipedia
~/airstore/tools/wikipedia search "albert einstein"

# Get article content
~/airstore/tools/wikipedia get_article "Albert_Einstein"

GitHub

# List repositories
~/airstore/tools/github list_repositories --owner=acme

# List issues
~/airstore/tools/github list_issues --owner=acme --repo=api
The GitHub tool requires setting the GITHUB_TOKEN environment variable in your config file.

Piping tools

Tools output JSON, so you can pipe to jq or other Unix tools:
# Parse with jq
~/airstore/tools/wikipedia search "einstein" | jq '.results[].title'

# Filter results
~/airstore/tools/filesystem list_directory /tmp | jq '.[] | select(.type == "file")'
Chain tools together:
# Search and store in memory
RESULTS=$(~/airstore/tools/wikipedia search "Alan Turing" | jq -c '.results[0]')
~/airstore/tools/memory create_entities "[{\"name\": \"turing-research\", \"type\": \"note\", \"observations\": [$RESULTS]}]"

Adding custom tools

Tools are configured in config.local.yaml under the tools.mcp section:
mode: local

gateway:
  grpc:
    port: 1993
  http:
    host: 127.0.0.1
    port: 1994

tools:
  mcp:
    # Each key becomes a tool name
    my-tool:
      command: npx
      args: ["-y", "@company/mcp-tool"]
      env:
        API_KEY: "${API_KEY}"
After mounting, the tool appears at ~/airstore/tools/my-tool.

Configuration options

FieldDescription
commandCommand to start the MCP server
argsArguments to pass to the command
envEnvironment variables (supports ${VAR} syntax)

Example configurations

Filesystem tool:
tools:
  mcp:
    filesystem:
      command: npx
      args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp", "/Users"]
GitHub tool (requires token):
tools:
  mcp:
    github:
      command: npx
      args: ["-y", "@modelcontextprotocol/server-github"]
      env:
        GITHUB_TOKEN: "${GITHUB_TOKEN}"
Custom internal tool:
tools:
  mcp:
    internal-api:
      command: /usr/local/bin/internal-mcp
      env:
        API_URL: https://internal.company.com
        API_KEY: "${INTERNAL_API_KEY}"

Building an MCP server

MCP servers implement the Model Context Protocol. Here’s a minimal TypeScript example:
import { Server } from "@modelcontextprotocol/sdk/server";

const server = new Server({
  name: "my-tool",
  version: "1.0.0"
});

server.setRequestHandler("tools/list", async () => ({
  tools: [
    {
      name: "hello",
      description: "Say hello",
      inputSchema: {
        type: "object",
        properties: {
          name: { type: "string", description: "Name to greet" }
        },
        required: ["name"]
      }
    }
  ]
}));

server.setRequestHandler("tools/call", async (request) => {
  const { name, arguments: args } = request.params;
  
  if (name === "hello") {
    return { 
      content: [{ type: "text", text: `Hello, ${args.name}!` }] 
    };
  }
});

server.connect(process.stdin, process.stdout);

Error handling

Tools return non-zero exit codes on failure:
~/airstore/tools/filesystem read_file /nonexistent/file
# Exit code: 1
# {"error": "File not found"}
Check exit codes in scripts:
if ~/airstore/tools/filesystem list_directory /tmp; then
  echo "Listed successfully"
else
  echo "Failed to list directory"
fi

Debugging

If a tool isn’t working:
  1. Run the command directly to check for errors:
    npx -y @modelcontextprotocol/server-filesystem /tmp
    
  2. Check environment variables are set:
    echo $GITHUB_TOKEN
    
  3. Mount with verbose logging:
    airstore mount ~/airstore --config config.local.yaml --verbose