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

fast-agent-typescript

v1.0.0

Published

<p align="center"> <a href="https://pypi.org/project/fast-agent-mcp/"><img src="https://img.shields.io/pypi/v/fast-agent-mcp?color=%2334D058&label=pypi" /></a> <a href="#"><img src="https://github.com/evalstate/fast-agent/actions/workflows/main-checks.yml

Readme

Overview

[!TIP] Documentation site is in production here : https://fast-agent.ai. Feel free to feed back what's helpful and what's not. There is also an LLMs.txt here

fast-agent-typescript enables you to create and interact with sophisticated Agents and Workflows in minutes. It is the first framework with complete, end-to-end tested MCP Feature support including Sampling. Both Anthropic (Haiku, Sonnet, Opus) and OpenAI models (gpt-4o/gpt-4.1 family, o1/o3 family) are supported.

The simple declarative syntax lets you concentrate on composing your Prompts and MCP Servers to build effective agents.

fast-agent-typescript is multi-modal, supporting Images and PDFs for both Anthropic and OpenAI endpoints via Prompts, Resources and MCP Tool Call results. The inclusion of passthrough and playback LLMs enable rapid development and test of TypeScript glue-code for your applications.

[!IMPORTANT] The fast-agent documentation repo is here: https://github.com/evalstate/fast-agent-docs. Please feel free to submit PRs for documentation, experience reports or other content you think others may find helpful. All help and feedback warmly received.

Agent Application Development

Prompts and configurations that define your Agent Applications are stored in simple files, with minimal boilerplate, enabling simple management and version control.

Chat with individual Agents and Components before, during and after workflow execution to tune and diagnose your application. Agents can request human input to get additional context for task completion.

Simple model selection makes testing Model <-> MCP Server interaction painless. You can read more about the motivation behind this project here

2025-03-23-fast-agent

Get started:

Install the library using npm:

npm install fast-agent-typescript   # install fast-agent TypeScript!

npx fastagent setup                 # create an example agent and config files
npx ts-node agent.ts               # run your first agent
npx ts-node agent.ts --model=o3-mini.low # specify a model

Example

import { FastAgent } from 'fast-agent-typescript';

// Create a new FastAgent instance
const app = new FastAgent('simple-agent-example');

// Define an agent with a custom instruction
app.agent(
  {
    name: 'simple',
    instruction: 'You are a helpful assistant that provides concise answers.',
  },
  async (agent) => {
    console.log('Starting simple agent...');

    // Send a message to the agent
    const response = await agent.send(
      'Hello! What can you help me with today?'
    );
    console.log('Agent response:', response);

    // Start an interactive prompt session
    await agent.prompt('Ask me anything!');
  }
);

// Run the agent
app.run();

Other quickstart examples include a Researcher Agent (with Evaluator-Optimizer workflow) and Data Analysis Agent (similar to the ChatGPT experience), demonstrating MCP Roots support.

[!TIP] Windows Users - there are a couple of configuration changes needed for the Filesystem and Docker MCP Servers - necessary changes are detailed within the configuration files.

Basic Agents

Defining an agent is as simple as:

app.agent({
  instruction: 'Given an object, respond only with an estimate of its size.',
});

We can then send messages to the Agent:

const agent = await app.run();
const moonSize = await agent.send('the moon');
console.log(moonSize);

Or start an interactive chat with the Agent:

const agent = await app.run();
await agent.interactive();

Here is the complete sizer.ts Agent application:

import { FastAgent } from 'fast-agent-typescript';

// Create the application
const app = new FastAgent('Agent Example');

app.agent(
  {
    instruction: 'Given an object, respond only with an estimate of its size.',
  },
  async (agent) => {
    await agent.interactive();
  }
);

app.run();

The Agent can then be run with npx ts-node sizer.ts.

Specify a model with the --model switch - for example npx ts-node sizer.ts --model sonnet.

Combining Agents and using MCP Servers

Agents can be chained to build a workflow, using MCP Servers defined in the fastagent.config.yaml file:

// Define URL fetcher agent
app.agent({
  name: 'url_fetcher',
  instruction: 'Given a URL, provide a complete and comprehensive summary',
  servers: ['fetch'], // Name of an MCP Server defined in fastagent.config.yaml
});

// Define social media agent
app.agent({
  name: 'social_media',
  instruction: `
    Write a 280 character social media post for any given text.
    Respond only with the post, never use hashtags.
  `,
});

// Create a chain workflow
app.chain(
  {
    name: 'post_writer',
    sequence: ['url_fetcher', 'social_media'],
  },
  async (agent) => {
    // using chain workflow
    await agent.post_writer('http://llmindset.co.uk');
  }
);

All Agents and Workflows respond to .send("message") or .prompt() to begin a chat session.

Saved as social.ts we can now run this workflow from the command line with:

npx ts-node social.ts --agent post_writer --message "<url>"

Add the --quiet switch to disable progress and message display and return only the final response - useful for simple automations.

Workflows

Chain

The chain workflow offers a more declarative approach to calling Agents in sequence:

app.chain({
  name: 'post_writer',
  sequence: ['url_fetcher', 'social_media'],
});

// we can them prompt it directly:
const agent = await app.run();
await agent.post_writer();

This starts an interactive session, which produces a short social media post for a given URL. If a chain is prompted it returns to a chat with last Agent in the chain. You can switch the agent to prompt by typing @agent-name.

Chains can be incorporated in other workflows, or contain other workflow elements (including other Chains). You can set an instruction to precisely describe it's capabilities to other workflow steps if needed.

Human Input

Agents can request Human Input to assist with a task or get additional context:

app.agent({
  instruction:
    'An AI agent that assists with basic tasks. Request Human Input when needed.',
  humanInput: true,
});

const agent = await app.run();
await agent.send('print the next number in the sequence');

Parallel

The Parallel Workflow sends the same message to multiple Agents simultaneously (fan-out), then uses the fan-in Agent to process the combined content.

app.agent({
  name: 'translate_fr',
  instruction: 'Translate the text to French',
});
app.agent({
  name: 'translate_de',
  instruction: 'Translate the text to German',
});
app.agent({
  name: 'translate_es',
  instruction: 'Translate the text to Spanish',
});

app.parallel({
  name: 'translate',
  fanOut: ['translate_fr', 'translate_de', 'translate_es'],
});

app.chain({
  name: 'post_writer',
  sequence: ['url_fetcher', 'social_media', 'translate'],
});

If you don't specify a fanIn agent, the parallel returns the combined Agent results verbatim.

parallel is also useful to ensemble ideas from different LLMs.

When using parallel in other workflows, specify an instruction to describe its operation.

Evaluator-Optimizer

Evaluator-Optimizers combine 2 agents: one to generate content (the generator), and the other to judge that content and provide actionable feedback (the evaluator). Messages are sent to the generator first, then the pair run in a loop until either the evaluator is satisfied with the quality, or the maximum number of refinements is reached. The final result from the Generator is returned.

If the Generator has useHistory off, the previous iteration is returned when asking for improvements - otherwise conversational context is used.

app.evaluatorOptimizer({
  name: 'researcher',
  generator: 'web_searcher',
  evaluator: 'quality_assurance',
  minRating: 'EXCELLENT',
  maxRefinements: 3,
});

const agent = await app.run();
await agent.researcher.send(
  'produce a report on how to make the perfect espresso'
);

When used in a workflow, it returns the last generator message as the result.

Router

Routers use an LLM to assess a message, and route it to the most appropriate Agent. The routing prompt is automatically generated based on the Agent instructions and available Servers.

app.router({
  name: 'route',
  agents: ['agent1', 'agent2', 'agent3'],
});

Orchestrator

Given a complex task, the Orchestrator uses an LLM to generate a plan to divide the task amongst the available Agents. The planning and aggregation prompts are generated by the Orchestrator, which benefits from using more capable models. Plans can either be built once at the beginning (planType: "full") or iteratively (planType: "iterative").

app.orchestrator({
  name: 'orchestrate',
  agents: ['task1', 'task2', 'task3'],
});

Agent Features

Calling Agents

All definitions allow omitting the name and instructions arguments for brevity:

app.agent({ instruction: 'You are a helpful agent' }); // Create an agent with a default name
app.agent({ name: 'greeter', instruction: 'Respond cheerfully!' }); // Create a named agent

const agent = await app.run();
const moonSize = await agent.send('the moon'); // Call the default agent with a message

const result = await agent.greeter('Good morning!'); // Send a message to an agent by name
const result2 = await agent.greeter.send('Hello!'); // You can call 'send' explicitly

await agent.greeter(); // If no message is specified, a chat session opens
await agent.greeter.prompt(); // that can be made more explicit
await agent.greeter.prompt({ defaultPrompt: 'OK' }); // and supports setting a default prompt

Defining Agents

Basic Agent

app.agent({
  name: 'agent', // name of the agent
  instruction: 'You are a helpful Agent', // base instruction for the agent
  servers: ['filesystem'], // list of MCP Servers for the agent
  model: 'o3-mini.high', // specify a model for the agent
  useHistory: true, // agent maintains chat history
  requestParams: { temperature: 0.7 }, // additional parameters for the LLM
  humanInput: true, // agent can request human input
});

Chain

app.chain({
  name: 'chain', // name of the chain
  sequence: ['agent1', 'agent2'], // list of agents in execution order
  instruction: 'instruction', // instruction to describe the chain for other workflows
  cumulative: false, // whether to accumulate messages through the chain
  continueWithFinal: true, // open chat with agent at end of chain after prompting
});

Parallel

app.parallel({
  name: 'parallel', // name of the parallel workflow
  fanOut: ['agent1', 'agent2'], // list of agents to run in parallel
  fanIn: 'aggregator', // name of agent that combines results (optional)
  instruction: 'instruction', // instruction to describe the parallel for other workflows
  includeRequest: true, // include original request in fan-in message
});

Evaluator-Optimizer

app.evaluatorOptimizer({
  name: 'researcher', // name of the workflow
  generator: 'web_searcher', // name of the content generator agent
  evaluator: 'quality_assurance', // name of the evaluator agent
  minRating: 'GOOD', // minimum acceptable quality (EXCELLENT, GOOD, FAIR, POOR)
  maxRefinements: 3, // maximum number of refinement iterations
});

Router

app.router({
  name: 'route', // name of the router
  agents: ['agent1', 'agent2', 'agent3'], // list of agent names router can delegate to
  model: 'o3-mini.high', // specify routing model
  useHistory: false, // router maintains conversation history
  humanInput: false, // whether router can request human input
});

Orchestrator

app.orchestrator({
  name: 'orchestrator', // name of the orchestrator
  instruction: 'instruction', // base instruction for the orchestrator
  agents: ['agent1', 'agent2'], // list of agent names this orchestrator can use
  model: 'o3-mini.high', // specify orchestrator planning model
  useHistory: false, // orchestrator doesn't maintain chat history (no effect)
  humanInput: false, // whether orchestrator can request human input
  planType: 'full', // planning approach: "full" or "iterative"
  maxIterations: 5, // maximum number of full plan attempts, or iterations
});

Multimodal Support

Add Resources to prompts using either the inbuilt prompt-server or MCP Types directly. Convenience class are made available to do so simply, for example:

const summary = await agent.withResource(
  'Summarise this PDF please',
  'mcp_server',
  'resource://fast-agent/sample.pdf'
);

MCP Tool Result Conversion

LLM APIs have restrictions on the content types that can be returned as Tool Calls/Function results via their Chat Completions API's:

  • OpenAI supports Text
  • Anthropic supports Text and Image

For MCP Tool Results, ImageResources and EmbeddedResources are converted to User Messages and added to the conversation.

Prompts

MCP Prompts are supported with applyPrompt(name, arguments), which always returns an Assistant Message. If the last message from the MCP Server is a 'User' message, it is sent to the LLM for processing. Prompts applied to the Agent's Context are retained - meaning that with useHistory: false, Agents can act as finely tuned responders.

Prompts can also be applied interactively through the interactive interface by using the /prompt command.

Sampling

Sampling LLMs are configured per Client/Server pair. Specify the model name in fastagent.config.yaml as follows:

mcp:
  servers:
    sampling_resource:
      command: 'npx'
      args: ['ts-node', 'sampling_resource_server.ts']
      sampling:
        model: 'haiku'

Secrets File

[!TIP] fast-agent will look recursively for a fastagent.secrets.yaml file, so you only need to manage this at the root folder of your agent definitions.

Interactive Shell

fast-agent

Project Notes

fast-agent-typescript builds on the mcp-agent project by Sarmad Qadri.

Contributing

Contributions and PRs are welcome - feel free to raise issues to discuss. Full guidelines for contributing and roadmap coming very soon. Get in touch!