Build and Execute Programmatic MCP Agents
MCP server enabling AI agents to discover tools dynamically, compose them via TypeScript code, persist state, and build reusable skills through programmatic
Why it matters
Develop intelligent agents that can discover, compose, and execute tools programmatically using TypeScript. This prototype enables state persistence and the creation of reusable skills within isolated Docker environments.
Outcomes
What it gets done
Dynamically discover and execute available tools.
Compose complex operations by writing TypeScript code.
Create and manage reusable skills and persistent states.
Execute code safely within isolated Docker containers.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/vb-programmatic-mcp-prototype | bash Capabilities
Tools your agent gets
Dynamic search and discovery of available tools instead of loading all tools at once
Execute discovered tools as needed to reduce context usage and improve response quality
Overview
Programmatic MCP Prototype MCP Server
This MCP server provides an agent architecture that supports progressive tool discovery, programmatic tool composition, state persistence, and skill building. It includes a core agent loop, MCP proxy server that aggregates multiple MCP servers, code generator for TypeScript bindings, and container runner for isolated execution. Use this when you want an AI agent to compose multiple MCP tool calls together in code rather than calling them one at a time, store intermediate results in a workspace, or build reusable skill libraries that combine operations.
What it does
Big Job: Let AI agents compose multiple MCP tools together in TypeScript code instead of making sequential tool calls.
Small Job: Write TypeScript that chains tool calls, stores intermediate results, and builds reusable skills.
Instead of exposing hundreds of tools upfront, the agent provides search_tools and execute_tool meta-tools. The model can then 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`);
}
The agent executes TypeScript in isolated Docker containers, enabling loops, conditionals, error handling, and state persistence across executions. Skills can be saved to ./generated/skills/ and reused in future tasks.
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
- Install dependencies:
npm install
Configure your MCP servers in
config/servers.tsSet your Anthropic API key:
export ANTHROPIC_API_KEY='your-key'
- 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
- Startup: Connects to configured MCP servers (bash, computer, container)
- Code Generation: Creates TypeScript functions for each tool with proper types
- Agent Loop: Simple while loop that calls Claude with MCP tools
- Tool Execution: Routes tool calls to appropriate backend MCP servers
- Code Execution: Runs TypeScript in isolated Docker containers
Benefits of Programmatic Tool Use
- Composition: Chain multiple tools without waiting between calls
- State: Store variables and reuse results
- Loops/Conditionals: Handle complex logic in code
- Error Handling: Try/catch and retry logic
- Efficiency: Make many tool calls in one execution
- Skills Library: Build reusable patterns over time
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.