Seamlessly convert agent specifications between JSON and Markdown formats with full fidelity preservation.
Agent Script Tools provides bi-directional conversion between structured JSON specifications and human-readable Markdown formats. This allows you to work in your preferred format while maintaining compatibility across different tools and workflows.
Conversion Overview
The conversion system preserves all specification data through round-trip conversions:
graph LR
A[JSON Specification] --> B[Pydantic Model]
B --> C[Markdown Format]
C --> D[Parsed AST]
D --> E[Pydantic Model]
E --> F[JSON Specification]
A -.->|Direct Load| B
F -.->|Round Trip| A
style A fill:#e1f5fe
style C fill:#f3e5f5
style F fill:#e1f5fe
CLI Commands
Basic Conversion Commands
Command Options
| Option |
Description |
Example |
-o, --output |
Specify output file path |
--output result.md |
| Input file |
Path to source specification |
examples/ai-engineer.json |
Programmatic Usage
Python API
Use the conversion functions directly in your Python code:
| Python |
|---|
| from agent_script_spec.models import AgentScriptSpecification
from agent_script_tools.drivers import to_markdown, from_markdown
import json
# Load JSON specification
with open("examples/ai-engineer.json") as f:
spec = AgentScriptSpecification.model_validate_json(f.read())
# Convert to Markdown
markdown_content = to_markdown(spec)
print(markdown_content[:200] + "...")
# Convert back from Markdown
spec_from_md = from_markdown(markdown_content)
# Verify round-trip conversion
assert spec == spec_from_md
print("✅ Round-trip conversion successful!")
|
Batch Processing
Process multiple specifications:
| Python |
|---|
| from pathlib import Path
from agent_script_tools.drivers import to_markdown, from_markdown
from agent_script_spec.models import AgentScriptSpecification
def convert_directory(input_dir: Path, output_dir: Path, to_format: str):
"""Convert all specifications in a directory."""
output_dir.mkdir(exist_ok=True)
for file_path in input_dir.glob("*.json" if to_format == "md" else "*.md"):
print(f"Converting {file_path.name}...")
if to_format == "md":
# JSON to Markdown
spec = AgentScriptSpecification.model_validate_json(file_path.read_text())
output_content = to_markdown(spec)
output_file = output_dir / f"{file_path.stem}.md"
else:
# Markdown to JSON
spec = from_markdown(file_path.read_text())
output_content = spec.model_dump_json(indent=2)
output_file = output_dir / f"{file_path.stem}.json"
output_file.write_text(output_content)
print(f"✅ Saved {output_file}")
# Usage
convert_directory(Path("specifications/json"), Path("specifications/md"), "md")
|
The Markdown format follows a structured layout with frontmatter:
Complete Structure
| Markdown |
|---|
| ---
name: agent-name
description: Brief description of the agent
tools: tool1, tool2, tool3
model: claude-3-5-sonnet
---
# Agent Name
## Role
Agent's primary role and function
## Expertise
Domain knowledge and technical skills
### Key Capabilities
* Capability 1: Detailed description
* Capability 2: Detailed description
### MCP Integration
* server-name: Description of integration
### Tool Usage
* category: Usage description
### Communication Protocol
Communication guidelines and preferences
## Interaction Model
Description of the interaction approach
### Phase 1
Phase description
Step 1: Step description
Step 2: Step description with complex substeps
* Substep A: Description
* Substep B: Description
#### End of Phase Instructions
Instructions for phase completion
### Phase 2
Next phase description...
## Final Instructions
### Core Competencies
* Competency: Description
### Guiding Principles
* Principle: Description
### Rules
#### DO
* Positive behavioral guideline
* Another positive rule
#### DO NOT
* Negative behavioral constraint
* Another constraint
### Approach
* Method: Approach description
## Deliverables
Essential outputs from the agent
* Deliverable: Description and format requirements
|
Conversion Features
Frontmatter Handling
The system automatically manages YAML frontmatter:
Complex Step Preservation
Multi-level steps are preserved accurately:
MCP Server Detection
MCP servers are automatically extracted from tools:
| Python |
|---|
| # Frontmatter tools
tools = {
"read", "write",
"mcp__context7__get-library-docs",
"mcp__sequential-thinking__analyze"
}
# Automatically detected MCP servers
mcp_servers = ["context7", "sequential-thinking"]
|
Conversion Gotchas
Common Issues
Tool List Format
Issue: Tools in JSON are arrays, but Markdown frontmatter uses comma-separated strings
Solution: The converter handles this automatically, but be aware when manually editing:
| YAML |
|---|
| # Correct frontmatter format
tools: read, write, execute
# Not: tools: ["read", "write", "execute"]
|
Step Numbering
Issue: Markdown parsing requires exact "Step N:" format
Solution: Always use the exact pattern:
| Markdown |
|---|
| # Correct
Step 1: Description
Step 2: Another description
# Incorrect
Step 1) Description
1. Description
|
Phase Numbering
Issue: Phases must follow "Phase N" pattern exactly
Solution: Use consistent naming:
| Markdown |
|---|
| # Correct
### Phase 1
### Phase 2
# Incorrect
### Phase One
### First Phase
|
Validation During Conversion
The conversion process includes automatic validation:
| Python |
|---|
| try:
# This will validate the specification
spec = from_markdown(markdown_content)
print("✅ Valid specification")
except ValueError as e:
print(f"❌ Validation error: {e}")
|
Round-trip Testing
Verify your conversions preserve data integrity:
Manual Testing
| Python |
|---|
| from agent_script_tools.drivers import to_markdown, from_markdown
from agent_script_spec.models import AgentScriptSpecification
# Load original specification
original = AgentScriptSpecification.model_validate_json(json_content)
# Convert to Markdown and back
markdown = to_markdown(original)
converted = from_markdown(markdown)
# Verify equality
if original == converted:
print("✅ Perfect round-trip conversion!")
else:
print("❌ Data loss detected in conversion")
# Find differences
original_dict = original.model_dump()
converted_dict = converted.model_dump()
# Use deepdiff or manual comparison
print("Original keys:", set(original_dict.keys()))
print("Converted keys:", set(converted_dict.keys()))
|
Automated Testing
Create test cases for your specifications:
| Python |
|---|
| import pytest
from pathlib import Path
def test_round_trip_conversion():
"""Test that all example specifications convert cleanly."""
examples_dir = Path("examples")
for json_file in examples_dir.glob("*.json"):
# Test JSON -> Markdown -> JSON
original_spec = AgentScriptSpecification.model_validate_json(
json_file.read_text()
)
markdown = to_markdown(original_spec)
converted_spec = from_markdown(markdown)
assert original_spec == converted_spec, f"Round-trip failed for {json_file}"
# Test key properties are preserved
assert original_spec.name == converted_spec.name
assert original_spec.frontmatter.tools == converted_spec.frontmatter.tools
assert len(original_spec.interaction_model.phases) == len(converted_spec.interaction_model.phases)
|
Best Practices
Workflow Recommendations
- Development: Start with Markdown for human readability
- Validation: Convert to JSON to validate structure
- Production: Use JSON for automated systems
- Documentation: Keep Markdown versions for team review
File Organization
| Text Only |
|---|
| specifications/
├── json/ # Production specifications
│ ├── ai-engineer.json
│ └── data-analyst.json
├── markdown/ # Human-readable versions
│ ├── ai-engineer.md
│ └── data-analyst.md
└── scripts/
└── sync-formats.py # Keep formats in sync
|
Next Steps