Tool

Build self-improving agents with programmatic tool discovery

Prototype MCP agent that writes and runs TypeScript code composing MCP tools together, with progressive tool discovery and reusable skills.

Works with typescriptmcp

47
Spark score
out of 100
Updated 5 months ago
Version 1.0.0

Add to Favorites

Why it matters

Enable AI agents to dynamically discover, compose, and execute MCP tools through TypeScript code generation while maintaining state and progressively building new skills across sessions.

Outcomes

What it gets done

01

Dynamically discover and compose MCP tools programmatically at runtime

02

Execute TypeScript code to orchestrate multi-tool workflows with state persistence

03

Build and accumulate reusable skills that agents can leverage in future tasks

04

Progressively expand agent capabilities through iterative tool experimentation

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/mcp-programmatic-mcp-prototype | bash

Overview

Programmatic MCP Prototype

A prototype MCP agent that lets a model write TypeScript code composing multiple MCP tools together in one execution, run in an isolated Docker container, with progressive on-demand tool discovery, persisted workspace state, and reusable skill functions built from generated tool bindings. Use it to explore programmatic MCP tool use, where a model chains many tool calls, loops, and error handling in generated code, instead of the standard one-tool-call-per-turn pattern, particularly when a workflow needs to reuse results across runs.

What it does

An MCP-based agent prototype exploring programmatic tool use: instead of calling one MCP tool per model turn, the agent generates TypeScript bindings for every connected server's tools and lets the model write actual code that composes several tool calls together, with loops, conditionals, and error handling, executed in one pass inside an isolated Docker container. It also supports progressive tool discovery, search_tools and execute_tool meta-tools let the model find relevant tools on demand instead of loading hundreds of tool definitions upfront, state persistence to a workspace directory across executions, and skill building, packaging a multi-step operation into a reusable function the model can call again later.

When to use - and when NOT to

Use it to explore or prototype an agent architecture where tool use benefits from real code rather than a sequence of individual tool calls - chaining multiple operations without round-tripping through the model between each one, storing intermediate results for a later step, or building up a library of reusable skills over a session. It is explicitly a prototype: the core agent loop is described as a simple while loop that can be swapped with other implementations, meaning it is a reference architecture to build on rather than a finished, production-hardened agent framework.

Inputs and outputs

Input is a set of configured MCP servers, config/servers.ts, the example wires up bash, computer, and a container runner, plus an ANTHROPIC_API_KEY for the underlying Claude calls. On startup the code generator creates typed TypeScript functions for every discovered tool, which the agent loop then makes available to the model as source it can import and compose. Output is whatever the generated code produces: files written to the workspace directory, console output, or a returned value from a defined skill function, all executed inside a Docker container built from the project's container-runner image.

Integrations

Ships with example MCP server integrations for bash, shell commands, and computer, general computer-use style actions, proxied through an MCP Proxy Server that aggregates multiple MCP servers into one unified interface for the code generator to bind against. Google Sheets is referenced in the skill-building example (sheets.getCells), illustrating how an additional MCP server would plug into the same pattern. Code execution is isolated via a dedicated Docker image, mcp-runner:latest, built from the container-runner source.

Who it's for

Agent framework developers and researchers exploring programmatic, code-based tool composition as an alternative to turn-by-turn tool calling, who want a working reference implementation to extend rather than a polished end-user product.

Source README

programmatic-mcp-prototype

An MCP-based agent with support for:

  • progressive tool discovery
  • programmatic tool composition
  • state persistence
  • skill building

Architecture

  • Core Agent Loop: Simple while loop that can be swapped with other implementations
  • MCP Proxy Server: Aggregates multiple MCP servers into one unified interface
  • Code Generator: Creates TypeScript bindings from MCP tool schemas
  • Container Runner: Executes TypeScript code in isolated Docker containers

Key Features

1. Progressive Tool Discovery

The model can search for and discover tools dynamically instead of loading all tools upfront. Rather than exposing hundreds of tools at once, the agent provides search_tools and execute_tool meta-tools that allow the model to find relevant tools as needed, reducing context usage and improving response quality.

2. Programmatic Tool Composition

The agent can write TypeScript code that composes MCP tools together:

// Example: The model can write code like this
import * as bash from './generated/servers/bash';
import * as computer from './generated/servers/computer';

const files = await bash.ls({ path: './documents' });
for (const file of files) {
  const content = await bash.readFile({ path: file });
  console.log(`File ${file}: ${content.length} bytes`);
}

3. State Persistence

Store intermediate results and data in the workspace directory:

import * as fs from 'fs/promises';

// Save CSV for later use
const csvData = await processData();
await fs.writeFile('./generated/workspace/data.csv', csvData);

// Load it in a future execution
const data = await fs.readFile('./generated/workspace/data.csv', 'utf-8');

4. Skill Building

Create reusable meta-tools that combine multiple operations:

// Build a skill in ./generated/skills/
export async function saveSheetAsCsv(sheetId: string) {
  import * as sheets from '../servers/sheets';
  import * as bash from '../servers/bash';
  
  const data = await sheets.getCells({ sheetId });
  const csv = data.map(row => row.join(',')).join('\n');
  const path = `../workspace/sheet-${sheetId}.csv`;
  await bash.writeFile({ path, content: csv });
  return path;
}

// Use the skill later
import { saveSheetAsCsv } from './generated/skills/save-sheet-as-csv';
const csvPath = await saveSheetAsCsv('abc123');

Setup

  1. Install dependencies:
npm install
  1. Configure your MCP servers in config/servers.ts

  2. Set your Anthropic API key:

export ANTHROPIC_API_KEY='your-key'
  1. Build Docker image for code execution:
docker build -t mcp-runner:latest src/servers/container-runner

Usage

Run the agent:

npm start

How It Works

  1. Startup: Connects to configured MCP servers (bash, computer, container)
  2. Code Generation: Creates TypeScript functions for each tool with proper types
  3. Agent Loop: Simple while loop that calls Claude with MCP tools
  4. Tool Execution: Routes tool calls to appropriate backend MCP servers
  5. Code Execution: Runs TypeScript in isolated Docker containers

Benefits of Programmatic Tool Use

  1. Composition: Chain multiple tools without waiting between calls
  2. State: Store variables and reuse results
  3. Loops/Conditionals: Handle complex logic in code
  4. Error Handling: Try/catch and retry logic
  5. Efficiency: Make many tool calls in one execution
  6. Skills Library: Build reusable patterns over time

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.