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

@grackle-ai/mcp

v0.117.0

Published

MCP (Model Context Protocol) server for Grackle — translates MCP tool calls to ConnectRPC

Readme

@grackle-ai/mcp

MCP (Model Context Protocol) server for Grackle — exposes Grackle's full capabilities as MCP tools so any AI agent can manage environments, spawn sessions, orchestrate tasks, and share knowledge.

This package translates MCP tool calls into ConnectRPC requests to the Grackle server. It implements the MCP Streamable HTTP transport and supports multiple concurrent client sessions.

Installation

npm install @grackle-ai/mcp

Or run the standalone server directly:

npx @grackle-ai/mcp

Quick Start

The MCP server connects to an already-running Grackle server. Start the Grackle server first, then launch the MCP server:

# 1. Start the Grackle server (installs the CLI if needed)
npx @grackle-ai/cli serve

# 2. Start the MCP server (reads the API key automatically)
npx @grackle-ai/mcp

The MCP server listens on http://127.0.0.1:7435/mcp by default.

Configuration

All configuration is via environment variables:

| Variable | Default | Description | |----------|---------|-------------| | GRACKLE_MCP_PORT | 7435 | Port the MCP server listens on | | GRACKLE_HOST | 127.0.0.1 | Bind address (must be a loopback address) | | GRACKLE_URL | http://127.0.0.1:7434 | URL of the Grackle gRPC server to connect to | | GRACKLE_API_KEY | (auto-loaded) | API key for authenticating with the gRPC server. If not set, reads from ~/.grackle/api-key | | LOG_LEVEL | info | Logging level (debug, info, warn, error) |

Programmatic Usage

The package also exports createMcpServer for embedding the MCP server in your own application:

import { createMcpServer } from "@grackle-ai/mcp";

const server = createMcpServer({
  bindHost: "127.0.0.1",
  mcpPort: 7435,
  grpcPort: 7434,
  apiKey: "your-api-key",
});

server.listen(7435, "127.0.0.1", () => {
  console.log("MCP server ready");
});

Authentication

The MCP server supports three authentication modes:

  • API key — Full access. Pass as Authorization: Bearer <api-key>.
  • OAuth — Full access. Token issued by the Grackle OAuth authorization server.
  • Scoped token — Limited tool access. Issued to agents working on a specific task. Only a subset of tools is available (see Scoped Access below).

Client Configuration

Claude Desktop / Claude Code

Add to your MCP configuration (claude_desktop_config.json or .mcp.json):

{
  "mcpServers": {
    "grackle": {
      "url": "http://127.0.0.1:7435/mcp",
      "headers": {
        "Authorization": "Bearer <your-api-key>"
      }
    }
  }
}

Any MCP-compatible client

Point your client at http://127.0.0.1:7435/mcp using the Streamable HTTP transport with a Bearer token in the Authorization header.


Tool Reference

The MCP server exposes a rich set of tools organized into groups. Each tool validates its inputs against a strict schema and returns structured JSON results.

Environment Tools

Manage compute environments where agents run (Docker, SSH, Codespace, local).

| Tool | Description | Parameters | |------|-------------|------------| | env_list | List all registered environments with status, adapter type, and runtime. | (none) | | env_list_docker_containers | List running Docker containers that can be attached to (Docker adapter attach mode). | (none) | | env_add | Register a new environment. The adapterConfig fields depend on adapterType (see below). For the Docker adapter, set adapterConfig.attach to an existing container name/ID to attach instead of creating one. | displayName (string), adapterType (local | ssh | codespace | docker), adapterConfig? (object), githubAccountId? (string, codespace/docker) | | env_provision | Provision an environment — start resources, install the agent, and connect. | environmentId (string), force? (boolean) | | env_stop | Stop a running environment without destroying its resources. | environmentId (string) | | env_destroy | Destroy an environment's backing resources (e.g., delete the container). | environmentId (string) | | env_remove | Remove an environment registration. Must be stopped first. | environmentId (string) | | env_wake | Wake a stopped environment by re-provisioning it. | environmentId (string) |

env_add is a discriminated union on adapterType — the tool's input schema advertises the exact adapterConfig fields valid for each adapter, and unknown fields are rejected. Pick the adapter that matches how the environment is reached:

  • local — a PowerLine already running on this machine. adapterConfig (all optional): host, port.
  • ssh — any host reachable over SSH. This is also how you attach to an already-running container that exposes an SSH endpoint. adapterConfig: host (required), user?, sshPort? (default 22), identityFile?, sshOptions? (string map), localPort?, env? (string map).
  • codespace — an existing GitHub Codespace. adapterConfig: codespaceName (required, from gh codespace list), localPort?, env? (string map). Optional top-level githubAccountId selects a stored GitHub account for gh.
  • docker — spawn a new container from an image, or attach to an existing one. adapterConfig (all optional): attach (existing container name/ID — when set, Grackle never creates/stops/removes the container and image/repo/volumes are ignored; use env_list_docker_containers to discover candidates), image (default grackle-powerline:latest), containerName, repo (owner/repo or HTTPS URL), volumes (string array), gpus, localPort, env (string map). Optional top-level githubAccountId authenticates gh for private repo clones.

Session Tools

Manage AI agent sessions — spawn, monitor, interact, and terminate.

| Tool | Description | Parameters | |------|-------------|------------| | session_spawn | Spawn a new agent session with a prompt and optional model config. | environmentId (string), prompt (string), maxTurns? (int), personaId? (string), workingDirectory? (string) | | session_resume | Resume a stopped agent session. | sessionId (string) | | session_status | List sessions with optional filtering by environment and status. | environmentId? (string), all? (boolean, default false) | | session_kill | Terminate a running session. Hard kill by default; graceful=true sends SIGTERM. | sessionId (string), graceful? (boolean, default false) | | session_attach | Stream events from a running session for a limited duration. | sessionId (string), timeoutSeconds? (int, default 30, max 300), maxEvents? (int) | | session_send_input | Send a text message to a session waiting for user input. | sessionId (string), text (string) |

Workspace Tools

Manage workspaces that group tasks, agents, and repositories.

| Tool | Description | Parameters | |------|-------------|------------| | workspace_list | List all workspaces with names, descriptions, repos, and status. | environmentId? (string) | | workspace_create | Create a new workspace. | name (string), environmentId (string), description? (string), repoUrl? (string), workingDirectory? (string), useWorktrees? (boolean), defaultPersonaId? (string) | | workspace_get | Get full details of a workspace by ID. | workspaceId (string) | | workspace_update | Update a workspace's name, description, repo, or settings. | workspaceId (string), name?, description?, repoUrl?, environmentId?, workingDirectory?, useWorktrees?, defaultPersonaId? | | workspace_archive | Archive a workspace, marking it as inactive. | workspaceId (string) | | workspace_link_environment | Link an additional environment to a workspace's pool. | workspaceId (string), environmentId (string) | | workspace_unlink_environment | Remove a linked environment from a workspace's pool. | workspaceId (string), environmentId (string) |

Task Tools

Create, manage, and run tasks within workspaces. Supports hierarchical task trees and dependency gating.

| Tool | Description | Parameters | |------|-------------|------------| | task_list | List tasks with optional search and status filters. | workspaceId? (string), search? (string), status? (string: not_started, working, paused, complete, failed) | | task_search | Fuzzy search tasks by title or description, ranked by relevance. Returns results with a relevanceScore (0.0–1.0, higher = better match). Prefer this over task_list when matching approximate descriptions. | query (string), workspaceId? (string), limit? (number, default 10), status? (string) | | task_create | Create a new task with dependencies and parent hierarchy. | workspaceId? (string), title (string), description? (string), dependsOn? (string[]), parentTaskId? (string), canDecompose? (boolean), defaultPersonaId? (string) | | task_show | Get full details of a task. | taskId (string) | | task_update | Update a task's title, description, status, or dependencies. | taskId (string), title?, description?, status? (enum), dependsOn? (string[]), sessionId? (string) | | task_start | Start a task by spawning an agent session. Supports IPC pipe modes. | taskId (string), personaId? (string), environmentId? (string), notes? (string), pipe? (sync | async | detach) | | task_delete | Permanently delete a task. | taskId (string) | | task_complete | Mark a task as complete (sticky status). | taskId (string) | | task_resume | Resume the latest session for a task. | taskId (string) |

Persona Tools

Manage agent personas — reusable templates defining system prompt, runtime, and model.

| Tool | Description | Parameters | |------|-------------|------------| | persona_list | List all available personas. | (none) | | persona_create | Create a new persona template (agent or script type). | name (string), systemPrompt? (string), description? (string), runtime? (string), model? (string), maxTurns? (int), type? (agent | script), script? (string) | | persona_show | Get full details of a persona. | personaId (string) | | persona_edit | Update an existing persona. | personaId (string), name?, systemPrompt?, description?, runtime?, model?, maxTurns?, type?, script? | | persona_delete | Delete a persona permanently. | personaId (string) |

Knowledge Graph Tools

Search a semantic knowledge graph across sessions and task context.

| Tool | Description | Parameters | |------|-------------|------------| | knowledge_search | Semantic search over the knowledge graph using natural language. | query (string), limit? (int, max 50), workspaceId? (string), expand? (boolean), expandDepth? (int, max 5) | | knowledge_get_node | Retrieve a specific node by ID with optional neighbor expansion. | id (string), expand? (boolean), expandDepth? (int, max 5) | | knowledge_create_node | Create a new knowledge entry (decision, insight, concept, snippet). | title (string), content (string), category? (string), tags? (string[]), workspaceId? (string), edges? (array of {toId, type}) |

IPC Tools

Inter-process communication between parent and child agent sessions.

| Tool | Description | Parameters | |------|-------------|------------| | ipc_spawn | Spawn a child agent session with an IPC pipe. | prompt (string), pipe (sync | async | detach), environmentId (string), personaId? (string), maxTurns? (int) | | ipc_write | Write a message to a child session via a file descriptor. | fd (int), message (string) | | ipc_close | Close a file descriptor, optionally stopping the child. | fd (int) | | ipc_terminate | Send SIGTERM to a child session via its fd for graceful shutdown. | fd (int) | | ipc_list_fds | List your open file descriptors (IPC connections). | (none) | | ipc_list_streams | List all active IPC streams with subscriber details and buffer depth. | (none) | | ipc_create_stream | Create a named stream for inter-session communication. Returns an rw fd. | name (string), selfEcho? (boolean, default false) | | ipc_attach | Grant another session access to a stream you hold an fd on. | fd (int), targetSessionId (string), permission? (r | w | rw), deliveryMode? (sync | async | detach) | | ipc_share_stream | Share a stream with your parent session. Auto-discovers the parent via the inherited pipe fd, grants access, and sends a [stream-ref] notification through the pipe. | fd? (int) or streamName? (string; exactly one required), permission? (r | w | rw), deliveryMode? (sync | async | detach) |

Log Tools

Retrieve session logs — raw events, formatted transcripts, or live tails.

| Tool | Description | Parameters | |------|-------------|------------| | logs_get | Retrieve session logs in raw, transcript, or live-tail mode. | sessionId (string), transcript? (boolean), tail? (boolean), timeoutSeconds? (int, default 10, max 60), maxEvents? (int) |

Token Tools

Manage secrets that are auto-forwarded to environments.

| Tool | Description | Parameters | |------|-------------|------------| | token_list | List configured tokens (values are never returned). | (none) | | token_set | Set a token for auto-forwarding to environments. | name (string), value (string), type? (env_var | file), envVar? (string), filePath? (string) | | token_delete | Delete a configured token. | name (string) |

Credential Provider Tools

Configure which credential providers (Claude, GitHub, Copilot, Codex) are auto-forwarded.

| Tool | Description | Parameters | |------|-------------|------------| | credential_provider_list | List current provider configuration. | (none) | | credential_provider_set | Set a provider mode. | provider (claude | github | copilot | codex), value (off | on | subscription | api_key) |

Config Tools

Read and write global configuration settings.

| Tool | Description | Parameters | |------|-------------|------------| | config_get_default_persona | Get the default persona for new sessions. | (none) | | config_set_default_persona | Set the default persona for new sessions. | personaId (string) |

Usage Tools

Query aggregated token usage and cost data.

| Tool | Description | Parameters | |------|-------------|------------| | usage_get | Get token usage and cost for a session, task, task tree, workspace, or environment. | scope (session | task | task_tree | workspace | environment), id (string) |

Widget Tools

MCP Apps UI widgets — interactive HTML rendered inline by capable hosts (and always by Grackle's own chat pane via the broker).

show_hello_widget is the Grackle-served demo widget: it references a static ui:// resource and appears in tools/list only when the host advertises the io.modelcontextprotocol/ui extension. The widget registry tools let an agent author and render its own widgets at runtime; they are ordinary scoped tools (always listed) and the rendered widget is captured by the broker into the session's chat. component_show renders agent-authored React/JSX against Grackle's own component library via a sandboxed React runtime (#1268).

| Tool | Description | Parameters | |------|-------------|------------| | show_hello_widget | Display the Grackle hello widget — a minimal interactive MCP Apps UI that echoes the provided message. | message (string, optional) | | widget_register | Register a reusable widget (HTML body) in the workspace so it can be re-rendered with different data. Returns the widget id. | name (string), body (string), description (string, optional), propsSchema (string, optional) | | widget_update | Update a registered widget's body/name/description/props schema; bumps its version. | id (string), body/name/description/propsSchema (optional) | | widget_list | List the reusable widgets registered in the workspace. | — | | widget_render | Render a registered widget inline (by id or name), optionally passing props (data). | id (string, optional), name (string, optional), props (object, optional) | | widget_show | Render a one-off widget inline from an inline HTML body, without persisting it. | body (string), props (object, optional) | | component_show | Render a React/JSX component inline against the Grackle component library (no persistence). source is JSX that calls render(<Component {...props}/>); React, props, and Grackle components are in scope. | source (string), props (object, optional) |

Widgets are workspace-scoped: a session may only register/render widgets in its own workspace (the workspaceId is taken from the session's scoped token). Agent-authored bodies render in the cross-origin sandbox with inline scripts allowed (script-src 'unsafe-inline'), isolated by the iframe origin + a restricted connect-src. component_show additionally runs in a sandboxed React runtime that transpiles + evaluates the JSX (script-src 'unsafe-eval'), kept safe by the same origin isolation.


MCP Apps (UI widgets)

Grackle's MCP server is a conformant MCP Apps (SEP-1865) provider. Hosts that support MCP Apps can fetch and render interactive HTML widgets inline.

How it works:

  • Capability negotiation — A host advertises support during initialize via the io.modelcontextprotocol/ui extension (with mimeTypes including text/html;profile=mcp-app). The server detects this and only lists Widget Tools to capable hosts; other clients see the data-only tools.

  • Resources — The server declares the resources capability and implements resources/list and resources/read. Widget UIs are served as ui://… resources with MIME text/html;profile=mcp-app.

  • Tool ↔ resource link — A widget tool carries _meta.ui.resourceUri (and the legacy _meta["ui/resourceUri"]) pointing at its ui:// resource. The host reads the resource and renders it, passing the tool's input and result into the widget.

  • Widget assets — The widget's browser scripts are served (unauthenticated, since they are non-sensitive static JS) from /widgets/<name>/… on the MCP server's HTTP origin.

  • Grackle chat-pane capture — When an agent in a Grackle session calls a widget tool, the MCP server also pushes a self-contained "widget" event (resource HTML + tool input/result) into that session's event stream, so the widget renders inline in Grackle's own chat UI — independent of whether the agent runtime preserves MCP _meta. This covers both the static show_hello_widget and the agent-authored registry (widget_register/widget_render/widget_show), whose render descriptor the broker reads from the tool result. (This in-process capture only runs when the MCP server is co-located with the Grackle server; the standalone npx @grackle-ai/mcp server does not emit chat widget events.)

Note: the widget's scripts load from the MCP server's origin, so a host whose sandbox CSP forbids cross-origin scripts won't render them. Grackle's own chat pane allows the MCP origin in its sandbox CSP, so widgets render there.

The current built-in widget is show_hello_widget (resource ui://grackle/hello-widget). Try it with the MCP Inspector, Claude Desktop, or Grackle's own chat.


Scoped Access

When an agent authenticates with a scoped token (issued automatically when a task session is started), tool access is controlled by the task's persona configuration.

Persona-Scoped Tool Filtering

Each persona can define an allowed_mcp_tools list that restricts which MCP tools its agents can use. When a scoped token connects:

  1. The server looks up the persona's allowed_mcp_tools from the token's personaId claim.
  2. If the persona defines a non-empty tool list, only those tools are exposed via tools/list.
  3. If the persona has no explicit tool list (empty allowed_mcp_tools), the default scoped set is used:
    • task_create, task_list, task_show, task_start, task_complete
    • session_attach, session_send_input
    • persona_list, persona_show
    • ipc_spawn, ipc_write, ipc_close, ipc_terminate, ipc_list_fds, ipc_create_stream, ipc_attach, ipc_share_stream
    • knowledge_search, knowledge_get_node
    • logs_get
    • workpad_write, workpad_read
    • schedule_list, schedule_show

Preset Tool Sets

Predefined presets are available for convenience (via CLI --mcp-tools-preset or the web UI):

| Preset | Description | |--------|-------------| | default | The 25-tool default scoped set (backward compatible) | | worker | Subset of default — no task creation capabilities | | orchestrator | Default + task management, session spawning, persona creation, scheduling | | admin | Full access to all available tools |

Scoped tokens also enforce workspace isolation — agents can only see tasks within their own workspace. Subtasks created by a scoped agent are automatically parented to the agent's own task. Tool calls to non-permitted tools return an error with a descriptive message listing the available tools.

Requirements

  • Node.js >= 22
  • A running Grackle server (@grackle-ai/cli)

License

MIT