npm package: @meldscience/mcp-stream-parser
Description: Structured parsing of MCP messages into text, thoughts, and actions (tool usage)
Author: Adam Avenir
Latest version: 0.6.1

# MCP Stream Parser

A stream parser for Claude's message API that provides real-time access to:
- Text content
- Thought processes
- Action invocations
- Error handling

## Installation

```bash
npm install @anthropic-ai/mcp-stream-parser
```

## Quick Start

```typescript
import { AnthropicStreamParser } from '@anthropic-ai/mcp-stream-parser';

const parser = new AnthropicStreamParser({
  apiKey: 'your-api-key'
});

// Listen for events
parser.on('text', event => {
  console.log('Text:', event.content);
});

parser.on('thought', event => {
  console.log('Thought:', event.content);
});

parser.on('action', event => {
  console.log('Action:', event.name, event.params);
});

parser.on('error', event => {
  console.error('Error:', event.error);
});

parser.on('typing', event => {
  if (event.isTyping) {
    console.log('Claude is typing...');
  } else {
    console.log('Claude stopped typing');
  }
});

// Send a message
await parser.sendMessage({
  model: 'claude-3-opus-20240229',
  content: 'Hello Claude!'
});
```

## Configuration

The parser can be configured with various options:

```typescript
const parser = new AnthropicStreamParser({
  apiKey: 'your-api-key',
  
  // Parser mode
  mode: ParserMode.MESSAGE, // or ParserMode.STREAM
  
  // System prompt configuration
  systemPrompt: {
    content: 'Your custom system prompt',
    prependInstructions: true // or false
  },
  
  // Message handling
  message: {
    maxLength: 2000,
    splitPoints: ['\n\n', '. ', ' '],
    overflow: 'split' // or 'error'
  },
  
  // Buffer management
  buffer: {
    maxSize: 64 * 1024, // 64KB
    overflow: 'error', // or 'truncate'
    flushOnNewline: true
  },
  
  // Throttling configuration
  throttle: {
    enabled: true,
    readingSpeed: 250, // words per minute
    minPause: 100, // minimum pause between emissions in ms
    maxBuffer: 200 // maximum characters to buffer before forcing emission
  },
  
  // Debug options
  debug: {
    enabled: true,
    state: true,
    events: true,
    buffer: true,
    json: true,
    stream: true,
    logger: console.debug
  }
});
```

## Events

### Text Event
Emitted for regular text content. Text events are throttled based on the throttling configuration to provide a more natural reading experience:
```typescript
interface TextEvent {
  type: EventType.TEXT;
  content: string;
  offset: number;
  blockIndex?: number;
  splitInfo?: {
    position: number;
    reason: string;
  };
}
```

### Thought Event
Emitted when Claude expresses its thought process. Thought events are emitted immediately without throttling:
```typescript
interface ThoughtEvent {
  type: EventType.THOUGHT;
  content: string;
  offset: number;
  blockIndex?: number;
  hasAction: boolean;
}
```

### Action Event
Emitted when Claude invokes an action. Action events are emitted immediately without throttling:
```typescript
interface ActionEvent {
  type: EventType.ACTION;
  name: string;
  params: Record<string, unknown>;
  offset: number;
  blockIndex?: number;
  thoughtContent?: string;
}
```

### Typing Event
Emitted when Claude starts or stops generating content:
```typescript
interface TypingEvent {
  type: EventType.TYPING;
  isTyping: boolean;
  offset: number;
  blockIndex?: number;
}
```

The typing event is emitted with `isTyping: true` when Claude starts processing content, and `isTyping: false` when it finishes processing a block or sending a message. This can be used to implement typing indicators in user interfaces.

Example usage:
```typescript
parser.on('typing', event => {
  if (event.isTyping) {
    console.log('Claude is typing...');
    // Show typing indicator
  } else {
    console.log('Claude stopped typing');
    // Hide typing indicator
  }
});
```

### Error Event
Emitted when parsing errors occur:
```typescript
interface ErrorEvent {
  type: EventType.ERROR;
  error: Error;
  fatal: boolean;
  offset: number;
  blockIndex?: number;
  partialContent?: string;
}
```

## Error Handling

The parser provides detailed error information through the error event:

```typescript
parser.on('error', event => {
  const { error, fatal, partialContent } = event;
  
  if (fatal) {
    console.error('Fatal error:', error);
    // Handle unrecoverable error
  } else {
    console.warn('Non-fatal error:', error);
    // Continue processing
  }
  
  if (partialContent) {
    console.log('Partial content:', partialContent);
    // Handle incomplete content
  }
});
```

## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Throttling

The parser includes a throttling mechanism to provide a more natural reading experience for text content. Throttling can be configured with the following options:

```typescript
const parser = new AnthropicStreamParser({
  apiKey: 'your-api-key',
  throttle: {
    enabled: true, // Enable/disable throttling
    readingSpeed: 250, // Target reading speed in words per minute
    minPause: 100, // Minimum pause between emissions in milliseconds
    maxBuffer: 200 // Maximum characters to buffer before forcing emission
  }
});
```

Note that thought and action events bypass the throttling mechanism and are emitted immediately to ensure responsive tool usage and thought process visibility.