Full-surface MCP server + Celaut .service (MCP HTTP + REST, seed/unsigned signer) - #1
Open
agenticaihome wants to merge 31 commits into
Open
Full-surface MCP server + Celaut .service (MCP HTTP + REST, seed/unsigned signer)#1agenticaihome wants to merge 31 commits into
agenticaihome wants to merge 31 commits into
Conversation
feat: update Source Box fields (Issue #2)
- Replaced hardcoded blake2b256 with downloadAndHash() from hashUtils - calculateHashFromUrl now uses the selected hash algorithm (sha3_256, blake2b, sha256, keccak256) - Chunked files: downloadAndHash fetches all chunks from manifest, concatenates, then hashes the complete content - handleAddSource validation also uses correct algorithm + chunked support - handleFileUpload uses computeHash with selected algorithm - Removed unused blake2b256 and uint8ArrayToHex imports - Custom algorithm shows 'select a known hash algorithm first' error
…lgorithm-chunked fix: calculateHashFromUrl uses selected algorithm + chunked file support
1. Hash Validation Toggle:
- Added hashValidationEnabled store (persisted, default false)
- Added checkbox toggle in SettingsModal under 'Verification' section
- FileSourceCreation now respects the setting — skips URL hash
verification when disabled
- Exported hashValidationEnabled from index.ts
2. Profile Detection Fallback:
- Added fallbackProfileDetection() for wallets where the
reputation-system library fails to detect profiles due to
R5 UTF-8 encoding edge case (R5 stores hex(utf8(tokenId))
instead of raw bytes)
- Queries Explorer API directly with ergoTreeTemplateHash + R4/R7
register filters, then checks both raw hex and UTF-8 decoded R5
- Falls back automatically when standard detection returns nothing
3. Fixed createProfileBox parameter order bug in sourceStore.ts
(explorerUri was in wrong position)
…gs-hash-toggle-and-profile-detection feat: hash validation toggle + fallback profile detection
Josemi's wallet has a JUDGE-type profile (from GoP) but the source app was filtering by PROFILE_TYPE_NFT_ID only. Now: 1. fetchAllUserProfiles called with empty types array [] to accept any type 2. Fallback detection no longer filters by R4 register This matches Game of Prompts behavior where profiles of any type are detected.
…-any-profile-type fix: accept any profile type for wallet detection
- Update svelte.config.js with dynamic BASE_PATH for GitHub Pages - Add esRawPlugin to vite.config.ts for .es contract files - Clean up vite.config.ts (remove unused config block) - Update deploy.yml to follow standardized template - Layout already has ssr=false and prerender=true
…b-pages-deploy feat: GitHub Pages deployment with dynamic base path and esRawPlugin
…meline, modals, etc.) Previously only 4 components were exported. Now all components from src/lib/components/ are available to library consumers, matching the full web app experience.
…t-all-library-components feat: export all library components
… validation FileSourceCreation now includes: - Hash Function ID selector with known algorithms - Content Hash + Content Format fields - Raw Format (toggleable via content-equals-raw checkbox) - Chunked file manifest support - Hash validation per algorithm - URL parameter pre-fill support Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t-all-library-components feat: updated FileSourceCreation with hash/format fields + library exports
Runs `npm run package` and commits updated dist/ when src/lib changes. No more need to run `npm run package` locally. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mirror the celaut-skills / reputation-system pattern for source-application:
mcp/ (stdio MCP, full surface)
- core.mjs framework-agnostic reads + pure helpers (Svelte-free port of
sourceFetch.ts + sourceObject.ts); Explorer search via
reputation-system/node
- lib.mjs makeSigner (SOURCE_SIGNER_MODE=seed|unsigned), fetchMainBox,
describeResult
- writes.mjs port of sourceStore.ts via create_*_with_signer
- tools.mjs shared TOOLS + HANDLERS (27 tools)
- server.mjs stdio bootstrap (console routed to stderr to keep JSON-RPC clean)
.service/ (Celaut microVM)
- server-http.mjs 0.0.0.0:8080 — /health, /mcp (Streamable HTTP, same tools),
and a REST API (/api/*) mirroring every method
- core/lib/writes/tools.mjs copies of the mcp/ modules
- Dockerfile, service.json (port 8080 http, api.ergoplatform.com net tag),
start.sh, pack_config.json, package.json, README.md
Both transports back every read and write with a SEED signer or an UNSIGNED
signer; unsigned mode keeps no key in the process and returns an unsigned tx.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…me fork branch The .service pinned reputation-system to github:agenticaihome/reputation-system#fix/seed-signer-derivation — a feature branch on a fork that could be deleted, breaking installs. Upstream reputation-systems/reputation-system:master already carries the full /node export (NautilusSigner/SeedSigner/UnsignedSigner + create_*_with_signer) and the @Scure BIP-39/32 Nautilus-compatible derivation, with dist/ committed. Re-point both root and .service to github:reputation-systems/reputation-system (canonical, undeletable). Verified: install exposes reputation-system/node and dist/signer.js contains the @Scure derivation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…vice # Conflicts: # package.json
…vice (DRY) Addresses the review on reputation-systems#13: the ~470-line mcp/core.mjs and its byte-for-byte copy under .service/ hand-ported logic that already lives in src/lib/ergo/*, so the two would drift. Reads now reuse src — no re-implementation: - mcp/_entry.mjs re-exports the read surface straight from src/lib/ergo/ {sourceFetch,sourceObject,envs,hashUtils,utils}.ts. - mcp/build.mjs (esbuild, `npm run build:mcp`) compiles it into one Node-loadable ESM module, mcp/_generated/lib.bundle.mjs (committed so the sealed VM needs no build toolchain). Browser-only edges are rewritten: reputation-system → reputation-system/node (external, same package writes.mjs uses → no drift), $app/environment → stub (browser=false), dompurify → passthrough stub (read-only data, only JSON.parsed). - mcp/core.mjs is now an 84-line thin adapter (was 470) that re-exports the bundle and defaults explorerUri. Writes keep the necessary thin Node signer adapter (writes.mjs/lib.mjs) — that's glue, not duplication (sourceStore.ts is browser-ergo-bound). Dedup mcp/ ↔ .service/: removed the four copied modules from .service/; server-http.mjs now imports ../mcp/{core,lib,writes,tools}.mjs. The Dockerfile preserves the sibling layout in the VM (/app/service + /app/mcp) so ../mcp resolves identically. One source of truth, no committed duplicate logic. deps: align mcp/ reputation-system to upstream github:reputation-systems/ reputation-system (matching root + .service; the fork pin was missed in 8c78ab7); add esbuild devDependency + build:mcp script. Net: ~1,250 lines of hand-maintained/duplicated read logic removed; ~150 lines of build glue + an 84-line adapter added (plus the generated bundle artifact). Verified: npm install; build:mcp; node --check all .mjs; core.mjs loads with no svelte/$app/dompurify errors; stdio + HTTP tools/list both return the same 27 tools; REST read returns a clean []; unsigned-mode write returns an unsigned EIP-12 tx. No on-chain submit, no secrets. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Mirrors the pattern already shipped for celaut-skills and reputation-system: a full-surface MCP server plus a Celaut
.servicemicroVM that exposes the entire Source Application library — every read, every write, and the pure helpers — backed by a SEED signer or an UNSIGNED signer.Additions
mcp/— stdio MCP server (full surface, 27 tools)core.mjs— framework-agnostic reads + pure helpers, a Svelte-free port ofsrc/lib/ergo/sourceFetch.ts+sourceObject.ts. Explorer box search and block-timestamp come fromreputation-system/node(the headless, Node-safe entry — samesearchBoxesthe app uses, including the required reputation-proofergoTreeTemplateHashfilter). Type NFT ids copied verbatim fromenvs.ts(placeholders preserved; non-real types return clean empty arrays).lib.mjs—makeSigner()from env (SOURCE_SIGNER_MODE=seed|unsigned),fetchMainBox(),describeResult()— thereputation-system/mcp/lib.mjspattern with aSOURCE_env prefix.writes.mjs— port ofsrc/lib/ergo/sourceStore.tsto the Node signer path viacreate_profile_with_signer/create_opinion_with_signer.tools.mjs— sharedTOOLS+HANDLERS(used by both transports, so they never drift).server.mjs— stdio bootstrap (console routed to stderr so the library's logs never corrupt the JSON-RPC stream)..service/— Celaut microVM (MCP HTTP and REST)server-http.mjs— binds0.0.0.0:8080:GET /health* /mcp— the same MCP tool surface over Streamable HTTP* /api/*— a clean JSON REST mirror of every method (reads via GET, writes via POST)core/lib/writes/tools.mjs— copies of themcp/modulesDockerfile,service.json(port 8080 http,init.entry_path app/start.sh, resources +api.ergoplatform.comnetwork tag),start.sh,pack_config.json,package.json,README.mdreputation-systemis wired as a dependency the same way celaut-skills does — here pinned togithub:agenticaihome/reputation-system#fix/seed-signer-derivation(the branch that ships the/nodeentry + Nautilus-compatible BIP-39/32 SeedSigner).Tools / endpoints
27 MCP tools:
get_source_config; readsfetch_file_sources_by_hash,fetch_invalid_file_sources,fetch_unavailable_sources,fetch_profile_opinions,fetch_file_sources_by_profile,fetch_invalid_file_sources_by_profile,fetch_unavailable_sources_by_profile,fetch_profile_opinions_by_author,search_by_hash,load_profile_data; helpersgroup_by_download_source,group_by_profile,calculate_profile_trust,aggregate_source_score,get_primary_url,get_all_urls,list_hash_algorithms,validate_hash,compute_hash; writescreate_profile_box,add_file_source,confirm_source,update_file_source,mark_invalid_source,mark_unavailable_source,trust_profile.REST routes mirror all of the above — see
.service/README.mdfor the full table and the write→opinion mapping.Write → opinion mapping
add_file_source/confirm_source→ opinion vsFILE_SOURCE_TYPE_NFT_ID(R5=fileHash, R8=true, R9=source entry)mark_invalid_source→ vsINVALID_FILE_SOURCE_TYPE_NFT_ID(R5=sourceBoxId, R8=false)mark_unavailable_source→ vsUNAVAILABLE_SOURCE_TYPE_NFT_ID(R5=sourceUrl, R8=false)trust_profile→ vsPROFILE_OPINION_TYPE_NFT_ID(R5=profileTokenId, R8=isTrusted)create_profile_box→create_profilevsPROFILE_TYPE_NFT_IDEvery opinion is split from the author's PROFILE box (
mainBoxId).Env vars
SOURCE_SIGNER_MODE=unsigned(default) |seedSOURCE_ADDRESSSOURCE_MNEMONIC(+ optionalSOURCE_MNEMONIC_PASSWORD,SOURCE_NODE_URI,SOURCE_ADDRESS_INDEX)SOURCE_EXPLORER_API(defaulthttps://api.ergoplatform.com),PORT(default 8080)How to run
Verification evidence (all real, mainnet)
node --checkpasses on all 10.mjsfiles.reputation-system/noderesolves:searchBoxes, getTimestampFromBlockId, SeedSigner, UnsignedSigner, create_opinion_with_signer, create_profile_with_signer.tools/list→ 27 tools; stdout is 100% JSON-RPC (console redirected to stderr).GET /health→{"status":"ok",...,"signerMode":"unsigned"}./mcptools/list→ 27 tools;tools/call compute_hash("abc",sha256)→ba7816bf…015ad(correct).GET /api/configreturns type NFT ids;GET /api/sources?hash=…→ clean[];GET /api/hash-algorithms→sha3_256,blake2b,sha256,keccak256,__custom__.POST /api/sourcesandadd_file_source) against a real on-chain profile box →submitted:false, full unsigned tx (2 inputs, 1 dataInput, 4 outputs, first output = reputation contract), no mnemonic in env.No seed-mode writes were run, no txs submitted, no wallets/secrets touched, and the reputation-system repo was not modified.
Honest gaps
update_file_source: the browser flow spends the previous FILE_SOURCE box viaupdate_opinion(Nautilus-only).reputation-system/nodeexposescreate_*_with_signerbut notupdate_opinion_with_signer, so this publishes a new FILE_SOURCE opinion for the same hash instead of spending the old box. Documented in code +.service/README.md.INVALID_FILE_SOURCE,UNAVAILABLE_SOURCE,PROFILE_OPINIONare still all-zero placeholders inenvs.ts(preserved verbatim). Reads/writes wire up correctly but won't match/clear real boxes until those NFTs are minted;FILE_SOURCE+PROFILEare real and return live data.0on failure (non-critical) rather than throwing, a small robustness change vs the original.🤖 Generated with Claude Code