Persistent cognitive memory layer for AI agents, built on ragmcp principles
Project description
๐ง memorymcp โ Persistent cognitive memory for AI agents
v1.0.2 โ Persistent, intelligent memory for AI agents. Store facts, episodes, and context across sessions. Query by meaning. Expose as an MCP server. Now with pluggable persistent backends (Redis, SQLite, Neo4j, pgvector).
What is memorymcp?
memorymcp gives AI agents a structured, persistent memory system inspired by cognitive science:
- Facts are stored with importance scores, confidence levels, and temporal validity
- Consolidation resolves contradictions automatically โ nothing is deleted, everything is archived
- Decay simulates forgetting: less-accessed facts fade over time, confirmed facts persist
- Semantic search (via ragmcp) retrieves the most relevant context for any query
- Persistent backends โ Redis, SQLite, Neo4j, and pgvector for production-grade storage
- MCP server exposes 16 memory tools natively to Claude Desktop, Cursor, or any MCP client
Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MemoryPipeline โ
โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ โ
โผ โผ โผ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ Tier 0 โ โ Tier 1 โ โ Tier 2 โ
โ HotCache โ โ Working โ โ Episodic โ
โ (LRU RAM) โ โ (task) โ โ (session) โ
โโโโโโโโฌโโโโโโโ โโโโโโโโฌโโโโโโโ โโโโโโโโฌโโโโโโโ
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ Tier 3 โ
โ Semantic โ
โ (ragmcp) โ
โโโโโโโโโโโโโโโโโโโ
Each tier has a distinct role and TTL. Hot facts bubble up to Tier 0 on access. Long-term knowledge is indexed semantically in Tier 3 and retrieved by meaning, not by key.
Quick Start
3-line usage
from memorymcp import MemoryFactory
pipeline = MemoryFactory.default()
await pipeline.store_fact("User prefers Python over JavaScript", importance=0.9)
Agent usage
from memorymcp import MemoryFactory
pipeline = MemoryFactory.default()
# Store what your agent learns
await pipeline.store_fact(
"User prefers Python over JavaScript",
fact_type="preference",
importance=0.9,
)
# Query relevant context by meaning
facts = await pipeline.query_memory("coding preferences", top_k=5)
for r in facts:
print(f"[{r.final_score:.2f}] {r.fact.content}")
# Assemble a prompt-ready context block
ctx = await pipeline.assemble_context(
query="what does the user prefer?",
session_id="sess_1",
max_tokens=2000,
)
print(ctx.render())
MCP server
from memorymcp import MemoryFactory
from memorymcp.mcp_server import MemoryMCPServer
pipeline = MemoryFactory.default()
MemoryMCPServer(pipeline).run()
Or from the command line:
memorymcp serve
Claude Desktop claude_desktop_config.json:
{
"mcpServers": {
"memorymcp": {
"command": "memorymcp",
"args": ["serve"]
}
}
}
Features
- ๐ง 4-tier memory โ HotCache / Working / Episodic / Semantic
- ๐ Semantic search powered by ragmcp (Qdrant, ChromaDB, InMemory)
- ๐ฏ Cross-encoder reranker (optional) โ re-scores retrieved facts for accuracy; measured recall@1 0.40 โ 0.88.
enable_rerank=True(pip install "mcpaisuite-memorymcp[rerank]") - ๐ Adaptive query expansion (optional) โ when a search scores weakly, an LLM rewrites the query into synonymous phrasings and re-searches, recovering hard paraphrases the embedder misses; measured retrieval recall@5 0.42 โ 0.92.
enable_query_expansion=True(adaptive โ one extra LLM call only when the first pass is weak) - ๐ Recency-aware injection โ retrieved facts are stamped with their age (
recorded 10 minutes ago) so the agent picks the current value when two facts conflict on the same attribute - โก Consolidation engine โ ADD / UPDATE / OVERWRITE / SKIP, with full audit trail
- ๐ Tri-modal decay โ linear / exponential / anchored + adaptive retrieval boost
- ๐ Fact graph with typed relations (supports / contradicts / supersedes / derived_from)
- ๐ก Confidence tracker โ score incremented by confirmations, decays on contradiction
- ๐ MCP server โ 16 tools, stdio transport, compatible with any MCP client
- ๐พ Persistent backends โ Redis (episodic, working, hot cache), SQLite (episodic), Neo4j (fact graph), pgvector (semantic)
- ๐ค Dual extractors โ Pattern (regex, zero-dep) + LLM-powered (any model via completion_fn)
- ๐งฉ Smart extraction โ question/noise filtering, correction detection, per-fact decay mode assignment
- ๐ Thread-safety โ All in-memory stores use
threading.Lockfor cross-event-loop safety (compatible with asyncio and anyio/trio) - ๐๏ธ Chroma semantic store โ ChromaDB support for persistent semantic fact storage with native dict variable handling
- ๐ง LLM fact extractor โ Optional LLM-based fact extraction (automatically wired when a kernel LLM is available, replacing the pattern-based extractor)
- ๐ PII filter โ email / phone / credit card / SSN detection, GDPR Art.17
forget_user - ๐ข Multi-tenancy โ namespace-based isolation, each tenant gets its own memory
- ๐ฆ Memory quotas โ per-namespace fact limits
- ๐ก๏ธ Audit logging โ SQLite + JSONL, immutable conflict log per fact
- ๐ Observability โ OpenTelemetry + Prometheus (optional)
- โฑ๏ธ Temporal facts โ
valid_from/valid_until, automatic expiry - ๐ญ MemoryFactory โ
default()/create()/from_env()/from_yaml()/from_ragmcp() - ๐ก Event streaming โ Event bus with 14 event types, subscribe/emit/async stream
- ๐ช Webhooks โ HTTP POST notifications on memory events, register/unregister endpoints
- ๐๏ธ Consolidation scheduler โ Cron-based scheduling for automatic consolidation cycles
- ๐ Memory analytics โ Fact type distribution, decay analysis, confidence distribution, retrieval patterns
- ๐ฅ Import/Export โ Full memory roundtrip with merge/overwrite strategies
- ๐ CLI โ
serve/query/store/stats/consolidate/forget-user
Installation
# Minimal โ no external services
pip install mcpaisuite-memorymcp
# With semantic search (recommended)
pip install "mcpaisuite-memorymcp[semantic]"
# Full stack (MCP + semantic + observability)
pip install "mcpaisuite-memorymcp[all]"
Requirements: Python 3.11+
Persistent Backends
memorymcp ships pluggable persistent backends so memory survives restarts. Mix and match per tier.
SQLite โ Episodic Store (zero dependencies)
pipeline = MemoryFactory.create(episodic_store="sqlite", sqlite_path="memory.db")
Redis โ Episodic, Working, and Hot Cache
pip install "mcpaisuite-memorymcp[redis]"
pipeline = MemoryFactory.create(
episodic_store="redis",
working_store="redis",
hot_cache="redis",
redis_url="redis://localhost:6379/0",
)
Neo4j โ Fact Graph
pip install "mcpaisuite-memorymcp[neo4j]"
pipeline = MemoryFactory.create(
fact_graph="neo4j",
neo4j_uri="bolt://localhost:7687",
neo4j_user="neo4j",
neo4j_password="password",
)
pgvector โ Semantic Store
pip install "mcpaisuite-memorymcp[pgvector]"
pipeline = MemoryFactory.create(
semantic_store="pgvector",
db_url="postgresql://localhost:5432/memory",
)
Usage
MemoryFactory
from memorymcp import MemoryFactory
# Zero config โ in-memory, no external services
pipeline = MemoryFactory.default()
# Read config from environment variables
pipeline = MemoryFactory.from_env()
# Read config from a YAML file
pipeline = MemoryFactory.from_yaml("memory_config.yaml")
# Attach to an existing ragmcp RAGPipeline
pipeline = MemoryFactory.from_ragmcp(rag_pipeline)
# Configurable โ choose extractor, decay, consolidation thresholds
pipeline = MemoryFactory.create(
extractor="llm",
completion_fn=my_llm_fn, # async (messages) -> str
decay_mode="exponential",
decay_half_life_days=14,
similarity_threshold=0.85,
contradiction_threshold=0.92,
)
# Full persistent backend configuration
pipeline = MemoryFactory.create(
episodic_store="redis", # "memory" | "redis" | "sqlite"
working_store="redis", # "memory" | "redis"
hot_cache="redis", # "memory" | "redis"
fact_graph="neo4j", # "memory" | "neo4j"
semantic_store="pgvector", # "memory" | "pgvector" | "chroma"
redis_url="redis://localhost:6379/0",
sqlite_path="memory.db",
neo4j_uri="bolt://localhost:7687",
neo4j_user="neo4j",
neo4j_password="password",
db_url="postgresql://localhost:5432/memory",
)
store_fact / query_memory
# Store a fact with optional metadata
fact = await pipeline.store_fact(
"The capital of France is Paris",
fact_type="knowledge",
importance=0.8,
tags=["geography", "europe"],
namespace="my_agent",
)
print(fact.id, fact.importance, fact.confidence)
# Query by meaning
results = await pipeline.query_memory(
"European capitals",
namespace="my_agent",
top_k=10,
confidence_gte=0.5,
)
for r in results:
print(f"score={r.final_score:.3f} | {r.fact.content}")
add_episode / get_session_context
# Add conversation turns to episodic memory
await pipeline.add_episode("user", "I love functional programming", session_id="sess_42")
await pipeline.add_episode("assistant", "Noted! I'll keep that in mind.", session_id="sess_42")
# Retrieve the session window
episodes = await pipeline.get_session_context("sess_42", last_n=20)
for ep in episodes:
print(f"{ep.role}: {ep.content}")
assemble_context
ctx = await pipeline.assemble_context(
query="user programming preferences",
session_id="sess_42",
namespace="default",
max_tokens=2000,
format="markdown",
)
print(ctx.render())
Working memory
# Set a key for the current task
await pipeline.working.set("current_task", "Refactor auth module", "sess_42")
# Retrieve snapshot
snapshot = await pipeline.working.snapshot("sess_42")
MCP server
from memorymcp.mcp_server import MemoryMCPServer, create_mcp_server
# High-level: run stdio server
MemoryMCPServer(pipeline).run()
# Low-level: get the MCP Server object for custom transports
server = create_mcp_server(pipeline, name="my-agent-memory")
CLI
# Start MCP server (stdio)
memorymcp serve
# Serve with persistent backends
memorymcp serve --episodic sqlite --redis-url redis://localhost:6379/0
# Query memory
memorymcp query "user preferences" --namespace my_agent --top-k 5
# Store a fact
memorymcp store "User prefers dark mode" --importance 0.7
# Show stats
memorymcp stats --namespace my_agent
# Run consolidation cycle
memorymcp consolidate --namespace my_agent
# GDPR โ erase all data for a user namespace
memorymcp forget-user --namespace my_agent
# View / update runtime config
memorymcp config
memorymcp config --set decay_mode=adaptive --set episodic_store=redis
Configuration (YAML)
namespace: my_agent
semantic:
backend: qdrant # qdrant | chroma | inmemory
url: http://localhost:6333
working:
max_entries: 100
ttl_seconds: 3600
episodic:
max_window: 50
decay:
mode: exponential # linear | exponential | anchored | adaptive
half_life_hours: 168 # 1 week default
quotas:
max_facts: 10000
pii:
action: redact # redact | block
Load it with:
pipeline = MemoryFactory.from_yaml("memory_config.yaml")
Memory Tiers
| Tier | Name | Backend | Default TTL | Use case |
|---|---|---|---|---|
| 0 | HotCache | LRU RAM | 5 min | Hot facts, frequent access |
| 1 | Working | InMemory | 1 hour | Current task context |
| 2 | Episodic | InMemory | Session | Conversation history |
| 3 | Semantic | ragmcp | Permanent | Long-term knowledge base |
Facts are promoted to Tier 0 (HotCache) automatically on each retrieval, ensuring the most-accessed facts are served from RAM with zero latency.
Consolidation
When a new fact arrives, the ConsolidationEngine searches for semantically similar existing facts and determines the correct action:
| Action | Condition | Effect |
|---|---|---|
| SKIP | Exact duplicate detected | Fact is ignored; no write |
| UPDATE | Similarity โฅ 0.85 | Adds a supports relation; confirmation count incremented |
| OVERWRITE | Similarity โฅ 0.92 (contradiction) | Old fact archived with valid_until=now; supersedes relation created |
| ADD | New information | Stored directly with no merge |
Nothing is ever hard-deleted by consolidation โ overwritten facts are archived with valid_until set and remain queryable with until= filters.
# Contradiction is handled automatically
await pipeline.store_fact("The meeting is on Monday")
await pipeline.store_fact("The meeting is on Tuesday") # triggers OVERWRITE
Decay Engine
The DecayEngine computes a decay score [0.0, 1.0] for each fact based on time since last update and retrieval frequency. Three decay modes are available, plus an optional adaptive retrieval boost:
| Mode | Behavior | Best for |
|---|---|---|
linear |
Gradual, constant fade | Short-lived task facts |
exponential |
Fast initial decay, stable plateau | General knowledge (default) |
anchored |
No decay; score stays at 1.0 | Critical / pinned facts |
adaptive |
Decay slows with each retrieval | User preferences, confirmed facts |
Facts with importance >= 1.0 are permanently anchored and never decay.
The adaptive multiplier is: 1 / (1 + retrieval_count ร 0.05) โ a fact retrieved 20 times decays twice as slowly.
Fact Extraction
memorymcp ships two extractors that run automatically when episodes are added:
PatternFactExtractor (default, zero dependencies)
Regex-based extraction for common patterns in EN/FR:
"I prefer X"/"je prรฉfรจre X"โ preference"I created X"/"I built X"โ simple"my name is X"โ simple"I work at X"โ simple"I always/never X"โ constraint"I believe/think X"โ belief
LLMFactExtractor (recommended for production)
Uses any LLM to extract structured facts with semantic understanding:
import litellm
async def completion_fn(messages):
resp = await litellm.acompletion(messages=messages, model="gpt-4o-mini")
return resp.choices[0].message.content
pipeline = MemoryFactory.create(extractor="llm", completion_fn=completion_fn)
The LLM extractor handles:
- Natural language:
"im alex, a dev who made ragmcp"โ 3 structured facts - Corrections:
"not memorymcp"(after context) โ"User is not working on memorymcp" - Decay assignment: each fact gets
anchored(name, identity),exponential(preferences), orlinear(today's task) - Relation extraction: auto-detects links between facts (created_by, related_to, describes, etc.)
- Noise filtering: questions,
"ok","thanks","tell me everything"โ skipped, no LLM call
Automatic extraction
When you call pipeline.add_episode(), extraction runs automatically in the background. For synchronous extraction with results:
# Add episode without auto-extraction
await pipeline.add_episode("user", "I'm Kim, 28, from Seoul", session_id="s1", extract=False)
# Extract synchronously โ returns the stored facts
facts = await pipeline.extract_facts(namespace="default", session_id="s1")
for f in facts:
print(f"{f.content} [{f.fact_type}] decay={f.metadata.get('decay_mode', 'exponential')}")
MCP Tools
memorymcp exposes 16 tools via the MCP protocol (stdio transport):
| Tool | Description |
|---|---|
query_memory |
Semantic search across all tiers with decay scoring |
store_fact |
Explicitly store a high-value fact with consolidation |
get_session_context |
Get the episodic window for a session |
add_episode |
Add a conversation turn (user / assistant / system) |
assemble_context |
Assemble memory context ready for prompt injection |
set_working_memory |
Set a key in working memory for the current task |
get_working_memory |
Get current task working memory snapshot |
forget_fact |
Soft-delete a fact from long-term memory |
memory_stats |
Get memory health statistics for a namespace |
memory_config |
View or update runtime memory configuration |
traverse_graph |
Walk the fact graph from a starting fact by relation type |
find_contradictions |
Detect contradicting facts in a namespace |
extract_facts |
Trigger explicit fact extraction from recent episodes |
export_memory |
Export all facts as JSON for backup or migration |
import_memory |
Import facts from JSON with merge/overwrite strategies |
memory_analytics |
Get analytics: type distribution, decay analysis, confidence stats, retrieval patterns |
Event Streaming, Webhooks, Scheduler & Analytics
Event bus
from memorymcp.events import MemoryEventBus, MemoryEventType
bus = MemoryEventBus()
# Subscribe to a namespace โ returns an asyncio.Queue
queue = bus.subscribe("my_agent")
event = await queue.get()
print(f"{event.type}: {event.message}")
# Or stream events asynchronously
async for event in bus.stream("my_agent"):
if event.type == MemoryEventType.fact_stored:
print(f"New fact: {event.message}")
Webhooks
from memorymcp.webhooks import MemoryWebhookManager
webhooks = MemoryWebhookManager()
# Register a webhook โ receives HTTP POST on matching events
webhooks.register(
url="https://example.com/hooks/memory",
events=["fact.stored", "contradiction.detected"],
)
webhooks.start()
# Unregister
webhooks.unregister(url="https://example.com/hooks/memory")
Consolidation scheduler
from memorymcp.scheduler import MemoryScheduler
scheduler = MemoryScheduler(pipeline=pipeline)
# Run consolidation every hour
scheduler.add(task_type="consolidation", cron="0 * * * *", namespace="default")
scheduler.start()
# Stop when done
scheduler.stop()
Memory analytics
from memorymcp.analytics import MemoryAnalytics
analytics = MemoryAnalytics(pipeline)
report = await analytics.namespace_summary(namespace="default")
print(report["fact_types"]) # {"preference": 42, "identity": 15, ...}
print(report["decay"]) # {"total": 65, "avg_decay": 0.72, "at_risk": 8, ...}
print(report["confidence"]) # {"total": 65, "high": 30, "medium": 20, "low": 5}
print(report["top_retrieved"]) # [{"id": ..., "content": ..., "retrieval_count": 12}, ...]
Import/Export roundtrip
# Export all facts
data = await pipeline.export(namespace="default")
# Import into another pipeline (or restore from backup)
await pipeline.import_memory(data, strategy="merge") # merge | overwrite
Integration with ragmcp
memorymcp uses ragmcp as its Tier 3 semantic backend. Any RAGPipeline from ragmcp can be injected directly:
from ragmcp.vectorstores import QdrantVectorStore
from ragmcp.embedders import FastEmbedEmbedder
from ragmcp.pipeline import RAGPipeline
from ragmcp.chunkers import RecursiveChunker
from memorymcp import MemoryFactory
rag = RAGPipeline(
embedder=FastEmbedEmbedder(),
vectorstore=QdrantVectorStore(url="http://localhost:6333"),
chunker=RecursiveChunker(chunk_size=256, overlap=32),
)
pipeline = MemoryFactory.from_ragmcp(rag)
Without ragmcp installed, memorymcp falls back to FallbackSemanticStore โ a keyword-based in-memory store that requires no external services.
Development / Contributing
git clone https://github.com/gashel01/memorymcp
cd memorymcp
pip install -e ".[dev]"
# Unit tests โ no external services needed
pytest tests/unit/ -v
# Full test suite
pytest tests/ -v # 303 tests
# With coverage
pytest tests/unit/ --cov=memorymcp --cov-report=html
Project structure:
memorymcp/
core/ โ Base classes and Pydantic models
working/ โ Tier 1: Working memory store
redis_store.py โ Redis working memory backend
episodic/ โ Tier 2: Episodic store
sqlite_store.py โ SQLite episodic backend
redis_store.py โ Redis episodic backend
semantic/ โ Tier 3: Semantic store (ragmcp wrapper)
pgvector_store.py โ pgvector semantic backend
hot_cache/ โ Tier 0: LRU RAM cache
_redis.py โ Redis hot cache backend
consolidation/ โ Consolidation engine
decay/ โ Decay engine
graph/ โ Fact graph (typed relations)
neo4j_graph.py โ Neo4j graph backend
extraction/ โ Pattern + LLM fact extractors
importance/ โ Heuristic importance scorer
confidence/ โ Confidence tracker
context/ โ Context assembler
events.py โ Event bus (14 event types, subscribe/emit/stream)
webhooks.py โ Webhook manager (HTTP POST on events)
scheduler.py โ Consolidation scheduler (cron support)
analytics.py โ Memory analytics (type distribution, decay, confidence, retrieval)
mcp_server.py โ MCP server (16 tools)
factory.py โ MemoryFactory
pipeline.py โ MemoryPipeline (main entry point)
Contributions are welcome. Please open an issue before submitting a large PR.
License
AGPL-3.0 โ see LICENSE.
Open source for individuals and open-source projects. For commercial use in closed-source products, a commercial license is available โ contact gaeldev@gmail.com.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcpaisuite_memorymcp-1.0.3.tar.gz.
File metadata
- Download URL: mcpaisuite_memorymcp-1.0.3.tar.gz
- Upload date:
- Size: 126.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1372088c4cdf3522945f7942ffc38a19a0c7fa0ca0ecb5cc1525c15a3e7217dd
|
|
| MD5 |
651663e7c34c8035a4c00ba6876e5943
|
|
| BLAKE2b-256 |
5dd9bb59bbee2ee45a591710bfbf75f090a5a789a3e6f5122019236cc18a5d69
|
Provenance
The following attestation bundles were made for mcpaisuite_memorymcp-1.0.3.tar.gz:
Publisher:
release.yml on gashel01/memorymcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcpaisuite_memorymcp-1.0.3.tar.gz -
Subject digest:
1372088c4cdf3522945f7942ffc38a19a0c7fa0ca0ecb5cc1525c15a3e7217dd - Sigstore transparency entry: 1841011902
- Sigstore integration time:
-
Permalink:
gashel01/memorymcp@98ff22010dc9b24ed368db6b8119a8ef6bbfa0d3 -
Branch / Tag:
refs/tags/v1.0.3 - Owner: https://github.com/gashel01
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@98ff22010dc9b24ed368db6b8119a8ef6bbfa0d3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mcpaisuite_memorymcp-1.0.3-py3-none-any.whl.
File metadata
- Download URL: mcpaisuite_memorymcp-1.0.3-py3-none-any.whl
- Upload date:
- Size: 99.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64189b6ffda49ba679362e875b12ffe952e4af0d9d3d031b6275136aa3796b45
|
|
| MD5 |
74f44831b5c696d0bbe778a791cc533e
|
|
| BLAKE2b-256 |
dee89413cd2d99210331873c9578ce4381f4dce175eb2c2c0272e70e2bba3619
|
Provenance
The following attestation bundles were made for mcpaisuite_memorymcp-1.0.3-py3-none-any.whl:
Publisher:
release.yml on gashel01/memorymcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcpaisuite_memorymcp-1.0.3-py3-none-any.whl -
Subject digest:
64189b6ffda49ba679362e875b12ffe952e4af0d9d3d031b6275136aa3796b45 - Sigstore transparency entry: 1841011969
- Sigstore integration time:
-
Permalink:
gashel01/memorymcp@98ff22010dc9b24ed368db6b8119a8ef6bbfa0d3 -
Branch / Tag:
refs/tags/v1.0.3 - Owner: https://github.com/gashel01
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@98ff22010dc9b24ed368db6b8119a8ef6bbfa0d3 -
Trigger Event:
push
-
Statement type: