VeriSom
Scores contract safety for Somnia Agents using on-chain analysis, RAG, and a VeriSom contract, returning a pre-interaction safety score.
README
VeriSom
On-chain contract safety infrastructure for autonomous agents.
VeriSom gives an AI agent a contract safety score before it approves, swaps, transfers, or calls a smart contract. It gathers verified source code when available, falls back to bytecode analysis when it is not, adds recent on-chain activity, builds a local RAG evidence set, submits the assembled context to the VeriSom contract on Somnia, and returns a direct machine-usable verdict.
Live landing page: verisom.vercel.app
Repository: github.com/anoop04singh/verisom
What VeriSom is
VeriSom is two things in one repository:
- A marketing landing page for the VeriSom MCP server.
- An agent-facing contract scoring service that exposes:
- a local
stdioMCP server for tools like Claude Desktop
- a local
The core job of the system is not to generate a long human audit report. It is to help an AI agent answer one operational question before interacting with a contract:
Should I interact with this contract right now?
The answer comes back as:
- a Somnia score
- a score band
- an
allow,review, oravoidrecommendation - structured findings
- the RAG context used
- the functions and transaction evidence used
- the exact contract context that was submitted for scoring
Core value proposition
- One tool call for the agent.
- One direct score result.
- One evidence trail explaining why the score exists.
- No Gemini embeddings or external embedding dependency.
- Verified source when possible, bytecode fallback when not.
- Private key can stay inside the local agent connector environment in
stdiomode.
Product surface
Landing page
The root page is a marketing site for the MCP server and setup flow.
MCP server
The server exposes a single tool:
score_contract_before_interaction
This tool:
- analyzes the target contract
- builds the contract context
- submits the request to the VeriSom contract
- waits for the Somnia Agents callback
- returns the final structured result directly
There is no request-id choreography required for the MCP caller.
HTTP routes
The repository also exposes direct HTTP routes:
POST /api/analyzePOST /api/requestGET /api/request/[requestId]GET|POST|DELETE /api/mcpGET /api/mcp/health
High-level architecture
+----------------------+
| Claude / Agent |
| or any MCP client |
+----------+-----------+
|
stdio MCP or HTTP MCP call
|
v
+------------+-------------+
| VeriSom Server |
| Next.js + MCP runtime |
+------------+-------------+
|
+----------------+----------------+
| |
v v
+-----------+-----------+ +-----------+-----------+
| Contract acquisition | | On-chain submission |
| + local RAG assembly | | to VeriSom/Somnia |
+-----------+-----------+ +-----------+-----------+
| |
v v
+--------------+----------------+ +---------+----------+
| Verified source or bytecode | | requestSafetyScore |
| Explorer metadata | | poll auditJobs |
| Recent transactions | | wait for event |
| Lexical retrieval | +---------+----------+
+--------------+----------------+ |
| |
+---------------+-----------------+
|
v
+-----------+------------+
| Final structured score |
| allow/review/avoid |
| provenance + evidence |
+------------------------+
End-to-end flow
Agent
|
| score_contract_before_interaction(targetAddress, intendedInteraction, auditFocus)
v
VeriSom MCP Server
|
|-- fetch explorer address metadata
|-- fetch smart contract profile
|-- fetch recent transactions
|
|-- if verified source exists:
| use source + ABI + metadata
|
|-- else:
| fetch deployed bytecode from RPC
| extract selectors, patterns, flags, strings
|
|-- build local knowledge documents
|-- rank documents with lexical retrieval
|-- build contract context string
|-- compute local heuristic findings
|
|-- call VeriSom contract: requestSafetyScore(...)
|-- wait until auditJobs(requestId).completed == true
|-- read parsedScore and callback event
|
|-- combine local heuristic recommendation
| with Somnia score
v
Return final result to agent
Verified-source path vs bytecode-fallback path
+---------------------------+
| Fetch explorer contract |
| metadata and source |
+-------------+-------------+
|
+-------------+-------------+
| Is verified source found? |
+------+--------------------+
| yes
v
+-----------------+------------------+
| Chunk source code and add ABI |
| Build verified-source documents |
+-----------------+------------------+
|
| no
v
+-----------------+------------------+
| Fetch deployed bytecode from RPC |
| Disassemble and inspect opcodes |
| Extract selectors and flags |
+-----------------+------------------+
|
v
+-------------+--------------+
| Build common RAG evidence |
| and contract context |
+----------------------------+
Implementation overview
Stack
- Next.js 15
- React 19
- TypeScript
ethersfor chain interaction@modelcontextprotocol/sdkfor MCP transportszodfor MCP tool schemas
Important files
- mcp-stdio.ts: local
stdioMCP entrypoint - lib/mcp-server.ts: MCP tool registration and final orchestration
- lib/audit-pipeline.ts: analysis pipeline entry
- lib/rag.ts: local lexical RAG document creation and ranking
- lib/bytecode-analyzer.ts: selector/pattern/flag extraction
- lib/context-builder.ts: final context string assembly
- lib/interaction-assessment.ts: local heuristic recommendation layer
- lib/verisom.ts: contract submission and polling
- lib/explorer.ts: explorer metadata and transaction fetchers
- lib/rpc.ts: raw RPC access
- app/api/mcp/route.ts: HTTP MCP transport
- app/api/analyze/route.ts: analysis-only HTTP route
- app/api/request/route.ts: submission route
app/api/request/[requestId]/route.ts: request status route- components/landing-page.tsx: landing page content/UI
Detailed architecture
1. Contract acquisition layer
Implemented primarily in lib/explorer.ts and lib/rpc.ts.
The acquisition layer pulls:
- explorer address metadata
- explorer contract metadata
- verified source code if available
- ABI if available
- recent transactions
- deployed bytecode from RPC when verification is missing
Explorer data comes from:
SOMNIA_EXPLORER_BASE_URL/api/v2/addresses/:addressSOMNIA_EXPLORER_BASE_URL/api/v2/addresses/:address/countersSOMNIA_EXPLORER_BASE_URL/api/v2/smart-contracts/:addressSOMNIA_EXPLORER_BASE_URL/api/v2/addresses/:address/transactions
RPC data is used to get deployed bytecode directly from chain state.
2. Bytecode analysis layer
Implemented in lib/bytecode-analyzer.ts.
When source is unavailable, VeriSom disassembles bytecode and extracts:
- opcode-level signals
- selectors inferred from
PUSH4 ... EQdispatch patterns - known selector signatures
- pattern fingerprints such as:
ERC20OwnableUpgradeable
- high-signal flags such as:
delegatecallcreatecreate2staticcallselfdestructpayable-surface
- printable embedded strings
This is not a full decompiler. It is a practical bytecode evidence layer for pre-transaction decision support.
3. Local RAG layer
Implemented in lib/rag.ts.
VeriSom uses fully local lexical retrieval.
What goes into the knowledge base
The RAG corpus is assembled from:
- contract overview metadata
- verified source chunks
- additional verified source files
- verified ABI
- bytecode analysis output
- summarized recent transactions
- individual recent transaction records
How retrieval works
- Build a synthetic audit query from:
- target address
- chain name
- default security concerns
- user-supplied
auditFocus
- Tokenize documents and query lexically.
- Score token overlap with category weighting.
- Rank all documents.
- Take the top retrieved items.
- Feed them into the final contract context.
Current retrieval mode:
local-lexical-rag
This keeps the system:
- offline-friendly
- deterministic
- inexpensive
- simple to run inside local agent environments
4. Context assembly layer
Implemented in lib/context-builder.ts.
The final contractContext string includes:
- audit target
- chain
- audit focus
- acquisition mode
- verified-source summary or bytecode summary
- proxy / implementation hints
- recent transaction summary
- retrieval mode
- retrieved evidence blocks
This context is what gets submitted on-chain to the VeriSom contract.
5. Local heuristic assessment layer
Implemented in lib/interaction-assessment.ts.
Before the Somnia result comes back, VeriSom computes local findings using:
- source verification status
- proxy detection
- bytecode flags
- upgradeability signals
- privileged functions
- pause / freeze controls
- mint / burn / rebase controls
- upgrade functions
- fund movement functions
- fee / tax / wallet-limit controls
- recent failed transactions
- missing activity history
This produces:
localHeuristicRecommendationlocalHeuristicRiskLevellocalHeuristicRiskScorereasonskeyFindings
The final recommendation is then reconciled with the Somnia score.
6. On-chain request and callback layer
Implemented in lib/verisom.ts and lib/verisom-abi.ts.
The current contract interaction flow is:
- Read
getRequiredDeposit() - Submit
requestSafetyScore(targetContract, chainName, contractContext)with the required deposit - Parse the
SafetyScoreRequestedevent from the receipt - Poll
auditJobs(requestId) - Query
SafetyScoreReceivedevents - Return the final parsed score and transaction reference
Relevant ABI surface:
getRequiredDeposit()
requestSafetyScore(address,string,string)
auditJobs(uint256)
SafetyScoreRequested(...)
SafetyScoreReceived(...)
MCP architecture
Local stdio mode
stdio mode is the recommended mode for Claude Desktop and similar local agent connectors.
Why:
- the private key can stay in the connector environment
- the agent does not need to resend
privateKeyevery call - the MCP server can use
AGENT_PRIVATE_KEYautomatically
Entrypoint:
Behavior:
allowEnvPrivateKey: true
MCP tool contract
Tool name
score_contract_before_interaction
Input
{
targetAddress: string;
chainName?: string;
intendedInteraction?: string;
auditFocus?: string;
privateKey?: string;
timeoutMs?: number;
pollIntervalMs?: number;
}
Output
{
targetAddress: string;
chainName: string;
somniaScore: number;
somniaStatus: string;
scoreBand: "strong" | "caution" | "danger" | "unknown";
scoreInterpretation: string;
recommendation: "allow" | "review" | "avoid";
shouldInteract: boolean;
riskLevel: "low" | "medium" | "high";
riskScore: number;
reasons: string[];
keyFindings: Array<{
title: string;
severity: "low" | "medium" | "high";
evidence: string;
}>;
proceedGuidance: string;
localHeuristicRecommendation: "allow" | "review" | "avoid";
localHeuristicRiskLevel: "low" | "medium" | "high";
localHeuristicRiskScore: number;
verified: boolean;
sourceMode: "verified-source" | "bytecode-fallback";
contractName: string | null;
compilerVersion: string | null;
proxyDetected: boolean;
implementationAddress: string | null;
retrievalMode: string;
recentTransactionCount: number;
privateKeySource: "input" | "env";
oracleTransactionHash: string;
ragContextUsed: Array<...>;
contractFunctionsUsed: Array<...>;
recentTransactionsUsed: Array<...>;
bytecodeSignalsUsed: {
patterns: Array<...>;
specialFlags: string[];
selectors: Array<...>;
} | null;
contractContext: string;
}
What the score means
VeriSom is a contract interaction risk gate, not a formal verification engine and not a complete manual audit replacement.
Agents should use it as:
- a pre-transaction control
- a contract selection filter
- a reason to stop and ask for review when the output says
revieworavoid
Local development setup
Prerequisites
- Node.js
- npm
- access to Somnia RPC and explorer endpoints
- a funded private key if you want to submit live score requests
Install
Clone the repository:
git clone https://github.com/anoop04singh/verisom.git
cd verisom
Then install dependencies:
cmd /c npm install
Configure environment
Create .env from .env.example.
Current environment variables:
SOMNIA_RPC_URL=https://api.infra.testnet.somnia.network
SOMNIA_EXPLORER_BASE_URL=https://shannon-explorer.somnia.network
VERISOM_CONTRACT_ADDRESS=0x45e89Bae0eD991b63F8988d13EcEC1Ae0eEdDA77
AGENT_PRIVATE_KEY=0xYOUR_AGENT_PRIVATE_KEY_HERE
CHAIN_NAME=Somnia Testnet
VERISOM_POLL_INTERVAL_MS=5000
Run the app
npm run dev
Then open:
Build for production
npm run build
npm run start
Claude config example
Open your Claude Desktop MCP config and add:
{
"mcpServers": {
"verisom": {
"command": "C:\\Users\\YOUR_USER\\Downloads\\verisom-final\\node_modules\\.bin\\tsx.cmd",
"args": [
"C:\\Users\\YOUR_USER\\Downloads\\verisom-final\\mcp-stdio.ts"
],
"env": {
"AGENT_PRIVATE_KEY": "0xYOUR_PRIVATE_KEY_HERE",
"SOMNIA_RPC_URL": "https://api.infra.testnet.somnia.network",
"SOMNIA_EXPLORER_BASE_URL": "https://shannon-explorer.somnia.network",
"VERISOM_CONTRACT_ADDRESS": "0x45e89Bae0eD991b63F8988d13EcEC1Ae0eEdDA77",
"CHAIN_NAME": "Somnia Testnet",
"VERISOM_POLL_INTERVAL_MS": "5000"
}
}
}
}
Then restart Claude Desktop.
Example Claude prompt
Use VeriSom to score this contract before interaction.
0x3203332165Fa483e317095DcBA7d56d2ED4E15bC
Example result shape
Target contract: 0x...
Somnia Agents score: 85
Score band: strong
Recommendation: allow
Risk level: low
Risk score: 15
Interpretation: The Somnia Agents score suggests comparatively lower observed risk.
Key findings:
- [low] Lower structural uncertainty: Verified source is available and no obvious proxy layer was detected.
Guidance: Proceed for the intended interaction, but still verify transaction parameters, token amounts, and approvals at execution time.
Repository layout
verisom-final/
|-- app/
| |-- api/
| | |-- analyze/route.ts
| | |-- mcp/route.ts
| | |-- mcp/health/route.ts
| | |-- request/route.ts
| | `-- request/[requestId]/route.ts
| |-- globals.css
| |-- icon.svg
| |-- layout.tsx
| `-- page.tsx
|-- components/
| `-- landing-page.tsx
|-- lib/
| |-- audit-pipeline.ts
| |-- bytecode-analyzer.ts
| |-- config.ts
| |-- context-builder.ts
| |-- explorer.ts
| |-- interaction-assessment.ts
| |-- mcp-server.ts
| |-- rag.ts
| |-- rpc.ts
| |-- types.ts
| |-- utils.ts
| |-- verisom-abi.ts
| `-- verisom.ts
|-- public/
| |-- verisom-logo.png
| `-- verisom-logo.svg
|-- mcp-stdio.ts
|-- package.json
`-- README.md
Limitations
- Bytecode analysis is heuristic, not decompilation.
- Explorer completeness affects metadata quality.
- Recent transaction interpretation depends on explorer response quality.
- On-chain score turnaround depends on the VeriSom contract workflow and callback timing.
- A strong score is not a guarantee of safety.
Recommended usage model
Use VeriSom when an agent is about to:
- approve a token
- call an arbitrary contract
- swap through an unknown router
- transfer value into a protocol
- interact with a newly discovered token or dApp
Recommended agent behavior:
allow: proceed with normal parameter checksreview: require human or policy reviewavoid: stop the interaction and choose another path
Verification
Useful local commands:
cmd /c npm run build
cmd /c npm run mcp:stdio
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.