Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
3c318ae
setup typescript project
kapustazh Jul 24, 2026
3ae65cc
add mcp server dependencies
kapustazh Jul 25, 2026
105d9f7
create mcp server factory
kapustazh Jul 25, 2026
9fff00e
setup code quality checks
kapustazh Jul 25, 2026
6d126e4
code quality github-workflow
kapustazh Jul 25, 2026
7b87ada
Merge pull request #1 from ikodo0/feature/set-up-mcp
ikodo0 Jul 25, 2026
88faf02
Merge pull request #2 from ikodo0/feat/set-up-workflow
ikodo0 Jul 25, 2026
fc0bd23
chore: document environment variables and Nuthatch deployment
ikodo0 Jul 25, 2026
34c426c
feat: define source adapter contract, registry types and fixtures
ikodo0 Jul 25, 2026
e886676
Merge pull request #4 from ikodo0/feature/data-pipeline
kapustazh Jul 25, 2026
02b50aa
add unit test infrastructure (#5)
kapustazh Jul 25, 2026
03ac0b2
Add MCP stdio lifecycle (#6)
kapustazh Jul 25, 2026
3bae142
feat(m2.2): enumerate Base DEX candidates
ikodo0 Jul 25, 2026
65eacf4
Add source adapter runtime validation (#7)
kapustazh Jul 25, 2026
37fe418
Merge pull request #9 from ikodo0/feat/m2.2-candidates
ikodo0 Jul 25, 2026
bfabc46
feat(m2): add redacted probe transport
ikodo0 Jul 25, 2026
cd475eb
feat(m2): add liveness sweep
ikodo0 Jul 25, 2026
758f9f3
feat(m2): add candidate data probes
ikodo0 Jul 25, 2026
97457b2
feat(m2.7): assert Graph deployment identity
ikodo0 Jul 25, 2026
2d7b974
Add shared gateway primitives (#10)
kapustazh Jul 25, 2026
7d00838
Merge pull request #11 from ikodo0/feat/m2.3-probe-sweep
ikodo0 Jul 25, 2026
d6ebb21
test(m2.3): capture primary liveness
ikodo0 Jul 25, 2026
a1a84e7
test(m2.3): capture alternate liveness
ikodo0 Jul 25, 2026
eacf954
test(m2.4): classify primary Uniswap schemas
ikodo0 Jul 25, 2026
5f16414
test(m2.4): classify alternate Uniswap schema
ikodo0 Jul 25, 2026
cb8269b
test(m2): capture blocked source evaluation
ikodo0 Jul 25, 2026
d732b79
test(m2): keep minimal source evidence
ikodo0 Jul 25, 2026
9d9a1ce
Define M0 core policy (#12)
kapustazh Jul 25, 2026
0087b2a
Merge branch 'develop' into feat/m2.3-live-evidence
ikodo0 Jul 25, 2026
55a6979
Merge pull request #13 from ikodo0/feat/m2.3-live-evidence
ikodo0 Jul 25, 2026
08e4377
Add compare_pools response contracts (#15)
kapustazh Jul 25, 2026
9fcc597
add canonical pool normalization primitives
kapustazh Jul 25, 2026
55e1295
M2: close source scope to two Tier-B Graph deployments (#17)
ikodo0 Jul 25, 2026
9072729
fix m2 probe harness review findings (#19)
kapustazh Jul 25, 2026
3dd19cc
M3: Graph adapter — registry loader and daily aggregation (#18)
ikodo0 Jul 25, 2026
acb02fd
M4: Nuthatch contract probe and freshness-view draft (#21)
ikodo0 Jul 25, 2026
a96067b
Graph: live PoolSourceResult adapter for locked compare-pools sources…
kapustazh Jul 25, 2026
443435f
bind compare_pools request schema to locked two-source Graph scope (#23)
kapustazh Jul 25, 2026
b04a6ca
bind Graph pool normalization to locked compare_pools allowlist (#24)
kapustazh Jul 25, 2026
555e6e5
M0-04: deterministic pool metrics ranking and Top-N (#25)
kapustazh Jul 25, 2026
eb799e0
M0-05: compare_pools coverage, freshness, and failure isolation (#26)
kapustazh Jul 25, 2026
754201d
M0-06: compare_pools MCP tool (#27)
kapustazh Jul 25, 2026
57c86fd
M4: Nuthatch nest — P0 contract, P5 view, P6 checks, P4 evidence (#28)
ikodo0 Jul 25, 2026
8ff3a7d
remove ai_reasoning from compare_pools response contract (#29)
kapustazh Jul 25, 2026
73e05d3
M5: Nuthatch adapter — client, response parsers, adapter (#30)
ikodo0 Jul 25, 2026
cecacb8
M0-07: MCP HTTP transport, registry build fix, testing guide (#31)
ikodo0 Jul 25, 2026
3198640
fix(http): drop the browser credential challenge (#33)
ikodo0 Jul 25, 2026
7f35d95
fix: the 7d window has never returned a value (#34)
ikodo0 Jul 25, 2026
27bdbc7
M0-08: one-command MCP smoke test (#32)
ikodo0 Jul 25, 2026
694d356
fix(http): share one rate limiter across sessions
ikodo0 Jul 25, 2026
5eeeb82
Merge pull request #35 from ikodo0/fix/m0-10-limiter-coverage
ikodo0 Jul 25, 2026
f8847a3
feat(m5.6): invoke live Nuthatch freshness
ikodo0 Jul 25, 2026
025f5aa
fix(m5): keep degraded provenance honest
ikodo0 Jul 25, 2026
bb50d17
docs(m5): describe live Nuthatch source
ikodo0 Jul 25, 2026
3b35347
Merge pull request #36 from ikodo0/feat/m5.6-nuthatch-live
ikodo0 Jul 25, 2026
c33d2bf
Merge pull request #37 from ikodo0/fix/m5.7-quality-defects
ikodo0 Jul 25, 2026
bc9b5d7
fix(http): expire abandoned MCP sessions
ikodo0 Jul 25, 2026
c6350ec
test(http): cover idle session lifecycle
ikodo0 Jul 25, 2026
cabd226
fix(http): expire abandoned SSE sessions
ikodo0 Jul 25, 2026
9841240
Merge pull request #38 from ikodo0/fix/m0.11-session-idle
ikodo0 Jul 26, 2026
f361d16
feat(m4.11): detect frozen Nuthatch backfills
ikodo0 Jul 25, 2026
a015138
fix(m4.11): configure RPC failover alerts
ikodo0 Jul 25, 2026
9bb0e40
fix(m4.11): restore valid RPC fallbacks
ikodo0 Jul 26, 2026
ea63215
fix(m3): version eight-day query provenance
ikodo0 Jul 25, 2026
a73af73
Merge pull request #39 from ikodo0/fix/m3.7-query-provenance
ikodo0 Jul 26, 2026
90448a9
Merge pull request #40 from ikodo0/fix/m4.11-backfill-watchdog
ikodo0 Jul 26, 2026
c3bdd84
add large swap search schemas
kapustazh Jul 26, 2026
ddc62dc
Merge pull request #41 from ikodo0/feature/large-swaps-schema
ikodo0 Jul 26, 2026
f54b083
fix(m0.8): close smoke test sessions
ikodo0 Jul 25, 2026
bf49351
fix(http): preserve MCP bearer challenges
ikodo0 Jul 25, 2026
2af1b72
test(smoke): lock accepted success statuses
ikodo0 Jul 26, 2026
3891392
fix(smoke): send negotiated protocol version
ikodo0 Jul 26, 2026
85bf7d9
Merge pull request #42 from ikodo0/fix/m0.10-review-followups
ikodo0 Jul 26, 2026
6a1fff0
normalize large swap events (#43)
kapustazh Jul 26, 2026
91fb0cc
feat(skill): guide verified pool research
ikodo0 Jul 26, 2026
4991bd6
feat(http): serve MCP at the root URL
ikodo0 Jul 26, 2026
a872b3c
docs: simplify public MCP connection
ikodo0 Jul 26, 2026
78df2ca
feat(mcp): teach clients verified pool research
ikodo0 Jul 26, 2026
6daa65a
fix(skill): align guidance with response schema
ikodo0 Jul 26, 2026
8486472
docs: add three-client MCP setup
ikodo0 Jul 26, 2026
ab4994a
feat(http): build public connection page
ikodo0 Jul 26, 2026
d4dfe3b
feat(http): route browsers to connection page
ikodo0 Jul 26, 2026
b3e5d2e
fix(http): validate MCP request origins
ikodo0 Jul 26, 2026
0c660ac
docs: explain MCP origin rejection
ikodo0 Jul 26, 2026
4177e6b
Merge pull request #44 from ikodo0/feat/m8.1-remote-connect
ikodo0 Jul 26, 2026
ea5e063
implement stable large swap pagination (#45)
kapustazh Jul 26, 2026
4d60252
docs: add one-command skill install (#46)
ikodo0 Jul 26, 2026
9f2bd15
Release find_large_swaps tool (#47)
kapustazh Jul 26, 2026
e101ec8
feat(http): add the public connection page assets
ikodo0 Jul 26, 2026
92badfe
feat(http): serve the connection page from a file
ikodo0 Jul 26, 2026
3570535
feat(http): route typeface requests before the MCP paths
ikodo0 Jul 26, 2026
509a49f
test(http): cover the connection page typeface route
ikodo0 Jul 26, 2026
c558281
Merge pull request #49 from ikodo0/feat/m0-11-public-landing
ikodo0 Jul 26, 2026
3c76313
feat: compare Base markets through Messari standardized subgraphs (#48)
kapustazh Jul 26, 2026
9ae01b1
feat(http): issue per-client bearer tokens
ikodo0 Jul 26, 2026
6e2e6de
feat(http): let callers take their own token
ikodo0 Jul 26, 2026
b009d6d
docs(http): point the setup guide at self-serve tokens
ikodo0 Jul 26, 2026
92b6a76
docs(http): record where the issued token store lives
ikodo0 Jul 26, 2026
baeffb9
test(http): cover the mint request a browser really sends
ikodo0 Jul 26, 2026
b2bae90
Merge pull request #50 from ikodo0/feat/m9-self-serve-tokens
ikodo0 Jul 26, 2026
88319df
Add source-bounded wallet research (#51)
kapustazh Jul 26, 2026
6f539cb
feat(http): add an OAuth browser flow for connecting
ikodo0 Jul 26, 2026
49d7b4e
feat(http): advertise the OAuth flow on a 401
ikodo0 Jul 26, 2026
abd5e04
test(http): cover the OAuth flow end to end
ikodo0 Jul 26, 2026
d4ca1bd
Merge pull request #52 from ikodo0/feat/m9.2-oauth-browser-flow
ikodo0 Jul 26, 2026
cc56558
fix(http): stop the origin allowlist blocking OAuth clients
ikodo0 Jul 26, 2026
d862e9b
Merge pull request #53 from ikodo0/fix/m9.4-oauth-origin-exemption
ikodo0 Jul 26, 2026
620d606
feat(http): make the shared deployment token optional (#54)
kapustazh Jul 26, 2026
d76a609
fix(http): stop the token page rejecting its own form (#56)
kapustazh Jul 26, 2026
96775e9
Rewrite the README and add an authentication guide (#55)
kapustazh Jul 26, 2026
7f4bf26
Blur the issued token and stop capping mints (#57)
kapustazh Jul 26, 2026
a9ca201
docs(readme): show one Cursor and Codex example instead of every clie…
kapustazh Jul 26, 2026
57f779e
feat(http): cover the issued token with asterisks instead of blurring…
kapustazh Jul 26, 2026
7afa418
feat(http): cover the token with asterisks and drop Shown once (#60)
kapustazh Jul 26, 2026
2a3b12e
fix(nuthatch): query pool__swap without CAST for wallet and LSS (#61)
kapustazh Jul 26, 2026
b2e9ace
docs(readme): note that Nuthatch is reachable only from the server
ikodo0 Jul 26, 2026
eb4615f
Merge pull request #62 from ikodo0/docs/m5-skill-nuthatch-boundary
ikodo0 Jul 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# The Graph gateway credential. Prefer sending this as an Authorization bearer
# token instead of embedding it in a gateway URL.
GRAPH_API_KEY=

# Ordered Base mainnet RPC endpoints passed to Nuthatch as repeatable --rpc
# arguments by nuthatch.service. Production loads them from the root-owned
# /etc/default/nuthatch; nuthatch.toml does not interpolate environment
# variables. Never commit keyed URLs or tokens. Use three independent providers
# and probe each endpoint's eth_getLogs range cap before deploying it. All three
# values are required by the documented nuthatch.service unit.
BASE_RPC_URL_PRIMARY=
BASE_RPC_URL_SECONDARY=
BASE_RPC_URL_TERTIARY=

# Private URL of the Nuthatch HTTP API, without a trailing slash. When
# DeepTrace and Nuthatch are co-located, use loopback so normal operation does
# not depend on Tailscale or public DNS. Never expose this URL to MCP users.
# Production example: http://127.0.0.1:8288
NUTHATCH_BASE_URL=

# Reserved for authenticated admin access if --no-admin is removed.
# Production currently disables the admin UI with --no-admin.
NUTHATCH_ADMIN_TOKEN=

# Gateway fixed-window rate limit: max requests per key (default: 30, maximum: 300).
DEEPTRACE_RATE_LIMIT_MAX_REQUESTS=30

# Gateway fixed-window duration in milliseconds (default: 60000, maximum: 3600000).
DEEPTRACE_RATE_LIMIT_WINDOW_MS=60000

# Per-source adapter timeout in milliseconds (default: 5000, maximum: 8000).
DEEPTRACE_SOURCE_TIMEOUT_MS=5000

# Where issued per-client bearer tokens are recorded, as SHA-256 digests only.
# Must live outside the deployed tree: the deploy rsyncs it with --delete, so an
# in-repo path is wiped on every release. Production: /var/lib/deeptrace/tokens.json
DEEPTRACE_TOKEN_STORE=

# Deprecated shared bearer token, kept only so pre-migration clients keep
# working. One leak exposes every client and cannot be revoked selectively.
# Leave it empty: clients mint their own token at /auth or through OAuth. When
# set it must be at least 32 characters, or startup fails.
DEEPTRACE_HTTP_TOKEN=

# Inactive MCP sessions expire after this many milliseconds (default: 1800000).
DEEPTRACE_HTTP_SESSION_IDLE_TIMEOUT_MS=1800000

# How often inactive MCP sessions are reaped (default: 60000).
DEEPTRACE_HTTP_SESSION_SWEEP_INTERVAL_MS=60000
41 changes: 41 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: code quality

on:
push:
pull_request:

permissions:
contents: read

jobs:
check:
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: checkout repository
uses: actions/checkout@v6

- name: setup node
uses: actions/setup-node@v6
with:
node-version: 22
cache: npm

- name: install dependencies
run: npm ci

- name: check formatting
run: npm run format:check

- name: lint code
run: npm run lint

- name: check types
run: npm run typecheck

- name: run unit tests
run: npm test

- name: build project
run: npm run build
53 changes: 53 additions & 0 deletions .github/workflows/nuthatch-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: nuthatch check

on:
push:
paths:
- "nest/**"
- ".github/workflows/nuthatch-check.yml"
pull_request:
paths:
- "nest/**"
- ".github/workflows/nuthatch-check.yml"

permissions:
contents: read

jobs:
check:
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
- name: checkout repository
uses: actions/checkout@v6

- name: validate nest structure
run: |
test -f nest/nuthatch.toml || { echo "nest/nuthatch.toml missing"; exit 1; }
test -f nest/schema.json || { echo "nest/schema.json missing"; exit 1; }
test -d nest/abis || { echo "nest/abis/ missing"; exit 1; }
test -d nest/views || { echo "nest/views/ missing"; exit 1; }
test -d nest/checks || { echo "nest/checks/ missing"; exit 1; }
test -d nest/checks/expected || { echo "nest/checks/expected/ missing"; exit 1; }

- name: validate view SQL exists
run: |
for view in pool_swap_freshness pool_swap_search wallet_swap_activity; do
test -f "nest/views/${view}.sql" || { echo "missing nest/views/${view}.sql"; exit 1; }
done

- name: validate check SQL files exist
run: |
for check in view_shape latest_swap_identity recent_count_24h provenance_not_null decimal_columns hot_sealed_no_duplicates swap_search_parity wallet_activity_parity; do
test -f "nest/checks/${check}.sql" || { echo "missing nest/checks/${check}.sql"; exit 1; }
test -f "nest/checks/expected/${check}.json" || { echo "missing nest/checks/expected/${check}.json"; exit 1; }
done

- name: validate no secrets in nest
run: |
if grep -rn "GRAPH_API_KEY\|Bearer \|api_key=\|NUTHATCH_ADMIN_TOKEN" nest/; then
echo "Secret found in nest/"
exit 1
fi
echo "No secrets found in nest/"
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
.env.*
!.env.example

# Local planning docs — working notes, not part of the deliverable
/DATA_PIPE_PLAN.md
/docs/M*_PLAN.md

# TypeScript / Node
node_modules/
dist/
Expand All @@ -24,3 +28,5 @@ coverage/
.yarn/cache/
.yarn/unplugged/
.pnp.*
/DEEPTRACE_HANDOFF.md
/DEV_PLAN.md
6 changes: 6 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dist
node_modules
package-lock.json
*.md
LICENSE
src/http/public/index.html
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 100,
"semi": true,
"singleQuote": false,
"trailingComma": "all"
}
Loading