PR

Programmatic MCP Server Prototype TypeScript Agent

Build with a programmatic MCP server prototype that composes tools, discovers capabilities progressively, persists state, and runs TypeScript agents.

Quick Install
npx -y @domdomegg/programmatic-mcp-prototype

Overview

This project is a programmatic MCP (Model Context Protocol) server prototype implemented in TypeScript. It’s designed to host and run TypeScript-based agents that can compose and invoke modular tools, progressively discover available capabilities, and persist state between runs. The server focuses on making agent orchestration and capability discovery explicit and programmatic for developers building complex automation flows or experimental agent behaviors.

You can run the prototype locally to experiment with agent patterns: register tools, attach agents that use them, and observe how the server tracks capabilities and state across sessions. It’s useful for quickly iterating on agent designs, integrating custom tools (HTTP, filesystem, execution), and exploring how tools can be discovered and composed at runtime.

Features

  • Programmatic TypeScript agents: write agents in TypeScript and execute them inside the MCP runtime.
  • Tool composition: register and compose modular tools (HTTP clients, file storage, code executors).
  • Progressive capability discovery: tools register their capabilities so agents and the server discover what’s available at runtime.
  • Persistent state: agent state and tool metadata persist across restarts for reproducible experiments.
  • Lightweight prototype server: runs locally, easy to extend for experimentation and integration.
  • Simple HTTP RPC for managing agents, tools and running workflows.

Installation / Configuration

Clone and run the prototype locally.

# clone the repo
git clone https://github.com/domdomegg/programmatic-mcp-prototype.git
cd programmatic-mcp-prototype

# install deps
npm install

# development server (watch mode)
npm run dev

# production build + start
npm run build
npm start

Environment variables (example .env):

PORT=3000           # server port
DATA_DIR=./data     # where persisted state is stored
NODE_ENV=development

If running TypeScript agent files directly for local experiments, you can use ts-node or tsx:

# run a standalone agent script (example)
npx tsx scripts/run-agent.ts

Available Tools / Resources

The prototype exposes a set of built-in resource types and an API to register additional custom tools:

  • http-client: make outbound HTTP requests from agents.
  • file-store: read/write JSON and blobs to the server’s data directory.
  • ts-executor: compile and run TypeScript snippets in a sandboxed environment.
  • capability-registry: list and query tool capabilities that have been discovered.
  • persistence: key/value store for agent state and session history.

Example table of management RPC endpoints (prototype):

EndpointMethodPurpose
/agentsPOSTCreate/register a new agent
/agents/:id/runPOSTTrigger an agent run
/agents/:id/stateGET/PUTGet or set persisted agent state
/toolsPOSTRegister a new tool
/capabilitiesGETList discovered capabilities

(Exact API shapes can be explored in the repository; these endpoints illustrate typical operations.)

Example: Programmatic TypeScript Agent

A minimal example showing how to programmatically create and run an agent that uses a tool and persists state:

// scripts/run-agent.ts
import { MCPServer } from '../src/server' // local prototype server API
import { createAgent } from '../src/agent'
import { FileStoreTool } from '../src/tools/file-store'

async function main() {
  const server = new MCPServer({ dataDir: './data' })
  await server.start(3000)

  // register a file-storage tool (persists agent outputs)
  server.tools.register(new FileStoreTool({ basePath: './data/files' }))

  // create a simple agent that appends timestamped entries to persistent state
  const agent = createAgent({
    id: 'logger-agent',
    run: async (ctx) => {
      const ts = new Date().toISOString()
      const state = await ctx.state.get('logs') ?? []
      state.push({ ts, note: 'tick' })
      await ctx.state.set('logs', state)
      // use the file-store tool to persist a snapshot
      await ctx.tools.get('file-store').write('snapshot.json', state)
      return { ok: true, ts }
    }
  })

  await server.agents.register(agent)
  const result = await server.agents.run('logger-agent')
  console.log('Agent run result:', result)
}

main().catch(console.error)

This demonstrates tool registration, state interaction, and invoking an agent run from code.

Use Cases

  • Data ingestion pipelines: compose HTTP client and file-store tools so agents fetch, transform, and persist data on schedules.

    • Example: agent polls an API, applies transformation in a TypeScript snippet, writes results to file-store.
  • Adaptive assistants: agents discover available tools at runtime (e.g., a calendar tool or email sender) and adapt their behavior based on discovered capabilities.

    • Example: agent queries the capability registry and branches execution paths depending on whether “email.send” is available.
  • Research / experimentation platform: rapidly prototype agent behaviors, persist state across experiments, and compare runs.

    • Example: run multiple agents with slightly different policies to evaluate performance and state drift.
  • Local development sandbox for orchestration: build integrated workflows that combine execution, storage, and external calls without deploying cloud infrastructure.

Next steps

  • Explore the repository source to see the server, agent, and tool implementations.
  • Extend or add new tools by implementing the tool interface and registering them with the server.
  • Use the HTTP RPC endpoints to integrate third-party systems or UI tooling for visual orchestration.

Repository: https://github.com/domdomegg/programmatic-mcp-prototype