Skip to main content
Glama
ivan-saorin

Substrate

by ivan-saorin
README.md
# Substrate - MCP Foundation Layer

Substrate provides the foundation for building production-grade Model Context Protocol (MCP) servers. It includes base classes, documentation, and patterns that ensure consistent, reliable implementations.

## Overview

Substrate is:

- **Foundation Layer**: Base classes and interfaces for all MCP servers
- **Documentation Server**: Serves methodology and architecture documentation
- **Pattern Library**: Common patterns for MCP implementation
- **Passive Component**: Provides structure but no active functionality

## Features

- **Base MCP Class**: Standard patterns for all MCP servers
- **Response Builders**: Structured response creation
- **Error Handling**: Consistent error patterns
- **Progress Tracking**: Real-time operation feedback
- **Sampling Support**: Intelligent assistance integration
- **Documentation Loading**: Flexible documentation system

## Installation

### As a Dependency

For use in your MCP server:

```bash
pip install substrate-mcp
```

Or in your `pyproject.toml`:

```toml
dependencies = [
    "substrate-mcp>=1.0.0",
    "fastmcp>=0.1.0"
]
```

### For Development

```bash
git clone https://github.com/ivan-saorin/substrate
cd substrate
pip install -e .
```

## Usage

### Creating an MCP Server

```python
from substrate import SubstrateMCP

class YourServer(SubstrateMCP):
    def __init__(self):
        super().__init__(
            name="your_mcp",
            version="1.0.0",
            description="Your MCP description"
        )
        self._register_tools()
    
    def _register_tools(self):
        @self.tool()
        async def your_tool(ctx, param: str):
            """Tool description"""
            result = await self.process(param)
            return self.create_response(
                success=True,
                data=result
            )
```

### Running Substrate Server

```bash
# Run the documentation server
python -m substrate

# Or with custom docs
SUBSTRATE_DOCS_DIR=/path/to/docs python -m substrate
```

### Docker Usage

```dockerfile
FROM python:3.12-slim

# Copy substrate
COPY substrate /substrate

# Copy your MCP
COPY your-mcp /app

WORKDIR /app

# Install both
RUN pip install -e /substrate && pip install -e .

CMD ["python", "-m", "your_mcp"]
```

## Documentation System

Substrate can serve different documentation sets:

1. **Bundled Docs**: Default examples included with substrate
2. **Custom Docs**: Your own methodology and architecture

### Custom Documentation

Mount your documentation at runtime:

```bash
# Docker
docker run -v ./my-docs:/substrate-docs substrate-mcp

# Local
export SUBSTRATE_DOCS_DIR=./my-docs
python -m substrate
```

Your documentation directory should contain:

- `atlas.md` - Development methodology
- `system-design.md` - System architecture
- `component-map.json` - Component registry

## Base Classes

### SubstrateMCP

The foundation for all MCP servers:

```python
class SubstrateMCP(FastMCP):
    """Base class providing:
    - Response building
    - Error handling
    - Progress tracking
    - Sampling support
    """
```

### Response Patterns

```python
# Success response
return self.create_response(
    success=True,
    data={"result": value},
    message="Operation completed"
)

# Error response
return self.create_error_response(
    error="Clear error message",
    error_type="validation",
    suggestions=["Try this", "Check that"]
)
```

### Progress Tracking

```python
async with self.progress_context("operation") as progress:
    await progress(0.1, "Starting...")
    # ... work ...
    await progress(0.5, "Halfway...")
    # ... more work ...
    await progress(1.0, "Complete!")
```

## Integration with AKAB

Substrate is designed to work with [AKAB](https://github.com/ivan-saorin/akab) for A/B testing:

```python
# In your MCP
result = await ctx.call_tool(
    "akab_quick_compare",
    prompt="Your prompt",
    providers=["anthropic_m", "openai_l"]
)
```

## Best Practices

1. **Production-Grade Only**: Real implementations, no mocks
2. **Clear Separation**: Each MCP does one thing well
3. **Explicit Interfaces**: No implicit behaviors
4. **Structured Errors**: Always provide actionable feedback
5. **Clean Logging**: Use stderr, never stdout

## Common Issues

### Stdout Pollution

MCP uses JSON-RPC over stdio. Any print() breaks the protocol.

**Solution**: Log to stderr

```python
logging.basicConfig(stream=sys.stderr)
```

### AsyncIO Conflicts

FastMCP manages its own event loop.

**Solution**: Don't use `asyncio.run()`

```python
def main():
    server = YourServer()
    server.run()  # Let FastMCP handle async
```

## Examples

See the included example documentation:

- `docs/atlas.md` - Example development methodology
- `docs/system-design.md` - Example system architecture
- `docs/component-map.json` - Example component structure

## Contributing

1. Follow the Atlas methodology
2. Ensure all tests pass
3. Update documentation as needed
4. Submit PR with clear description

## License

MIT License - see LICENSE file for details