npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vutler/mcp

v1.0.0

Published

Unified MCP server for the Vutler workspace and agent operations

Readme

@vutler/mcp

Unified public MCP package for Vutler workspaces.

Quick Start

Run directly:

VUTLER_API_KEY=vt_your_key_here npx @vutler/mcp

Bootstrap a client config and immediately validate the written file:

VUTLER_API_KEY=vt_your_key_here npx @vutler/mcp --bootstrap claude-code --embed-key
VUTLER_API_KEY=vt_your_key_here npx @vutler/mcp --bootstrap claude-desktop --embed-key

If you do not want to persist a real key yet, bootstrap safely with a placeholder and rerun doctor after replacing it:

npx @vutler/mcp --bootstrap cursor

List supported clients:

npx @vutler/mcp --list-clients

Print a ready-to-paste client config:

npx @vutler/mcp --print-config claude-code
npx @vutler/mcp --print-config claude-desktop
npx @vutler/mcp --print-config cursor
npx @vutler/mcp --print-config vscode
npx @vutler/mcp --print-config continue

Write or update a real config file:

npx @vutler/mcp --setup claude-code
npx @vutler/mcp --setup claude-desktop
npx @vutler/mcp --setup cursor --path ./.mcp.json

By default, setup writes a placeholder API key so secrets are not persisted accidentally. To embed the current VUTLER_API_KEY explicitly:

VUTLER_API_KEY=vt_your_key_here npx @vutler/mcp --setup claude-code --embed-key

Validate credentials, connectivity, plan-gated tool exposure, and optionally the real client config file:

VUTLER_API_KEY=vt_your_key_here npx @vutler/mcp --doctor
VUTLER_API_KEY=vt_your_key_here npx @vutler/mcp --doctor --json
VUTLER_API_KEY=vt_your_key_here npx @vutler/mcp --doctor --client claude-code
VUTLER_API_KEY=vt_your_key_here npx @vutler/mcp --doctor --client claude-desktop --path ~/Library/Application\ Support/Claude/claude_desktop_config.json

Print the required environment variables:

npx @vutler/mcp --print-env

Environment

  • VUTLER_API_URL
    • optional
    • defaults to https://app.vutler.ai
  • VUTLER_API_KEY
    • required
    • use a workspace API key from Vutler

Supported Client Templates

Claude Code

Project-scoped .mcp.json:

{
  "mcpServers": {
    "vutler": {
      "command": "npx",
      "args": ["-y", "@vutler/mcp"],
      "env": {
        "VUTLER_API_URL": "https://app.vutler.ai",
        "VUTLER_API_KEY": "vt_your_key_here"
      }
    }
  }
}

Claude Desktop

{
  "mcpServers": {
    "vutler": {
      "command": "npx",
      "args": ["-y", "@vutler/mcp"],
      "env": {
        "VUTLER_API_URL": "https://app.vutler.ai",
        "VUTLER_API_KEY": "vt_your_key_here"
      }
    }
  }
}

Cursor

{
  "mcpServers": {
    "vutler": {
      "command": "npx",
      "args": ["-y", "@vutler/mcp"],
      "env": {
        "VUTLER_API_URL": "https://app.vutler.ai",
        "VUTLER_API_KEY": "vt_your_key_here"
      }
    }
  }
}

Continue.dev

{
  "mcpServers": {
    "vutler": {
      "command": "npx",
      "args": ["-y", "@vutler/mcp"],
      "env": {
        "VUTLER_API_URL": "https://app.vutler.ai",
        "VUTLER_API_KEY": "vt_your_key_here"
      }
    }
  }
}

VS Code

{
  "mcpServers": {
    "vutler": {
      "command": "npx",
      "args": ["-y", "@vutler/mcp"],
      "env": {
        "VUTLER_API_URL": "https://app.vutler.ai",
        "VUTLER_API_KEY": "vt_your_key_here"
      }
    }
  }
}

Notes

  • --bootstrap is the shortest operational path: it writes the client config and then runs doctor against that exact file.
  • --setup merges into an existing mcpServers object instead of wiping unrelated MCP entries.
  • --force lets setup replace an invalid JSON config file and stores a timestamped backup first.
  • --dry-run resolves the target path and merged config without writing to disk.
  • --doctor --client ... validates the resolved config path, confirms mcpServers.vutler, checks that it launches @vutler/mcp, and flags placeholder API keys.
  • Tool exposure remains gated by the workspace plan and capabilities.
  • Legacy packages such as @vutler/mcp-office, @vutler/mcp-nexus, and packages/mcp-server should not be used for new integrations.

Tool Reference

All tools are categorized into Lifecycle Tools (24 total, always available) and Workspace Tools (18 total, plan-gated).

Lifecycle Tools (24)

Available regardless of workspace plan. Used for onboarding, authentication, account provisioning, and workspace setup.

Account Creation

vutler_signup

Create a new Vutler workspace (headless).

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | email | string | yes | Email address for the workspace owner | | password | string | yes | Password for the workspace owner | | name | string | no | Workspace name (defaults to domain from email) | | client_name | string | no | Display name for this MCP client |

Returns: { api_key, workspace_id, user_id, trial_info }

Example:

{
  "tool": "vutler_signup",
  "params": {
    "email": "[email protected]",
    "password": "secure_password_123",
    "name": "Company Workspace",
    "client_name": "Claude Code"
  }
}
vutler_authenticate

Start device flow authentication (like gh auth login). Returns device code and user code for browser-based authorization.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | client_name | string | no | Display name for this client (e.g., "Claude Code") | | scope | string | no | Requested scope: mcp:onboarding (default) or mcp:full |

Returns: { device_code, user_code (XXXX-XXXX format), verification_url }

Example:

{
  "tool": "vutler_authenticate",
  "params": {
    "client_name": "Claude Code",
    "scope": "mcp:onboarding"
  }
}
vutler_authenticate_poll

Poll device flow authentication status until authorized or denied.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | device_code | string | yes | Device code from vutler_authenticate response |

Returns: { status (pending|authorized|expired|denied), api_key (when authorized) }

Example:

{
  "tool": "vutler_authenticate_poll",
  "params": {
    "device_code": "DEV_abc123def456"
  }
}
vutler_choose_plan

List available plans or initiate Stripe checkout for a specific plan.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan_id | string | no | Plan ID to checkout (omit to list all plans) | | interval | string | no | Billing interval: monthly or yearly | | success_url | string | no | URL to redirect after successful payment | | cancel_url | string | no | URL to redirect if payment is cancelled |

Returns: { plans[] } or { checkout_url }

Example (list plans):

{
  "tool": "vutler_choose_plan"
}

Example (checkout):

{
  "tool": "vutler_choose_plan",
  "params": {
    "plan_id": "office_starter",
    "interval": "monthly",
    "success_url": "https://myapp.com/success",
    "cancel_url": "https://myapp.com/cancel"
  }
}

Email Verification

vutler_verify_email_request

Send a 6-digit OTP code via Brevo SMTP for email verification.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | email | string | yes | Email address to verify |

Returns: { success, expires_in_seconds }

Constraints:

  • Code TTL: 1 hour
  • Max 5 attempts per email
  • 60 second resend cooldown

Example:

{
  "tool": "vutler_verify_email_request",
  "params": {
    "email": "[email protected]"
  }
}
vutler_verify_email_submit

Submit the 6-digit OTP code to verify ownership of an email address.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | email | string | yes | Email address being verified | | code | string | yes | 6-digit code received via email |

Returns: { verified (boolean) }

Example:

{
  "tool": "vutler_verify_email_submit",
  "params": {
    "email": "[email protected]",
    "code": "123456"
  }
}

Sender Domain

vutler_get_sender_domain_dns

Provision a Brevo sender domain and retrieve required DNS records for email sending.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | domain | string | yes | Domain name to use as sender (e.g., "mail.company.com") |

Returns: { dns_records { dkim, dmarc, spf, brevo_verification_code } }

Notes:

  • Idempotent: calling twice returns the same records
  • Records must be added to DNS before verifying

Example:

{
  "tool": "vutler_get_sender_domain_dns",
  "params": {
    "domain": "mail.company.com"
  }
}
vutler_authenticate_sender_domain

Trigger Brevo verification of DNS records for a sender domain.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | domain | string | yes | Domain name to verify | | confirm | boolean | no | Set to true to proceed with verification (dry-run by default) |

Returns: { status (verified|pending|failed), details }

Example:

{
  "tool": "vutler_authenticate_sender_domain",
  "params": {
    "domain": "mail.company.com",
    "confirm": true
  }
}

Scope Elevation

vutler_elevate_scope

Start scope elevation from mcp:onboarding to mcp:full. Returns a token and user code for browser-based authorization.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | (none) | | | No parameters |

Returns: { token, user_code (XXXX-XXXX), verification_url }

Notes:

  • Token TTL: 24 hours (sliding)
  • Use vutler_elevate_scope_poll to check authorization status

Example:

{
  "tool": "vutler_elevate_scope"
}
vutler_elevate_scope_poll

Poll scope elevation status until authorized or expired.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | token | string | yes | Token from vutler_elevate_scope response |

Returns: { status (pending|authorized|expired|denied) }

Example:

{
  "tool": "vutler_elevate_scope_poll",
  "params": {
    "token": "tok_elevation_abc123"
  }
}
vutler_revoke_scope_elevation

Immediately revoke scope elevation and downgrade back to mcp:onboarding.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | (none) | | | No parameters |

Returns: { success }

Example:

{
  "tool": "vutler_revoke_scope_elevation"
}

Service Account Keys

vutler_create_service_account_key

Create a workspace-wide service account key for programmatic access.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | name | string | yes | Human-readable name for this key | | description | string | no | Optional description | | scope | string | no | Scope: mcp:onboarding (default) or mcp:full |

Returns: { id, secret (shown once), name, scope, created_at }

Permissions: Admin only

Notes:

  • Secret is shown once; store it securely immediately
  • Keys can be revoked but not rotated

Example:

{
  "tool": "vutler_create_service_account_key",
  "params": {
    "name": "CI/CD Pipeline",
    "description": "GitHub Actions deployment key",
    "scope": "mcp:full"
  }
}
vutler_list_service_account_keys

List all service account keys in the workspace (metadata only, no secrets).

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | (none) | | | No parameters |

Returns: { keys[] { id, name, scope, created_at, last_used_at } }

Permissions: Admin only

Example:

{
  "tool": "vutler_list_service_account_keys"
}
vutler_revoke_service_account_key

Revoke a service account key, immediately invalidating it.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | id | string | yes | ID of the key to revoke | | confirm | boolean | no | Set to true to proceed (dry-run by default) |

Returns: { success }

Permissions: Admin only

Notes:

  • Irreversible action
  • Revoked keys are logged in audit trail

Example:

{
  "tool": "vutler_revoke_service_account_key",
  "params": {
    "id": "sakey_abc123",
    "confirm": true
  }
}

Onboarding Orchestration

vutler_onboarding_status

Get a comprehensive snapshot of the workspace state, including plan, agents, providers, integrations, and setup gaps.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | (none) | | | No parameters |

Returns: { plan, agents[], providers[], integrations[], mailboxes[], drive_config, memory_config, coordinator_config, gaps[] }

Example:

{
  "tool": "vutler_onboarding_status"
}
vutler_generate_next_steps

Generate a prioritized list of next actions for the workspace, with references to tool names and URLs.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | (none) | | | No parameters |

Returns: { steps[] { priority, title, description, tool_name, url } }

Example:

{
  "tool": "vutler_generate_next_steps"
}
vutler_recommend_agent_setup

Get AI-powered recommendations for 3-5 agent templates based on business description and domains.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | business_description | string | yes | Description of the business or use case | | domains | array | no | List of problem domains (e.g., ["sales", "support"]) |

Returns: { recommendations[] { template_id, name, description, match_score } }

Example:

{
  "tool": "vutler_recommend_agent_setup",
  "params": {
    "business_description": "SaaS startup doing B2B lead outreach and customer support",
    "domains": ["sales", "support"]
  }
}
vutler_create_agent_from_role

Create a new agent from a template.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | template_id | string | yes | ID of the template to use (e.g., "agent_sales") | | name | string | yes | Display name for the agent | | username | string | no | Unique username for the agent (auto-generated if omitted) | | confirm | boolean | no | Set to true to create; defaults to dry-run |

Returns: { agent_id, name, username, template_id, status }

Example:

{
  "tool": "vutler_create_agent_from_role",
  "params": {
    "template_id": "agent_sales",
    "name": "Sales Outreach Agent",
    "username": "sales_agent_001",
    "confirm": true
  }
}
vutler_configure_agent_access

Set agent capabilities and access policies (chat, email, drive, tasks, calendar, memory, social, sandbox).

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | agent_id | string | yes | ID of the agent to configure | | allow | array | no | List of capabilities to enable | | deny | array | no | List of capabilities to explicitly deny | | access_policy | object | no | Advanced policy settings per capability | | confirm | boolean | no | Set to true to apply; defaults to dry-run |

Returns: { agent_id, capabilities, access_policy, applied }

Example:

{
  "tool": "vutler_configure_agent_access",
  "params": {
    "agent_id": "agent_sales_001",
    "allow": ["chat", "email", "drive", "memory"],
    "deny": ["sandbox"],
    "access_policy": {
      "email": { "domains_allowed": ["company.com"], "max_recipients": 10 },
      "drive": { "max_file_size_mb": 100 }
    },
    "confirm": true
  }
}
vutler_validate_workspace_runtime

Smoke test the workspace runtime. Validates workspace exists, LLM provider is configured, agents run, coordinator is active, and memory/mailbox are operational.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | (none) | | | No parameters |

Returns: { checks { workspace, llm_provider, agents, coordinator, memory, mailbox }, all_pass }

Example:

{
  "tool": "vutler_validate_workspace_runtime"
}

Information Flows

vutler_connect_information_flow

Wire email routes (prefix → agent) and drive → memory mappings to set up information flow.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | email_routes | array | no | List of { prefix (e.g., "sales@"), agent_id } mappings | | drive_routes | array | no | List of { drive_path, memory_collection } mappings | | confirm | boolean | no | Set to true to apply; defaults to dry-run |

Returns: { email_routes, drive_routes, applied }

Notes:

  • Chat routing uses vutler_route_chat_channel
  • This tool handles non-chat information flows

Example:

{
  "tool": "vutler_connect_information_flow",
  "params": {
    "email_routes": [
      { "prefix": "sales@", "agent_id": "agent_sales_001" },
      { "prefix": "support@", "agent_id": "agent_support_001" }
    ],
    "drive_routes": [
      { "drive_path": "/CRM", "memory_collection": "crm_knowledge" }
    ],
    "confirm": true
  }
}
vutler_route_chat_channel

Bind a chat channel to a primary agent, with optional fallback via keywords.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel_id | string | yes | ID of the chat channel (e.g., Slack, Discord, Teams) | | primary_agent_id | string | yes | Agent to handle incoming messages | | fallback_agent_id | string | no | Agent to route to if keywords match | | keywords | array | no | Keywords to trigger fallback routing | | auto_reply | string | no | Auto-reply message template | | approval_required | boolean | no | Require human approval before agent responds | | confirm | boolean | no | Set to true to apply; defaults to dry-run |

Returns: { channel_id, primary_agent_id, fallback_agent_id, routing_active, applied }

Example:

{
  "tool": "vutler_route_chat_channel",
  "params": {
    "channel_id": "slack_channel_sales",
    "primary_agent_id": "agent_sales_001",
    "fallback_agent_id": "agent_support_001",
    "keywords": ["urgent", "help", "error"],
    "auto_reply": "Message received. An agent will respond shortly.",
    "approval_required": false,
    "confirm": true
  }
}
vutler_configure_coordinator_routing

Set up declarative routing rules on the workspace coordinator.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | routing_rules | array | yes | List of { pattern, agent_id, priority } rules | | default_agent_id | string | no | Agent to handle unmatched messages | | confirm | boolean | no | Set to true to apply; defaults to dry-run |

Returns: { routing_rules, default_agent_id, applied }

Example:

{
  "tool": "vutler_configure_coordinator_routing",
  "params": {
    "routing_rules": [
      { "pattern": "invoice*", "agent_id": "agent_finance_001", "priority": 10 },
      { "pattern": "meeting*", "agent_id": "agent_calendar_001", "priority": 8 }
    ],
    "default_agent_id": "agent_general_001",
    "confirm": true
  }
}
vutler_sync_drive_to_memory

One-shot synchronization of drive files to Snipara memory system.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | mapping_id | string | no | ID of a pre-configured drive→memory mapping | | drive_path | string | no | Drive path to sync (if not using mapping_id) | | snipara_collection | string | yes | Target Snipara collection name | | recursive | boolean | no | Recursively sync subdirectories (default: true) | | agent_id | string | no | Agent ID for access control | | max_files | number | no | Max files to sync per run (1-200, default: 100) |

Returns: { synced_count, errors[], next_cursor }

Example:

{
  "tool": "vutler_sync_drive_to_memory",
  "params": {
    "drive_path": "/Company Docs",
    "snipara_collection": "company_knowledge",
    "recursive": true,
    "max_files": 50
  }
}

Workspace Tools (18)

Plan-gated tools for managing agents, email, tasks, files, calendar, chat, memory, and clients.

Agents

list_agents

List all agents in the workspace.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | status | string | no | Filter by status: active, paused, archived | | role | string | no | Filter by agent role or template |

Returns: { agents[] { id, name, status, role, last_activity } }

Example:

{
  "tool": "list_agents",
  "params": {
    "status": "active"
  }
}
run_agent

Queue a task for an agent to execute.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | agent_id | string | yes | ID of the agent to run | | instructions | string | yes | Task instructions or goal | | title | string | no | Human-readable task title | | priority | string | no | Priority level: low, normal, high | | context | object | no | Additional context (e.g., customer data) |

Returns: { task_id, status, queued_at }

Example:

{
  "tool": "run_agent",
  "params": {
    "agent_id": "agent_sales_001",
    "instructions": "Find and email all leads from TechCorp who haven't been contacted in 30 days",
    "title": "TechCorp Lead Outreach",
    "priority": "high",
    "context": { "company": "TechCorp", "days_since_contact": 30 }
  }
}
stop_agent

Stop the runtime of a specific agent.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | agent_id | string | yes | ID of the agent to stop |

Returns: { agent_id, status, stopped_at }

Example:

{
  "tool": "stop_agent",
  "params": {
    "agent_id": "agent_sales_001"
  }
}

Email

send_email

Send an email message.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | to | string | yes | Recipient email address | | subject | string | yes | Email subject line | | body | string | yes | Plain text email body | | htmlBody | string | no | HTML version of the email |

Returns: { message_id, sent_at }

Example:

{
  "tool": "send_email",
  "params": {
    "to": "[email protected]",
    "subject": "Q2 Performance Review",
    "body": "Your Q2 performance review is ready. Please log in to review feedback.",
    "htmlBody": "<p>Your Q2 performance review is ready.</p><p><a href=\"https://app.com/review\">View Review</a></p>"
  }
}
list_emails

List emails in the workspace mailbox.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | folder | string | no | Folder to list: inbox, sent, archived, spam | | limit | number | no | Max emails to return (default: 50, max: 500) |

Returns: { emails[] { id, from, to, subject, date, snippet } }

Example:

{
  "tool": "list_emails",
  "params": {
    "folder": "inbox",
    "limit": 20
  }
}
read_email

Read a single email message in full.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | email_id | string | yes | ID of the email to read | | folder | string | no | Folder containing the email |

Returns: { id, from, to, cc, subject, body, htmlBody, date, attachments[] }

Example:

{
  "tool": "read_email",
  "params": {
    "email_id": "msg_abc123",
    "folder": "inbox"
  }
}

Tasks

list_tasks

List tasks in the workspace.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | status | string | no | Filter by status: open, in_progress, completed, cancelled | | limit | number | no | Max tasks to return (default: 50) |

Returns: { tasks[] { id, title, status, assignee, priority, due_date } }

Example:

{
  "tool": "list_tasks",
  "params": {
    "status": "open",
    "limit": 10
  }
}
create_task

Create a new task.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | title | string | yes | Task title | | description | string | no | Task description | | assignee | string | no | Assignee email or agent ID | | priority | string | no | Priority: low, normal, high |

Returns: { task_id, title, status, created_at }

Example:

{
  "tool": "create_task",
  "params": {
    "title": "Review Q2 sales pipeline",
    "description": "Analyze open deals and forecast close probability",
    "assignee": "[email protected]",
    "priority": "high"
  }
}
update_task

Update an existing task.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | task_id | string | yes | ID of the task to update | | status | string | no | New status | | title | string | no | Updated title | | description | string | no | Updated description |

Returns: { task_id, updated_fields, modified_at }

Example:

{
  "tool": "update_task",
  "params": {
    "task_id": "task_abc123",
    "status": "completed"
  }
}

Drive

list_files

List files in the workspace drive.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | path | string | no | Drive path to list (default: root) | | limit | number | no | Max files to return (default: 50) |

Returns: { files[] { id, name, path, mime_type, size, modified_at } }

Example:

{
  "tool": "list_files",
  "params": {
    "path": "/Sales",
    "limit": 20
  }
}
upload_file

Upload a file to the workspace drive.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | file_name | string | yes | Name of the file (e.g., "report.pdf") | | content | string | yes | File content (text or base64) | | path | string | no | Drive path to upload to (default: root) | | mime_type | string | no | MIME type (auto-detected if omitted) | | encoding | string | no | Content encoding: utf8 (default) or base64 |

Returns: { file_id, name, path, size, uploaded_at }

Example:

{
  "tool": "upload_file",
  "params": {
    "file_name": "Q2_Revenue_Report.pdf",
    "content": "JVBERi0xLjQK...",
    "path": "/Reports",
    "mime_type": "application/pdf",
    "encoding": "base64"
  }
}
download_file

Download a file from the workspace drive (returns base64 encoded content).

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | file_id | string | yes | ID of the file to download | | path | string | no | Drive path (if file_id is not available) |

Returns: { file_id, name, content (base64), mime_type, size }

Example:

{
  "tool": "download_file",
  "params": {
    "file_id": "file_abc123"
  }
}

Calendar

list_events

List calendar events.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | start | string | no | Start date (ISO 8601, e.g., "2025-01-01T00:00:00Z") | | end | string | no | End date (ISO 8601) | | source | string | no | Calendar source: workspace, personal, all |

Returns: { events[] { id, title, start, end, attendees[] } }

Example:

{
  "tool": "list_events",
  "params": {
    "start": "2025-01-01T00:00:00Z",
    "end": "2025-02-01T00:00:00Z",
    "source": "workspace"
  }
}
create_event

Create a new calendar event.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | title | string | yes | Event title | | start | string | yes | Start time (ISO 8601) | | end | string | no | End time (ISO 8601); defaults to start + 1 hour | | description | string | no | Event description | | color | string | no | Event color code |

Returns: { event_id, title, start, end, created_at }

Example:

{
  "tool": "create_event",
  "params": {
    "title": "Q2 Planning Session",
    "start": "2025-02-15T14:00:00Z",
    "end": "2025-02-15T15:00:00Z",
    "description": "Review Q2 goals and initiatives",
    "color": "#FF5733"
  }
}

Chat

send_chat

Send a message to a chat channel.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel_id | string | yes | ID of the chat channel | | message | string | yes | Message text |

Returns: { message_id, sent_at, channel_id }

Example:

{
  "tool": "send_chat",
  "params": {
    "channel_id": "slack_channel_sales",
    "message": "Q2 sales forecast updated. Check the shared drive for details."
  }
}

Memory

search_memory

Search the workspace memory system (Snipara).

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | query | string | yes | Search query or question |

Returns: { results[] { id, title, snippet, score } }

Example:

{
  "tool": "search_memory",
  "params": {
    "query": "customer onboarding checklist"
  }
}

Clients

list_clients

List client records in the workspace.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | (none) | | | No parameters |

Returns: { clients[] { id, name, email, notes, logo_url } }

Example:

{
  "tool": "list_clients"
}
create_client

Create a new client record.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | name | string | yes | Client name | | email | string | no | Client email address | | notes | string | no | Internal notes about the client | | logo_url | string | no | URL to client logo image |

Returns: { client_id, name, email, created_at }

Example:

{
  "tool": "create_client",
  "params": {
    "name": "Acme Corp",
    "email": "[email protected]",
    "notes": "Enterprise client, 500+ employees",
    "logo_url": "https://acmecorp.com/logo.png"
  }
}

Plan Gating

Tool availability is determined by workspace plan. All 24 Lifecycle Tools are always available.

| Plan | Workspace Tools Available | |------|--------------------------| | free | list_agents, run_agent, stop_agent | | office_starter | list_agents, run_agent, stop_agent, send_email, list_emails, read_email, list_tasks, create_task, update_task, list_files, upload_file, download_file, list_events, create_event, send_chat, search_memory | | office_team | office_starter + list_clients, create_client | | agents_starter | list_agents, run_agent, stop_agent, search_memory | | agents_pro | agents_starter (same as agents_starter) | | full / enterprise / beta | all 18 workspace tools |

Note: All 24 Lifecycle Tools are always available regardless of workspace plan or tier.


Architecture

The Vutler MCP package implements a two-tier tool architecture:

  1. Lifecycle Tools — Account provisioning, authentication, workspace setup, and onboarding orchestration. Available to all users, always.
  2. Workspace Tools — Operational APIs for agents, email, tasks, files, calendar, chat, memory, and clients. Gated by workspace plan.

For detailed architecture documentation, implementation patterns, and design decisions, see docs/mcp-lifecycle.md.

Key design principles:

  • Stateless device flows — No client-side token storage; use vutler_authenticate + vutler_authenticate_poll
  • Dry-run by default — Operations with confirm: true parameter preview before execution
  • Scoped access — Service account keys and scope elevation enforce minimal privilege
  • Plan transparency — Doctor validates exactly which tools are available to the client
  • Audit trail — All lifecycle operations are logged for security and compliance