mathpix 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +53 -0
- data/README.md +114 -1
- data/lib/mathpix/batch.rb +7 -8
- data/lib/mathpix/batched_document_conversion.rb +238 -0
- data/lib/mathpix/client.rb +33 -27
- data/lib/mathpix/configuration.rb +5 -9
- data/lib/mathpix/conversion.rb +2 -6
- data/lib/mathpix/document.rb +47 -12
- data/lib/mathpix/document_batcher.rb +191 -0
- data/lib/mathpix/mcp/auth/oauth_provider.rb +8 -9
- data/lib/mathpix/mcp/base_tool.rb +8 -5
- data/lib/mathpix/mcp/elicitations/ambiguity_elicitation.rb +8 -11
- data/lib/mathpix/mcp/elicitations/base_elicitation.rb +2 -0
- data/lib/mathpix/mcp/elicitations/confidence_elicitation.rb +2 -1
- data/lib/mathpix/mcp/elicitations.rb +1 -1
- data/lib/mathpix/mcp/middleware/cors_middleware.rb +2 -6
- data/lib/mathpix/mcp/middleware/oauth_middleware.rb +2 -6
- data/lib/mathpix/mcp/middleware/rate_limiting_middleware.rb +19 -18
- data/lib/mathpix/mcp/resources/formats_list_resource.rb +54 -54
- data/lib/mathpix/mcp/resources/hierarchical_router.rb +9 -18
- data/lib/mathpix/mcp/resources/latest_snip_resource.rb +22 -22
- data/lib/mathpix/mcp/resources/recent_snips_resource.rb +11 -10
- data/lib/mathpix/mcp/resources/snip_stats_resource.rb +14 -12
- data/lib/mathpix/mcp/server.rb +18 -18
- data/lib/mathpix/mcp/tools/batch_convert_tool.rb +31 -37
- data/lib/mathpix/mcp/tools/check_document_status_tool.rb +5 -5
- data/lib/mathpix/mcp/tools/convert_document_tool.rb +15 -14
- data/lib/mathpix/mcp/tools/convert_image_tool.rb +15 -14
- data/lib/mathpix/mcp/tools/convert_strokes_tool.rb +13 -13
- data/lib/mathpix/mcp/tools/get_account_info_tool.rb +1 -1
- data/lib/mathpix/mcp/tools/get_usage_tool.rb +5 -7
- data/lib/mathpix/mcp/tools/list_formats_tool.rb +30 -30
- data/lib/mathpix/mcp/tools/search_results_tool.rb +13 -14
- data/lib/mathpix/mcp/transports/http_streaming_transport.rb +129 -118
- data/lib/mathpix/mcp/transports/sse_stream_handler.rb +37 -35
- data/lib/mathpix/result.rb +3 -2
- data/lib/mathpix/version.rb +1 -1
- data/lib/mathpix.rb +3 -1
- metadata +60 -2
@@ -12,36 +12,37 @@ module Mathpix
|
|
12
12
|
#
|
13
13
|
# The geodesic path: official SDK + core gem delegation
|
14
14
|
class ConvertImageTool < BaseTool
|
15
|
-
description
|
15
|
+
description 'Convert image (PNG, JPG, etc.) to LaTeX, text, or other formats using Mathpix OCR'
|
16
16
|
|
17
17
|
input_schema(
|
18
18
|
properties: {
|
19
19
|
image_path: {
|
20
|
-
type:
|
21
|
-
description:
|
20
|
+
type: 'string',
|
21
|
+
description: 'Path to image file or URL (http:// or https://)'
|
22
22
|
},
|
23
23
|
formats: {
|
24
|
-
type:
|
25
|
-
items: { type:
|
26
|
-
description:
|
24
|
+
type: 'array',
|
25
|
+
items: { type: 'string' },
|
26
|
+
description: 'Output formats: latex, text, mathml, asciimath, latex_styled, text_display, data, html (default: latex_styled, text)'
|
27
27
|
},
|
28
28
|
include_line_data: {
|
29
|
-
type:
|
30
|
-
description:
|
29
|
+
type: 'boolean',
|
30
|
+
description: 'Include line-level bounding boxes in response'
|
31
31
|
},
|
32
32
|
include_word_data: {
|
33
|
-
type:
|
34
|
-
description:
|
33
|
+
type: 'boolean',
|
34
|
+
description: 'Include word-level bounding boxes in response'
|
35
35
|
},
|
36
36
|
confidence_threshold: {
|
37
|
-
type:
|
38
|
-
description:
|
37
|
+
type: 'number',
|
38
|
+
description: 'Minimum confidence threshold (0.0-1.0)'
|
39
39
|
}
|
40
40
|
},
|
41
|
-
required: [
|
41
|
+
required: ['image_path']
|
42
42
|
)
|
43
43
|
|
44
|
-
def self.call(image_path:, formats: nil, include_line_data: false, include_word_data: false,
|
44
|
+
def self.call(image_path:, server_context:, formats: nil, include_line_data: false, include_word_data: false,
|
45
|
+
confidence_threshold: nil)
|
45
46
|
safe_execute do
|
46
47
|
client = mathpix_client(server_context)
|
47
48
|
|
@@ -12,32 +12,32 @@ module Mathpix
|
|
12
12
|
#
|
13
13
|
# The geodesic path: official SDK + stroke recognition
|
14
14
|
class ConvertStrokesTool < BaseTool
|
15
|
-
description
|
15
|
+
description 'Convert handwritten strokes to LaTeX, text, or other formats using Mathpix OCR'
|
16
16
|
|
17
17
|
input_schema(
|
18
18
|
properties: {
|
19
19
|
strokes: {
|
20
|
-
type:
|
21
|
-
description:
|
20
|
+
type: 'array',
|
21
|
+
description: 'Array of stroke arrays, where each stroke is an array of [x, y] coordinates'
|
22
22
|
},
|
23
23
|
formats: {
|
24
|
-
type:
|
25
|
-
items: { type:
|
26
|
-
description:
|
24
|
+
type: 'array',
|
25
|
+
items: { type: 'string' },
|
26
|
+
description: 'Output formats: latex, text, mathml, asciimath (default: latex_styled, text)'
|
27
27
|
},
|
28
28
|
width: {
|
29
|
-
type:
|
30
|
-
description:
|
29
|
+
type: 'number',
|
30
|
+
description: 'Canvas width for stroke normalization'
|
31
31
|
},
|
32
32
|
height: {
|
33
|
-
type:
|
34
|
-
description:
|
33
|
+
type: 'number',
|
34
|
+
description: 'Canvas height for stroke normalization'
|
35
35
|
}
|
36
36
|
},
|
37
|
-
required: [
|
37
|
+
required: ['strokes']
|
38
38
|
)
|
39
39
|
|
40
|
-
def self.call(strokes:, formats: nil, width: nil, height: nil
|
40
|
+
def self.call(strokes:, server_context:, formats: nil, width: nil, height: nil)
|
41
41
|
safe_execute do
|
42
42
|
client = mathpix_client(server_context)
|
43
43
|
|
@@ -57,7 +57,7 @@ module Mathpix
|
|
57
57
|
# Format response
|
58
58
|
response_data = {
|
59
59
|
success: true,
|
60
|
-
input_type:
|
60
|
+
input_type: 'strokes',
|
61
61
|
stroke_count: strokes.length,
|
62
62
|
formats: output_formats,
|
63
63
|
results: {
|
@@ -12,7 +12,7 @@ module Mathpix
|
|
12
12
|
#
|
13
13
|
# The geodesic path: official SDK + account management
|
14
14
|
class GetAccountInfoTool < BaseTool
|
15
|
-
description
|
15
|
+
description 'Get Mathpix account information, plan details, and limits'
|
16
16
|
|
17
17
|
input_schema(
|
18
18
|
properties: {},
|
@@ -12,19 +12,19 @@ module Mathpix
|
|
12
12
|
#
|
13
13
|
# The geodesic path: official SDK + usage tracking
|
14
14
|
class GetUsageTool < BaseTool
|
15
|
-
description
|
15
|
+
description 'Get Mathpix API usage statistics and remaining credits'
|
16
16
|
|
17
17
|
input_schema(
|
18
18
|
properties: {
|
19
19
|
detailed: {
|
20
|
-
type:
|
21
|
-
description:
|
20
|
+
type: 'boolean',
|
21
|
+
description: 'Include detailed breakdown by operation type (default: false)'
|
22
22
|
}
|
23
23
|
},
|
24
24
|
required: []
|
25
25
|
)
|
26
26
|
|
27
|
-
def self.call(detailed: false
|
27
|
+
def self.call(server_context:, detailed: false)
|
28
28
|
safe_execute do
|
29
29
|
client = mathpix_client(server_context)
|
30
30
|
|
@@ -42,9 +42,7 @@ module Mathpix
|
|
42
42
|
}
|
43
43
|
}
|
44
44
|
|
45
|
-
if detailed && usage_data['breakdown']
|
46
|
-
response_data[:breakdown] = usage_data['breakdown']
|
47
|
-
end
|
45
|
+
response_data[:breakdown] = usage_data['breakdown'] if detailed && usage_data['breakdown']
|
48
46
|
|
49
47
|
json_response(response_data)
|
50
48
|
rescue Mathpix::APIError => e
|
@@ -12,53 +12,53 @@ module Mathpix
|
|
12
12
|
#
|
13
13
|
# The geodesic path: official SDK + format catalog
|
14
14
|
class ListFormatsTool < BaseTool
|
15
|
-
description
|
15
|
+
description 'List all available output formats for Mathpix OCR operations'
|
16
16
|
|
17
17
|
input_schema(
|
18
18
|
properties: {
|
19
19
|
category: {
|
20
|
-
type:
|
21
|
-
description:
|
22
|
-
enum: [
|
20
|
+
type: 'string',
|
21
|
+
description: 'Filter by category: image, document, or all (default: all)',
|
22
|
+
enum: %w[image document all]
|
23
23
|
}
|
24
24
|
},
|
25
25
|
required: []
|
26
26
|
)
|
27
27
|
|
28
|
-
def self.call(category:
|
28
|
+
def self.call(server_context:, category: 'all')
|
29
29
|
safe_execute do
|
30
30
|
# Static format definitions
|
31
31
|
image_formats = [
|
32
|
-
{ name:
|
33
|
-
{ name:
|
34
|
-
{ name:
|
35
|
-
{ name:
|
36
|
-
{ name:
|
37
|
-
{ name:
|
38
|
-
{ name:
|
39
|
-
{ name:
|
40
|
-
{ name:
|
32
|
+
{ name: 'latex_styled', description: 'LaTeX with styling', type: 'image' },
|
33
|
+
{ name: 'text', description: 'Plain text', type: 'image' },
|
34
|
+
{ name: 'latex_list', description: 'Array of LaTeX expressions', type: 'image' },
|
35
|
+
{ name: 'mathml', description: 'MathML markup', type: 'image' },
|
36
|
+
{ name: 'asciimath', description: 'AsciiMath notation', type: 'image' },
|
37
|
+
{ name: 'text_display', description: 'Display-style text', type: 'image' },
|
38
|
+
{ name: 'latex_simplified', description: 'Simplified LaTeX', type: 'image' },
|
39
|
+
{ name: 'data', description: 'Full response data with metadata', type: 'image' },
|
40
|
+
{ name: 'html', description: 'HTML markup', type: 'image' }
|
41
41
|
]
|
42
42
|
|
43
43
|
document_formats = [
|
44
|
-
{ name:
|
45
|
-
{ name:
|
46
|
-
{ name:
|
47
|
-
{ name:
|
48
|
-
{ name:
|
44
|
+
{ name: 'markdown', description: 'Markdown format', type: 'document' },
|
45
|
+
{ name: 'latex', description: 'LaTeX document', type: 'document' },
|
46
|
+
{ name: 'html', description: 'HTML document', type: 'document' },
|
47
|
+
{ name: 'docx', description: 'Microsoft Word document', type: 'document' },
|
48
|
+
{ name: 'tex.zip', description: 'LaTeX with figures (zipped)', type: 'document' }
|
49
49
|
]
|
50
50
|
|
51
51
|
# Filter by category
|
52
52
|
formats = case category
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
when 'image'
|
54
|
+
image_formats
|
55
|
+
when 'document'
|
56
|
+
document_formats
|
57
|
+
when 'all'
|
58
|
+
image_formats + document_formats
|
59
|
+
else
|
60
|
+
image_formats + document_formats
|
61
|
+
end
|
62
62
|
|
63
63
|
# Format response
|
64
64
|
response_data = {
|
@@ -67,8 +67,8 @@ module Mathpix
|
|
67
67
|
count: formats.length,
|
68
68
|
formats: formats,
|
69
69
|
usage: {
|
70
|
-
image_capture:
|
71
|
-
document_conversion:
|
70
|
+
image_capture: 'Use with snap() or ConvertImageTool',
|
71
|
+
document_conversion: 'Use with document() or ConvertDocumentTool'
|
72
72
|
}
|
73
73
|
}
|
74
74
|
|
@@ -12,31 +12,31 @@ module Mathpix
|
|
12
12
|
#
|
13
13
|
# The geodesic path: official SDK + search filtering
|
14
14
|
class SearchResultsTool < BaseTool
|
15
|
-
description
|
15
|
+
description 'Search recent Mathpix capture results with optional text filtering'
|
16
16
|
|
17
17
|
input_schema(
|
18
18
|
properties: {
|
19
19
|
query: {
|
20
|
-
type:
|
21
|
-
description:
|
20
|
+
type: 'string',
|
21
|
+
description: 'Search query to filter results by LaTeX or text content'
|
22
22
|
},
|
23
23
|
limit: {
|
24
|
-
type:
|
25
|
-
description:
|
24
|
+
type: 'number',
|
25
|
+
description: 'Maximum number of results to return (default: 10, max: 100)'
|
26
26
|
},
|
27
27
|
offset: {
|
28
|
-
type:
|
29
|
-
description:
|
28
|
+
type: 'number',
|
29
|
+
description: 'Offset for pagination (default: 0)'
|
30
30
|
},
|
31
31
|
include_content: {
|
32
|
-
type:
|
33
|
-
description:
|
32
|
+
type: 'boolean',
|
33
|
+
description: 'Include full LaTeX/text content in results (default: false)'
|
34
34
|
}
|
35
35
|
},
|
36
36
|
required: []
|
37
37
|
)
|
38
38
|
|
39
|
-
def self.call(query: nil, limit: 10, offset: 0, include_content: false
|
39
|
+
def self.call(server_context:, query: nil, limit: 10, offset: 0, include_content: false)
|
40
40
|
safe_execute do
|
41
41
|
client = mathpix_client(server_context)
|
42
42
|
|
@@ -53,8 +53,8 @@ module Mathpix
|
|
53
53
|
if query && !query.empty?
|
54
54
|
query_lower = query.downcase
|
55
55
|
results = results.select do |result|
|
56
|
-
|
57
|
-
|
56
|
+
result.latex&.downcase&.include?(query_lower) ||
|
57
|
+
result.text&.downcase&.include?(query_lower)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -98,11 +98,10 @@ module Mathpix
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
-
private
|
102
|
-
|
103
101
|
def self.truncate(text, max_length)
|
104
102
|
return nil unless text
|
105
103
|
return text if text.length <= max_length
|
104
|
+
|
106
105
|
"#{text[0...max_length]}..."
|
107
106
|
end
|
108
107
|
end
|