Skip to content
PluginStats

@earendil-works/pi-mcp weekly downloads statistics

By earendil-works · npm · MCP servers

Standalone Model Context Protocol client for pi and other applications

View on npm Stale · Oct 18, 2026

@earendil-works/pi-mcp has 1,380,341 recorded weekly downloads on npm, a change of -14.9% over the past 7 days, ranking #178 of 2,391 tracked listings.

Weekly downloads
1,380,341
Official API · Oct 18, 2026
7-day growth
-14.9%
-241.4K weekly downloads
30-day growth
—
Insufficient history
90-day growth
—
Insufficient history
Rank
#178
Among tracked npm listings

About @earendil-works/pi-mcp

@earendil-works/pi-mcp

A small, standalone Model Context Protocol client. It does not depend on the official MCP SDK or other pi packages.

The package provides a transport-neutral client core, stdio and Streamable HTTP transports, and an in-memory testing transport.

Usage

import { McpClient, StdioTransport } from "@earendil-works/pi-mcp";

const transport = new StdioTransport({
	command: "npx",
	args: ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"],
});
const client = new McpClient({
	name: "my-client",
	version: "1.0.0",
	roots: [{ uri: "file:///workspace", name: "workspace" }],
});

await client.connect(transport);
const tools = await client.listTools();
const result = await client.callTool("search", { query: "MCP" });
await client.close();

For a remote server, use new StreamableHttpTransport({ url, headers }). Fetch can be injected for proxying or custom networking.

Tools for an LLM

toLlmContent(result) converts a CallToolResult to text and image content for a model, in the shape of @earendil-works/pi-ai's TextContent and ImageContent. Text and images pass through, embedded text and image resources are unwrapped, and audio, resource links, and binary resources become short text placeholders. A result without content blocks but with structuredContent becomes its JSON.

Wrapping an MCP tool as a pi-agent-core AgentTool:

import type { AgentTool } from "@earendil-works/pi-agent-core";
import { toLlmContent } from "@earendil-works/pi-mcp";
import { Type } from "typebox";

const tools: AgentTool[] = (await client.listTools()).map((tool) => ({
	// Providers allow at most 64 characters of [A-Za-z0-9_-].
	name: `mcp_${tool.name}`.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 64),
	label: tool.title ?? tool.name,
	description: tool.description ?? tool.name,
	// Providers require an object schema, and some reject one without `properties`.
	parameters: Type.Unsafe({ ...tool.inputSchema, type: "object", properties: tool.inputSchema.properties ?? {} }),
	execute: async (_toolCallId, params, signal) => {
		const result = await client.callTool(tool.name, params as Record<string, unknown>, { signal });
		// MCP reports tool failures in the result instead of as a protocol error.
		return { content: toLlmContent(result), details: undefined, isError: result.isError === true };
	},
}));

The mcp-codemode example also forwards progress, passes structuredContent through, and lets @earendil-works/pi-codemode scripts call the tools.

OAuth

@earendil-works/pi-mcp/oauth provides the MCP OAuth client subset without depending on the official SDK:

import { McpClient, StreamableHttpTransport } from "@earendil-works/pi-mcp";
import {
	adaptOAuthProvider,
	authorizeMcp,
	McpOAuthAuthorizationRequiredError,
	McpOAuthProvider,
	OAuthCallbackServer,
} from "@earendil-works/pi-mcp/oauth";

const serverUrl = "https://mcp.example.com/mcp";
const callback = await OAuthCallbackServer.listen();
let authorizationUrl: URL | undefined;
const oauth = new McpOAuthProvider({
	serverUrl,
	redirectUrl: callback.redirectUrl,
	clientMetadata: { client_name: "My MCP client" },
	onRedirect: (url) => {
		authorizationUrl = url;
	},
});

const connect = () => {
	const client = new McpClient({ name: "my-client", version: "1.0.0" });
	return {
		client,
		connected: client.connect(
			new StreamableHttpTransport({ url: serverUrl, authProvider: adaptOAuthProvider(oauth) }),
		),
	};
};

const first = connect();
try {
	await first.connected;
} catch (error) {
	if (!(error instanceof McpOAuthAuthorizationRequiredError)) throw error;
	const state = await oauth.state();
	const result = callback.waitForCallback(state);
	// Open authorizationUrl in the user's browser here.
	const { code } = await result;
	await authorizeMcp(oauth, { serverUrl, authorizationCode: code });
}

const { client, connected } = connect();
await connected;

Inject McpOAuthStateStore into McpOAuthProvider for durable credentials. The package does not open a browser or choose where credentials are stored.

The OAuth implementation is adapted from the MIT-licensed Model Context Protocol TypeScript SDK v1.29.0. Its license is included under LICENSES/.

An MCP transport owns framing and I/O. It delivers individual JSON-RPC messages to McpClient; the client owns request correlation, initialization, timeouts, cancellation, server requests, and protocol-level helpers.

Supported protocol surface

  • MCP protocol version 2025-11-25, accepting servers that negotiate 2025-06-18, 2025-03-26, or 2024-11-05
  • initialization and notifications/initialized
  • ping
  • paginated tools/list
  • tools/call, including structured content
  • progress notifications and timeout renewal
  • request cancellation
  • Streamable HTTP sessions, the server-to-client GET stream with reconnection, and resumption of dropped response streams with Last-Event-ID
  • stdio shutdown per the spec (close stdin, then SIGTERM, then SIGKILL), applied to the server's whole process group
  • server ping and roots/list requests
  • logging and tool-list-change notifications through the generic notification API
  • OAuth protected-resource and authorization-server discovery
  • PKCE authorization code flow, dynamic client registration, token refresh (one refresh shared by concurrent 401s), and step-up authorization for insufficient_scope

Batch JSON-RPC messages, legacy HTTP+SSE, servers, sampling, and tasks are outside the initial core.

Testing

@earendil-works/pi-mcp/testing exports createInMemoryTransportPair() for client and adapter tests.

Description from the npm listing.

  • mcp
  • model-context-protocol
  • client

README badge

Show your rank in a README or on your website. The badge updates automatically.

Charts

Images: 30d · 1y · all time · 1600×900 dark

Adoption over time

@earendil-works/pi-mcp weekly downloads on npm, last 90 days: 1,380,341 weekly downloads as of Oct 18, 2026.@earendil-works/pi-mcpWeekly downloads on npm · Last 90 days1,380,341downloads / week0200K400K600K800K1M1.2M1.4M1.6M1.8MJul 20Aug 4Aug 19Sep 3Sep 18Oct 3Oct 18downloads / weekobservedarchived (Internet Archive)no observationsJul 23, 2026 – Oct 18, 2026 · 88 observations · Updated Oc…pluginstats.com
@earendil-works/pi-mcp weekly downloads on npm, last 90 days: 1,380,341 weekly downloads as of Oct 18, 2026.

7/30/90-day growth

@earendil-works/pi-mcp weekly downloads growth on npm: -14.9% over 7 days, 30-day growth unavailable, 90-day growth unavailable.@earendil-works/pi-mcpWeekly downloads growth on npm1,380,341downloads / week now7-day growth-241,390 weekly downloads-14.9%30-day growth+1,380,341 weekly downlo…Insufficient history90-day growth+1,380,341 weekly downlo…Insufficient historyGrowth vs. nearest observation to each baseline date · Updated Oct 18, 2026pluginstats.com
@earendil-works/pi-mcp weekly downloads growth on npm: -14.9% over 7 days, 30-day growth unavailable, 90-day growth unavailable.

Ranking history

@earendil-works/pi-mcp npm ranking history: currently #178 (by weekly downloads).@earendil-works/pi-mcpnpm ranking · by weekly downloads · Last 90 days#178current rank#60#80#100#120#140#160#180#200Jul 23Aug 7Aug 22Sep 6Sep 21Oct 6Oct 21rankOct 17, 2026 – Oct 21, 2026 · 5 observations · Updated Oct 18, 2026pluginstats.com
@earendil-works/pi-mcp npm ranking history: currently #178 (by weekly downloads).

Listing placement

All npm2,389 listings · 120 pages · 1,196 shown · page 9, #18 (overall #178)
All npm: every listing in weekly downloads order

Listing placement

MCP servers300 listings · 15 pages · page 1, #10 (overall #10)
MCP servers: every listing in weekly downloads order

Filled points are observed values; hollow points come from Internet Archive snapshots of the listing page. Dashed segments span periods with no observations — values between points are not interpolated.

Each band is one page of 20. Weekly downloads on a linear scale. Placement is projected from weekly downloads, so it can differ from the marketplace's own sort order. Hover a dot to see the listing.

Recent observations

Full history (544)
Recent weekly downloads observations for @earendil-works/pi-mcp
Date (UTC)Weekly downloadsChange vs. previous
1,380,341+370K
1,010,341-227.9K
1,238,268+168.6K
1,069,643-315.5K
1,385,127-280.4K
1,665,5090
1,665,509+43.8K
1,621,731+22.2K
1,599,513+39K
1,560,559+33K
1,527,542-17.5K
1,545,069-32.3K
1,577,345-111.8K
1,689,193—

Similar npm MCP servers plugins

All 20 @earendil-works/pi-mcp alternatives

Data source

Weekly downloads (trailing 7 complete days) come from the official npm downloads API. Downloads include CI and mirrors and are not equivalent to installs or users. npm publishes no ratings.

Listing: https://www.npmjs.com/package/@earendil-works/pi-mcp. First seen Oct 16, 2026; last successful collection Oct 21, 2026. See the methodology.