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

@ackuity/inline-proxy

v0.7.7

Published

A transparent MCP proxy that intercepts tool calls and evaluates them against the [Ackuity Inline Decision Engine](https://ackuity.ai) before they reach the MCP server. Destructive operations (DELETE, DROP, TRUNCATE) are blocked in real time.

Readme

Ackuity Inline MCP Proxy

A transparent MCP proxy that intercepts tool calls and evaluates them against the Ackuity Inline Decision Engine before they reach the MCP server. Destructive operations (DELETE, DROP, TRUNCATE) are blocked in real time.

How It Works

MCP Client (LLM Agent)
        │
        ▼
┌──────────────────────┐
│  Ackuity Inline      │
│  MCP Proxy           │──── tools/call ──▶ Inline Decision Engine
│                      │◀─── allow/block ──┘
└──────────────────────┘
        │ (if allowed)
        ▼
   MCP Server (e.g. DAB)

The proxy sits between any MCP client and MCP server. When it sees a tools/call request, it sends the tool name and arguments to the Ackuity protect_tools API. If the decision is block, an error is returned to the client and the call never reaches the MCP server.

Installation

npx @ackuity/inline-proxy

Or install globally:

npm install -g @ackuity/inline-proxy

For local development:

git clone https://github.com/Ackuity/ackuity-mcp-proxy.git
cd ackuity-mcp-proxy
npm install
npm run build

Configuration

Set these environment variables, or add them to a .env file in the project root:

| Variable | Required | Description | Default | |--------------------|----------|--------------------------------------------------|------------------------------------------------------| | INLINE_API_TOKEN | Yes | Bearer token for the Inline Decision Engine | — | | INLINE_URL | Yes | Protect tools endpoint URL | — | | INLINE_AGENT_ID | Yes | Agent ID registered with the Inline Engine | — |

Usage

The proxy supports three modes depending on how your MCP client and server communicate.

Mode 1: stdio

Client connects via stdin/stdout. Proxy spawns the MCP server as a child process.

node dist/main.js --mode stdio --cmd "dab start --config dab-config.json"

Use this when your MCP client (e.g. Claude Desktop, Cursor) expects to launch a command.

Mode 2: stdio-to-server

Client connects via stdin/stdout. Proxy forwards to an already-running HTTP MCP server.

node dist/main.js --mode stdio-to-server --target http://localhost:5000/mcp

Use this when your MCP server is already running on HTTP and your client expects stdio.

Mode 3: server

Proxy runs as an HTTP server. Both client and MCP server communicate over HTTP.

node dist/main.js --mode server --target http://localhost:5000/mcp --port 7500

Use this when your MCP client connects over HTTP (e.g. a web app or remote agent).

How to Use with Your Agent

Option 1: Spawn the proxy from your agent (stdio / stdio-to-server)

If your agent uses the MCP SDK, you can launch the proxy as a subprocess using StdioClientTransport. The proxy reads Ackuity credentials from environment variables, so pass them via env.

Replace <ACKUITY-DIST-REF> in the examples below depending on how you installed the proxy:

| Install method | command | <ACKUITY-DIST-REF> | |---|---|---| | Cloned and built locally | node | path/to/ackuity-inline-proxy/dist/main.js | | npx from GitHub | npx | github:Ackuity/ackuity-mcp-proxy | | Published to npm | npx | @ackuity/inline-proxy |

TypeScript / JavaScript

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

const transport = new StdioClientTransport({
  command: "npx",  // or "node" if running locally
  args: [
    "<ACKUITY-DIST-REF>",
    "--mode", "stdio-to-server",
    "--target", "http://localhost:5000/mcp",
  ],
  env: {
    ...process.env,
    INLINE_API_TOKEN: "your_token_here",
    INLINE_URL: "https://inline.ackuity.ai/api/v1/inline/protect_tools",
    INLINE_AGENT_ID: "your_agent_id_here",
  },
});

const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(transport);

// All tool calls now go through the Ackuity Inline Decision Engine
const tools = await client.listTools();
const result = await client.callTool({ name: "read_records", arguments: { entity: "Employees" } });

Tip: Use --mode stdio with --cmd instead if you want the proxy to also spawn the MCP server:

args: [
  "<ACKUITY-DIST-REF>",
  "--mode", "stdio",
  "--cmd", "npx @azure/data-api-builder start --config dab-config.json",
],

Python

from mcp.client.stdio import stdio_client, StdioServerParameters

server = StdioServerParameters(
    command="npx",  # or "node" if running locally
    args=[
        "<ACKUITY-DIST-REF>",
        "--mode", "stdio-to-server",
        "--target", "http://localhost:5000/mcp",
    ],
    env={
        **os.environ,
        "INLINE_API_TOKEN": "your_token_here",
        "INLINE_URL": "https://inline.ackuity.ai/api/v1/inline/protect_tools",
        "INLINE_AGENT_ID": "your_agent_id_here",
    },
)

async with stdio_client(server) as (read_stream, write_stream):
    async with ClientSession(read_stream, write_stream) as session:
        await session.initialize()
        result = await session.call_tool("read_records", {"entity": "Employees"})

Option 2: Run the proxy as a Docker container (server mode)

When running in server mode, the proxy exposes an HTTP endpoint at /mcp. This is ideal for containerized deployments where your agent and MCP server are separate services.

docker-compose.yml

services:
  mcp-server:
    image: your-mcp-server-image
    ports:
      - "5000:5000"

  ackuity-proxy:
    image: node:22-slim
    working_dir: /app
    command: npx @ackuity/inline-proxy --mode server --target http://mcp-server:5000/mcp --port 7500
    ports:
      - "7500:7500"
    environment:
      INLINE_API_TOKEN: ${INLINE_API_TOKEN}
      INLINE_URL: ${INLINE_URL}
      INLINE_AGENT_ID: ${INLINE_AGENT_ID}
    depends_on:
      - mcp-server

  agent:
    image: your-agent-image
    environment:
      MCP_ENDPOINT: http://ackuity-proxy:7500/mcp
    depends_on:
      - ackuity-proxy

Your agent connects to http://ackuity-proxy:7500/mcp instead of directly to the MCP server. All tool calls are evaluated by the Ackuity Inline Decision Engine before reaching the MCP server.

With a .env file

INLINE_API_TOKEN=your_token_here
INLINE_URL=https://inline.ackuity.ai/api/v1/inline/protect_tools
INLINE_AGENT_ID=your_agent_id_here

Then run:

docker compose up

Using Server Mode with OAuth / Authenticated MCP Servers

If your MCP server requires authentication (e.g. OAuth, API keys, or session tokens), server mode is the recommended approach. The proxy runs as a standalone HTTP service, so authentication is handled entirely between your agent and the MCP server — the proxy transparently forwards headers and credentials while still intercepting tool calls for evaluation.

Why server mode for authenticated setups

In stdio mode, the proxy spawns the MCP server as a child process, which makes it difficult to pass authentication context. In server mode, the proxy sits between your agent and an already-authenticated MCP server over HTTP, so:

  • Your agent authenticates with the MCP server as usual (OAuth flows, bearer tokens, etc.)
  • The proxy intercepts only tools/call requests for security evaluation
  • All other traffic (including auth handshakes) passes through unchanged

Example: OAuth-protected MCP server

# 1. Start your MCP server (handles its own OAuth)
your-mcp-server --port 5000

# 2. Start the Ackuity proxy in front of it
npx @ackuity/inline-proxy --mode server --target http://localhost:5000/mcp --port 7500

# 3. Point your agent to the proxy instead of the MCP server
# Agent connects to http://localhost:7500/mcp

Your agent's existing authentication flow (OAuth redirects, token refresh, etc.) works as before — just change the MCP endpoint URL to point to the proxy.

Token expiry

If the MCP server returns a 401 Unauthorized or 403 Forbidden, the token has expired. Your agent is responsible for refreshing the token with the OAuth provider and retrying the request — the proxy passes these status codes through unchanged.

Example: Agent passing a bearer token

// Your agent sends requests to the proxy, which forwards to the MCP server
const response = await fetch("http://localhost:7500/mcp", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer <your-oauth-token>",  // Passed through to MCP server
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    method: "tools/call",
    params: { name: "delete_record", arguments: { id: 123 } },
  }),
});
// The proxy evaluates the tool call with Ackuity before forwarding

Fail-Closed Behavior

If the Inline Decision Engine is unreachable or returns an error (e.g. invalid token), the proxy blocks the tool call rather than forwarding it. This prevents destructive operations from slipping through during outages.

Project Structure

src/
├── main.ts            Entry point, arg parsing, mode selection
├── common.ts          Shared utilities (logging, arg parser, constants)
├── inline_engine.ts   Protect Tools API types, response manager, API call
└── mode.ts            ProxyMode interface and implementations (Stdio, StdioToServer, Server)

Logging

All MCP traffic is logged to proxy_logs/proxy_traffic.txt in the working directory. Status messages are written to stderr with a [PROXY] prefix.